From: Christian Brauner <brauner@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
Jann Horn <jannh@google.com>, Jan Kara <jack@suse.cz>,
Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Oleg Nesterov <oleg@redhat.com>,
linux-alpha@vger.kernel.org, linux-snps-arc@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-csky@vger.kernel.org, linux-hexagon@vger.kernel.org,
linux-m68k@lists.linux-m68k.org, linux-mips@vger.kernel.org,
linux-openrisc@vger.kernel.org, linux-parisc@vger.kernel.org,
linux-sh@vger.kernel.org, sparclinux@vger.kernel.org,
linux-um@lists.infradead.org, Jens Axboe <axboe@kernel.dk>,
io-uring@vger.kernel.org, netdev@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-gpio@vger.kernel.org,
linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
bpf@vger.kernel.org, David Airlie <airlied@redhat.com>,
virtualization@lists.linux.dev, kvm@vger.kernel.org,
kexec@lists.infradead.org, linux-hyperv@vger.kernel.org,
"Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH RFC POC 01/50] file: install files on syscall exit
Date: Tue, 15 Sep 2026 13:30:47 +0200 [thread overview]
Message-ID: <20260915-work-fd-reserve-unify-folded-v1-1-4d5217d6b246@kernel.org> (raw)
In-Reply-To: <20260915-work-fd-reserve-unify-folded-v1-0-4d5217d6b246@kernel.org>
So we've spoken about this idea quite a few times over the years that
we could reserve fds and files on a task and then install or a clean
them up on syscall success or error and get rid of most of the
complicated cleanup dance that we have.
My original approach to this had been to implement FD_PREPARE() based on
cleanup guards and use scopes to make this happen. The other idea was
what I'm illustrating here. It is overall equally robust and makes the
install fd and file pattern work even if it there's a ton of cleanup or
setup work happening in the middle. This is particular evident in the
conversions of various dma/drm code later in the series.
So this lets the syscall path do the install. fd_prepare() allocates a
descriptor like get_unused_fd_flags() does and records it in a slot on
the task. fd_stage() attaches the file to that slot and returns the
number.
When the syscall returns success the exit path installs every staged
file. When it returns an error it drops the descriptors and the files.
So a caller reserves, hands the number to userspace whenever it wants,
creates the file, stages it and returns errors without unwinding
anything.
fd_prepare() returns the slot itself, as a const pointer. The
preexisting fd_prepare_fd() and fd_prepare_file() give access to the fd
and file.
get_unused_fd_flags() and fd_install() don't change. A descriptor is
only reserved where a caller asks for it. And open(), dup() and all
other syscalls that maximize speed simply use FD_ADD().
The task keeps two slots inline. For SCM_RIGHTS and multi-descriptor
ioctls a spill array is added. It stick with the task.
Reservations belong to the thread and the syscall that made them. A
child of fork() starts without any. A thread can't unshare its
fdtagble with outstanding reservations. Kernel threads never return to
userspace so nothing would commit. Anything left at exit is a bug and
gets warned about and dropped.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/file.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/file.h | 37 +++++++--
include/linux/sched.h | 21 ++++++
kernel/exit.c | 1 +
kernel/fork.c | 1 +
5 files changed, 256 insertions(+), 7 deletions(-)
diff --git a/fs/file.c b/fs/file.c
index 628ca07dc4b1..90351241bb07 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -630,14 +630,215 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
files->next_fd = fd;
}
-void put_unused_fd(unsigned int fd)
+/* Release @fd in the table, its slot is the caller's business. */
+static void fd_release(unsigned int fd)
{
struct files_struct *files = current->files;
+
spin_lock(&files->file_lock);
__put_unused_fd(files, fd);
spin_unlock(&files->file_lock);
}
+/* Enough for SCM_MAX_FD, and a page of slots on 4K pages. */
+#define FD_SLOTS_SPILL_MIN 256
+
+static struct fd_slot *fd_slot(struct fd_slots *slots, unsigned int idx)
+{
+ if (idx < FD_SLOTS_INLINE)
+ return &slots->inline_slots[idx];
+ return &slots->spill[idx - FD_SLOTS_INLINE];
+}
+
+/* Room for slot @idx in the spill array, doubling as it fills up. */
+static noinline struct fd_slot *fd_slots_spill(struct fd_slots *slots,
+ unsigned int idx)
+{
+ unsigned int max = slots->spill_max;
+ struct fd_slot *spill;
+
+ idx -= FD_SLOTS_INLINE;
+ if (idx < max)
+ return &slots->spill[idx];
+
+ max = max ? max * 2 : FD_SLOTS_SPILL_MIN;
+ spill = kvrealloc(slots->spill, array_size(max, sizeof(*spill)),
+ GFP_KERNEL_ACCOUNT);
+ if (!spill)
+ return NULL;
+ slots->spill = spill;
+ slots->spill_max = max;
+ return &spill[idx];
+}
+
+/* Record @fd in the next slot, returns the slot. */
+static struct fd_slot *fd_slot_record(int fd)
+{
+ struct fd_slots *slots = ¤t->fd_slots;
+ unsigned int idx = slots->nr;
+ struct fd_slot *slot;
+
+ /* Nothing would ever commit what a kernel thread prepares. */
+ VFS_WARN_ON_ONCE(current->flags & PF_KTHREAD);
+
+ if (likely(idx < FD_SLOTS_INLINE)) {
+ slot = &slots->inline_slots[idx];
+ } else {
+ slot = fd_slots_spill(slots, idx);
+ if (!slot)
+ return ERR_PTR(-ENOMEM);
+ }
+ ACCESS_PRIVATE(slot, fd) = fd;
+ ACCESS_PRIVATE(slot, file) = NULL;
+ slots->nr = idx + 1;
+ return slot;
+}
+
+/* The slot holding @fd, if this syscall prepared it. */
+static inline int fd_slot_find(struct fd_slots *slots, unsigned int fd)
+{
+ unsigned int idx = slots->nr;
+
+ while (idx--) {
+ if (ACCESS_PRIVATE(fd_slot(slots, idx), fd) == fd)
+ return idx;
+ }
+ return -1;
+}
+
+/**
+ * fd_prepare - allocate a descriptor that the syscall exit installs
+ * @flags: O_CLOEXEC or 0
+ *
+ * Returns the prepared slot as a const handle or an error pointer.
+ */
+const struct fd_slot *fd_prepare(unsigned flags)
+{
+ struct fd_slot *slot;
+ int fd;
+
+ fd = get_unused_fd_flags(flags);
+ if (fd < 0)
+ return ERR_PTR(fd);
+
+ slot = fd_slot_record(fd);
+ if (IS_ERR(slot))
+ fd_release(fd);
+ return slot;
+}
+EXPORT_SYMBOL(fd_prepare);
+
+/**
+ * fd_stage - attach the file to a prepared slot
+ * @slot: slot from fd_prepare()
+ * @file: the file to install, consumed
+ *
+ * Returns the number. The syscall exit installs @file there when the syscall
+ * returns success and drops it when the syscall returns an error.
+ */
+int fd_stage(const struct fd_slot *slot, struct file *file)
+{
+ struct fd_slot *s = (struct fd_slot *)slot;
+
+ VFS_WARN_ON_ONCE(ACCESS_PRIVATE(s, file));
+ ACCESS_PRIVATE(s, file) = file;
+ return ACCESS_PRIVATE(s, fd);
+}
+EXPORT_SYMBOL(fd_stage);
+
+/**
+ * __fd_slot_fd - the descriptor number of a prepared slot
+ * @slot: slot from fd_prepare()
+ */
+int __fd_slot_fd(const struct fd_slot *slot)
+{
+ return ACCESS_PRIVATE(slot, fd);
+}
+EXPORT_SYMBOL(__fd_slot_fd);
+
+/**
+ * __fd_slot_file - the file staged into a slot, to configure before install
+ * @slot: slot from fd_prepare()
+ *
+ * Returns the file handed to fd_stage(), or NULL before one is staged.
+ */
+struct file *__fd_slot_file(const struct fd_slot *slot)
+{
+ return ACCESS_PRIVATE(slot, file);
+}
+EXPORT_SYMBOL(__fd_slot_file);
+
+/* Install every staged file, release the slots that never got one. */
+static void fd_slots_install(struct fd_slots *slots)
+{
+ unsigned int idx;
+
+ for (idx = 0; idx < slots->nr; idx++) {
+ struct fd_slot *slot = fd_slot(slots, idx);
+
+ if (ACCESS_PRIVATE(slot, file))
+ fd_install(ACCESS_PRIVATE(slot, fd),
+ ACCESS_PRIVATE(slot, file));
+ else
+ fd_release(ACCESS_PRIVATE(slot, fd));
+ }
+}
+
+/* Release every slot's descriptor and drop the staged files. */
+static void fd_slots_drop(struct fd_slots *slots)
+{
+ struct files_struct *files = current->files;
+ unsigned int idx;
+
+ spin_lock(&files->file_lock);
+ for (idx = 0; idx < slots->nr; idx++)
+ __put_unused_fd(files, ACCESS_PRIVATE(fd_slot(slots, idx), fd));
+ spin_unlock(&files->file_lock);
+ for (idx = 0; idx < slots->nr; idx++) {
+ struct fd_slot *slot = fd_slot(slots, idx);
+
+ if (ACCESS_PRIVATE(slot, file))
+ fput(ACCESS_PRIVATE(slot, file));
+ }
+}
+
+static __always_inline void fd_slots_finish(struct fd_slots *slots, bool failed)
+{
+ if (likely(!failed))
+ fd_slots_install(slots);
+ else
+ fd_slots_drop(slots);
+ slots->nr = 0;
+}
+
+/* Install or drop the prepared descriptors based on @ret. */
+void __fd_slots_commit(long ret)
+{
+ fd_slots_finish(¤t->fd_slots, IS_ERR_VALUE(ret));
+}
+
+void exit_fd_slots(void)
+{
+ struct fd_slots *slots = ¤t->fd_slots;
+
+ /* A syscall must not exit with prepared descriptors outstanding. */
+ if (WARN_ON_ONCE(slots->nr))
+ fd_slots_finish(slots, true);
+ kvfree(slots->spill);
+}
+
+/**
+ * put_unused_fd - give a descriptor back before it got a file
+ * @fd: descriptor returned by get_unused_fd_flags()
+ *
+ * Not for a prepared descriptor, the syscall exit releases that one.
+ */
+void put_unused_fd(unsigned int fd)
+{
+ VFS_WARN_ON_ONCE(fd_slot_find(¤t->fd_slots, fd) >= 0);
+ fd_release(fd);
+}
+
EXPORT_SYMBOL(put_unused_fd);
/*
diff --git a/include/linux/file.h b/include/linux/file.h
index 27484b444d31..fe2893eea945 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -91,6 +91,8 @@ extern bool get_close_on_exec(unsigned int fd);
extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile);
extern int get_unused_fd_flags(unsigned flags);
extern void put_unused_fd(unsigned int fd);
+void __fd_slots_commit(long ret);
+void exit_fd_slots(void);
DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T),
get_unused_fd_flags(flags), unsigned flags)
@@ -118,6 +120,12 @@ DEFINE_FREE(fput, struct file *, if (!IS_ERR_OR_NULL(_T)) fput(_T))
extern void fd_install(unsigned int fd, struct file *file);
+struct fd_slot;
+const struct fd_slot *fd_prepare(unsigned flags);
+int fd_stage(const struct fd_slot *slot, struct file *file);
+int __fd_slot_fd(const struct fd_slot *slot);
+struct file *__fd_slot_file(const struct fd_slot *slot);
+
int receive_fd(struct file *file, int __user *ufd, unsigned int o_flags);
int receive_fd_replace(int new_fd, struct file *file, unsigned int o_flags);
@@ -148,15 +156,32 @@ struct fd_prepare {
/* Typedef for fd_prepare cleanup guards. */
typedef struct fd_prepare class_fd_prepare_t;
+/* Do not use directly. */
+static inline int __fd_prepare_fd_old(struct fd_prepare fdf)
+{
+ return fdf.__fd;
+}
+
+/* Do not use directly. */
+static inline struct file *__fd_prepare_file_old(struct fd_prepare fdf)
+{
+ return fdf.__file;
+}
+
/*
- * Accessors for fd_prepare class members.
- * _Generic() is used for zero-cost type safety.
+ * Accessors for a prepared descriptor. _Generic() bridges struct fd_prepare
+ * (the cleanup class below) and struct fd_slot (fd_prepare()) while callers are
+ * converted; the struct fd_prepare arm goes away with FD_PREPARE().
*/
-#define fd_prepare_fd(_fdf) \
- (_Generic((_fdf), struct fd_prepare: (_fdf).__fd))
+#define fd_prepare_fd(_x) _Generic((_x), \
+ struct fd_prepare: __fd_prepare_fd_old, \
+ struct fd_slot *: __fd_slot_fd, \
+ const struct fd_slot *: __fd_slot_fd)(_x)
-#define fd_prepare_file(_fdf) \
- (_Generic((_fdf), struct fd_prepare: (_fdf).__file))
+#define fd_prepare_file(_x) _Generic((_x), \
+ struct fd_prepare: __fd_prepare_file_old, \
+ struct fd_slot *: __fd_slot_file, \
+ const struct fd_slot *: __fd_slot_file)(_x)
/* Do not use directly. */
static inline void class_fd_prepare_destructor(const struct fd_prepare *fdf)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8b3d47a325cc..52bbf9931908 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -832,6 +832,24 @@ struct task_ipi_mask {
struct task_ipi_mask { };
#endif
+/* Descriptors this syscall prepared, installed when it returns. */
+#define FD_SLOTS_INLINE 2
+
+struct file;
+
+struct fd_slot {
+ struct file * __private file;
+ int __private fd;
+};
+
+/* Inline up to FD_SLOTS_INLINE slots, the rest in the spill. */
+struct fd_slots {
+ unsigned int nr;
+ unsigned int spill_max;
+ struct fd_slot *spill;
+ struct fd_slot inline_slots[FD_SLOTS_INLINE];
+};
+
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
@@ -1206,6 +1224,9 @@ struct task_struct {
/* Open file information: */
struct files_struct *files;
+ /* Descriptors prepared by the current syscall: */
+ struct fd_slots fd_slots;
+
#ifdef CONFIG_IO_URING
struct io_uring_task *io_uring;
struct io_restriction *io_uring_restrict;
diff --git a/kernel/exit.c b/kernel/exit.c
index 97686af89501..ee108353a62c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1000,6 +1000,7 @@ void __noreturn do_exit(long code)
exit_sem(tsk);
exit_shm(tsk);
+ exit_fd_slots();
exit_files(tsk);
exit_fs(tsk);
if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
index 416758c8a3d4..59c5cfa3e482 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -980,6 +980,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
tsk->btrace_seq = 0;
#endif
tsk->splice_pipe = NULL;
+ memset(&tsk->fd_slots, 0, sizeof(tsk->fd_slots));
tsk->task_frag.page = NULL;
tsk->wake_q.next = NULL;
tsk->worker_private = NULL;
--
2.53.0
next prev parent reply other threads:[~2026-09-15 11:31 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 11:30 [PATCH RFC POC 00/50] file: handle files on syscall exit Christian Brauner
2026-09-15 11:30 ` Christian Brauner [this message]
2026-09-15 11:55 ` [PATCH RFC POC 01/50] file: install " sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 02/50] entry: commit fds " Christian Brauner
2026-09-15 11:52 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 03/50] alpha: " Christian Brauner
2026-09-15 11:50 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 04/50] ARC: " Christian Brauner
2026-09-15 11:48 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 05/50] ARM: " Christian Brauner
2026-09-15 11:59 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 06/50] arm64: " Christian Brauner
2026-09-15 11:48 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 07/50] csky: " Christian Brauner
2026-09-15 11:47 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 08/50] hexagon: " Christian Brauner
2026-09-15 11:49 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 09/50] m68k: " Christian Brauner
2026-09-15 11:50 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 10/50] microblaze: " Christian Brauner
2026-09-15 11:48 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 11/50] MIPS: " Christian Brauner
2026-09-15 11:45 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 12/50] nios2: " Christian Brauner
2026-09-15 11:54 ` sashiko-bot
2026-09-15 11:30 ` [PATCH RFC POC 13/50] openrisc: " Christian Brauner
2026-09-15 12:02 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 14/50] parisc: " Christian Brauner
2026-09-15 11:59 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 15/50] sh: " Christian Brauner
2026-09-15 11:55 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 16/50] sparc: " Christian Brauner
2026-09-15 11:57 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 17/50] um: " Christian Brauner
2026-09-15 11:55 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 18/50] xtensa: " Christian Brauner
2026-09-15 12:00 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 19/50] file: require the syscall exit hook from every architecture Christian Brauner
2026-09-15 11:54 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 20/50] file: warn when the descriptor table is unshared with slots Christian Brauner
2026-09-15 12:02 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 21/50] io_uring: commit fds per request Christian Brauner
2026-09-15 12:11 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 22/50] net: install SCM_RIGHTS descriptors when recvmsg() returns Christian Brauner
2026-09-15 12:03 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 23/50] file: open-code receive_fd()'s immediate install Christian Brauner
2026-09-15 12:00 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 24/50] file: make FD_ADD() a standalone " Christian Brauner
2026-09-15 12:01 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 25/50] file: reimplement FD_PREPARE() on the deferred fd_prepare() path Christian Brauner
2026-09-15 12:05 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 26/50] dma-buf: stop unwinding sync file descriptors by hand Christian Brauner
2026-09-15 12:05 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 27/50] drm/amdkfd: stop collecting CRIU dma-buf descriptors for a final install Christian Brauner
2026-09-15 12:04 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 28/50] drm/msm: install the out-fence descriptor when the ioctl returns Christian Brauner
2026-09-15 12:04 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 29/50] drm/virtio: " Christian Brauner
2026-09-15 12:11 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 30/50] drm/vmwgfx: " Christian Brauner
2026-09-15 12:09 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 31/50] vfio: install the migration data " Christian Brauner
2026-09-15 12:07 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 32/50] liveupdate: install the session descriptors " Christian Brauner
2026-09-15 12:09 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 33/50] io_uring/zcrx: install the exported descriptor when the request returns Christian Brauner
2026-09-15 12:09 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 34/50] sctp: install the peeloff descriptor when the syscall returns Christian Brauner
2026-09-15 12:14 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 35/50] ALSA: compress: install the task descriptors when the ioctl returns Christian Brauner
2026-09-15 12:13 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 36/50] nitro_enclaves: install the enclave descriptor " Christian Brauner
2026-09-15 12:13 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 37/50] tpm: vtpm_proxy: install the server " Christian Brauner
2026-09-15 12:14 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 38/50] perf: stop putting the event descriptor back on failure Christian Brauner
2026-09-15 12:12 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 39/50] seccomp: stop putting the listener " Christian Brauner
2026-09-15 12:14 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 40/50] KVM: stop putting descriptors " Christian Brauner
2026-09-15 12:15 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 41/50] KVM: guest_memfd: stop putting the descriptor " Christian Brauner
2026-09-15 12:16 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 42/50] drm: stop unwinding descriptors by hand Christian Brauner
2026-09-15 12:17 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 43/50] drm/amdgpu: stop unwinding the fence descriptor " Christian Brauner
2026-09-15 12:14 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 44/50] drm/etnaviv: install the out-fence descriptor when the ioctl returns Christian Brauner
2026-09-15 12:15 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 45/50] accel/habanalabs: stop putting the dma-buf descriptor back on failure Christian Brauner
2026-09-15 12:18 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 46/50] xen/gntdev-dmabuf: stop putting the " Christian Brauner
2026-09-15 12:21 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 47/50] iio: buffer: install the buffer descriptor when the ioctl returns Christian Brauner
2026-09-15 12:18 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 48/50] misc: fastrpc: install the dma-buf " Christian Brauner
2026-09-15 12:20 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 49/50] iommufd: stop putting descriptors back on failure Christian Brauner
2026-09-15 12:21 ` sashiko-bot
2026-09-15 11:31 ` [PATCH RFC POC 50/50] Drivers: hv: mshv: " Christian Brauner
2026-09-15 12:19 ` sashiko-bot
2026-09-15 16:02 ` [PATCH RFC POC 00/50] file: handle files on syscall exit Linus Torvalds
2026-09-15 22:21 ` Rob Clark
2026-09-15 22:54 ` Linus Torvalds
2026-09-16 7:09 ` Christian Brauner
2026-09-15 17:51 ` Jann Horn
2026-09-15 19:08 ` Linus Torvalds
2026-09-16 9:50 ` David Laight
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260915-work-fd-reserve-unify-folded-v1-1-4d5217d6b246@kernel.org \
--to=brauner@kernel.org \
--cc=airlied@redhat.com \
--cc=axboe@kernel.dk \
--cc=bpf@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=io-uring@vger.kernel.org \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=kexec@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-csky@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-hexagon@vger.kernel.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-openrisc@vger.kernel.org \
--cc=linux-parisc@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=linux-snps-arc@lists.infradead.org \
--cc=linux-um@lists.infradead.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mingo@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=sparclinux@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
--cc=virtualization@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox