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);
>  

Reply via email to