[AMD Official Use Only - AMD Internal Distribution Only]

Ping ...

> -----Original Message-----
> From: Jesse.Zhang <[email protected]>
> Sent: Wednesday, January 28, 2026 6:58 PM
> To: [email protected]
> Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
> <[email protected]>; Zhang, Jesse(Jie) <[email protected]>;
> Deucher, Alexander <[email protected]>; Zhang, Jesse(Jie)
> <[email protected]>
> Subject: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
>
> Implement the AMDGPU_USERQ_OP_MODIFY ioctl operation to enable runtime
> updates of compute queues.
>
> v2: move queue size validate to a separate patch
>     remove the check for AMDGPU_HW_IP_COMPUTE  (Alex)
>
> Suggested-by: Alex Deucher <[email protected]>
> Signed-off-by: Jesse Zhang <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 61
> +++++++++++++++++++++++  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h |  3
> ++
>  include/uapi/drm/amdgpu_drm.h             |  1 +
>  3 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 256ceca6d429..3003aba22e1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -837,6 +837,7 @@ static int amdgpu_userq_input_args_validate(struct
> drm_device *dev,
>
>       switch (args->in.op) {
>       case AMDGPU_USERQ_OP_CREATE:
> +     case AMDGPU_USERQ_OP_MODIFY:
>               if (args->in.flags &
> ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
>
> AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
>                       return -EINVAL;
> @@ -901,6 +902,60 @@ bool amdgpu_userq_enabled(struct drm_device *dev)
>       return false;
>  }
>
> +static int amdgpu_modify_queue(struct drm_file *filp, union
> +drm_amdgpu_userq *args) {
> +     struct amdgpu_fpriv *fpriv = filp->driver_priv;
> +     struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> +     struct amdgpu_device *adev = uq_mgr->adev;
> +     struct amdgpu_usermode_queue *queue;
> +     const struct amdgpu_userq_funcs *userq_funcs;
> +     int r;
> +
> +     mutex_lock(&uq_mgr->userq_mutex);
> +     queue = amdgpu_userq_find(uq_mgr, args->in.queue_id);
> +     if (!queue) {
> +             drm_file_err(uq_mgr->file, "Queue %u not found\n", args-
> >in.queue_id);
> +             r = -EINVAL;
> +             goto unlock;
> +     }
> +
> +     userq_funcs = adev->userq_funcs[queue->queue_type];
> +
> +     /*
> +      * Unmap the queue if it's mapped or preempted to ensure a clean update.
> +      * If the queue is already unmapped or hung, we skip this step.
> +      */
> +     if (queue->state == AMDGPU_USERQ_STATE_MAPPED ||
> +         queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
> +             r = amdgpu_userq_unmap_helper(queue);
> +             if (r) {
> +                     drm_file_err(uq_mgr->file, "Failed to unmap queue 
> %llu\n",
> +                                     queue->doorbell_index);
> +                     goto unlock;
> +             }
> +     }
> +
> +     r = userq_funcs->mqd_update(queue, &args->in);
> +     if (r)
> +             goto unlock;
> +     /*
> +      * If the queue is considered active (has valid size, address, and
> percentage),
> +      * we attempt to map it. This effectively starts the queue or restarts 
> it
> +      * if it was previously running.
> +      */
> +     if (AMDGPU_USERQ_IS_ACTIVE(queue)) {
> +             r = amdgpu_userq_map_helper(queue);
> +             if (r)
> +                     drm_file_err(uq_mgr->file, "Failed to remap queue %llu 
> after
> update\n",
> +                             queue->doorbell_index);
> +     }
> +
> +unlock:
> +     mutex_unlock(&uq_mgr->userq_mutex);
> +
> +     return r;
> +}
> +
>  int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>                      struct drm_file *filp)
>  {
> @@ -920,6 +975,12 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void
> *data,
>                       drm_file_err(filp, "Failed to create usermode queue\n");
>               break;
>
> +
> +     case AMDGPU_USERQ_OP_MODIFY:
> +             r = amdgpu_modify_queue(filp, args);
> +             if (r)
> +                     drm_file_err(filp, "Failed to modify usermode queue\n");
> +             break;
>       case AMDGPU_USERQ_OP_FREE:
>               r = amdgpu_userq_destroy(filp, args->in.queue_id);
>               if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> index 833468b58603..7cd1ea94e368 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> @@ -31,6 +31,9 @@
>  #define to_ev_fence(f) container_of(f, struct amdgpu_eviction_fence, base)
> #define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr)
> #define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr,
> name)
> +#define AMDGPU_USERQ_IS_ACTIVE(q) ((q)->userq_prop->queue_size > 0 &&
> \
> +                           (q)->userq_prop->hqd_base_gpu_addr != 0 &&  \
> +                           (q)->userq_prop->queue_percentage > 0)
>
>  enum amdgpu_userq_state {
>       AMDGPU_USERQ_STATE_UNMAPPED = 0,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h 
> index
> c52949ea8c1e..aa9b31578c6b 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -330,6 +330,7 @@ union drm_amdgpu_ctx {
>  /* user queue IOCTL operations */
>  #define AMDGPU_USERQ_OP_CREATE       1
>  #define AMDGPU_USERQ_OP_FREE 2
> +#define AMDGPU_USERQ_OP_MODIFY 3
>
>  /* queue priority levels */
>  /* low < normal low < normal high < high */
> --
> 2.49.0

Reply via email to