From: Vitaly Prosyak <[email protected]>
During GPU reset, reset_domain->sem is held exclusively (down_write)
for the entire reset sequence, which prevents any concurrent firmware
operations - they all require down_read of reset_sem before running.
However psp_resume() unconditionally takes firmware.mutex, which
inverts the lock ordering that lockdep has learned from the init path:
firmware.mutex -> reservation_ww_class_mutex
-> userq_mutex -> reset_domain->sem
Lockdep reports a circular dependency when psp_resume() tries to
acquire firmware.mutex while reset_domain->sem is already held
(via amdgpu_device_lock_reset_domain).
Since down_write(reset_domain->sem) already provides the necessary
mutual exclusion against concurrent firmware operations during reset,
skip firmware.mutex when called from a GPU reset context.
Signed-off-by: Vitaly Prosyak <[email protected]>
Change-Id: Ie4c3093269d473b9859b36f67c832ad8143627cc
---
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index a0f6df5067e6..da344a21063c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -3954,7 +3954,12 @@ static int psp_resume(struct amdgpu_ip_block *ip_block)
}
}
- mutex_lock(&adev->firmware.mutex);
+ /* reset_domain->sem is held exclusively during GPU reset, so no
+ * concurrent firmware operations can run; skip firmware.mutex to
+ * avoid inverting the firmware.mutex -> reset_domain->sem ordering.
+ */
+ if (!amdgpu_in_reset(adev))
+ mutex_lock(&adev->firmware.mutex);
ret = amdgpu_ucode_init_bo(adev);
if (ret)
@@ -4017,13 +4022,15 @@ static int psp_resume(struct amdgpu_ip_block *ip_block)
"SECUREDISPLAY: Failed to initialize
SECUREDISPLAY\n");
}
- mutex_unlock(&adev->firmware.mutex);
+ if (!amdgpu_in_reset(adev))
+ mutex_unlock(&adev->firmware.mutex);
return 0;
failed:
dev_err(adev->dev, "PSP resume failed\n");
- mutex_unlock(&adev->firmware.mutex);
+ if (!amdgpu_in_reset(adev))
+ mutex_unlock(&adev->firmware.mutex);
return ret;
}
--
2.43.0