From: Vitaly Prosyak <[email protected]>
halt_activities() calls drm_client_dev_suspend() which takes
clientlist_mutex. The userq restore path establishes the ordering:
clientlist_mutex -> userq_mutex -> reset_domain->sem
Taking reset_domain->sem before halt_activities() inverts
clientlist_mutex -> reset_domain->sem and triggers:
WARNING: possible circular locking dependency detected
kworker/u128:0 is trying to acquire lock:
(&dev->clientlist_mutex), at: drm_client_dev_suspend+0x2d/0xf0
but task is already holding lock:
(&reset_domain->sem), at: amdgpu_device_lock_reset_domain+0x1c/0x30 [amdgpu]
Chain exists of:
&dev->clientlist_mutex --> &userq_mgr->userq_mutex --> &reset_domain->sem
Move amdgpu_device_recovery_get_reset_lock() to after halt_activities().
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_device.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d7640da9f6de..c248d589f755 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5786,19 +5786,23 @@ int amdgpu_device_gpu_recover(struct amdgpu_device
*adev,
/* Cannot be called after locking reset domain */
amdgpu_ras_pre_reset(adev, &device_list);
- /* We need to lock reset domain only once both for XGMI and single
device */
- amdgpu_device_recovery_get_reset_lock(adev, &device_list);
-
/* unmap all the mappings of doorbell and framebuffer to prevent user
space from
* accessing them
*/
unmap_mapping_range(adev->ddev.anon_inode->i_mapping, 0, 0, 1);
amdgpu_amdkfd_clear_kfd_mapping(adev);
+ /* Halt activities before taking reset lock to avoid circular
dependency:
+ * halt_activities -> drm_client_dev_suspend -> dc_lock, while display
+ * IRQ path holds dc_lock and tries to acquire reset_domain->sem.
+ */
amdgpu_device_halt_activities(adev, job, reset_context, &device_list,
hive, need_emergency_restart);
if (need_emergency_restart)
goto skip_sched_resume;
+
+ /* Take reset lock after halt_activities to avoid AB-BA deadlock */
+ amdgpu_device_recovery_get_reset_lock(adev, &device_list);
/*
* Must check guilty signal here since after this point all old
* HW fences are force signaled.
--
2.54.0