From 5f37a6be83c7dd38cc2dc1513c05cdf1c2f951af Mon Sep 17 00:00:00 2001
From: psucien <bad_cast@protonmail.com>
Date: Wed, 29 May 2024 16:03:37 +0200
Subject: [PATCH] video_core: amdgpu: fix for a deadlock in wait on idle

---
 src/video_core/amdgpu/liverpool.cpp | 29 +++++++++++------------------
 src/video_core/amdgpu/liverpool.h   |  3 ---
 2 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp
index ae5bd4bc..163c1e31 100644
--- a/src/video_core/amdgpu/liverpool.cpp
+++ b/src/video_core/amdgpu/liverpool.cpp
@@ -18,7 +18,8 @@ Liverpool::Liverpool() {
 
 Liverpool::~Liverpool() {
     process_thread.request_stop();
-    cv_submit.notify_one();
+    num_submits = -1;
+    num_submits.notify_one();
     process_thread.join();
 }
 
@@ -26,10 +27,7 @@ void Liverpool::Process(std::stop_token stoken) {
     Common::SetCurrentThreadName("GPU_CommandProcessor");
 
     while (!stoken.stop_requested()) {
-        {
-            std::unique_lock lock{m_submit};
-            cv_submit.wait(lock, stoken, [this]() { return num_submits != 0; });
-        }
+        num_submits.wait(0);
 
         if (stoken.stop_requested()) {
             break;
@@ -63,13 +61,14 @@ void Liverpool::Process(std::stop_token stoken) {
                 --num_submits;
             }
         }
-        cv_complete.notify_all(); // Notify GPU idle
+        num_submits.notify_all();
     }
 }
 
 void Liverpool::WaitGpuIdle() {
-    std::unique_lock lock{m_submit};
-    cv_complete.wait(lock, [this]() { return num_submits == 0; });
+    while (const auto old = num_submits.load()) {
+        num_submits.wait(old);
+    }
 }
 
 Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
@@ -309,11 +308,8 @@ void Liverpool::SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb) {
         queue.submits.emplace(task.handle);
     }
 
-    {
-        std::unique_lock lock{m_submit};
-        ++num_submits;
-    }
-    cv_submit.notify_one();
+    ++num_submits;
+    num_submits.notify_one();
 }
 
 void Liverpool::SubmitAsc(u32 vqid, std::span<const u32> acb) {
@@ -326,11 +322,8 @@ void Liverpool::SubmitAsc(u32 vqid, std::span<const u32> acb) {
         queue.submits.emplace(task.handle);
     }
 
-    {
-        std::unique_lock lock{m_submit};
-        ++num_submits;
-    }
-    cv_submit.notify_one();
+    ++num_submits;
+    num_submits.notify_one();
 }
 
 } // namespace AmdGpu
diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h
index 1ddf4fc9..ed9899f8 100644
--- a/src/video_core/amdgpu/liverpool.h
+++ b/src/video_core/amdgpu/liverpool.h
@@ -771,9 +771,6 @@ private:
 
     Vulkan::Rasterizer* rasterizer{};
     std::jthread process_thread{};
-    std::condition_variable_any cv_submit{};
-    std::condition_variable cv_complete{};
-    std::mutex m_submit{};
     std::atomic<u32> num_submits{};
 };