From: Vitaly Prosyak <[email protected]>

cancel_delayed_work_sync() waits for any running work instance to finish.
hang_detect_work takes userq_mutex during its run, so calling
cancel_delayed_work_sync() inside userq_mutex in amdgpu_userq_destroy()
risks deadlock:

  amdgpu_userq_destroy holds userq_mutex
  -> cancel_delayed_work_sync -> __flush_work (waits for work)
  -> hang_detect_work (running) tries to acquire userq_mutex
  -> DEADLOCK

  WARNING: possible circular locking dependency detected
  amd_basic/3761 is trying to acquire lock:
    (work_completion)(&(&queue->hang_detect_work)->work), at: __flush_work
  but task is already holding lock:
    (&userq_mgr->userq_mutex), at: amdgpu_userq_destroy+0x76/0x3e0 [amdgpu]

Move the cancel before mutex_lock() to eliminate this dependency.

Cc: Christian Koenig <[email protected]>
Cc: Alex Deucher <[email protected]>
Cc: Sunil Khatri <[email protected]>
Signed-off-by: Vitaly Prosyak <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 0a816b3c5ff9..52cd7d1c9f2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -543,12 +543,15 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, 
struct amdgpu_usermode_que
        trace_amdgpu_userq_destroy_start(queue);
 
        cancel_delayed_work_sync(&uq_mgr->resume_work);
+       /* Cancel before taking userq_mutex: cancel_delayed_work_sync() waits
+        * for any running instance, which itself takes userq_mutex.
+        */
+       cancel_delayed_work_sync(&queue->hang_detect_work);
 
        mutex_lock(&uq_mgr->userq_mutex);
        amdgpu_userq_wait_for_last_fence(queue);
 
        amdgpu_userq_detach_doorbell(queue);
-       cancel_delayed_work_sync(&queue->hang_detect_work);
 
 #if defined(CONFIG_DEBUG_FS)
        debugfs_remove_recursive(queue->debugfs_queue);
-- 
2.54.0

Reply via email to