drm/amdgpu: cancel hang_detect_work before taking userq_mutex

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 <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Sunil Khatri <sunil.khatri@amd.com>
Cc: Prike Liang <prike.liang@amd.com>
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Vitaly Prosyak 2026-08-24 17:44:24 -04:00 • committed by Alex Deucher
commit 38f4fe785b