On Tue, Jul 7, 2026 at 8:04 AM Lazar, Lijo <[email protected]> wrote:
>
>
>
> 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.
If something in the reset path fails, the end helper doesn't get run
so the ref count will be off. It could potentially be moved to the
job_timedout() and kfd queue reset paths however.
Alex
>
> 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)
>