drm/amdgpu/gfx11: fix EOP interrupt routing for KQ and userq

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

Require a strict (me,pipe,queue) match in the gfx case, then userq gfx
EOPs fall through to amdgpu_userq_process_fence_irq().

Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 88e589cc811ba907209a426c426c469bcb4bb894)
Cc: stable@vger.kernel.org
This commit is contained in:
Jesse Zhang 2026-06-11 10:14:32 +08:00 committed by Alex Deucher
parent 426ffae6ec
commit 0a3d354603

View File

@ -6507,25 +6507,33 @@ static int gfx_v11_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:
if (pipe_id == 0)
amdgpu_fence_process(&adev->gfx.gfx_ring[0]);
else
amdgpu_fence_process(&adev->gfx.gfx_ring[1]);
/*
* 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)) {
amdgpu_fence_process(ring);
return 0;
}
}
break;
case 1:
case 2:
@ -6537,13 +6545,20 @@ static int gfx_v11_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;
}