KCQ EOPs were misrouted into the userq fence path when enable_mes
is true. Try KQ by ring_id first (KCQ and UQ never share a HW
slot); fall back to amdgpu_userq_process_fence_irq() on miss.

Suggested-by: Alex Deucher <[email protected]>
Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 30 ++++++++++++++++----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index d9b1fc29e9d8..c5fbfc6d8338 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -4843,31 +4843,32 @@ static int gfx_v12_0_eop_irq(struct amdgpu_device *adev,
                             struct amdgpu_iv_entry *entry)
 {
        u32 doorbell_offset = entry->src_data[0];
-       u8 me_id, pipe_id, queue_id;
-       struct amdgpu_ring *ring;
-       int i;
 
        DRM_DEBUG("IH: CP EOP\n");
 
-       if (adev->enable_mes && doorbell_offset) {
-               amdgpu_userq_process_fence_irq(adev, doorbell_offset);
-       } else {
-               me_id = (entry->ring_id & 0x0c) >> 2;
-               pipe_id = (entry->ring_id & 0x03) >> 0;
-               queue_id = (entry->ring_id & 0x70) >> 4;
+       if (!adev->gfx.disable_kq) {
+               u8 me_id = (entry->ring_id & 0x0c) >> 2;
+               u8 pipe_id = (entry->ring_id & 0x03) >> 0;
+               u8 queue_id = (entry->ring_id & 0x70) >> 4;
+               struct amdgpu_ring *ring;
+               int i;
 
                switch (me_id) {
                case 0:
                        /*
                         * MES splits gfx HQDs per (me,pipe): KGQ owns queue=0,
                         * userq gfx owns queue>=1 (see 
amdgpu_mes_get_hqd_mask).
+                        * Require a strict (me,pipe,queue) match so userq gfx
+                        * EOPs fall through to 
amdgpu_userq_process_fence_irq().
                         */
                        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)) {
                                        amdgpu_fence_process(ring);
+                                       return 0;
+                               }
                        }
                        break;
                case 1:
@@ -4880,13 +4881,20 @@ static int gfx_v12_0_eop_irq(struct amdgpu_device *adev,
                                 */
                                if ((ring->me == me_id) &&
                                    (ring->pipe == pipe_id) &&
-                                   (ring->queue == queue_id))
+                                   (ring->queue == queue_id)) {
                                        amdgpu_fence_process(ring);
+                                       return 0;
+                               }
                        }
                        break;
+               default:
+                       break;
                }
        }
 
+       if (adev->enable_mes && doorbell_offset)
+               amdgpu_userq_process_fence_irq(adev, doorbell_offset);
+
        return 0;
 }
 
-- 
2.49.0

Reply via email to