The MES query_status hang detection needs a live CP and so cannot find a CP-frozen gfx user queue. The MES firmware has a CP_CNTX_STAT fallback (find_hung_queue_by_cp_ctx_stat) that locates a hung gfx queue from its pipe/hqd slot without query_status, but the driver never fed it the slot.
Extend mes_detect_and_reset_queue_input and amdgpu_mes_detect_and_reset_hung_queues() with a connected pipe/queue hint (pipe 0 -> connected_queue_index, pipe 1 -> _p1); callers that do not know the slot pass -1 to keep the existing behaviour. Signed-off-by: Jesse Zhang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 19 +++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 9 ++++++++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 9d3b40c385c9..f5ae16f7b4ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -2299,7 +2299,8 @@ int amdgpu_gfx_reset_mes_compute(struct amdgpu_device *adev, */ goto fence_reset; r = amdgpu_mes_detect_and_reset_hung_queues(adev, AMDGPU_RING_TYPE_COMPUTE, - true, &num_hung, adev->gfx.mec.mes_hung_db_array, 0); + true, &num_hung, adev->gfx.mec.mes_hung_db_array, 0, + -1, 0); if (r) goto out; if (hung_queue_count) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 1e3a23c81552..40e966a0d676 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -513,9 +513,11 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev, bool detect_only, unsigned int *hung_db_num, u32 *hung_db_array, - uint32_t xcc_id) + uint32_t xcc_id, + int connected_pipe, + int connected_queue_index) { - struct mes_detect_and_reset_queue_input input; + struct mes_detect_and_reset_queue_input input = {0}; u32 *db_array = adev->mes.hung_queue_db_array_cpu_addr[xcc_id]; int hqd_info_offset = adev->mes.hung_queue_hqd_info_offset, r, i; @@ -534,6 +536,19 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev, input.detect_only = detect_only; input.xcc_id = xcc_id; + /* + * For a CP-frozen gfx queue the MES query_status hang detection can't + * see it; hand the MES the exact pipe/queue slot so its CP_CNTX_STAT + * fallback can find and reset it. + */ + if (connected_pipe == 0) { + input.use_connected_queue_index = true; + input.connected_queue_index = connected_queue_index; + } else if (connected_pipe == 1) { + input.use_connected_queue_index_p1 = true; + input.connected_queue_index_p1 = connected_queue_index; + } + r = adev->mes.funcs->detect_and_reset_hung_queues(&adev->mes, &input); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index c67db2d6e122..a5d0e649d113 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -350,6 +350,11 @@ struct mes_detect_and_reset_queue_input { u32 queue_type; bool detect_only; u32 xcc_id; + /* gfx-only: locate a CP-frozen queue the MES query_status path can't see */ + bool use_connected_queue_index; + bool use_connected_queue_index_p1; + u32 connected_queue_index; + u32 connected_queue_index_p1; }; struct mes_inv_tlbs_pasid_input { @@ -544,7 +549,9 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev, bool detect_only, unsigned int *hung_db_num, u32 *hung_db_array, - uint32_t xcc_id); + uint32_t xcc_id, + int connected_pipe, + int connected_queue_index); uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id); -- 2.49.0
