[PATCH 4/5] kernel: increase the size of kthread's comm

From: Yafang Shao
Date: Wed Sep 29 2021 - 07:51:32 EST


Some of the kthreads' comm are trucated due to the limitation of
TASK_COMM_LEN, for example,

rcu_tasks_kthre
rcu_tasks_rude_
rcu_tasks_trace
ecryptfs-kthrea
vfio-irqfd-clea
ext4-rsv-conver
jbd2/nvme0n1p2-
...

Besides the in-tree kthreads listed above, the out-of-tree kthreads may
also be trucated, for example,

rtase_work_queu
nvidia-modeset/
UVM global queu
UVM deferred re
...

That is not expected by the author of these kthreads.

This patch increases the size of ktread's comm from 16 to 24, which is
the same with workqueue's, to improve this situation. After this cahnge,
the name of kthread can be fully displayed in /proc/[pid]/comm,
for example,

rcu_tasks_kthread
rcu_tasks_rude_kthread
rcu_tasks_trace_kthread
ecryptfs-kthread
vfio-irqfd-cleanup
ext4-rsv-conversion
jbd2/nvme0n1p2-8
...

Because there're only a few of kthreads, so it won't increase too much
memory.

Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx>
---
fs/exec.c | 5 ++++-
include/linux/sched.h | 2 ++
kernel/fork.c | 9 ++++++++-
kernel/kthread.c | 2 +-
4 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 021c9dc727bc..4bf0501b7766 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1222,9 +1222,12 @@ EXPORT_SYMBOL_GPL(__get_task_comm);

void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
{
+ size_t size;
+
task_lock(tsk);
trace_task_rename(tsk, buf);
- strscpy(tsk->comm, buf, TASK_COMM_LEN);
+ size = tsk->flags & PF_KTHREAD ? KTHREAD_COMM_LEN : TASK_COMM_LEN;
+ strscpy(tsk->comm, buf, size);
task_unlock(tsk);
perf_event_comm(tsk, exec);
}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 959eaef248fc..6b336eba4ff6 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -276,6 +276,8 @@ struct task_group;

/* Task command name length: */
#define TASK_COMM_LEN 16
+/* KTHREAD_COMM_LEN must be >= TASK_COMM_LEN */
+#define KTHREAD_COMM_LEN 24

extern void scheduler_tick(void);

diff --git a/kernel/fork.c b/kernel/fork.c
index 227aec240501..a2939353383d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -723,7 +723,14 @@ static void mmdrop_async(struct mm_struct *mm)

static int task_comm_alloc(struct task_struct *p)
{
- p->comm = kzalloc(TASK_COMM_LEN, GFP_KERNEL);
+ size_t size;
+
+ /*
+ * PF_KTHREAD may be cleared in exec, but the allocated memory can
+ * be safely freed.
+ */
+ size = p->flags & PF_KTHREAD ? KTHREAD_COMM_LEN : TASK_COMM_LEN;
+ p->comm = kzalloc(size, GFP_KERNEL);
if (!p->comm)
return -ENOMEM;

diff --git a/kernel/kthread.c b/kernel/kthread.c
index 5b37a8567168..6def951c605a 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -398,7 +398,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
task = create->result;
if (!IS_ERR(task)) {
static const struct sched_param param = { .sched_priority = 0 };
- char name[TASK_COMM_LEN];
+ char name[KTHREAD_COMM_LEN];

/*
* task is already visible to other tasks, so updating
--
2.17.1