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

Reply via email to