On 7/14/26 10:10, Srinivasan Shanmugam wrote: > WAIT_EVENT currently provides the per-file queue, matching, and lifetime > infrastructure, but no producer creates records when a user queue fence > completes. > > Add an IRQ-safe helper which appends a WAIT_EVENT record using the queue > pointer as the internal routing key. The record takes a queue reference > before it is published and releases it through the existing record > cleanup paths. > > The producer does not translate the queue pointer back to a queue ID. > Instead, the WAIT_EVENT ioctl adds the queue ID supplied by the waiter > to the matched record immediately before returning it to userspace. This > keeps queue IDs at the UAPI boundary while retaining queue-pointer-based > matching internally. > > Call the helper from amdgpu_userq_process_fence_irq(), next to the > existing EVENTFD notification. This reuses the established > doorbell-to-queue lookup and does not add another queue lookup or change > the GFX interrupt handling. > > Signed-off-by: Srinivasan Shanmugam <[email protected]> > Reviewed-by: Alex Deucher <[email protected]>
What you do with the queue_id still looks a bit fishy to me, but I don't really have time to check that in detail. Acked-by: Christian König <[email protected]> Regards, Christian. > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 6 +++ > .../gpu/drm/amd/amdgpu/amdgpu_wait_event.c | 53 +++++++++++++++++++ > .../gpu/drm/amd/amdgpu/amdgpu_wait_event.h | 4 ++ > 3 files changed, 63 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > index aa17e55d52e8..28f9d3fe0e80 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > @@ -264,6 +264,7 @@ void amdgpu_userq_process_fence_irq(struct amdgpu_device > *adev, u32 doorbell) > struct xarray *xa = &adev->userq_doorbell_xa; > struct amdgpu_usermode_queue *queue; > struct amdgpu_eventfd_mgr *eventfd_mgr; > + struct amdgpu_wait_event_mgr *wait_event_mgr; > unsigned long flags; > int r; > > @@ -286,6 +287,11 @@ void amdgpu_userq_process_fence_irq(struct amdgpu_device > *adev, u32 doorbell) > amdgpu_eventfd_signal(eventfd_mgr, > DRM_AMDGPU_EVENT_TYPE_USERQ_EOP, > queue); > + > + wait_event_mgr = amdgpu_userq_wait_event_mgr(queue->userq_mgr); > + amdgpu_wait_event_add(wait_event_mgr, > + DRM_AMDGPU_EVENT_TYPE_USERQ_EOP, > + queue); > } > xa_unlock_irqrestore(xa, flags); > } > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.c > index f98de1d94b56..ddbd03059916 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.c > @@ -63,6 +63,27 @@ static bool amdgpu_wait_event_valid_type(u32 event_type) > } > } > > +static void > +amdgpu_wait_event_set_queue_id(struct amdgpu_wait_event_record *rec, > + u32 queue_id) > +{ > + rec->data.queue_id = queue_id; > + > + switch (rec->data.event_type) { > + case DRM_AMDGPU_EVENT_TYPE_USERQ_EOP: > + rec->data.u.queue.queue_id = queue_id; > + break; > + case DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET: > + rec->data.u.reset.queue_id = queue_id; > + break; > + case DRM_AMDGPU_EVENT_TYPE_SCRATCH: > + rec->data.u.scratch.queue_id = queue_id; > + break; > + default: > + break; > + } > +} > + > static void > amdgpu_wait_event_record_free(struct amdgpu_wait_event_record *rec) > { > @@ -167,6 +188,35 @@ void amdgpu_wait_event_mgr_init(struct > amdgpu_wait_event_mgr *mgr) > mgr->dead = false; > } > > +void amdgpu_wait_event_add(struct amdgpu_wait_event_mgr *mgr, > + u32 event_type, > + struct amdgpu_usermode_queue *queue) > +{ > + struct amdgpu_wait_event_record *rec; > + unsigned long flags; > + > + rec = kzalloc(sizeof(*rec), GFP_ATOMIC); > + if (!rec) > + return; > + > + kref_get(&queue->refcount); > + rec->queue = queue; > + rec->data.event_type = event_type; > + rec->data.seqno = atomic64_inc_return(&mgr->seqno); > + > + spin_lock_irqsave(&mgr->lock, flags); > + if (mgr->dead) { > + spin_unlock_irqrestore(&mgr->lock, flags); > + amdgpu_wait_event_record_free(rec); > + return; > + } > + > + list_add_tail(&rec->node, &mgr->pending); > + spin_unlock_irqrestore(&mgr->lock, flags); > + > + wake_up_interruptible(&mgr->wq); > +} > + > void amdgpu_wait_event_mgr_fini(struct amdgpu_wait_event_mgr *mgr) > { > struct amdgpu_wait_event_record *rec, *tmp; > @@ -270,6 +320,9 @@ int amdgpu_wait_event_drm_ioctl(struct drm_device *dev, > void *data, > } > } > > + if (queue) > + amdgpu_wait_event_set_queue_id(rec, args->queue_id); > + > if (copy_to_user(u64_to_user_ptr(args->out_ptr), &rec->data, > sizeof(rec->data))) > ret = -EFAULT; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.h > index e887fffdc4ac..07e043dcc2e7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wait_event.h > @@ -56,6 +56,10 @@ void amdgpu_wait_event_mgr_fini(struct > amdgpu_wait_event_mgr *mgr); > void amdgpu_wait_event_remove_queue(struct amdgpu_wait_event_mgr *mgr, > struct amdgpu_usermode_queue *queue); > > +void amdgpu_wait_event_add(struct amdgpu_wait_event_mgr *mgr, > + u32 event_type, > + struct amdgpu_usermode_queue *queue); > + > int amdgpu_wait_event_drm_ioctl(struct drm_device *dev, void *data, > struct drm_file *file_priv); >
