On Thu, Jun 11, 2026 at 10:38 AM SHANMUGAM, SRINIVASAN
<[email protected]> wrote:
>
> Public
>
> RB was added by mistake onto this patch, this patch needs to be reviewed.
>
> Thanks in advance!
> Srini
>
> > -----Original Message-----
> > From: amd-gfx <[email protected]> On Behalf Of 
> > Srinivasan
> > Shanmugam
> > Sent: Thursday, June 11, 2026 8:03 PM
> > To: Koenig, Christian <[email protected]>; Deucher, Alexander
> > <[email protected]>
> > Cc: [email protected]; SHANMUGAM, SRINIVASAN
> > <[email protected]>
> > Subject: [PATCH v12 5/5] drm/amdgpu: Use queue references for queue-aware
> > EVENTFD subscriptions
> >
> > Queue-scoped EVENTFD subscriptions originally used queue_id as part of the
> > routing key. However, queue_id is only a UAPI-visible handle and can be 
> > reused
> > after a queue is destroyed, making it unsuitable as a stable identifier for 
> > internal
> > EVENTFD tracking.
> >
> > Rework queue-scoped EVENTFD handling to resolve queue_id to the
> > corresponding amdgpu_usermode_queue object in the ioctl path before calling 
> > into
> > the EVENTFD helpers. Resolve the eventfd file descriptor to an eventfd 
> > context in
> > the same place.
> >
> > EVENTFD subscriptions now store the actual queue pointer and eventfd context
> > instead of the reusable queue identifier and raw eventfd file descriptor.
> >
> > Use the existing user queue refcounting infrastructure to keep queues alive 
> > while
> > EVENTFD subscriptions exist. Release those references during unbind, manager
> > teardown, and explicit queue cleanup.
> >
> > Introduce amdgpu_eventfd_remove_queue() to remove all subscriptions 
> > associated
> > with a queue when that queue is removed from the USERQ manager. This 
> > prevents
> > EVENTFD from retaining stale queue references after queue removal.
> >
> > Queue-scoped subscriptions are matched using the queue pointer, while GPU-
> > scoped subscriptions continue to operate without an associated queue.
> >
> > Also validate supported event types, distinguish queue-scoped events from 
> > GPU-
> > scoped events, and allow eventfd file descriptor 0 by rejecting only 
> > negative values.
> >
> > EVENTFD remains notification-only and does not carry event payloads.
> >
> > v11: (per Christian)
> > - Convert queue_id to a queue pointer in the ioctl path before calling
> >   EVENTFD helpers.
> > - Convert the eventfd file descriptor to an eventfd context in the ioctl
> >   path before calling EVENTFD helpers.
> > - Store queue pointers in EVENTFD entries instead of reusable queue_id
> >   values.
> > - Add queue cleanup to remove EVENTFD subscriptions when queues are
> >   removed from the USERQ manager.
> >
> > v12:
> > - Remove explicit NULL checks before amdgpu_userq_put() and rely on the
> >   _put helper to handle NULL queue pointers. (Christian)
> >
> > Cc: Alex Deucher <[email protected]>
> > Suggested-by: Christian König <[email protected]>
> > Signed-off-by: Srinivasan Shanmugam <[email protected]>
> > Reviewed-by: Christian König <[email protected]>

Reviewed-by: Alex Deucher <[email protected]>
It would be good to add proper kerneldoc for this interface as well.
Add a kerneldoc page that describes how userspace interacts with this
API.

Alex

> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c   | 146 ++++++++++++------
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h   |  17 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  79 ++++++++--
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c     |   6 +
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h     |   3 -
> >  .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c   |   1 +
> >  .../drm/amd/amdgpu/amdgpu_userq_internal.h    |  37 +++++
> >  7 files changed, 225 insertions(+), 64 deletions(-)  create mode 100644
> > drivers/gpu/drm/amd/amdgpu/amdgpu_userq_internal.h
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> > index c777d563f1b5..7e90d9aad84e 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> > @@ -28,12 +28,15 @@
> >   * Event metadata/details are expected to be consumed separately through 
> > the
> >   * corresponding wait/event path.
> >   *
> > + * Queue-scoped subscriptions store a refcounted queue pointer, not the
> > + * reusable UAPI queue_id.
> >   */
> >
> >  #include <linux/slab.h>
> >  #include <linux/err.h>
> >
> >  #include "amdgpu_eventfd.h"
> > +#include "amdgpu_userq_internal.h"
> >
> >  #define AMDGPU_EVENTFD_MAX_BINDS 4096
> >
> > @@ -132,7 +135,7 @@ amdgpu_eventfd_id_get_or_create(struct
> > amdgpu_eventfd_mgr *mgr,
> >   *
> >   * The manager stores mappings:
> >   *
> > - *   event_id -> list of eventfds
> > + *   event_type -> list of eventfds
> >   *
> >   * The xarray provides efficient lookup of event type containers.
> >   */
> > @@ -168,6 +171,7 @@ void amdgpu_eventfd_mgr_fini(struct
> > amdgpu_eventfd_mgr *mgr)
> >
> >               hlist_for_each_entry_safe(e, tmp, &id->entries, hnode) {
> >                       hlist_del(&e->hnode);
> > +                     amdgpu_userq_put(e->queue);
> >                       eventfd_ctx_put(e->ctx);
> >                       kfree(e);
> >               }
> > @@ -180,55 +184,49 @@ void amdgpu_eventfd_mgr_fini(struct
> > amdgpu_eventfd_mgr *mgr)  }
> >
> >  /**
> > - * amdgpu_eventfd_bind - bind an eventfd to an event type
> > + * amdgpu_eventfd_bind - bind eventfd to an EVENTFD subscription
> >   * @mgr: eventfd manager
> >   * @event_type: kernel-defined AMDGPU event type
> > - * @eventfd: eventfd file descriptor
> > + * @queue: queue pointer for queue-scoped events, or NULL for
> > + GPU-scoped events
> > + * @ctx: eventfd context
> >   *
> > - * Register an eventfd subscription for the specified event type.
> > - * Duplicate subscriptions are treated as success.
> > + * The caller resolves queue_id to @queue and eventfd to @ctx before
> > + * calling this helper. This helper assumes ownership of the references
> > + * passed in. On success, the EVENTFD entry retains those references.
> > + * On duplicate binds or errors, the references are dropped before
> > + * returning.
> >   *
> >   * Return:
> >   * 0 on success or a negative error code.
> >   */
> >  int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr,
> > -                     u32 event_type, int eventfd)
> > +                     u32 event_type,
> > +                     struct amdgpu_usermode_queue *queue,
> > +                     struct eventfd_ctx *ctx)
> >  {
> >       struct amdgpu_eventfd_id *id;
> >       struct amdgpu_eventfd_entry *e = NULL, *it;
> > -     struct eventfd_ctx *ctx;
> >       unsigned long flags;
> >       bool dup = false;
> >       int r = 0; /* duplicate binds are treated as success */
> >
> > -     if (!mgr || !event_type || eventfd < 0)
> > +     if (!mgr || !event_type || !ctx)
> >               return -EINVAL;
> >
> > -     /*
> > -      * Enforce total bind limit without a separate manager lock.
> > -      * For duplicate binds, we decrement back before returning success.
> > -      */
> >       if (atomic_inc_return(&mgr->bind_count) >
> > AMDGPU_EVENTFD_MAX_BINDS) {
> > -             atomic_dec(&mgr->bind_count);
> > -             return -ENOSPC;
> > -     }
> > -
> > -     ctx = eventfd_ctx_fdget(eventfd);
> > -     if (IS_ERR(ctx)) {
> > -             atomic_dec(&mgr->bind_count);
> > -             return PTR_ERR(ctx);
> > +             r = -ENOSPC;
> > +             goto out_put_refs;
> >       }
> >
> >       id = amdgpu_eventfd_id_get_or_create(mgr, event_type);
> >       if (!id) {
> >               r = -ENOMEM;
> > -             goto out_put_ctx;
> > +             goto out_dec_bind_count;
> >       }
> >
> > -     /* check for duplicate binding */
> >       xa_lock_irqsave(&mgr->ids, flags);
> >       hlist_for_each_entry(it, &id->entries, hnode) {
> > -             if (it->ctx == ctx) {
> > +             if (it->ctx == ctx && it->queue == queue) {
> >                       dup = true;
> >                       break;
> >               }
> > @@ -236,24 +234,24 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr
> > *mgr,
> >       xa_unlock_irqrestore(&mgr->ids, flags);
> >
> >       if (dup)
> > -             goto out_put_ctx; /* duplicate bind: success */
> > +             goto out_dec_bind_count;
> >
> > -     /* Allocate entry only after ctx/id prerequisites are satisfied. */
> >       e = kzalloc(sizeof(*e), GFP_KERNEL);
> >       if (!e) {
> >               r = -ENOMEM;
> > -             goto out_put_ctx;
> > +             goto out_dec_bind_count;
> >       }
> >
> >       e->ctx = ctx;
> > +     e->queue = queue;
> >
> >       /*
> >        * Re-check duplicate under lock to close the race with another bind()
> > -      * for the same event_type and eventfd context.
> > +      * for the same (event_type, queue, ctx).
> >        */
> >       xa_lock_irqsave(&mgr->ids, flags);
> >       hlist_for_each_entry(it, &id->entries, hnode) {
> > -             if (it->ctx == ctx) {
> > +             if (it->ctx == ctx && it->queue == queue) {
> >                       dup = true;
> >                       break;
> >               }
> > @@ -262,6 +260,8 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr
> > *mgr,
> >       if (!dup) {
> >               hlist_add_head(&e->hnode, &id->entries);
> >               id->n_entries++;
> > +             queue = NULL;
> > +             ctx = NULL;
> >               e = NULL; /* consumed */
> >       }
> >       xa_unlock_irqrestore(&mgr->ids, flags); @@ -273,41 +273,43 @@ int
> > amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr,
> >
> >  out_free_entry:
> >       kfree(e);
> > -out_put_ctx:
> > -     eventfd_ctx_put(ctx);
> > +out_dec_bind_count:
> >       atomic_dec(&mgr->bind_count);
> > +out_put_refs:
> > +     amdgpu_userq_put(queue);
> > +     eventfd_ctx_put(ctx);
> >
> >       return r;
> >  }
> >
> >  /**
> > - * amdgpu_eventfd_unbind - remove an eventfd subscription
> > + * amdgpu_eventfd_unbind - remove an EVENTFD subscription
> >   * @mgr: eventfd manager
> >   * @event_type: kernel-defined AMDGPU event type
> > - * @eventfd: eventfd file descriptor
> > + * @queue: queue pointer for queue-scoped events, or NULL for
> > + GPU-scoped events
> > + * @ctx: eventfd context
> >   *
> > - * Remove an existing subscription for the specified event type.
> > + * The caller resolves queue_id to @queue and eventfd to @ctx before
> > + * calling this helper. This helper assumes ownership of the references
> > + * passed in and drops them before returning.
> >   *
> >   * Return:
> >   * 0 on success or a negative error code.
> >   */
> >  int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr,
> > -                       u32 event_type, int eventfd)
> > +                       u32 event_type,
> > +                       struct amdgpu_usermode_queue *queue,
> > +                       struct eventfd_ctx *ctx)
> >  {
> >       struct amdgpu_eventfd_id *id;
> >       struct amdgpu_eventfd_entry *e;
> >       struct hlist_node *tmp;
> > -     struct eventfd_ctx *ctx;
> >       unsigned long flags;
> >       bool removed = false;
> >
> > -     if (!mgr || !event_type || eventfd < 0)
> > +     if (!mgr || !event_type || !ctx)
> >               return -EINVAL;
> >
> > -     ctx = eventfd_ctx_fdget(eventfd);
> > -     if (IS_ERR(ctx))
> > -             return PTR_ERR(ctx);
> > -
> >       xa_lock_irqsave(&mgr->ids, flags);
> >
> >       id = xa_load(&mgr->ids, event_type);
> > @@ -315,13 +317,14 @@ int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr
> > *mgr,
> >               goto out_unlock;
> >
> >       hlist_for_each_entry_safe(e, tmp, &id->entries, hnode) {
> > -             if (e->ctx != ctx)
> > +             if (e->ctx != ctx || e->queue != queue)
> >                       continue;
> >
> >               hlist_del(&e->hnode);
> >               id->n_entries--;
> >               removed = true;
> >
> > +             amdgpu_userq_put(e->queue);
> >               eventfd_ctx_put(e->ctx);
> >               kfree(e);
> >
> > @@ -338,21 +341,68 @@ int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr
> > *mgr,
> >  out_unlock:
> >       xa_unlock_irqrestore(&mgr->ids, flags);
> >       eventfd_ctx_put(ctx);
> > +     amdgpu_userq_put(queue);
> >
> >       return removed ? 0 : -ENOENT;
> >  }
> >
> >  /**
> > - * amdgpu_eventfd_signal - signal all eventfds bound to an event type
> > + * amdgpu_eventfd_remove_queue - remove all EVENTFD bindings for a
> > + queue
> >   * @mgr: eventfd manager
> > - * @event_type: kernel-defined AMDGPU event type
> > + * @queue: queue being destroyed/released
> >   *
> > - * Notify all subscribers associated with the specified event type.
> > + * Remove all subscriptions that hold a reference to @queue.
> > + * This is called when the queue id is released so EVENTFD can drop
> > + * its queue references before the queue is finally destroyed.
> > + */
> > +void amdgpu_eventfd_remove_queue(struct amdgpu_eventfd_mgr *mgr,
> > +                              struct amdgpu_usermode_queue *queue) {
> > +     struct amdgpu_eventfd_id *id;
> > +     struct amdgpu_eventfd_entry *e;
> > +     struct hlist_node *tmp;
> > +     unsigned long index;
> > +     unsigned long flags;
> > +
> > +     if (!mgr || !queue)
> > +             return;
> > +
> > +     xa_lock_irqsave(&mgr->ids, flags);
> > +
> > +     xa_for_each(&mgr->ids, index, id) {
> > +             hlist_for_each_entry_safe(e, tmp, &id->entries, hnode) {
> > +                     if (e->queue != queue)
> > +                             continue;
> > +
> > +                     hlist_del(&e->hnode);
> > +                     id->n_entries--;
> > +
> > +                     amdgpu_userq_put(e->queue);
> > +                     eventfd_ctx_put(e->ctx);
> > +                     kfree(e);
> > +
> > +                     atomic_dec(&mgr->bind_count);
> > +             }
> > +
> > +             if (!id->n_entries) {
> > +                     __xa_erase(&mgr->ids, index);
> > +                     kfree(id);
> > +             }
> > +     }
> > +
> > +     xa_unlock_irqrestore(&mgr->ids, flags); }
> > +
> > +/**
> > + * amdgpu_eventfd_signal - signal matching eventfd subscriptions
> > + * @mgr: eventfd manager
> > + * @event_type: kernel-defined AMDGPU event type
> > + * @queue: queue pointer for queue-scoped events, or NULL for
> > +GPU-scoped events
> >   *
> >   * Signaling is notification-only and does not carry additional payload.
> >   */
> >  void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr *mgr,
> > -                        u32 event_type)
> > +                        u32 event_type, struct amdgpu_usermode_queue 
> > *queue)
> >  {
> >       struct amdgpu_eventfd_id *id;
> >       struct amdgpu_eventfd_entry *e;
> > @@ -369,8 +419,10 @@ void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr
> > *mgr,
> >
> >       id = xa_load(&mgr->ids, event_type);
> >       if (id) {
> > -             hlist_for_each_entry(e, &id->entries, hnode)
> > -                     eventfd_signal(e->ctx);
> > +             hlist_for_each_entry(e, &id->entries, hnode) {
> > +                     if (e->queue == queue)
> > +                             eventfd_signal(e->ctx);
> > +             }
> >       }
> >
> >       xa_unlock_irqrestore(&mgr->ids, flags); diff --git
> > a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> > index e13b86240afc..8dbae07b0d84 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> > @@ -32,8 +32,11 @@
> >  #include <linux/eventfd.h>
> >  #include <linux/xarray.h>
> >
> > +struct amdgpu_usermode_queue;
> > +
> >  struct amdgpu_eventfd_entry {
> >       struct eventfd_ctx *ctx;
> > +     struct amdgpu_usermode_queue *queue;
> >       struct hlist_node hnode;
> >  };
> >
> > @@ -52,11 +55,19 @@ void amdgpu_eventfd_mgr_init(struct
> > amdgpu_eventfd_mgr *mgr);  void amdgpu_eventfd_mgr_fini(struct
> > amdgpu_eventfd_mgr *mgr);
> >
> >  int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr,
> > -                     u32 event_type, int eventfd);
> > +                     u32 event_type,
> > +                     struct amdgpu_usermode_queue *queue,
> > +                     struct eventfd_ctx *ctx);
> >  int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr,
> > -                       u32 event_type, int eventfd);
> > +                       u32 event_type,
> > +                       struct amdgpu_usermode_queue *queue,
> > +                       struct eventfd_ctx *ctx);
> > +
> > +void amdgpu_eventfd_remove_queue(struct amdgpu_eventfd_mgr *mgr,
> > +                              struct amdgpu_usermode_queue *queue);
> >
> >  void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr *mgr,
> > -                        u32 event_type);
> > +                        u32 event_type,
> > +                        struct amdgpu_usermode_queue *queue);
> >
> >  #endif /* __AMDGPU_EVENTFD_H__ */
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > index 7cc54b7e3b81..3cb675a33945 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > @@ -46,6 +46,7 @@
> >  #include "amdgpu_reset.h"
> >  #include "amd_pcie.h"
> >  #include "amdgpu_userq.h"
> > +#include "amdgpu_userq_internal.h"
> >
> >  void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)  { @@ -
> > 634,11 +635,71 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
> >       return 0;
> >  }
> >
> > +static bool amdgpu_eventfd_queue_scoped(u32 event_type) {
> > +     switch (event_type) {
> > +     case DRM_AMDGPU_EVENT_TYPE_USERQ_EOP:
> > +     case DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET:
> > +     case DRM_AMDGPU_EVENT_TYPE_SCRATCH:
> > +             return true;
> > +     default:
> > +             return false;
> > +     }
> > +}
> > +
> > +static bool amdgpu_eventfd_valid_type(u32 event_type) {
> > +     switch (event_type) {
> > +     case DRM_AMDGPU_EVENT_TYPE_USERQ_EOP:
> > +     case DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET:
> > +     case DRM_AMDGPU_EVENT_TYPE_MEMORY_EXCEPTION:
> > +     case DRM_AMDGPU_EVENT_TYPE_SCRATCH:
> > +     case DRM_AMDGPU_EVENT_TYPE_GPU_RESET:
> > +             return true;
> > +     default:
> > +             return false;
> > +     }
> > +}
> > +
> > +static int amdgpu_eventfd_get_refs(struct amdgpu_fpriv *fpriv,
> > +                                struct drm_amdgpu_eventfd *args,
> > +                                struct amdgpu_usermode_queue **queue,
> > +                                struct eventfd_ctx **ctx)
> > +{
> > +     *queue = NULL;
> > +     *ctx = NULL;
> > +
> > +     if (!amdgpu_eventfd_valid_type(args->event_type))
> > +             return -EINVAL;
> > +
> > +     if (amdgpu_eventfd_queue_scoped(args->event_type)) {
> > +             if (!args->queue_id)
> > +                     return -EINVAL;
> > +
> > +             *queue = amdgpu_userq_get(&fpriv->userq_mgr, args->queue_id);
> > +             if (!*queue)
> > +                     return -ENOENT;
> > +     } else if (args->queue_id) {
> > +             return -EINVAL;
> > +     }
> > +
> > +     *ctx = eventfd_ctx_fdget(args->eventfd);
> > +     if (IS_ERR(*ctx)) {
> > +             amdgpu_userq_put(*queue);
> > +             return PTR_ERR(*ctx);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> >  int amdgpu_eventfd_ioctl(struct drm_device *dev, void *data,
> >                        struct drm_file *file_priv)
> >  {
> >       struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
> >       struct drm_amdgpu_eventfd *args = data;
> > +     struct amdgpu_usermode_queue *queue;
> > +     struct eventfd_ctx *ctx;
> > +     int r;
> >
> >       if (!fpriv)
> >               return -EINVAL;
> > @@ -649,24 +710,20 @@ int amdgpu_eventfd_ioctl(struct drm_device *dev, void
> > *data,
> >       if (args->flags || !args->event_type || args->eventfd < 0)
> >               return -EINVAL;
> >
> > -     /*
> > -      * Queue-scoped subscriptions are enabled by the later
> > -      * queue-reference routing patch. Until then, keep
> > -      * queue_id zero.
> > -      */
> > -     if (args->queue_id)
> > -             return -EINVAL;
> > +     r = amdgpu_eventfd_get_refs(fpriv, args, &queue, &ctx);
> > +     if (r)
> > +             return r;
> >
> >       switch (args->op) {
> >       case DRM_AMDGPU_EVENTFD_OP_BIND:
> >               return amdgpu_eventfd_bind(&fpriv->eventfd_mgr,
> > -                                        args->event_type,
> > -                                        args->eventfd);
> > +                                        args->event_type, queue, ctx);
> >       case DRM_AMDGPU_EVENTFD_OP_UNBIND:
> >               return amdgpu_eventfd_unbind(&fpriv->eventfd_mgr,
> > -                                          args->event_type,
> > -                                          args->eventfd);
> > +                                          args->event_type, queue, ctx);
> >       default:
> > +             amdgpu_userq_put(queue);
> > +             eventfd_ctx_put(ctx);
> >               return -EINVAL;
> >       }
> >  }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > index 427c09c83d6b..b77385e35e4e 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > @@ -33,6 +33,7 @@
> >  #include "amdgpu_userq.h"
> >  #include "amdgpu_hmm.h"
> >  #include "amdgpu_userq_fence.h"
> > +#include "amdgpu_userq_internal.h"
> >
> >  /*
> >   * Get the per-file eventfd manager associated with this userq manager.
> > @@ -872,6 +873,8 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void 
> > *data,
> >               if (!queue)
> >                       return -ENOENT;
> >
> > +             amdgpu_eventfd_remove_queue(&fpriv->eventfd_mgr, queue);
> > +
> >               amdgpu_userq_put(queue);
> >               break;
> >       }
> > @@ -1232,6 +1235,9 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr
> > *userq_mgr)
> >               if (!queue)
> >                       break;
> >
> > +
> >       amdgpu_eventfd_remove_queue(amdgpu_userq_eventfd_mgr(userq_mgr),
> > +                                         queue);
> > +
> >               amdgpu_userq_put(queue);
> >       }
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > index 8c4b55517a0a..e1a7d0dbc436 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > @@ -144,9 +144,6 @@ struct amdgpu_db_info {
> >       struct amdgpu_userq_obj *db_obj;
> >  };
> >
> > -struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr
> > *uq_mgr, u32 qid); -void amdgpu_userq_put(struct amdgpu_usermode_queue
> > *queue);
> > -
> >  int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file 
> > *filp);
> >
> >  int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct 
> > drm_file
> > *file_priv, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> > index 008330a0d852..8795156270f2 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> > @@ -31,6 +31,7 @@
> >
> >  #include "amdgpu.h"
> >  #include "amdgpu_userq_fence.h"
> > +#include "amdgpu_userq_internal.h"
> >
> >  #define AMDGPU_USERQ_MAX_HANDLES     (1U << 16)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_internal.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_internal.h
> > new file mode 100644
> > index 000000000000..f41ec9167581
> > --- /dev/null
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_internal.h
> > @@ -0,0 +1,37 @@
> > +/*
> > + * Copyright 2026 Advanced Micro Devices, Inc.
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> > +obtaining a
> > + * copy of this software and associated documentation files (the
> > +"Software"),
> > + * to deal in the Software without restriction, including without
> > +limitation
> > + * the rights to use, copy, modify, merge, publish, distribute,
> > +sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom
> > +the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be
> > +included in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
> > KIND,
> > +EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > +MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN
> > NO EVENT
> > +SHALL
> > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY
> > CLAIM,
> > +DAMAGES OR
> > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
> > +OTHERWISE,
> > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
> > THE USE
> > +OR
> > + * OTHER DEALINGS IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#ifndef __AMDGPU_USERQ_INTERNAL_H__
> > +#define __AMDGPU_USERQ_INTERNAL_H__
> > +
> > +#include <linux/types.h>
> > +
> > +struct amdgpu_userq_mgr;
> > +struct amdgpu_usermode_queue;
> > +
> > +struct amdgpu_usermode_queue *
> > +amdgpu_userq_get(struct amdgpu_userq_mgr *userq_mgr, u32 queue_id);
> > +
> > +void amdgpu_userq_put(struct amdgpu_usermode_queue *queue);
> > +
> > +#endif /* __AMDGPU_USERQ_INTERNAL_H__ */
> > --
> > 2.34.1
>

Reply via email to