[PATCH RFC POC 26/50] dma-buf: stop unwinding sync file descriptors by hand
From: Christian Brauner <brauner@kernel.org>
Date: 2026-09-15 11:34:39
Also in:
bpf, dri-devel, io-uring, kexec, kvm, linux-alpha, linux-arm-kernel, linux-arm-msm, linux-fsdevel, linux-gpio, linux-hyperv, linux-m68k, linux-mips, linux-mm, linux-sh, linux-um, lkml, netdev, sparclinux, virtualization
Subsystem:
dma buffer sharing framework, sync file framework, the rest · Maintainers:
Sumit Semwal, Christian König, Linus Torvalds
Rely on the fd exit path machinery. Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> --- drivers/dma-buf/dma-buf.c | 33 ++++++++++------------------ drivers/dma-buf/sw_sync.c | 40 +++++++++++----------------------- drivers/dma-buf/sync_file.c | 52 +++++++++++++-------------------------------- 3 files changed, 38 insertions(+), 87 deletions(-)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index d504c636dc29..f0d581fad7ae 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c@@ -440,7 +440,8 @@ static long dma_buf_export_sync_file(struct dma_buf *dmabuf, enum dma_resv_usage usage; struct dma_fence *fence = NULL; struct sync_file *sync_file; - int fd, ret; + int ret; + const struct fd_slot *fd; if (copy_from_user(&arg, user_data, sizeof(arg))) return -EFAULT;
@@ -451,14 +452,14 @@ static long dma_buf_export_sync_file(struct dma_buf *dmabuf, if ((arg.flags & DMA_BUF_SYNC_RW) == 0) return -EINVAL; - fd = get_unused_fd_flags(O_CLOEXEC); - if (fd < 0) - return fd; + fd = fd_prepare(O_CLOEXEC); + if (IS_ERR(fd)) + return PTR_ERR(fd); usage = dma_resv_usage_rw(arg.flags & DMA_BUF_SYNC_WRITE); ret = dma_resv_get_singleton(dmabuf->resv, usage, &fence); if (ret) - goto err_put_fd; + return ret; if (!fence) fence = dma_fence_get_stub();
@@ -467,26 +468,14 @@ static long dma_buf_export_sync_file(struct dma_buf *dmabuf, dma_fence_put(fence); - if (!sync_file) { - ret = -ENOMEM; - goto err_put_fd; - } - - arg.fd = fd; - if (copy_to_user(user_data, &arg, sizeof(arg))) { - ret = -EFAULT; - goto err_put_file; - } + if (!sync_file) + return -ENOMEM; - fd_install(fd, sync_file->file); + arg.fd = fd_stage(fd, sync_file->file); + if (copy_to_user(user_data, &arg, sizeof(arg))) + return -EFAULT; return 0; - -err_put_file: - fput(sync_file->file); -err_put_fd: - put_unused_fd(fd); - return ret; } static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 8df20b0218a9..90852950e4e3 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c@@ -344,8 +344,7 @@ static int sw_sync_debugfs_release(struct inode *inode, struct file *file) static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, unsigned long arg) { - int fd = get_unused_fd_flags(O_CLOEXEC); - int err; + const struct fd_slot *fd = fd_prepare(O_CLOEXEC); struct sync_pt *pt; struct sync_file *sync_file; struct sw_sync_create_fence_data data;
@@ -353,41 +352,26 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, /* SW sync fence are inherently unsafe and can deadlock the kernel */ add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK); - if (fd < 0) - return fd; + if (IS_ERR(fd)) + return PTR_ERR(fd); - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { - err = -EFAULT; - goto err; - } + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) + return -EFAULT; pt = sync_pt_create(obj, data.value); - if (!pt) { - err = -ENOMEM; - goto err; - } + if (!pt) + return -ENOMEM; sync_file = sync_file_create(&pt->base); dma_fence_put(&pt->base); - if (!sync_file) { - err = -ENOMEM; - goto err; - } - - data.fence = fd; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - fput(sync_file->file); - err = -EFAULT; - goto err; - } + if (!sync_file) + return -ENOMEM; - fd_install(fd, sync_file->file); + data.fence = fd_stage(fd, sync_file->file); + if (copy_to_user((void __user *)arg, &data, sizeof(data))) + return -EFAULT; return 0; - -err: - put_unused_fd(fd); - return err; } static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg)
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2166bbdf7e4a..316fffc4067e 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c@@ -213,56 +213,34 @@ static __poll_t sync_file_poll(struct file *file, poll_table *wait) static long sync_file_ioctl_merge(struct sync_file *sync_file, unsigned long arg) { - int fd = get_unused_fd_flags(O_CLOEXEC); - int err; + const struct fd_slot *fd = fd_prepare(O_CLOEXEC); struct sync_file *fence2, *fence3; struct sync_merge_data data; - if (fd < 0) - return fd; + if (IS_ERR(fd)) + return PTR_ERR(fd); - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { - err = -EFAULT; - goto err_put_fd; - } + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) + return -EFAULT; - if (data.flags || data.pad) { - err = -EINVAL; - goto err_put_fd; - } + if (data.flags || data.pad) + return -EINVAL; fence2 = sync_file_fdget(data.fd2); - if (!fence2) { - err = -ENOENT; - goto err_put_fd; - } + if (!fence2) + return -ENOENT; data.name[sizeof(data.name) - 1] = '\0'; fence3 = sync_file_merge(data.name, sync_file, fence2); - if (!fence3) { - err = -ENOMEM; - goto err_put_fence2; - } - - data.fence = fd; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - err = -EFAULT; - goto err_put_fence3; - } - - fd_install(fd, fence3->file); fput(fence2->file); - return 0; - -err_put_fence3: - fput(fence3->file); + if (!fence3) + return -ENOMEM; -err_put_fence2: - fput(fence2->file); + data.fence = fd_stage(fd, fence3->file); + if (copy_to_user((void __user *)arg, &data, sizeof(data))) + return -EFAULT; -err_put_fd: - put_unused_fd(fd); - return err; + return 0; } static int sync_fill_fence_info(struct dma_fence *fence,
--
2.53.0