This makes the logic from drm_syncobj_eventfd_ioctl available to callers that already have a drm_syncobj.
Signed-off-by: Julian Orth ju.orth@gmail.com --- drivers/gpu/drm/drm_syncobj.c | 37 ++++++++++++++++++++++++++++++------- include/drm/drm_syncobj.h | 2 ++ 2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 648afd1f4fdd..3e8fb7e0cace 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1502,8 +1502,6 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data, { struct drm_syncobj_eventfd *args = data; struct drm_syncobj *syncobj; - struct eventfd_ctx *ev_fd_ctx; - struct syncobj_eventfd_entry *entry; int ret;
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) @@ -1519,7 +1517,33 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data, if (!syncobj) return -ENOENT;
- ev_fd_ctx = eventfd_ctx_fdget(args->fd); + ret = drm_syncobj_register_eventfd(syncobj, args->fd, args->point, args->flags); + + drm_syncobj_put(syncobj); + + return ret; +} + +/** + * drm_syncobj_register_eventfd - register an eventfd for a syncobj + * @syncobj: sync object to add the eventfd to + * @ev_fd: eventfd file descriptor to signal + * @point: timeline point to wait for + * @flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE or 0 + * + * Registers an eventfd that will be signaled when the point is + * signaled or available. + * + * Returns 0 on success or a negative error value on failure. + */ +int drm_syncobj_register_eventfd(struct drm_syncobj *syncobj, + int ev_fd, u64 point, u32 flags) +{ + struct eventfd_ctx *ev_fd_ctx; + struct syncobj_eventfd_entry *entry; + int ret; + + ev_fd_ctx = eventfd_ctx_fdget(ev_fd); if (IS_ERR(ev_fd_ctx)) { ret = PTR_ERR(ev_fd_ctx); goto err_fdget; @@ -1532,20 +1556,19 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data, } entry->syncobj = syncobj; entry->ev_fd_ctx = ev_fd_ctx; - entry->point = args->point; - entry->flags = args->flags; + entry->point = point; + entry->flags = flags;
drm_syncobj_add_eventfd(syncobj, entry); - drm_syncobj_put(syncobj);
return 0;
err_kzalloc: eventfd_ctx_put(ev_fd_ctx); err_fdget: - drm_syncobj_put(syncobj); return ret; } +EXPORT_SYMBOL(drm_syncobj_register_eventfd);
int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 7677fd995be0..85e7ca7f7896 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -134,6 +134,8 @@ signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, uint32_t count, uint32_t flags, signed long timeout, uint32_t *idx, ktime_t *deadline); +int drm_syncobj_register_eventfd(struct drm_syncobj *syncobj, + int ev_fd, u64 point, u32 flags); void drm_syncobj_free(struct kref *kref); int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, struct dma_fence *fence);