On 6/10/26 08:03, 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 during bind and unbind.
> EVENTFD subscriptions now hold references to the actual queue objects
> instead of the reusable queue identifiers.
> 
> Use the existing user queue refcounting infrastructure to keep queues
> alive while subscriptions exist, and 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 being released. This ensures
> that EVENTFD does not retain stale queue references after queues are
> removed from the USERQ manager.
> 
> Queue-scoped subscriptions are now matched using the queue pointer,
> while GPU-scoped subscriptions continue to operate without an associated
> queue.
> 
> Also update the EVENTFD infrastructure to:
> 
> distinguish queue-scoped and GPU-scoped event types, allow eventfd file
> descriptor 0 by rejecting only negative values, validate supported event
> types, and avoid relying on reusable queue identifiers for signaling.
> 
> EVENTFD remains notification-only and does not carry event payloads.
> 
> 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 | 240 ++++++++++++++------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h |  19 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c     |  24 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c   |   4 +
>  4 files changed, 209 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> index 3a6e08a3d0c1..db743435605f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.c
> @@ -24,37 +24,63 @@
>  /*
>   * Render-node eventfd subscription infrastructure.
>   *
> - * This module provides a simple event notification mechanism for render-node
> - * clients using Linux eventfd objects.
> + * EVENTFD is notification-only. It wakes userspace when a GPU event happens.
> + * Event metadata/details are expected to be consumed separately through the
> + * corresponding wait/event path.
>   *
> - * Userspace can bind an eventfd to a userspace-defined event_id. When the
> - * driver signals that event_id, all eventfds bound to it are notified.
> - *
> - * This mechanism is intended to support lightweight GPU event notifications
> - * without polling from userspace.
> + * Queue-scoped subscriptions use queue_id only for lookup at bind/unbind 
> time.
> + * The EVENTFD entry stores a refcounted queue pointer, not the reusable UAPI
> + * queue_id.
>   */
>  
>  #include <linux/slab.h>
>  #include <linux/err.h>
> +#include <drm/amdgpu_drm.h>
>  
> +#include "amdgpu.h"
>  #include "amdgpu_eventfd.h"
> +#include "amdgpu_userq.h"
>  
>  #define AMDGPU_EVENTFD_MAX_BINDS 4096
>  
> +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 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;
> +     }
> +}
> +
>  /**
> - * amdgpu_eventfd_id_alloc - allocate an event id container
> - * @event_id: userspace-defined event identifier
> - *
> - * Each event_id represents a notification category. Multiple eventfds can
> - * be bound to the same event_id.
> + * amdgpu_eventfd_id_alloc - allocate an event type container
> + * @event_type: kernel-defined AMDGPU event type
>   *
> - * This function allocates the container which stores the list of eventfds
> - * associated with that event_id.
> + * Each event_type has one container. For queue-scoped events, individual
> + * subscriptions inside the container are distinguished by the refcounted
> + * queue pointer stored in each entry.
>   *
>   * Return:
>   * Pointer to the newly allocated structure or NULL on failure.
>   */
> -static struct amdgpu_eventfd_id *amdgpu_eventfd_id_alloc(u32 event_id)
> +static struct amdgpu_eventfd_id *amdgpu_eventfd_id_alloc(u32 event_type)
>  {
>       struct amdgpu_eventfd_id *id;
>  
> @@ -62,43 +88,40 @@ static struct amdgpu_eventfd_id 
> *amdgpu_eventfd_id_alloc(u32 event_id)
>       if (!id)
>               return NULL;
>  
> -     id->event_id = event_id;
> +     id->event_type = event_type;

I think you might want to move renaming event_id to event_type in a separate 
patch or even into the initial patch.

It creates a lot of extra unecessary noise in this patch.

>       INIT_HLIST_HEAD(&id->entries);
>       id->n_entries = 0;
> +
>       return id;
>  }
>  
>  /**
> - * amdgpu_eventfd_id_get_or_create - find or create an event_id entry
> + * amdgpu_eventfd_id_get_or_create - find or create an event_type entry
>   * @mgr: eventfd manager
> - * @event_id: event identifier
> - *
> - * This helper returns the container associated with the given event_id.
> - * If it does not exist, it will create one.
> + * @event_type: kernel-defined AMDGPU event type
>   *
> - * The function is designed to be callable without holding any locks.
> - * Memory allocation is done outside the xarray lock to avoid blocking
> - * inside critical sections.
> + * This helper returns the container associated with the given event_type.
> + * If it does not exist, it creates one.
>   *
>   * Return:
> - * Pointer to the event_id structure or NULL on failure.
> + * Pointer to the event_type structure or NULL on failure.
>   */
>  static struct amdgpu_eventfd_id *
> -amdgpu_eventfd_id_get_or_create(struct amdgpu_eventfd_mgr *mgr, u32 event_id)
> +amdgpu_eventfd_id_get_or_create(struct amdgpu_eventfd_mgr *mgr, u32 
> event_type)
>  {
>       struct amdgpu_eventfd_id *id;
>       struct amdgpu_eventfd_id *new_id;
> -     XA_STATE(xas, &mgr->ids, event_id);
> +     XA_STATE(xas, &mgr->ids, event_type);
>       unsigned long flags;
>       int r;
>  
>       xa_lock_irqsave(&mgr->ids, flags);
> -     id = xa_load(&mgr->ids, event_id);
> +     id = xa_load(&mgr->ids, event_type);
>       xa_unlock_irqrestore(&mgr->ids, flags);
>       if (id)
>               return id;
>  
> -     new_id = amdgpu_eventfd_id_alloc(event_id);
> +     new_id = amdgpu_eventfd_id_alloc(event_type);
>       if (!new_id)
>               return NULL;
>  
> @@ -174,6 +197,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);
>               }
> @@ -186,51 +210,61 @@ void amdgpu_eventfd_mgr_fini(struct amdgpu_eventfd_mgr 
> *mgr)
>  }
>  
>  /**
> - * amdgpu_eventfd_bind - bind eventfd to an event_id
> + * amdgpu_eventfd_bind - bind eventfd to an EVENTFD subscription
>   * @mgr: eventfd manager
> - * @event_id: userspace event identifier
> + * @userq_mgr: user queue manager used to resolve queue_id
> + * @event_type: kernel-defined AMDGPU event type
> + * @queue_id: UAPI queue id for queue-scoped events, or 0 for GPU-scoped 
> events
>   * @eventfd: eventfd file descriptor
>   *
> - * This function allows userspace to subscribe to notifications for a
> - * specific event_id.
> - *
> - * Multiple eventfds can be bound to the same event_id.
> - *
> - * Duplicate bindings of the same eventfd are treated as success and do
> - * not create additional entries.
> + * For queue-scoped events, queue_id is used only to look up the queue.
> + * The entry stores the refcounted queue pointer, not queue_id.
>   *
>   * Return:
>   * 0 on success, negative error code on failure.
>   */
> -int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, u32 event_id, int 
> eventfd)
> +int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr,
> +                     struct amdgpu_userq_mgr *userq_mgr,
> +                     u32 event_type, u32 queue_id, int eventfd)
>  {
>       struct amdgpu_eventfd_id *id;
>       struct amdgpu_eventfd_entry *e, *it;
>       struct eventfd_ctx *ctx;
> +     struct amdgpu_usermode_queue *queue = NULL;
>       unsigned long flags;
>       bool dup = false;
>  
> -     if (!mgr || !event_id || eventfd < 0)
> +     if (!mgr || eventfd < 0 || !amdgpu_eventfd_valid_type(event_type))
>               return -EINVAL;
>  
> -     /*
> -      * Enforce total bind limit without a separate manager lock.
> -      * For duplicate binds, we decrement back before returning success.
> -      */
> +     if (amdgpu_eventfd_queue_scoped(event_type)) {
> +             if (!userq_mgr || !queue_id)
> +                     return -EINVAL;
> +
> +             queue = amdgpu_userq_get(userq_mgr, queue_id);
> +             if (!queue)
> +                     return -ENOENT;
> +     } else if (queue_id) {
> +             return -EINVAL;
> +     }
> +
>       if (atomic_inc_return(&mgr->bind_count) > AMDGPU_EVENTFD_MAX_BINDS) {
>               atomic_dec(&mgr->bind_count);
> +             amdgpu_userq_put(queue);
>               return -ENOSPC;
>       }
>  
>       ctx = eventfd_ctx_fdget(eventfd);
>       if (IS_ERR(ctx)) {
>               atomic_dec(&mgr->bind_count);
> +             amdgpu_userq_put(queue);
>               return PTR_ERR(ctx);
>       }
>  
> -     id = amdgpu_eventfd_id_get_or_create(mgr, event_id);
> +     id = amdgpu_eventfd_id_get_or_create(mgr, event_type);
>       if (!id) {
>               eventfd_ctx_put(ctx);
> +             amdgpu_userq_put(queue);
>               atomic_dec(&mgr->bind_count);
>               return -ENOMEM;
>       }
> @@ -238,7 +272,7 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>       /* 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;
>               }
> @@ -247,6 +281,7 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>  
>       if (dup) {
>               eventfd_ctx_put(ctx);
> +             amdgpu_userq_put(queue);
>               atomic_dec(&mgr->bind_count);
>               return 0;
>       }
> @@ -255,10 +290,13 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>       e = kzalloc(sizeof(*e), GFP_KERNEL);
>       if (!e) {
>               eventfd_ctx_put(ctx);
> +             amdgpu_userq_put(queue);
>               atomic_dec(&mgr->bind_count);
>               return -ENOMEM;
>       }
> +
>       e->ctx = ctx;
> +     e->queue = queue;
>  
>       /*
>        * Re-check duplicate under lock to close the race with another bind()
> @@ -266,7 +304,7 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>        */
>       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;
>               }
> @@ -281,6 +319,7 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>  
>       if (dup) {
>               eventfd_ctx_put(ctx);
> +             amdgpu_userq_put(queue);
>               kfree(e);
>               atomic_dec(&mgr->bind_count);
>               return 0;
> @@ -290,53 +329,70 @@ int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr, 
> u32 event_id, int eventf
>  }
>  
>  /**
> - * amdgpu_eventfd_unbind - remove eventfd binding
> + * amdgpu_eventfd_unbind - remove EVENTFD binding
>   * @mgr: eventfd manager
> - * @event_id: event identifier
> + * @userq_mgr: user queue manager used to resolve queue_id
> + * @event_type: kernel-defined AMDGPU event type
> + * @queue_id: UAPI queue id for queue-scoped events, or 0 for GPU-scoped 
> events
>   * @eventfd: eventfd file descriptor
>   *
> - * Removes an existing binding between an event_id and an eventfd.
> - *
>   * Return:
>   * 0 if removed, -ENOENT if binding does not exist.
>   */
> -int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr, u32 event_id, int 
> eventfd)
> +int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr,
> +                       struct amdgpu_userq_mgr *userq_mgr,
> +                       u32 event_type, u32 queue_id, int eventfd)
>  {
>       struct amdgpu_eventfd_id *id;
>       struct amdgpu_eventfd_entry *e;
>       struct hlist_node *tmp;
>       struct eventfd_ctx *ctx;
> +     struct amdgpu_usermode_queue *queue = NULL;
>       unsigned long flags;
>       bool removed = false;
>  
> -     if (!mgr || !event_id || eventfd < 0)
> +     if (!mgr || eventfd < 0 || !amdgpu_eventfd_valid_type(event_type))
>               return -EINVAL;
>  
> +     if (amdgpu_eventfd_queue_scoped(event_type)) {
> +             if (!userq_mgr || !queue_id)
> +                     return -EINVAL;
> +
> +             queue = amdgpu_userq_get(userq_mgr, queue_id);
> +             if (!queue)
> +                     return -ENOENT;
> +     } else if (queue_id) {
> +             return -EINVAL;
> +     }
> +
>       ctx = eventfd_ctx_fdget(eventfd);
> -     if (IS_ERR(ctx))
> +     if (IS_ERR(ctx)) {
> +             amdgpu_userq_put(queue);
>               return PTR_ERR(ctx);
> +     }
>  
>       xa_lock_irqsave(&mgr->ids, flags);
>  
> -     id = xa_load(&mgr->ids, event_id);
> +     id = xa_load(&mgr->ids, event_type);
>       if (!id)
>               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);
>  
>               atomic_dec(&mgr->bind_count);
>  
>               if (!id->n_entries) {
> -                     __xa_erase(&mgr->ids, event_id);
> +                     __xa_erase(&mgr->ids, event_type);
>                       kfree(id);
>               }
>  
> @@ -346,27 +402,75 @@ int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr 
> *mgr, u32 event_id, int even
>  out_unlock:
>       xa_unlock_irqrestore(&mgr->ids, flags);
>       eventfd_ctx_put(ctx);
> +     amdgpu_userq_put(queue);
>  
>       return removed ? 0 : -ENOENT;
>  }
>  
>  /**
> - * amdgpu_eventfd_signal - notify all eventfds bound to event_id
> + * amdgpu_eventfd_remove_queue - remove all EVENTFD bindings for a queue
>   * @mgr: eventfd manager
> - * @event_id: event identifier
> + * @queue: queue being destroyed/released
>   *
> - * This function is typically called from interrupt context.
> + * 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--;
> +
> +                     eventfd_ctx_put(e->ctx);
> +                     amdgpu_userq_put(e->queue);
> +                     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 - notify all 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
>   *
> - * All eventfds registered for the given event_id will be signaled.
> - * Userspace processes waiting on those eventfds will wake up.
> + * This can run from IRQ context. The queue pointer must refer to the actual
> + * queue object, not the reusable UAPI queue_id.
>   */
> -void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr *mgr, u32 event_id)
> +void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr *mgr, u32 event_type,
> +                        struct amdgpu_usermode_queue *queue)
>  {
>       struct amdgpu_eventfd_id *id;
>       struct amdgpu_eventfd_entry *e;
>       unsigned long flags;
>  
> -     if (!mgr || !event_id)
> +     if (!mgr || !amdgpu_eventfd_valid_type(event_type))
>               return;
>  
>       /*
> @@ -375,10 +479,12 @@ void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr 
> *mgr, u32 event_id)
>        */
>       xa_lock_irqsave(&mgr->ids, flags);
>  
> -     id = xa_load(&mgr->ids, event_id);
> +     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 248afb1f2f14..9ea3283e92bd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eventfd.h
> @@ -32,13 +32,17 @@
>  #include <linux/xarray.h>
>  #include <linux/atomic.h>
>  
> +struct amdgpu_userq_mgr;
> +struct amdgpu_usermode_queue;
> +
>  struct amdgpu_eventfd_entry {
>       struct eventfd_ctx *ctx;
> +     struct amdgpu_usermode_queue *queue;
>       struct hlist_node hnode;
>  };
>  
>  struct amdgpu_eventfd_id {
> -     u32 event_id;
> +     u32 event_type;
>       struct hlist_head entries;
>       u32 n_entries;
>  };
> @@ -51,9 +55,16 @@ struct amdgpu_eventfd_mgr {
>  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_id, int 
> eventfd);
> -int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr, u32 event_id, int 
> eventfd);
> +int amdgpu_eventfd_bind(struct amdgpu_eventfd_mgr *mgr,
> +                     struct amdgpu_userq_mgr *userq_mgr,
> +                     u32 event_type, u32 queue_id, int eventfd);
> +int amdgpu_eventfd_unbind(struct amdgpu_eventfd_mgr *mgr,
> +                       struct amdgpu_userq_mgr *userq_mgr,
> +                       u32 event_type, u32 queue_id, int eventfd);
> +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_id);
> +void amdgpu_eventfd_signal(struct amdgpu_eventfd_mgr *mgr, 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 f7c750094393..0db128def289 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -649,22 +649,32 @@ 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)
> +     switch (args->event_type) {
> +     case DRM_AMDGPU_EVENT_TYPE_USERQ_EOP:
> +     case DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET:
> +     case DRM_AMDGPU_EVENT_TYPE_SCRATCH:
> +             break;
> +     case DRM_AMDGPU_EVENT_TYPE_MEMORY_EXCEPTION:
> +             if (args->queue_id)
> +                     return -EINVAL;
> +             break;
> +     default:
>               return -EINVAL;
> +     }

Doesn't that duplicate the functionality of amdgpu_eventfd_queue_scoped() ?

In general I think it would be cleaner if you convert the queue_id into the 
queue pointer here.

Same could be done for eventfd.

Regards,
Christian. 

>  
>       switch (args->op) {
>       case DRM_AMDGPU_EVENTFD_OP_BIND:
>               return amdgpu_eventfd_bind(&fpriv->eventfd_mgr,
> +                                        &fpriv->userq_mgr,
>                                          args->event_type,
> +                                        args->queue_id,
>                                          args->eventfd);
>       case DRM_AMDGPU_EVENTFD_OP_UNBIND:
>               return amdgpu_eventfd_unbind(&fpriv->eventfd_mgr,
> -                                          args->event_type,
> -                                          args->eventfd);
> +                                              &fpriv->userq_mgr,
> +                                              args->event_type,
> +                                              args->queue_id,
> +                                              args->eventfd);
>       default:
>               return -EINVAL;
>       }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 376813e9623f..45981adbd7d3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -869,6 +869,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;
>       }
> @@ -1229,6 +1231,8 @@ 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);
>       }
>  

Reply via email to