[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
