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: 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 | 6 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 36 +++++++++++++++++++++++++ include/uapi/drm/amdgpu_drm.h | 18 +++++++++++++ 4 files changed, 62 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9e650b3707e3..decac4cc44cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -460,6 +460,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 8ab8f9dc4cfa..31449c7a0ae8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -635,6 +635,42 @@ 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 || !fpriv->eventfd_mgr) + return -EINVAL; + if (args->flags) + return -EINVAL; + if (!args->event_id) + return -EINVAL; + if (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 || !fpriv->eventfd_mgr) + return -ENODEV; + if (args->flags) + return -EINVAL; + if (!args->event_id) + return -EINVAL; + if (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..32c8bb8a9293 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,18 @@ union drm_amdgpu_gem_create { struct drm_amdgpu_gem_create_out out; }; +struct drm_amdgpu_eventfd_bind { + __u32 event_id; + __s32 eventfd; + __u32 flags; +}; + +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
