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

Reply via email to