amdgpu_mes_userq_notify_unmap_work_handler() submits a MES misc op
without holding reset_domain->sem, so it can ring the MES doorbell while
the GPU is being reset:
WARNING: amdgpu_device.c:928 at amdgpu_device_skip_hw_access+0x73/0x90
[amdgpu]
Workqueue: events amdgpu_mes_userq_notify_unmap_work_handler [amdgpu]
Call Trace:
amdgpu_mm_wdoorbell64+0x20/0x70 [amdgpu]
mes_v11_0_ring_set_wptr+0x71/0x80 [amdgpu]
amdgpu_ring_commit+0x5b/0xa0 [amdgpu]
mes_v11_0_submit_pkt_and_poll_completion.constprop.0+0x207/0x520 [amdgpu]
mes_v11_0_misc_op+0x8b/0x240 [amdgpu]
amdgpu_mes_notify_unmap_queue+0xa3/0x110 [amdgpu]
amdgpu_mes_userq_notify_unmap_work_handler+0x24/0x70 [amdgpu]
Only send the notification when reset_domain->sem can be trylocked. The
work re-arms itself while the HW queues are oversubscribed, so the
notification is retried once the reset has finished.
Fixes: a3e112968588 ("drm/amdgpu/userq: create the same workaround of
oversubscription timer")
Signed-off-by: Prike Liang <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 4cb37cdbf821..09009925611a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1192,7 +1192,11 @@ static void
amdgpu_mes_userq_notify_unmap_work_handler(struct work_struct *work)
userq_notify_unmap_work.work);
struct amdgpu_device *adev = mes->adev;
- amdgpu_mes_notify_unmap_queue(adev);
+ /* MES is unusable during GPU recovery; the re-arm below retries later
*/
+ if (down_read_trylock(&adev->reset_domain->sem)) {
+ amdgpu_mes_notify_unmap_queue(adev);
+ up_read(&adev->reset_domain->sem);
+ }
/* Re-arm if still oversubscribed */
if (atomic_read(&mes->userq_hw_queue_count) >
--
2.34.1