Destroying a hung user queue issues a MES REMOVE_QUEUE that times out,
The destroy path only logged the error and freed the queue, so the
next userq submission failed and forced a GPU reset attributed to an innocent 
workload.

Kick the userq reset work when unmap fails so the GPU is recovered at
destroy time.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index fb7e18c841ee..aa5cc5642e87 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -542,6 +542,15 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, 
struct amdgpu_usermode_que
        amdgpu_userq_cleanup(queue);
        mutex_unlock(&uq_mgr->userq_mutex);
 
+       /*
+        * A failed unmap means MES could not remove the hung queue and is now
+        * unresponsive.  Recover the GPU here so the wedged MES does not fail
+        * the next, unrelated queue submission and trigger a reset attributed
+        * to an innocent workload.
+        */
+       if (r)
+               queue_work(adev->reset_domain->wq, &uq_mgr->reset_work);
+
        cancel_delayed_work_sync(&queue->hang_detect_work);
        uq_funcs->mqd_destroy(queue);
        queue->userq_mgr = NULL;
-- 
2.49.0

Reply via email to