diff mbox series

[RFC,5/9] kernel/fork: Add helper to fork from io_uring

Message ID 20241209234316.4132786-6-krisman@suse.de (mailing list archive)
State New
Headers show
Series Launching processes with io_uring | expand

Commit Message

Gabriel Krisman Bertazi Dec. 9, 2024, 11:43 p.m. UTC
From: Josh Triplett <josh@joshtriplett.org>

Introduce a helper to fork a new process from io_uring.  This is
different from the io_uring io_worker in multiple ways: First, it can
return to userspace following a execve, doesn't have PF_USER_WORKER set,
and doesn't share most process structures with the  the parent.  It
shares the MM though, allowing the helper to do limited io_uring
operations.

The sole use of this is the io_uring OP_CLONE command, which prepares
the ground for EXECVE from io_uring.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Co-developed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
---
 include/linux/sched/task.h |  1 +
 kernel/fork.c              | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 0f2aeb37bbb0..a76f05a886ad 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -98,6 +98,7 @@  extern pid_t kernel_clone(struct kernel_clone_args *kargs);
 struct task_struct *copy_process(struct pid *pid, int trace, int node,
 				 struct kernel_clone_args *args);
 struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
+struct task_struct *create_io_uring_spawn_task(int (*fn)(void *), void *arg);
 struct task_struct *fork_idle(int);
 extern pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
 			    unsigned long flags);
diff --git a/kernel/fork.c b/kernel/fork.c
index 56baa320a720..fa983a0614ce 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2757,6 +2757,25 @@  struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
 	return copy_process(NULL, 0, node, &args);
 }
 
+/*
+ * This is like kernel_clone(), but shaved down and tailored for io_uring_spawn.
+ * It returns a created task, or an error pointer. The returned task is
+ * inactive, and the caller must fire it up through wake_up_new_task(p).
+ */
+struct task_struct *create_io_uring_spawn_task(int (*fn)(void *), void *arg)
+{
+	unsigned long flags = CLONE_CLEAR_SIGHAND;
+	struct kernel_clone_args args = {
+		.flags		= ((lower_32_bits(flags) | CLONE_VM |
+				    CLONE_UNTRACED) & ~CSIGNAL),
+		.exit_signal	= (lower_32_bits(flags) & CSIGNAL),
+		.fn		= fn,
+		.fn_arg		= arg,
+	};
+
+	return copy_process(NULL, 0, NUMA_NO_NODE, &args);
+}
+
 /*
  *  Ok, this is the main fork-routine.
  *