On Tue, Sep 1, 2026 at 5:00 AM Timur Kristóf <[email protected]> wrote:
>
> Remove the caller_handles_kernel_queues argument from
> the amdgpu_sdma_reset_engine() function and make it
> always handle kernel queues.
>
> Now the SDMA recovery sequence is more consistent
> between callers for the KFD as follows.
> Before recovery: first the KFD is suspended,
> then the SDMA queue contents are backed up.
> After recovery: first the SDMA queue contents
> are restored, then the KFD is resumed.
>
> Signed-off-by: Timur Kristóf <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      | 68 ++++++++++---------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |  3 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c      |  2 +-
>  .../drm/amd/amdkfd/kfd_device_queue_manager.c |  2 +-
>  4 files changed, 38 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
> index 9eebd8380834..e586df5f97bc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
> @@ -542,16 +542,14 @@ static int amdgpu_sdma_soft_reset(struct amdgpu_device 
> *adev, u32 instance_id)
>  }
>
>  /**
> - * amdgpu_sdma_reset_engine - Reset a specific SDMA engine
> + * amdgpu_sdma_reset_engine() - Reset a specific SDMA engine instance.
> + *
>   * @adev: Pointer to the AMDGPU device
>   * @instance_id: Logical ID of the SDMA engine instance to reset
> - * @caller_handles_kernel_queues: Skip kernel queue processing. Caller
> - * will handle it.
>   *
>   * Returns: 0 on success, or a negative error code on failure.
>   */
> -int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t 
> instance_id,
> -                            bool caller_handles_kernel_queues)
> +int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t 
> instance_id)
>  {
>         struct amdgpu_sdma_instance *sdma_instance = 
> &adev->sdma.instance[instance_id];
>         struct amdgpu_ring *gfx_ring = &sdma_instance->ring;
> @@ -564,20 +562,23 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device 
> *adev, uint32_t instance_id,
>
>         mutex_lock(&sdma_instance->engine_reset_mutex);
>
> -       if (!caller_handles_kernel_queues) {
> -               /* Stop the scheduler's work queue for the GFX and page rings 
> if they are running.
> -                * This ensures that no new tasks are submitted to the queues 
> while
> -                * the reset is in progress.
> -                */
> +       /*
> +        * Stop the scheduler's work queue for the GFX and page rings if they 
> are running.
> +        * This ensures that no new tasks are submitted to the queues while
> +        * the reset is in progress.
> +        */
> +       if (amdgpu_ring_sched_ready(gfx_ring) && 
> !drm_sched_is_stopped(&gfx_ring->sched))
>                 drm_sched_wqueue_stop(&gfx_ring->sched);
> -               gfx_fence = amdgpu_ring_find_guilty_fence(gfx_ring);
> -               amdgpu_ring_reset_helper_begin(gfx_ring, gfx_fence);
>
> -               if (adev->sdma.has_page_queue) {
> +       gfx_fence = amdgpu_ring_find_guilty_fence(gfx_ring);
> +       amdgpu_ring_reset_helper_begin(gfx_ring, gfx_fence);
> +
> +       if (adev->sdma.has_page_queue) {
> +               if (amdgpu_ring_sched_ready(gfx_ring) && 
> !drm_sched_is_stopped(&gfx_ring->sched))

These should use page_ring.  Other than that, it looks good to me.

Alex

>                         drm_sched_wqueue_stop(&page_ring->sched);
> -                       page_fence = amdgpu_ring_find_guilty_fence(page_ring);
> -                       amdgpu_ring_reset_helper_begin(page_ring, page_fence);
> -               }
> +
> +               page_fence = amdgpu_ring_find_guilty_fence(page_ring);
> +               amdgpu_ring_reset_helper_begin(page_ring, page_fence);
>         }
>
>         if (sdma_instance->funcs->stop_kernel_queue) {
> @@ -612,22 +613,25 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device 
> *adev, uint32_t instance_id,
>         }
>
>  exit:
> -       if (!caller_handles_kernel_queues) {
> -               /* Restart the scheduler's work queue for the GFX and page 
> rings
> -                * if they were stopped by this function. This allows new 
> tasks
> -                * to be submitted to the queues after the reset is complete.
> -                */
> -               if (!ret) {
> -                       ret = amdgpu_ring_reset_helper_end(gfx_ring, 
> gfx_fence);
> +       /* Restart the scheduler's work queue for the GFX and page rings
> +        * if they were stopped by this function. This allows new tasks
> +        * to be submitted to the queues after the reset is complete.
> +        */
> +       if (!ret) {
> +               ret = amdgpu_ring_reset_helper_end(gfx_ring, gfx_fence);
> +               if (ret)
> +                       goto unlock;
> +
> +               if (amdgpu_ring_sched_ready(gfx_ring))
> +                       drm_sched_wqueue_start(&gfx_ring->sched);
> +
> +               if (adev->sdma.has_page_queue) {
> +                       ret = amdgpu_ring_reset_helper_end(page_ring, 
> page_fence);
>                         if (ret)
>                                 goto unlock;
> -                       drm_sched_wqueue_start(&gfx_ring->sched);
> -                       if (adev->sdma.has_page_queue) {
> -                               ret = amdgpu_ring_reset_helper_end(page_ring, 
> page_fence);
> -                               if (ret)
> -                                       goto unlock;
> +
> +                       if (amdgpu_ring_sched_ready(page_ring))
>                                 drm_sched_wqueue_start(&page_ring->sched);
> -                       }
>                 }
>         }
>  unlock:
> @@ -662,13 +666,11 @@ int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring 
> *ring,
>                 return -EINVAL;
>         }
>
> -       amdgpu_ring_reset_helper_begin(ring, timedout_fence);
> -
>         amdgpu_amdkfd_suspend(adev, true);
> -       r = amdgpu_sdma_reset_engine(adev, ring->me, true);
> +       r = amdgpu_sdma_reset_engine(adev, ring->me);
>         amdgpu_amdkfd_resume(adev, true);
>         if (r)
>                 return r;
>
> -       return amdgpu_ring_reset_helper_end(ring, timedout_fence);
> +       return 0;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
> index cb41453c1a19..5709d438e824 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
> @@ -153,8 +153,7 @@ struct amdgpu_buffer_funcs {
>                                  uint32_t byte_count);
>  };
>
> -int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t 
> instance_id,
> -                            bool caller_handles_kernel_queues);
> +int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t 
> instance_id);
>
>  int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring *ring,
>                                    unsigned int vmid,
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c 
> b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> index 77f385b9ef53..796ea9f74763 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
> @@ -1583,7 +1583,7 @@ static int sdma_v4_4_2_reset_queue(struct amdgpu_ring 
> *ring,
>         int r;
>
>         amdgpu_amdkfd_suspend(adev, true);
> -       r = amdgpu_sdma_reset_engine(adev, id, false);
> +       r = amdgpu_sdma_reset_engine(adev, id);
>         amdgpu_amdkfd_resume(adev, true);
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
> b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> index a23384571193..f9fbc5628fb4 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -2576,7 +2576,7 @@ static int reset_hung_queues_sdma(struct 
> device_queue_manager *dqm)
>                                 continue;
>
>                         /* Reset engine and check. */
> -                       if (amdgpu_sdma_reset_engine(dqm->dev->adev, i, 
> false) ||
> +                       if (amdgpu_sdma_reset_engine(dqm->dev->adev, i) ||
>                             
> dqm->dev->kfd2kgd->hqd_sdma_get_doorbell(dqm->dev->adev, i, j) ||
>                             !set_sdma_queue_as_reset(dqm, doorbell_off)) {
>                                 r = -ENOTRECOVERABLE;
> --
> 2.55.0
>

Reply via email to