On 2/16/26 16:49, Srinivasan Shanmugam wrote:
> Add amdgpu_eventfd_signal(), a helper to signal an eventfd previously
> bound to an event_id for the given drm_file (amdgpu_fpriv).
> 
> The helper is IRQ-safe: it uses RCU read-side protection and lockless
> xa_load() to find the mapping. Bind/unbind and final teardown already
> use call_rcu() + synchronize_rcu(), ensuring safe lifetime of entries.
> 
> Cc: Harish Kasiviswanathan <[email protected]>
> Cc: Felix Kuehling <[email protected]>
> Cc: Alex Deucher <[email protected]>
> Cc: Christian König <[email protected]>
> Signed-off-by: Srinivasan Shanmugam <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 21 +++++++++++++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 2baeb0b20df1..b0e9b7ff2f80 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -473,6 +473,7 @@ int amdgpu_eventfd_bind_ioctl(struct drm_device *dev, 
> void *data,
>  int amdgpu_eventfd_unbind_ioctl(struct drm_device *dev, void *data,
>                               struct drm_file *file_priv);
>  void amdgpu_eventfd_registry_fini(struct amdgpu_fpriv *fpriv);
> +void amdgpu_eventfd_signal(struct amdgpu_fpriv *fpriv, u32 event_id, u64 
> count);
>  
>  int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 43da5bc36b7c..66e2ae8b7c8a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -745,6 +745,27 @@ int amdgpu_eventfd_unbind_ioctl(struct drm_device *dev, 
> void *data,
>       return 0;
>  }
>  
> +void amdgpu_eventfd_signal(struct amdgpu_fpriv *fpriv, u32 event_id, u64 
> count)
> +{
> +     struct amdgpu_eventfd_entry *e;
> +     struct eventfd_ctx *ctx;
> +
> +     if (!fpriv || !count)
> +             return;
> +
> +     /*
> +      * IRQ-side: lockless lookup. Lifetime is protected by:
> +      *  - bind/unbind freeing entries via call_rcu()
> +      *  - registry_fini() calling synchronize_rcu() before xa_destroy()
> +      */
> +     rcu_read_lock();
> +     e = xa_load(&fpriv->eventfd_xa, event_id);
> +     ctx = e ? READ_ONCE(e->ctx) : NULL;
> +     if (ctx)
> +             eventfd_signal(ctx);
> +     rcu_read_unlock();

Using RCU like this would work but is not the usual design pattern.

I would rather use the xa_lock_irqsafe()/irqrestore functions and keep the xa 
locked while the eventfd signals.

Regards,
Christian.

> +}
> +
>  /*
>   * Userspace get information ioctl
>   */

Reply via email to