On 6/11/26 09:26, Srinivasan Shanmugam wrote:
> 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.
> 
> Cc: Alex Deucher <[email protected]>
> Suggested-by: Christian König <[email protected]>
> Signed-off-by: Srinivasan Shanmugam <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c   | 151 ++++++++++++------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h   |  17 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  81 ++++++++--
>  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    |  36 +++++
>  7 files changed, 231 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..3efe1841880e 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,8 @@ void amdgpu_eventfd_mgr_fini(struct amdgpu_eventfd_mgr 
> *mgr)
>  
>               hlist_for_each_entry_safe(e, tmp, &id->entries, hnode) {
>                       hlist_del(&e->hnode);
> +                     if (e->queue)

The NULL check is superflous. You do that multiple times in the patch.

In general it is good practice to have the NULL check in the _put function and 
we should already have that.

Apart from that it looks good to me, but that needs a hell lot of test cases to 
exercise everything.

Thanks,
Christian.

> +                             amdgpu_userq_put(e->queue);
>                       eventfd_ctx_put(e->ctx);
>                       kfree(e);
>               }
> @@ -180,55 +185,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 +235,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 +261,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 +274,44 @@ 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:
> +     if (queue)
> +             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 +319,15 @@ 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;
>  
> +             if (e->queue)
> +                     amdgpu_userq_put(e->queue);
>               eventfd_ctx_put(e->ctx);
>               kfree(e);
>  
> @@ -338,21 +344,70 @@ int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr 
> *mgr,
>  out_unlock:
>       xa_unlock_irqrestore(&mgr->ids, flags);
>       eventfd_ctx_put(ctx);
> +     if (queue)
> +             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--;
> +
> +                     if (e->queue)
> +                             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 +424,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..66344d03f91e 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,72 @@ 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)) {
> +             if (*queue)
> +                     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 +711,21 @@ 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:
> +             if (queue)
> +                     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..3b24fbb294e5
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_internal.h
> @@ -0,0 +1,36 @@
> +/*
> + * 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);
> +

Reply via email to