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

Reply via email to