[PATCH 3/5] drm/amdgpu: take reset lock after halt_activities

<[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.