Given a syncobj FD, returns the underlying drm_syncobj.

Signed-off-by: Julian Orth <[email protected]>
---
 drivers/gpu/drm/drm_syncobj.c | 37 +++++++++++++++++++++++++++----------
 include/drm/drm_syncobj.h     |  1 +
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 8d9fd1917c6e..d992aa082ace 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -684,6 +684,31 @@ int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int 
*p_fd)
 }
 EXPORT_SYMBOL(drm_syncobj_get_fd);
 
+/**
+ * drm_syncobj_from_fd - lookup and reference a syncobj.
+ * @fd: syncobj file descriptor
+ *
+ * Returns a reference to the syncobj pointed to by @fd or NULL. The
+ * reference must be released by calling drm_syncobj_put().
+ */
+struct drm_syncobj *drm_syncobj_from_fd(int fd)
+{
+       struct drm_syncobj *syncobj;
+
+       CLASS(fd, f)(fd);
+
+       if (fd_empty(f))
+               return NULL;
+
+       if (fd_file(f)->f_op != &drm_syncobj_file_fops)
+               return NULL;
+
+       syncobj = fd_file(f)->private_data;
+       drm_syncobj_get(syncobj);
+       return syncobj;
+}
+EXPORT_SYMBOL(drm_syncobj_from_fd);
+
 static int drm_syncobj_handle_to_fd(struct drm_file *file_private,
                                    u32 handle, int *p_fd)
 {
@@ -701,20 +726,12 @@ static int drm_syncobj_handle_to_fd(struct drm_file 
*file_private,
 static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
                                    int fd, u32 *handle)
 {
-       struct drm_syncobj *syncobj;
-       CLASS(fd, f)(fd);
+       struct drm_syncobj *syncobj = drm_syncobj_from_fd(fd);
        int ret;
 
-       if (fd_empty(f))
-               return -EINVAL;
-
-       if (fd_file(f)->f_op != &drm_syncobj_file_fops)
+       if (!syncobj)
                return -EINVAL;
 
-       /* take a reference to put in the xarray */
-       syncobj = fd_file(f)->private_data;
-       drm_syncobj_get(syncobj);
-
        ret = xa_alloc(&file_private->syncobj_xa, handle, syncobj, xa_limit_32b,
                       GFP_KERNEL);
        if (ret)
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index b40052132e52..5da9988834b5 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -117,6 +117,7 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
                                     u32 handle);
+struct drm_syncobj *drm_syncobj_from_fd(int fd);
 void drm_syncobj_add_point(struct drm_syncobj *syncobj,
                           struct dma_fence_chain *chain,
                           struct dma_fence *fence,

-- 
2.54.0

Reply via email to