On 07-Jul-26 1:35 AM, Alex Deucher wrote:
If gfx is hung, we shouldn't need this since gfx won't be
powered down, but we could potentially have a case where
a queue can be preempted, but due logic errors in the commands,
the fence never signals. GFX could potentially go into
the off state. Protect against that.
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Alex Deucher <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 34 +++++++++++++++++---------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index f03cbf358cd7b..516a621d11faa 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -9528,6 +9528,7 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring,
return -ENOMEM;
}
+ amdgpu_gfx_off_ctrl(adev, false);
Can this be moved to helper begin/end logic - check against
sdma/compute/gfx rings? It doesn't harm to include sdma even for SOCs
where it's outside of GFX domain.
Thanks,
Lijo
addr = amdgpu_bo_gpu_offset(ring->mqd_obj) +
offsetof(struct v10_gfx_mqd, cp_gfx_hqd_active);
tmp = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
@@ -9547,28 +9548,33 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring,
r = amdgpu_ring_test_ring(kiq_ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
if (r)
- return r;
+ goto fail;
r = gfx_v10_0_kgq_init_queue(ring, true);
if (r) {
DRM_ERROR("fail to init kgq\n");
- return r;
+ goto fail;
}
spin_lock_irqsave(&kiq->ring_lock, flags);
if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size)) {
spin_unlock_irqrestore(&kiq->ring_lock, flags);
- return -ENOMEM;
+ r = -ENOMEM;
+ goto fail;
}
kiq->pmf->kiq_map_queues(kiq_ring, ring);
amdgpu_ring_commit(kiq_ring);
r = amdgpu_ring_test_ring(kiq_ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
if (r)
- return r;
+ goto fail;
- return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+ r = amdgpu_ring_reset_helper_end(ring, timedout_fence);
+
+fail:
+ amdgpu_gfx_off_ctrl(adev, true);
+ return r;
}
static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
@@ -9593,13 +9599,14 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
return -ENOMEM;
}
+ amdgpu_gfx_off_ctrl(adev, false);
kiq->pmf->kiq_unmap_queues(kiq_ring, ring, RESET_QUEUES,
0, 0);
amdgpu_ring_commit(kiq_ring);
r = amdgpu_ring_test_ring(kiq_ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
if (r)
- return r;
+ goto fail;
/* make sure dequeue is complete*/
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
@@ -9617,28 +9624,33 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
if (r) {
dev_err(adev->dev, "fail to wait on hqd deactivate\n");
- return r;
+ goto fail;
}
r = gfx_v10_0_kcq_init_queue(ring, true);
if (r) {
dev_err(adev->dev, "fail to init kcq\n");
- return r;
+ goto fail;
}
spin_lock_irqsave(&kiq->ring_lock, flags);
if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size)) {
spin_unlock_irqrestore(&kiq->ring_lock, flags);
- return -ENOMEM;
+ r = -ENOMEM;
+ goto fail;
}
kiq->pmf->kiq_map_queues(kiq_ring, ring);
amdgpu_ring_commit(kiq_ring);
r = amdgpu_ring_test_ring(kiq_ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
if (r)
- return r;
+ goto fail;
+
+ r = amdgpu_ring_reset_helper_end(ring, timedout_fence);
- return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+fail:
+ amdgpu_gfx_off_ctrl(adev, true);
+ return r;
}
static void gfx_v10_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)