[PATCH RFC POC 42/50] drm: stop unwinding descriptors by hand

Christian Brauner brauner at kernel.org
Tue Sep 15 04:31:28 PDT 2026


Rely on the fd exit path machinery.

Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
---
 drivers/gpu/drm/drm_lease.c   | 20 +++++++++-----------
 drivers/gpu/drm/drm_prime.c   | 13 +++++--------
 drivers/gpu/drm/drm_syncobj.c | 44 +++++++++++++------------------------------
 3 files changed, 27 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 5d2cf724cbd7..b95747cf79a7 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -484,7 +484,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	struct file *lessee_file = NULL;
 	struct file *lessor_file = lessor_priv->filp;
 	struct drm_file *lessee_priv;
-	int fd = -1;
+	const struct fd_slot *fd;
 	uint32_t *object_ids;
 
 	/* Can't lease without MODESET */
@@ -529,10 +529,10 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	}
 
 	/* Allocate a file descriptor for the lease */
-	fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
-	if (fd < 0) {
+	fd = fd_prepare(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+	if (IS_ERR(fd)) {
 		idr_destroy(&leases);
-		ret = fd;
+		ret = PTR_ERR(fd);
 		goto out_lessor;
 	}
 
@@ -543,7 +543,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	if (IS_ERR(lessee)) {
 		ret = PTR_ERR(lessee);
 		idr_destroy(&leases);
-		goto out_leases;
+		goto out_lessor;
 	}
 
 	/* Clone the lessor file to create a new file for us */
@@ -562,12 +562,13 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	lessee_priv->authenticated = 1;
 
 	/* Pass fd back to userspace */
-	drm_dbg_lease(dev, "Returning fd %d id %d\n", fd, lessee->lessee_id);
-	cl->fd = fd;
+	drm_dbg_lease(dev, "Returning fd %d id %d\n", fd_prepare_fd(fd),
+		      lessee->lessee_id);
+	cl->fd = fd_prepare_fd(fd);
 	cl->lessee_id = lessee->lessee_id;
 
 	/* Hook up the fd */
-	fd_install(fd, lessee_file);
+	fd_stage(fd, lessee_file);
 
 	drm_master_put(&lessor);
 	drm_dbg_lease(dev, "drm_mode_create_lease_ioctl succeeded\n");
@@ -576,9 +577,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 out_lessee:
 	drm_master_put(&lessee);
 
-out_leases:
-	put_unused_fd(fd);
-
 out_lessor:
 	drm_master_put(&lessor);
 	drm_dbg_lease(dev, "drm_mode_create_lease_ioctl failed: %d\n", ret);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 9b44c78cd77f..e33d84ac7256 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -513,19 +513,16 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
 			       int *prime_fd)
 {
 	struct dma_buf *dmabuf;
-	int fd = get_unused_fd_flags(flags);
+	const struct fd_slot *fd = fd_prepare(flags);
 
-	if (fd < 0)
-		return fd;
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
 	dmabuf = drm_gem_prime_handle_to_dmabuf(dev, file_priv, handle, flags);
-	if (IS_ERR(dmabuf)) {
-		put_unused_fd(fd);
+	if (IS_ERR(dmabuf))
 		return PTR_ERR(dmabuf);
-	}
 
-	fd_install(fd, dmabuf->file);
-	*prime_fd = fd;
+	*prime_fd = fd_stage(fd, dmabuf->file);
 	return 0;
 }
 EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 2fa170a29a62..621858b6ac43 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -663,25 +663,14 @@ static const struct file_operations drm_syncobj_file_fops = {
  */
 int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd)
 {
-	struct file *file;
-	int fd;
-
-	fd = get_unused_fd_flags(O_CLOEXEC);
-	if (fd < 0)
-		return fd;
-
-	file = anon_inode_getfile("syncobj_file",
-				  &drm_syncobj_file_fops,
-				  syncobj, 0);
-	if (IS_ERR(file)) {
-		put_unused_fd(fd);
-		return PTR_ERR(file);
-	}
+	FD_PREPARE(fdf, O_CLOEXEC,
+		   anon_inode_getfile("syncobj_file", &drm_syncobj_file_fops,
+				      syncobj, 0));
+	if (IS_ERR(fdf))
+		return PTR_ERR(fdf);
 
 	drm_syncobj_get(syncobj);
-	fd_install(fd, file);
-
-	*p_fd = fd;
+	*p_fd = fd_prepare_fd(fdf);
 	return 0;
 }
 EXPORT_SYMBOL(drm_syncobj_get_fd);
@@ -762,31 +751,24 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private,
 	int ret;
 	struct dma_fence *fence;
 	struct sync_file *sync_file;
-	int fd = get_unused_fd_flags(O_CLOEXEC);
+	const struct fd_slot *fd = fd_prepare(O_CLOEXEC);
 
-	if (fd < 0)
-		return fd;
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
 	ret = drm_syncobj_find_fence(file_private, handle, point, 0, &fence);
 	if (ret)
-		goto err_put_fd;
+		return ret;
 
 	sync_file = sync_file_create(fence);
 
 	dma_fence_put(fence);
 
-	if (!sync_file) {
-		ret = -EINVAL;
-		goto err_put_fd;
-	}
-
-	fd_install(fd, sync_file->file);
+	if (!sync_file)
+		return -EINVAL;
 
-	*p_fd = fd;
+	*p_fd = fd_stage(fd, sync_file->file);
 	return 0;
-err_put_fd:
-	put_unused_fd(fd);
-	return ret;
 }
 /**
  * drm_syncobj_open - initializes syncobj file-private structures at devnode open time

-- 
2.53.0




More information about the linux-arm-kernel mailing list