KCQ and user queues never share a HW slot, so a KQ ring_id hit is
authoritative. Match KQ first; only call into the userq path when
no KQ owns the faulting slot.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 7c269cb75e07..e32dfc654ee7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -5016,10 +5016,11 @@ static void gfx_v12_0_handle_priv_fault(struct 
amdgpu_device *adev,
         */
        u32 doorbell_offset = entry->src_data[0] & 0x3ff;
 
-       if (adev->enable_mes && doorbell_offset) {
-               amdgpu_userq_process_reset_irq(adev, entry->pasid,
-                                              doorbell_offset);
-       } else if (!adev->gfx.disable_kq) {
+       /*
+        * Try KQ first by ring_id; UQ as fallback. KCQ and UQ never share
+        * a HW slot (compute_hqd_mask contract).
+        */
+       if (!adev->gfx.disable_kq) {
                u8 me_id, pipe_id, queue_id;
                struct amdgpu_ring *ring;
                int i;
@@ -5033,8 +5034,10 @@ static void gfx_v12_0_handle_priv_fault(struct 
amdgpu_device *adev,
                        for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
                                ring = &adev->gfx.gfx_ring[i];
                                if (ring->me == me_id && ring->pipe == pipe_id 
&&
-                                   ring->queue == queue_id)
+                                   ring->queue == queue_id) {
                                        drm_sched_fault(&ring->sched);
+                                       return;
+                               }
                        }
                        break;
                case 1:
@@ -5042,8 +5045,10 @@ static void gfx_v12_0_handle_priv_fault(struct 
amdgpu_device *adev,
                        for (i = 0; i < adev->gfx.num_compute_rings; i++) {
                                ring = &adev->gfx.compute_ring[i];
                                if (ring->me == me_id && ring->pipe == pipe_id 
&&
-                                   ring->queue == queue_id)
+                                   ring->queue == queue_id) {
                                        drm_sched_fault(&ring->sched);
+                                       return;
+                               }
                        }
                        break;
                default:
@@ -5051,6 +5056,11 @@ static void gfx_v12_0_handle_priv_fault(struct 
amdgpu_device *adev,
                        break;
                }
        }
+
+       /* No KQ matched: HW slot is a MES-scheduled user queue. */
+       if (adev->enable_mes && doorbell_offset)
+               amdgpu_userq_process_reset_irq(adev, entry->pasid,
+                                              doorbell_offset);
 }
 
 static int gfx_v12_0_priv_reg_irq(struct amdgpu_device *adev,
-- 
2.49.0

Reply via email to