On Sat, Jun 20, 2026 at 11:38 AM Jesse Zhang <[email protected]> wrote:
>
> Split amdgpu_gfx_mes_reset_queue_start() into reset+unmap now and queue
> reinit later, and do the remap only after amdgpu_mes_resume(). Avoids
> re-adding legacy queues while MES gangs are still suspended.
>
> Suggested-by: Shaoyun Liu <[email protected]>
> Signed-off-by: Jesse Zhang <[email protected]>

The series is:
Acked-by: Alex Deucher <[email protected]>

Is there a way we can clean this up in a future patch set?  It's
getting really complicated.

Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 70 +++++++++++++++++++------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h |  1 +
>  2 files changed, 55 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> index 982b41606d48..a5b835d0c166 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> @@ -1989,10 +1989,24 @@ static ssize_t 
> amdgpu_gfx_get_compute_reset_mask(struct device *dev,
>         return amdgpu_show_reset_mask(buf, adev->gfx.compute_supported_reset);
>  }
>
> +static int amdgpu_gfx_mes_reset_queue_reinit(struct amdgpu_ring *ring)
> +{
> +       struct amdgpu_device *adev = ring->adev;
> +       int r;
> +
> +       amdgpu_gfx_mqd_reset_restore(ring);
> +
> +       r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
> +       if (r)
> +               dev_err(adev->dev, "failed to remap kgq\n");
> +
> +       return r;
> +}
> +
>  static int amdgpu_gfx_mes_reset_queue_start(struct amdgpu_ring *ring,
>                                              unsigned int vmid,
>                                              struct amdgpu_fence 
> *timedout_fence,
> -                                            bool use_mmio)
> +                                            bool use_mmio, bool *need_reinit)
>  {
>         struct amdgpu_device *adev = ring->adev;
>         bool reinit_queue;
> @@ -2007,6 +2021,9 @@ static int amdgpu_gfx_mes_reset_queue_start(struct 
> amdgpu_ring *ring,
>         else
>                 reinit_queue = use_mmio;
>
> +       if (need_reinit)
> +               *need_reinit = false;
> +
>         amdgpu_ring_reset_helper_begin(ring, timedout_fence);
>
>         r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, use_mmio, 
> 0);
> @@ -2018,13 +2035,9 @@ static int amdgpu_gfx_mes_reset_queue_start(struct 
> amdgpu_ring *ring,
>                                                   RESET_QUEUES, 0, 0, 0);
>                 if (r)
>                         return r;
> -               amdgpu_gfx_mqd_reset_restore(ring);
>
> -               r = amdgpu_mes_map_legacy_queue(adev, ring, 0);
> -               if (r) {
> -                       dev_err(adev->dev, "failed to remap kgq\n");
> -                       return r;
> -               }
> +               if (need_reinit)
> +                       *need_reinit = true;
>         }>         return 0;
>  }
> @@ -2034,12 +2047,19 @@ int amdgpu_gfx_mes_reset_queue(struct amdgpu_ring 
> *ring,
>                                struct amdgpu_fence *timedout_fence,
>                                bool use_mmio)
>  {
> +       bool need_reinit;
>         int r;
>
> +       /* Single-queue reset (no suspend/resume): re-add the queue inline. */
>         r = amdgpu_gfx_mes_reset_queue_start(ring, vmid, timedout_fence,
> -                                             use_mmio);
> +                                             use_mmio, &need_reinit);
>         if (r)
>                 return r;
> +       if (need_reinit) {
> +               r = amdgpu_gfx_mes_reset_queue_reinit(ring);
> +               if (r)
> +                       return r;
> +       }
>         return amdgpu_ring_reset_helper_end(ring, timedout_fence);
>  }
>
> @@ -2239,7 +2259,8 @@ static int amdgpu_gfx_reset_mes_kcq(struct 
> amdgpu_device *adev,
>                                     struct amdgpu_ring *guilty_ring,
>                                     unsigned int db,
>                                     struct amdgpu_ring **out_ring,
> -                                   struct amdgpu_fence **out_fence)
> +                                   struct amdgpu_fence **out_fence,
> +                                   bool *out_reinit)
>  {
>         bool use_mmio = adev->gfx.mec.use_mmio_for_reset;
>         struct amdgpu_fence *fence;
> @@ -2248,14 +2269,16 @@ static int amdgpu_gfx_reset_mes_kcq(struct 
> amdgpu_device *adev,
>
>         *out_ring = NULL;
>         *out_fence = NULL;
> +       *out_reinit = false;
>         for (i = 0; i < adev->gfx.num_compute_rings; i++) {
>                 ring = &adev->gfx.compute_ring[i];
>                 if (ring == guilty_ring)
>                         continue;
>                 if (ring->doorbell_index == db) {
>                         fence = amdgpu_ring_find_guilty_fence(ring);
> +                       /* reset + unmap now; re-add (map) is deferred to 
> after resume */
>                         r = amdgpu_gfx_mes_reset_queue_start(ring, 0, fence,
> -                                                             use_mmio);
> +                                                             use_mmio, 
> out_reinit);
>                         if (r)
>                                 return r;
>                         *out_ring = ring;
> @@ -2306,12 +2329,16 @@ int amdgpu_gfx_reset_mes_compute(struct amdgpu_device 
> *adev,
>  fence_reset:
>         /* reset the queue this came from if specified */
>         if (ring) {
> +               bool reinit = false;
> +
> +               /* reset + unmap now; re-add (map) is deferred to after 
> resume */
>                 r = amdgpu_gfx_mes_reset_queue_start(ring, 0, guilty_fence,
> -                                                     use_mmio);
> +                                                     use_mmio, &reinit);
>                 if (r)
>                         goto out;
>                 deferred_end[n_deferred].ring = ring;
>                 deferred_end[n_deferred].fence = guilty_fence;
> +               deferred_end[n_deferred].reinit = reinit;
>                 n_deferred++;
>         }
>         if (uq) {
> @@ -2322,6 +2349,7 @@ int amdgpu_gfx_reset_mes_compute(struct amdgpu_device 
> *adev,
>         for (i = 0; i < num_hung; i++) {
>                 struct amdgpu_ring *hr = NULL;
>                 struct amdgpu_fence *hf = NULL;
> +               bool hr_reinit = false;
>
>                 pipe = hqd_info[i].pipe_index;
>                 queue = hqd_info[i].queue_index;
> @@ -2330,12 +2358,13 @@ int amdgpu_gfx_reset_mes_compute(struct amdgpu_device 
> *adev,
>                 /* reset any KCQs */
>                 r = amdgpu_gfx_reset_mes_kcq(adev, ring,
>                                              
> adev->gfx.mec.mes_hung_db_array[i],
> -                                            &hr, &hf);
> +                                            &hr, &hf, &hr_reinit);
>                 if (r)
>                         goto out;
>                 if (hr) {
>                         deferred_end[n_deferred].ring = hr;
>                         deferred_end[n_deferred].fence = hf;
> +                       deferred_end[n_deferred].reinit = hr_reinit;
>                         n_deferred++;
>                 }
>                 /* reset any KFD queues */
> @@ -2372,12 +2401,21 @@ int amdgpu_gfx_reset_mes_compute(struct amdgpu_device 
> *adev,
>         /* resume all will enable the non-hung queues */
>         amdgpu_mes_resume(adev, 0);
>
> -       /* Now CP is running again — replay backed-up commands and ring
> -        * doorbells on each reset queue.
> +       /* Now CP is running again — for queues that were unmapped during the
> +        * reset, re-add (map) them only now that MES is resumed and back to a
> +        * normal state, then replay backed-up commands and ring doorbells on
> +        * each reset queue.
>          */
>         for (i = 0; i < n_deferred; i++) {
> -               int er = amdgpu_ring_reset_helper_end(deferred_end[i].ring,
> -                                                     deferred_end[i].fence);
> +               int er;
> +
> +               if (deferred_end[i].reinit) {
> +                       er = 
> amdgpu_gfx_mes_reset_queue_reinit(deferred_end[i].ring);
> +                       if (er && !r)
> +                               r = er;
> +               }
> +               er = amdgpu_ring_reset_helper_end(deferred_end[i].ring,
> +                                                 deferred_end[i].fence);
>                 if (er && !r)
>                         r = er;
>         }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
> index aefd4f03b443..9432107c96a1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
> @@ -550,6 +550,7 @@ struct amdgpu_gfx {
>  struct amdgpu_gfx_deferred_entry {
>         struct amdgpu_ring      *ring;
>         struct amdgpu_fence     *fence;
> +       bool                    reinit;
>  };
>
>  struct amdgpu_gfx_ras_reg_entry {
> --
> 2.49.0
>

Reply via email to