[PATCH 03/11] kthread: Pass in the thread's name during creation

Mike Christie
2023-03-10T22:05:47Z

This has us pass in the thread's name during creation in kernel_thread.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
kernel/kthread.c | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/kernel/kthread.c b/kernel/kthread.c
index 63574cee925e..831a55b406d8 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -38,6 +38,7 @@ struct task_struct *kthreadd_task;
struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
+ char *full_name;
int (*threadfn)(void *data);
void *data;
int node;
@@ -343,10 +344,15 @@ static int kthread(void *_create)
/* Release the structure when caller killed by a fatal signal. */
done = xchg(&create->done, NULL);
if (!done) {
+ kfree(create->full_name);
kfree(create);
kthread_exit(-EINTR);
}

+ if (strlen(create->full_name) >= TASK_COMM_LEN)
+ self->full_name = create->full_name;
+ else
+ kfree(create->full_name);
self->threadfn = threadfn;
self->data = data;

@@ -396,12 +402,13 @@ static void create_kthread(struct kthread_create_info *create)
current->pref_node_fork = create->node;
#endif
/* We want our own signal handler (we take no signals by default). */
- pid = kernel_thread(kthread, create, NULL,
+ pid = kernel_thread(kthread, create, create->full_name,
CLONE_FS | CLONE_FILES | SIGCHLD);
if (pid < 0) {
/* Release the structure when caller killed by a fatal signal. */
struct completion *done = xchg(&create->done, NULL);

+ kfree(create->full_name);
if (!done) {
kfree(create);
return;
@@ -428,6 +435,11 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
create->data = data;
create->node = node;
create->done = &done;
+ create->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
+ if (!create->full_name) {
+ task = ERR_PTR(-ENOMEM);
+ goto free_create;
+ }

spin_lock(&kthread_create_lock);
list_add_tail(&create->list, &kthread_create_list);
@@ -454,26 +466,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
wait_for_completion(&done);
}
task = create->result;
- if (!IS_ERR(task)) {
- char name[TASK_COMM_LEN];
- va_list aq;
- int len;
-
- /*
- * task is already visible to other tasks, so updating
- * COMM must be protected.
- */
- va_copy(aq, args);
- len = vsnprintf(name, sizeof(name), namefmt, aq);
- va_end(aq);
- if (len >= TASK_COMM_LEN) {
- struct kthread *kthread = to_kthread(task);
-
- /* leave it truncated when out of memory. */
- kthread->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
- }
- set_task_comm(task, name);
- }
+free_create:
kfree(create);
return task;
}
--
2.25.1