[PATCH 08/10] drm/syncobj: Add a syncobj_array_find helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The wait ioctl has a bunch of code to read an syncobj handle array from
userspace and turn it into an array of syncobj pointers.  We're about to
add two new IOCTLs which will need to work with arrays of syncobj
handles so let's make some helpers.

Signed-off-by: Jason Ekstrand <jason@xxxxxxxxxxxxxx>
---
 drivers/gpu/drm/drm_syncobj.c | 89 ++++++++++++++++++++++++++++---------------
 1 file changed, 58 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index cccd3bd..15e74ca 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -798,58 +798,43 @@ static int drm_syncobj_array_wait(struct drm_device *dev,
 	return 0;
 }
 
-int
-drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
-		       struct drm_file *file_private)
+static int drm_syncobj_array_find(struct drm_file *file_private,
+				  void *user_handles, uint32_t count_handles,
+				  struct drm_syncobj ***syncobjs_out)
 {
-	struct drm_syncobj_wait *args = data;
-	uint32_t *handles;
+	uint32_t i, *handles;
 	struct drm_syncobj **syncobjs;
-	int ret = 0;
-	uint32_t i;
-
-	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
-		return -ENODEV;
-
-	if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
-			    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
-		return -EINVAL;
-
-	if (args->count_handles == 0)
-		return -EINVAL;
+	int ret;
 
-	/* Get the handles from userspace */
-	handles = kmalloc_array(args->count_handles, sizeof(uint32_t),
-				GFP_KERNEL);
+	handles = kmalloc_array(count_handles, sizeof(*handles), GFP_KERNEL);
 	if (handles == NULL)
 		return -ENOMEM;
 
-	if (copy_from_user(handles,
-			   u64_to_user_ptr(args->handles),
-			   sizeof(uint32_t) * args->count_handles)) {
+	if (copy_from_user(handles, user_handles,
+			   sizeof(uint32_t) * count_handles)) {
 		ret = -EFAULT;
 		goto err_free_handles;
 	}
 
-	syncobjs = kcalloc(args->count_handles,
-			   sizeof(struct drm_syncobj *), GFP_KERNEL);
-	if (!syncobjs) {
+	syncobjs = kmalloc_array(count_handles, sizeof(*syncobjs), GFP_KERNEL);
+	if (syncobjs == NULL) {
 		ret = -ENOMEM;
 		goto err_free_handles;
 	}
 
-	for (i = 0; i < args->count_handles; i++) {
+	for (i = 0; i < count_handles; i++) {
 		syncobjs[i] = drm_syncobj_find(file_private, handles[i]);
 		if (!syncobjs[i]) {
 			ret = -ENOENT;
-			goto err_free_fence_array;
+			goto err_put_syncobjs;
 		}
 	}
 
-	ret = drm_syncobj_array_wait(dev, file_private,
-				     args, syncobjs);
+	kfree(handles);
+	*syncobjs_out = syncobjs;
+	return 0;
 
-err_free_fence_array:
+err_put_syncobjs:
 	while (i-- > 0)
 		drm_syncobj_put(syncobjs[i]);
 	kfree(syncobjs);
@@ -858,3 +843,45 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
 
 	return ret;
 }
+
+static void drm_syncobj_array_free(struct drm_syncobj **syncobjs,
+				   uint32_t count)
+{
+	uint32_t i;
+	for (i = 0; i < count; i++)
+		drm_syncobj_put(syncobjs[i]);
+	kfree(syncobjs);
+}
+
+int
+drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_private)
+{
+	struct drm_syncobj_wait *args = data;
+	struct drm_syncobj **syncobjs;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+		return -ENODEV;
+
+	if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+			    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+		return -EINVAL;
+
+	if (args->count_handles == 0)
+		return -EINVAL;
+
+	ret = drm_syncobj_array_find(file_private,
+				     u64_to_user_ptr(args->handles),
+				     args->count_handles,
+				     &syncobjs);
+	if (ret < 0)
+		return ret;
+
+	ret = drm_syncobj_array_wait(dev, file_private,
+				     args, syncobjs);
+
+	drm_syncobj_array_free(syncobjs, args->count_handles);
+
+	return ret;
+}
-- 
2.5.0.400.gff86faf

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux