On Fri, Aug 28, 2026 at 12:25 AM Jesse Zhang <[email protected]> wrote:
>
> Implement the update_mqd callback for gfx11 compute and GFX user queues.
> Save the read pointer, re-run init_mqd to rebuild the HQD, then restore
> the saved read pointer and forward the write pointer to the user wptr, so
> a re-enabled queue resumes at the first un-consumed packet rather than
> replaying the ring from 0.
>
> v2: rebuild the HQD via init_mqd and save/restore the rptr, matching the
>     SDMA update_mqd style, instead of patching individual MQD fields in
>     place. Keeps all update_mqd callbacks consistent.
>
> Signed-off-by: Jesse Zhang <[email protected]>
> Suggested-by: Alexander Deucher <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 44 ++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index a447562977ab..1feb7c9ee5c6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -4256,6 +4256,26 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device 
> *adev, void *m,
>         return 0;
>  }
>
> +/*
> + * GFX update_mqd: init_mqd resets the ring rptr/wptr, so re-run it to 
> rebuild
> + * the HQD, then restore the saved rptr and forward the user wptr.
> + */
> +static int gfx_v11_0_gfx_mqd_update(struct amdgpu_device *adev, void *m,
> +                                   struct amdgpu_mqd_prop *prop,
> +                                   u64 user_wptr)
> +{
> +       struct v11_gfx_mqd *mqd = m;
> +       u32 saved_rptr = mqd->cp_gfx_hqd_rptr;
> +
> +       gfx_v11_0_gfx_mqd_init(adev, mqd, prop);
> +
> +       mqd->cp_gfx_hqd_rptr = saved_rptr;
> +       mqd->cp_gfx_hqd_wptr = lower_32_bits(user_wptr);
> +       mqd->cp_gfx_hqd_wptr_hi = upper_32_bits(user_wptr);

This seems fragile.  Rather than doing it this way, can we just use
mqd_init() as is and add a new
prop->modify flag?  Then we can use that in init_mqd to skip state
that should be retained from the MQD.

Alex

> +
> +       return 0;
> +}
> +
>  static int gfx_v11_0_kgq_init_queue(struct amdgpu_ring *ring)
>  {
>         struct amdgpu_device *adev = ring->adev;
> @@ -4477,6 +4497,26 @@ static int gfx_v11_0_compute_mqd_init(struct 
> amdgpu_device *adev, void *m,
>         return 0;
>  }
>
> +/*
> + * Compute update_mqd: init_mqd resets the ring rptr/wptr, so re-run it to
> + * rebuild the HQD, then restore the saved rptr and forward the user wptr.
> + */
> +static int gfx_v11_0_compute_mqd_update(struct amdgpu_device *adev, void *m,
> +                                       struct amdgpu_mqd_prop *prop,
> +                                       u64 user_wptr)
> +{
> +       struct v11_compute_mqd *mqd = m;
> +       u32 saved_rptr = mqd->cp_hqd_pq_rptr;
> +
> +       gfx_v11_0_compute_mqd_init(adev, mqd, prop);
> +
> +       mqd->cp_hqd_pq_rptr = saved_rptr;
> +       mqd->cp_hqd_pq_wptr_lo = lower_32_bits(user_wptr);
> +       mqd->cp_hqd_pq_wptr_hi = upper_32_bits(user_wptr);
> +
> +       return 0;
> +}
> +
>  static int gfx_v11_0_kiq_init_register(struct amdgpu_ring *ring)
>  {
>         struct amdgpu_device *adev = ring->adev;
> @@ -7271,11 +7311,15 @@ static void gfx_v11_0_set_mqd_funcs(struct 
> amdgpu_device *adev)
>                 sizeof(struct v11_gfx_mqd);
>         adev->mqds[AMDGPU_HW_IP_GFX].init_mqd =
>                 gfx_v11_0_gfx_mqd_init;
> +       adev->mqds[AMDGPU_HW_IP_GFX].update_mqd =
> +               gfx_v11_0_gfx_mqd_update;
>         /* set compute eng mqd */
>         adev->mqds[AMDGPU_HW_IP_COMPUTE].mqd_size =
>                 sizeof(struct v11_compute_mqd);
>         adev->mqds[AMDGPU_HW_IP_COMPUTE].init_mqd =
>                 gfx_v11_0_compute_mqd_init;
> +       adev->mqds[AMDGPU_HW_IP_COMPUTE].update_mqd =
> +               gfx_v11_0_compute_mqd_update;
>  }
>
>  static void gfx_v11_0_set_user_wgp_inactive_bitmap_per_sh(struct 
> amdgpu_device *adev,
> --
> 2.49.0
>

Reply via email to