Introduce two new UAPI ioctls to allow userspace to bind and unbind an eventfd to a userspace-defined event_id on the render node.
The design supports multiple eventfds bound to the same event_id. Therefore, unbind includes the eventfd to remove a specific binding. UAPI is placed last in the series since it enables the userspace-facing feature. Cc: Alex Deucher <[email protected]> Cc: Christian König <[email protected]> Signed-off-by: Srinivasan Shanmugam <[email protected]> Change-Id: Ibe6a3be80f6435c1fe2a3243b63e6ed2fc6391ee --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 28 +++++++++++++++++++++ include/uapi/drm/amdgpu_drm.h | 33 +++++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6d652e8ac978..0955290f180b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -458,6 +458,12 @@ struct amdgpu_fpriv { struct amdgpu_eventfd_mgr eventfd_mgr; }; +struct drm_device; +struct drm_file; + +int amdgpu_eventfd_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int amdgpu_eventfd_unbind_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); + int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv); /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 03814a23eb54..0393026534f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -3062,6 +3062,8 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_SIGNAL, amdgpu_userq_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_WAIT, amdgpu_userq_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_GEM_LIST_HANDLES, amdgpu_gem_list_handles_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_EVENTFD_BIND, amdgpu_eventfd_bind_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_EVENTFD_UNBIND, amdgpu_eventfd_unbind_ioctl, DRM_RENDER_ALLOW), }; static const struct drm_driver amdgpu_kms_driver = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad27274a9e92..e06bb19bcb12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -634,6 +634,34 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, return 0; } +int amdgpu_eventfd_bind_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct amdgpu_fpriv *fpriv = file_priv->driver_priv; + struct drm_amdgpu_eventfd_bind *args = data; + + if (!fpriv) + return -EINVAL; + if (args->flags || !args->event_id || args->eventfd < 0) + return -EINVAL; + + return amdgpu_eventfd_bind(&fpriv->eventfd_mgr, args->event_id, args->eventfd); +} + +int amdgpu_eventfd_unbind_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct amdgpu_fpriv *fpriv = file_priv->driver_priv; + struct drm_amdgpu_eventfd_unbind *args = data; + + if (!fpriv) + return -ENODEV; + if (args->flags || !args->event_id || args->eventfd < 0) + return -EINVAL; + + return amdgpu_eventfd_unbind(&fpriv->eventfd_mgr, args->event_id, args->eventfd); +} + /* * Userspace get information ioctl */ diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 22fcf2a69134..5fdaa141cf82 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -39,6 +39,8 @@ extern "C" { #endif #define DRM_AMDGPU_GEM_CREATE 0x00 +#define DRM_AMDGPU_EVENTFD_BIND 0x1A +#define DRM_AMDGPU_EVENTFD_UNBIND 0x1B #define DRM_AMDGPU_GEM_MMAP 0x01 #define DRM_AMDGPU_CTX 0x02 #define DRM_AMDGPU_BO_LIST 0x03 @@ -79,6 +81,10 @@ extern "C" { #define DRM_IOCTL_AMDGPU_USERQ_SIGNAL DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_SIGNAL, struct drm_amdgpu_userq_signal) #define DRM_IOCTL_AMDGPU_USERQ_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait) #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles) +#define DRM_IOCTL_AMDGPU_EVENTFD_BIND \ + DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_EVENTFD_BIND, struct drm_amdgpu_eventfd_bind) +#define DRM_IOCTL_AMDGPU_EVENTFD_UNBIND \ + DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_EVENTFD_UNBIND, struct drm_amdgpu_eventfd_unbind) /** * DOC: memory domains @@ -204,6 +210,33 @@ union drm_amdgpu_gem_create { struct drm_amdgpu_gem_create_out out; }; +/** + * struct drm_amdgpu_eventfd_bind - Bind an eventfd to an event_id. + * @event_id: Userspace-defined event identifier. + * @eventfd: eventfd file descriptor. + * @flags: Must be 0. + * + * Duplicate binds of the same eventfd to the same event_id are idempotent + * and return success without creating an additional binding. + */ +struct drm_amdgpu_eventfd_bind { + __u32 event_id; + __s32 eventfd; + __u32 flags; +}; + +/** + * struct drm_amdgpu_eventfd_unbind - Unbind an eventfd from an event_id. + * @event_id: Userspace-defined event identifier. + * @eventfd: eventfd file descriptor. + * @flags: Must be 0. + */ +struct drm_amdgpu_eventfd_unbind { + __u32 event_id; + __s32 eventfd; + __u32 flags; +}; + /** Opcode to create new residency list. */ #define AMDGPU_BO_LIST_OP_CREATE 0 /** Opcode to destroy previously created residency list */ -- 2.34.1
