Suspend MES gangs before attempting to remove user queues, and resume them in the same function. Skip the operation when there are no user queues. Suspend, removal and resume are best effort while preparing hardware reset; a firmware error must not prevent that reset or be treated as proof that DMA has stopped. Queue and process fences remain pending until hardware reset succeeds.
Signed-off-by: Prike Liang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 2eba234a504e..e6ce9d12bdb4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -1607,6 +1607,12 @@ void amdgpu_userq_pre_reset(struct amdgpu_device *adev) unsigned long queue_id; lockdep_assert_held_write(&adev->reset_domain->sem); + if (xa_empty(&adev->userq_doorbell_xa)) + return; + + /* Best effort: only the subsequent hardware reset proves quiescence. */ + if (amdgpu_mes_suspend(adev, 0)) + dev_dbg(adev->dev, "Continuing GPU reset after MES suspend failure\n"); xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) { if (queue->state == AMDGPU_USERQ_STATE_MAPPED || @@ -1619,6 +1625,10 @@ void amdgpu_userq_pre_reset(struct amdgpu_device *adev) trace_amdgpu_userq_state_changed(queue, AMDGPU_USERQ_STATE_RESET_PENDING); queue->state = AMDGPU_USERQ_STATE_RESET_PENDING; } + + /* Pair locally, including partial suspension and failed queue removal. */ + if (amdgpu_mes_resume(adev, 0)) + dev_dbg(adev->dev, "Continuing GPU reset after MES resume failure\n"); } /* Called after successful hardware reset, before allocations during resume. */ -- 2.34.1
