[PATCH RFC POC 42/50] drm: stop unwinding descriptors by hand
From: Christian Brauner
Date: Tue Sep 15 2026 - 08:05:13 EST
Rely on the fd exit path machinery.
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
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