From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org,
Alexander Viro <viro@zeniv.linux.org.uk>,
Jens Axboe <axboe@kernel.dk>, Jan Kara <jack@suse.cz>,
Tejun Heo <tj@kernel.org>, Jann Horn <jannh@google.com>,
Christian Brauner <brauner@kernel.org>
Subject: [PATCH RFC DRAFT POC 01/11] kthread: refactor __kthread_create_on_node() to take a struct argument
Date: Tue, 03 Mar 2026 14:49:12 +0100 [thread overview]
Message-ID: <20260303-work-kthread-nullfs-v1-1-87e559b94375@kernel.org> (raw)
In-Reply-To: <20260303-work-kthread-nullfs-v1-0-87e559b94375@kernel.org>
Refactor __kthread_create_on_node() to take a const struct
kthread_create_info pointer instead of individual parameters. The
caller fills in the relevant fields in a stack-local struct and the
helper heap-copies it, making it trivial to add new kthread creation
options without changing the function signature.
As part of this, collapse __kthread_create_worker_on_node() into
__kthread_create_on_node() by adding a kthread_worker:1 bitfield to
struct kthread_create_info. When set, the unified helper allocates and
initializes the kthread_worker internally, removing the need for a
separate helper.
Also switch create_kthread() from the kernel_thread() wrapper to
constructing struct kernel_clone_args directly and calling
kernel_clone(). This makes the clone flags explicit and prepares for
passing richer per-kthread arguments through kernel_clone_args in
subsequent patches.
No functional change.
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
kernel/kthread.c | 87 +++++++++++++++++++++++++++++++-------------------------
1 file changed, 48 insertions(+), 39 deletions(-)
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 791210daf8b4..84d535c7a635 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -45,6 +45,7 @@ struct kthread_create_info
int (*threadfn)(void *data);
void *data;
int node;
+ u32 kthread_worker:1;
/* Result passed back to kthread_create() from kthreadd. */
struct task_struct *result;
@@ -451,13 +452,20 @@ int tsk_fork_get_node(struct task_struct *tsk)
static void create_kthread(struct kthread_create_info *create)
{
int pid;
+ struct kernel_clone_args args = {
+ .flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED,
+ .exit_signal = SIGCHLD,
+ .fn = kthread,
+ .fn_arg = create,
+ .name = create->full_name,
+ .kthread = 1,
+ };
#ifdef CONFIG_NUMA
current->pref_node_fork = create->node;
#endif
/* We want our own signal handler (we take no signals by default). */
- pid = kernel_thread(kthread, create, create->full_name,
- CLONE_FS | CLONE_FILES | SIGCHLD);
+ pid = kernel_clone(&args);
if (pid < 0) {
/* Release the structure when caller killed by a fatal signal. */
struct completion *done = xchg(&create->done, NULL);
@@ -472,21 +480,32 @@ static void create_kthread(struct kthread_create_info *create)
}
}
-static __printf(4, 0)
-struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
- void *data, int node,
+static struct task_struct *__kthread_create_on_node(const struct kthread_create_info *info,
const char namefmt[],
va_list args)
{
DECLARE_COMPLETION_ONSTACK(done);
+ struct kthread_worker *worker = NULL;
struct task_struct *task;
- struct kthread_create_info *create = kmalloc_obj(*create);
+ struct kthread_create_info *create;
+ create = kmalloc_obj(*create);
if (!create)
return ERR_PTR(-ENOMEM);
- create->threadfn = threadfn;
- create->data = data;
- create->node = node;
+
+ *create = *info;
+
+ if (create->kthread_worker) {
+ worker = kzalloc_obj(*worker);
+ if (!worker) {
+ kfree(create);
+ return ERR_PTR(-ENOMEM);
+ }
+ kthread_init_worker(worker);
+ create->threadfn = kthread_worker_fn;
+ create->data = worker;
+ }
+
create->done = &done;
create->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
if (!create->full_name) {
@@ -520,6 +539,8 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
}
task = create->result;
free_create:
+ if (IS_ERR(task))
+ kfree(worker);
kfree(create);
return task;
}
@@ -552,11 +573,16 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
const char namefmt[],
...)
{
+ struct kthread_create_info info = {
+ .threadfn = threadfn,
+ .data = data,
+ .node = node,
+ };
struct task_struct *task;
va_list args;
va_start(args, namefmt);
- task = __kthread_create_on_node(threadfn, data, node, namefmt, args);
+ task = __kthread_create_on_node(&info, namefmt, args);
va_end(args);
return task;
@@ -1045,34 +1071,6 @@ int kthread_worker_fn(void *worker_ptr)
}
EXPORT_SYMBOL_GPL(kthread_worker_fn);
-static __printf(3, 0) struct kthread_worker *
-__kthread_create_worker_on_node(unsigned int flags, int node,
- const char namefmt[], va_list args)
-{
- struct kthread_worker *worker;
- struct task_struct *task;
-
- worker = kzalloc_obj(*worker);
- if (!worker)
- return ERR_PTR(-ENOMEM);
-
- kthread_init_worker(worker);
-
- task = __kthread_create_on_node(kthread_worker_fn, worker,
- node, namefmt, args);
- if (IS_ERR(task))
- goto fail_task;
-
- worker->flags = flags;
- worker->task = task;
-
- return worker;
-
-fail_task:
- kfree(worker);
- return ERR_CAST(task);
-}
-
/**
* kthread_create_worker_on_node - create a kthread worker
* @flags: flags modifying the default behavior of the worker
@@ -1086,13 +1084,24 @@ __kthread_create_worker_on_node(unsigned int flags, int node,
struct kthread_worker *
kthread_create_worker_on_node(unsigned int flags, int node, const char namefmt[], ...)
{
+ struct kthread_create_info info = {
+ .node = node,
+ .kthread_worker = 1,
+ };
struct kthread_worker *worker;
+ struct task_struct *task;
va_list args;
va_start(args, namefmt);
- worker = __kthread_create_worker_on_node(flags, node, namefmt, args);
+ task = __kthread_create_on_node(&info, namefmt, args);
va_end(args);
+ if (IS_ERR(task))
+ return ERR_CAST(task);
+
+ worker = kthread_data(task);
+ worker->flags = flags;
+ worker->task = task;
return worker;
}
EXPORT_SYMBOL(kthread_create_worker_on_node);
--
2.47.3
next prev parent reply other threads:[~2026-03-03 13:49 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-03 13:49 [PATCH RFC DRAFT POC 00/11] fs,kthread: isolate all kthreads in nullfs Christian Brauner
2026-03-03 13:49 ` Christian Brauner [this message]
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 02/11] kthread: remove unused flags argument from kthread worker creation API Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 03/11] kthread: add extensible kthread_create()/kthread_run() pattern Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 04/11] fs: notice when init abandons fs sharing Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 05/11] fs: add LOOKUP_IN_INIT Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 06/11] fs: add file_open_init() Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 07/11] block: add bdev_file_open_init() Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 08/11] fs: allow to pass lookup flags to filename_*() Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 09/11] fs: add init_root() Christian Brauner
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 10/11] tree-wide: make all kthread path lookups to use LOOKUP_IN_INIT Christian Brauner
2026-03-03 15:03 ` Christoph Hellwig
2026-03-03 13:49 ` [PATCH RFC DRAFT POC 11/11] fs: isolate all kthreads in nullfs Christian Brauner
2026-03-06 7:26 ` [PATCH RFC DRAFT POC 00/11] fs,kthread: " Askar Safin
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=20260303-work-kthread-nullfs-v1-1-87e559b94375@kernel.org \
--to=brauner@kernel.org \
--cc=axboe@kernel.dk \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/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