Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH v8 0/6] sched: Add support for long task name
@ 2026-10-30 21:38 André Almeida
  2026-10-30 21:38 ` [PATCH v8 1/6] treewide: Get rid of get_task_comm() André Almeida
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

* Use case

When debugging and tracing complex programs with hundreds of threads, 16 bytes
long thread names are not enough anymore. cmd_line can show a lot of
characters, but it's not affected by pthread_setname_np() or
prctl(PR_SET_NAME), so let's give the same love kthreads got with commit
6b59808bfe48 ("workqueue: Show the latest workqueue name in 
/proc/PID/{comm,stat,status}"). This patchset creates a new
PR_{SET,GET}_EXT_NAME that supports 64 bytes long names.

It also introduces a new function copy_task_comm() that ensures that the string
is always NUL-terminated despite of mismatching sizes of buffers. We can't just
use strscpy() because it proved to give some overhead [0] in tracing.

* Patchset

Patch 1 and 2 do some prep work in order to avoid buffer overflows around
the kernel, now that current->comm is bigger. It also make sure that if
the destination buffer is smaller than TASK_COMM_EXT_LEN, it will
be NUL-terminated.

Patch 3 adds a KUnit for the new function copy_task_comm()

Patch 4 sets current->comm length to TASK_COMM_EXT_LEN and take care of
making sure that current userspace APIs gets only TASK_COMM_LEN.

Patch 5 creates new prctl() to set and get all the TASK_COMM_EXT_LEN bytes.

Patch 6 adapts the existing selftest for this new interface.

* Testing

selftests/prctl/set-process-name.c survives this patchset, and it was extended
to the new interface. KUnit test was modified to support copy_task_comm().

I ran the same benchmark as at [0], and no significant change was found.

* Changes

Changes in v8:
- Rebased on top of 7.4 and collected tags
- Added a explanation about out of bounds read at patch 4/6.
- Link to v7: https://patch.msgid.link/20260911-tonyk-long_name-v7-0-34e1ee1564ae@igalia.com

Changes in v7:
- Fixed build errors (for good): bpf test and security/smack
- Link to v6: https://patch.msgid.link/20260910-tonyk-long_name-v6-0-d70afbf194c5@igalia.com

Since v6:
- Fix build error in security/
- Fix size of comm buffer for i915 and blktrace
- Fix KUnit test logic
- Link to v5: https://patch.msgid.link/20260827-tonyk-long_name-v5-0-5fa843782a00@igalia.com

Since v4:
- Remove copy_task_comm() calls for structs other than struct task_struct
- copy_task_comm(): Add checks for len > TASK_COMM_LEN and len < 0
- Link to v4: https://patch.msgid.link/20260717-tonyk-long_name-v4-0-1fedfc870d21@igalia.com

Since v3:
 - Simplify Get rid of get_task_comm() commit
 - Simplify copy_task_comm(): just do a memcpy + NUL char at the end
 - Link to v3: https://patch.msgid.link/20260612-tonyk-long_name-v3-0-7989b66e8a99@igalia.com

Since v2:
 - Add a custom function copy_task_comm() that uses memcpy when possible and
 fallback to strscpy(). It always ensures that the string in NUL-terminated
 - Add KUnit test for the new function
 - Link to v2: https://patch.msgid.link/20260524-tonyk-long_name-v2-0-332f6bd041c4@igalia.com

Since v1:
 - Replace new strtostr() with strscpy()
 - Don't replace memcpy in tools/
 - Link to v1: https://patch.msgid.link/20260517-tonyk-long_name-v1-0-3c282eaa91e2@igalia.com

[0] https://lore.kernel.org/lkml/20260526190625.3f4aca0a@gandalf.local.home/

---
André Almeida (6):
      treewide: Get rid of get_task_comm()
      treewide: Replace memcpy(..., current->comm) with copy_task_comm()
      lib/string_kunit: Add test for copy_task_comm()
      sched: Extend task command name with TASK_COMM_EXT_LEN
      prctl: Add support for long user thread names
      selftests: prctl: Add test for long thread names

 drivers/connector/cn_proc.c                        |  2 +-
 drivers/dma-buf/sw_sync.c                          |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c    |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c       |  2 +-
 .../gpu/drm/i915/display/intel_display_driver.c    |  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c        |  4 +-
 drivers/gpu/drm/lima/lima_ctx.c                    |  2 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c            |  2 +-
 drivers/gpu/drm/panthor/panthor_gem.c              |  2 +-
 drivers/gpu/drm/panthor/panthor_sched.c            |  2 +-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c             |  2 +-
 drivers/hwtracing/stm/core.c                       |  2 +-
 drivers/tty/tty_audit.c                            |  2 +-
 fs/binfmt_elf.c                                    |  2 +-
 fs/binfmt_elf_fdpic.c                              |  2 +-
 fs/proc/array.c                                    |  2 +-
 include/linux/coredump.h                           |  2 +-
 include/linux/sched.h                              | 33 ++++++-------
 include/linux/tracepoint.h                         |  4 +-
 include/trace/events/block.h                       | 10 ++--
 include/trace/events/coredump.h                    |  2 +-
 include/trace/events/f2fs.h                        |  4 +-
 include/trace/events/oom.h                         |  2 +-
 include/trace/events/osnoise.h                     |  2 +-
 include/trace/events/sched.h                       | 10 ++--
 include/trace/events/signal.h                      |  2 +-
 include/trace/events/task.h                        |  4 +-
 include/uapi/linux/prctl.h                         |  3 ++
 kernel/audit.c                                     |  6 ++-
 kernel/auditsc.c                                   |  6 ++-
 kernel/printk/printk.c                             |  2 +-
 kernel/sys.c                                       | 23 +++++++--
 kernel/trace/blktrace.c                            |  6 ++-
 lib/tests/string_kunit.c                           | 38 +++++++++++++++
 net/bluetooth/hci_sock.c                           |  2 +-
 net/netfilter/nf_tables_api.c                      |  4 +-
 security/integrity/integrity_audit.c               |  3 +-
 security/ipe/audit.c                               |  3 +-
 security/landlock/domain.c                         |  2 +-
 security/lsm_audit.c                               |  7 +--
 security/smack/smack_access.c                      |  4 +-
 security/smack/smack_lsm.c                         |  4 +-
 .../selftests/bpf/test_kmods/bpf_testmod-events.h  |  2 +-
 tools/testing/selftests/prctl/set-process-name.c   | 57 +++++++++++++++++++---
 48 files changed, 200 insertions(+), 93 deletions(-)
---
base-commit: 4dd16e31135ea8437a720222df34e8745f385d6d
change-id: 20260516-tonyk-long_name-b9f345aeb041

Best regards,
--  
André Almeida <andrealmeid@igalia.com>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v8 1/6] treewide: Get rid of get_task_comm()
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
@ 2026-10-30 21:38 ` André Almeida
  2026-10-30 21:38 ` [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm() André Almeida
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

Since commit 4cc0473d7754 ("get rid of __get_task_comm()"),
get_task_comm() does just a redundant check for the buffer size and call
strscpy_pad(). Replace get_task_comm() calls with strscpy_pad(), that will
do the right thing if the buffers sizes doesn't match: zero-pad if it's
bigger, and truncate if it's smaller.

Link: https://lore.kernel.org/lkml/CAHk-=wi5c=_-FBGo_88CowJd_F-Gi6Ud9d=TALm65ReN7YjrMw@mail.gmail.com/
Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes from v1:
 - Fix for security/ipe/audit.c and net/netfilter/nf_tables_api.c
---
 drivers/connector/cn_proc.c                        |  2 +-
 drivers/dma-buf/sw_sync.c                          |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c    |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c       |  2 +-
 drivers/gpu/drm/lima/lima_ctx.c                    |  2 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c            |  2 +-
 drivers/gpu/drm/panthor/panthor_gem.c              |  2 +-
 drivers/gpu/drm/panthor/panthor_sched.c            |  2 +-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c             |  2 +-
 drivers/hwtracing/stm/core.c                       |  2 +-
 drivers/tty/tty_audit.c                            |  2 +-
 fs/binfmt_elf.c                                    |  2 +-
 fs/binfmt_elf_fdpic.c                              |  2 +-
 fs/proc/array.c                                    |  2 +-
 include/linux/sched.h                              | 19 -------------------
 kernel/audit.c                                     |  6 ++++--
 kernel/auditsc.c                                   |  6 ++++--
 kernel/printk/printk.c                             |  2 +-
 kernel/sys.c                                       |  2 +-
 net/bluetooth/hci_sock.c                           |  2 +-
 net/netfilter/nf_tables_api.c                      |  4 +++-
 security/integrity/integrity_audit.c               |  3 ++-
 security/ipe/audit.c                               |  3 ++-
 security/landlock/domain.c                         |  2 +-
 security/lsm_audit.c                               |  7 ++++---
 security/smack/smack_access.c                      |  4 ++--
 security/smack/smack_lsm.c                         |  4 +++-
 31 files changed, 47 insertions(+), 55 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 0056ab81fbc3..c78243ed3c2a 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -278,7 +278,7 @@ void proc_comm_connector(struct task_struct *task)
 	ev->what = PROC_EVENT_COMM;
 	ev->event_data.comm.process_pid  = task->pid;
 	ev->event_data.comm.process_tgid = task->tgid;
-	get_task_comm(ev->event_data.comm.comm, task);
+	strscpy_pad(ev->event_data.comm.comm, task->comm);
 
 	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
 	msg->ack = 0; /* not used */
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 8df20b0218a9..d501657ad801 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -312,7 +312,7 @@ static int sw_sync_debugfs_open(struct inode *inode, struct file *file)
 	struct sync_timeline *obj;
 	char task_comm[TASK_COMM_LEN];
 
-	get_task_comm(task_comm, current);
+	strscpy_pad(task_comm, current->comm);
 
 	obj = sync_timeline_create(task_comm);
 	if (!obj)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c
index 9b10d015671c..2c92bb12c269 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c
@@ -73,7 +73,7 @@ struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
 	/* This reference gets released in amdkfd_fence_release */
 	mmgrab(mm);
 	fence->mm = mm;
-	get_task_comm(fence->timeline_name, current);
+	strscpy_pad(fence->timeline_name, current->comm);
 	spin_lock_init(&fence->lock);
 	fence->context_id = context_id;
 	dma_fence_init(&fence->base, &amdkfd_fence_ops, &fence->lock,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
index f8652fd0525d..1700898add72 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
@@ -131,7 +131,7 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_eviction_fence_mgr *evf_mgr,
 		return -ENOMEM;
 
 	ev_fence->evf_mgr = evf_mgr;
-	get_task_comm(ev_fence->timeline_name, current);
+	strscpy_pad(ev_fence->timeline_name, current->comm);
 	spin_lock_init(&ev_fence->lock);
 	dma_fence_init64(&ev_fence->base, &amdgpu_eviction_fence_ops,
 			 &ev_fence->lock, evf_mgr->ev_fence_ctx,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 47e852c15c36..3f5a0fa2dba2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -3721,7 +3721,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
 	}
 
 	con->init_task_pid = task_pid_nr(current);
-	get_task_comm(con->init_task_comm, current);
+	strscpy_pad(con->init_task_comm, current->comm);
 
 	mutex_init(&con->critical_region_lock);
 	INIT_LIST_HEAD(&con->critical_region_head);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index c1257f530e9a..58086a7c06ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -85,7 +85,7 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
 
 	fence_drv->adev = adev;
 	fence_drv->context = dma_fence_context_alloc(1);
-	get_task_comm(fence_drv->timeline_name, current);
+	strscpy_pad(fence_drv->timeline_name, current->comm);
 
 	*fence_drv_req = fence_drv;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 2bd07007def4..825b6c721fa0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2585,10 +2585,10 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
 	}
 
 	vm->task_info->task.pid = current->pid;
-	get_task_comm(vm->task_info->task.comm, current);
+	strscpy_pad(vm->task_info->task.comm, current->comm);
 
 	vm->task_info->tgid = current->tgid;
-	get_task_comm(vm->task_info->process_name, current->group_leader);
+	strscpy_pad(vm->task_info->process_name, current->group_leader->comm);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 249f07f30951..d6f32bc44aef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -565,7 +565,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
 	}
 
 	vres->task.pid = task_pid_nr(current);
-	get_task_comm(vres->task.comm, current);
+	strscpy_pad(vres->task.comm, current->comm);
 	list_add_tail(&vres->vres_node, &mgr->allocated_vres_list);
 
 	if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS && adjust_dcc_size) {
diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
index 68ede7a725e2..e8c5c3601bf1 100644
--- a/drivers/gpu/drm/lima/lima_ctx.c
+++ b/drivers/gpu/drm/lima/lima_ctx.c
@@ -29,7 +29,7 @@ int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
 		goto err_out0;
 
 	ctx->pid = task_pid_nr(current);
-	get_task_comm(ctx->pname, current);
+	strscpy_pad(ctx->pname, current->comm);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 518f24549b9d..4ddf95407aed 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -48,7 +48,7 @@ static void panfrost_gem_debugfs_bo_add(struct panfrost_device *pfdev,
 					struct panfrost_gem_object *bo)
 {
 	bo->debugfs.creator.tgid = current->tgid;
-	get_task_comm(bo->debugfs.creator.process_name, current->group_leader);
+	strscpy_pad(bo->debugfs.creator.process_name, current->group_leader->comm);
 
 	mutex_lock(&pfdev->debugfs.gems_lock);
 	list_add_tail(&bo->debugfs.node, &pfdev->debugfs.gems_list);
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 22b57ab6f929..a598e077f76a 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -54,7 +54,7 @@ static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo)
 						    struct panthor_device, base);
 
 	bo->debugfs.creator.tgid = current->tgid;
-	get_task_comm(bo->debugfs.creator.process_name, current->group_leader);
+	strscpy_pad(bo->debugfs.creator.process_name, current->group_leader->comm);
 
 	mutex_lock(&ptdev->gems.lock);
 	list_add_tail(&bo->debugfs.node, &ptdev->gems.node);
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index a343c5180e01..4954044decd4 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -3595,7 +3595,7 @@ static void group_init_task_info(struct panthor_group *group)
 	struct task_struct *task = current->group_leader;
 
 	group->task_info.pid = task->pid;
-	get_task_comm(group->task_info.comm, task);
+	strscpy_pad(group->task_info.comm, task->comm);
 }
 
 static void add_group_kbo_sizes(struct panthor_device *ptdev,
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 81e70a12b356..eb486b147461 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -50,7 +50,7 @@ static void virtio_gpu_create_context_locked(struct virtio_gpu_device *vgdev,
 	} else {
 		char dbgname[TASK_COMM_LEN];
 
-		get_task_comm(dbgname, current);
+		strscpy_pad(dbgname, current->comm);
 		virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id,
 					      vfpriv->context_init, strlen(dbgname),
 					      dbgname);
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index f48c6a8a0654..c7715439964e 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -634,7 +634,7 @@ static ssize_t stm_char_write(struct file *file, const char __user *buf,
 		char comm[sizeof(current->comm)];
 		char *ids[] = { comm, "default", NULL };
 
-		get_task_comm(comm, current);
+		strscpy_pad(comm, current->comm);
 
 		err = stm_assign_first_policy(stmf->stm, &stmf->output, ids, 1);
 		/*
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index d014af6ab060..d514a81d0a5c 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -77,7 +77,7 @@ static void tty_audit_log(const char *description, dev_t dev,
 	audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d minor=%d comm=",
 			 description, pid, uid, loginuid, sessionid,
 			 MAJOR(dev), MINOR(dev));
-	get_task_comm(name, current);
+	strscpy_pad(name, current->comm);
 	audit_log_untrustedstring(ab, name);
 	audit_log_format(ab, " data=");
 	audit_log_n_hex(ab, data, size);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bf7f8f47548d..cd59409a7975 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1554,7 +1554,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
 	SET_UID(psinfo->pr_uid, from_kuid_munged(cred->user_ns, cred->uid));
 	SET_GID(psinfo->pr_gid, from_kgid_munged(cred->user_ns, cred->gid));
 	rcu_read_unlock();
-	get_task_comm(psinfo->pr_fname, p);
+	strscpy_pad(psinfo->pr_fname, p->comm);
 
 	return 0;
 }
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index d3872169f55e..9e3ba25e4c8f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1376,7 +1376,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
 	SET_UID(psinfo->pr_uid, from_kuid_munged(cred->user_ns, cred->uid));
 	SET_GID(psinfo->pr_gid, from_kgid_munged(cred->user_ns, cred->gid));
 	rcu_read_unlock();
-	get_task_comm(psinfo->pr_fname, p);
+	strscpy_pad(psinfo->pr_fname, p->comm);
 
 	return 0;
 }
diff --git a/fs/proc/array.c b/fs/proc/array.c
index f6f75d206762..8ebb7cf1a7b0 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -110,7 +110,7 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
 	else if (p->flags & PF_KTHREAD)
 		get_kthread_comm(tcomm, sizeof(tcomm), p);
 	else
-		get_task_comm(tcomm, p);
+		strscpy_pad(tcomm, p->comm);
 
 	if (escape)
 		seq_escape_str(m, tcomm, ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1c93da75226e..0564aabb1393 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2042,25 +2042,6 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
 	__set_task_comm(tsk, from, false);		\
 })
 
-/*
- * - Why not use task_lock()?
- *   User space can randomly change their names anyway, so locking for readers
- *   doesn't make sense. For writers, locking is probably necessary, as a race
- *   condition could lead to long-term mixed results.
- *   The strscpy_pad() in __set_task_comm() can ensure that the task comm is
- *   always NUL-terminated and zero-padded. Therefore the race condition between
- *   reader and writer is not an issue.
- *
- * - BUILD_BUG_ON() can help prevent the buf from being truncated.
- *   Since the callers don't perform any return value checks, this safeguard is
- *   necessary.
- */
-#define get_task_comm(buf, tsk) ({			\
-	BUILD_BUG_ON(sizeof(buf) < TASK_COMM_LEN);	\
-	strscpy_pad(buf, (tsk)->comm);			\
-	buf;						\
-})
-
 static __always_inline void scheduler_ipi(void)
 {
 	/*
diff --git a/kernel/audit.c b/kernel/audit.c
index 631d6d4a23cf..08e9d97f2a82 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1667,7 +1667,8 @@ static void audit_log_multicast(int group, const char *op, int err)
 	audit_put_tty(tty);
 	audit_log_task_context(ab); /* subj= */
 	audit_log_format(ab, " comm=");
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 	audit_log_d_path_exe(ab, current->mm); /* exe= */
 	audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err);
 	audit_log_end(ab);
@@ -2483,7 +2484,8 @@ void audit_log_task_info(struct audit_buffer *ab)
 			 audit_get_sessionid(current));
 	audit_put_tty(tty);
 	audit_log_format(ab, " comm=");
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 	audit_log_d_path_exe(ab, current->mm);
 	audit_log_task_context(ab);
 }
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 552ba9f4fb0a..545388e5ac29 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2881,7 +2881,8 @@ void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
 	audit_log_format(ab, " pid=%u", task_tgid_nr(current));
 	audit_log_task_context(ab); /* subj= */
 	audit_log_format(ab, " comm=");
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 	audit_log_end(ab);
 }
 EXPORT_SYMBOL_GPL(__audit_log_nfcfg);
@@ -2917,7 +2918,8 @@ static void audit_log_task(struct audit_buffer *ab)
 			 sessionid);
 	audit_log_task_context(ab);
 	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 	audit_log_d_path_exe(ab, current->mm);
 }
 
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9a205f94bfac..6d9cd4d96003 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2247,7 +2247,7 @@ static u16 printk_sprint(char *text, u16 size, int facility,
 static void printk_store_execution_ctx(struct printk_info *info)
 {
 	info->caller_id2 = printk_caller_id2();
-	get_task_comm(info->comm, current);
+	strscpy_pad(info->comm, current->comm);
 }
 
 static void pmsg_load_execution_ctx(struct printk_message *pmsg,
diff --git a/kernel/sys.c b/kernel/sys.c
index 755bfa5ccd92..31eef656dbd6 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2612,7 +2612,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		proc_comm_connector(me);
 		break;
 	case PR_GET_NAME:
-		get_task_comm(comm, me);
+		strscpy_pad(comm, me->comm);
 		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
 			return -EFAULT;
 		break;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 3da994d1fe65..82b6511c7d01 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -104,7 +104,7 @@ static bool hci_sock_gen_cookie(struct sock *sk)
 			id = 0xffffffff;
 
 		hci_pi(sk)->cookie = id;
-		get_task_comm(hci_pi(sk)->comm, current);
+		strscpy_pad(hci_pi(sk)->comm, current->comm);
 		return true;
 	}
 
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 59ac623e6805..6881d20616eb 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -9779,9 +9779,11 @@ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
 	if (!nlh)
 		goto nla_put_failure;
 
+	strscpy_pad(buf, current->comm);
+
 	if (nla_put_be32(skb, NFTA_GEN_ID, htonl(nft_base_seq(net))) ||
 	    nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
-	    nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
+	    nla_put_string(skb, NFTA_GEN_PROC_NAME, buf))
 		goto nla_put_failure;
 
 	nlmsg_end(skb, nlh);
diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c
index 22106aaeb0df..27b125e09974 100644
--- a/security/integrity/integrity_audit.c
+++ b/security/integrity/integrity_audit.c
@@ -46,7 +46,8 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
 			 audit_get_sessionid(current));
 	audit_log_task_context(ab);
 	audit_log_format(ab, " op=%s cause=%s comm=", op, cause);
-	audit_log_untrustedstring(ab, get_task_comm(name, current));
+	strscpy_pad(name, current->comm);
+	audit_log_untrustedstring(ab, name);
 	if (fname) {
 		audit_log_format(ab, " name=");
 		audit_log_untrustedstring(ab, fname);
diff --git a/security/ipe/audit.c b/security/ipe/audit.c
index b6f8fb54085a..0d5c683b3d61 100644
--- a/security/ipe/audit.c
+++ b/security/ipe/audit.c
@@ -145,7 +145,8 @@ void ipe_audit_match(const struct ipe_eval_ctx *const ctx,
 	audit_log_format(ab, "ipe_op=%s ipe_hook=%s enforcing=%d pid=%d comm=",
 			 op, audit_hook_names[ctx->hook], READ_ONCE(enforce),
 			 task_tgid_nr(current));
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 
 	if (ctx->file) {
 		audit_log_d_path(ab, " path=", &ctx->file->f_path);
diff --git a/security/landlock/domain.c b/security/landlock/domain.c
index 4c0b1f0e1db5..902cf41a3048 100644
--- a/security/landlock/domain.c
+++ b/security/landlock/domain.c
@@ -564,7 +564,7 @@ static struct landlock_details *get_current_details(void)
 	memcpy(details->exe_path, path_str, path_size);
 	details->pid = get_pid(task_tgid(current));
 	details->uid = from_kuid(&init_user_ns, current_uid());
-	get_task_comm(details->comm, current);
+	strscpy_pad(details->comm, current->comm);
 	return details;
 }
 
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 955b2e7b2c8e..8f8c29e8c03d 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -276,8 +276,8 @@ void audit_log_lsm_data(struct audit_buffer *ab,
 			if (pid) {
 				char tskcomm[sizeof(tsk->comm)];
 				audit_log_format(ab, " opid=%d ocomm=", pid);
-				audit_log_untrustedstring(ab,
-				    get_task_comm(tskcomm, tsk));
+				strscpy_pad(tskcomm, tsk->comm);
+				audit_log_untrustedstring(ab, tskcomm);
 			}
 		}
 		break;
@@ -421,7 +421,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 	char comm[sizeof(current->comm)];
 
 	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
-	audit_log_untrustedstring(ab, get_task_comm(comm, current));
+	strscpy_pad(comm, current->comm);
+	audit_log_untrustedstring(ab, comm);
 	audit_log_lsm_data(ab, a);
 }
 
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index fb85356266e5..0e7b2edcc3d6 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -335,10 +335,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
 	if (sad->subj_tsk) {
 		char comm[TASK_COMM_LEN];
 
+		strscpy_pad(comm, sad->subj_tsk->comm);
 		audit_log_format(ab, " subj_pid=%d subj_comm=",
 			task_tgid_nr(sad->subj_tsk));
-		audit_log_untrustedstring(ab,
-			get_task_comm(comm, sad->subj_tsk));
+		audit_log_untrustedstring(ab, comm);
 	}
 }
 
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 28a8e12603ce..e8c678a36c15 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -138,6 +138,8 @@ smk_bu_tsk_to_obj(struct task_struct *tsk, const struct task_smack *tsp,
 	char acc[SMK_NUM_ACCESS_TYPE + 1];
 	char comm[TASK_COMM_LEN];
 
+	strscpy_pad(comm, tsk->comm);
+
 	if (rc <= 0)
 		return rc;
 	if (rc > SMACK_UNCONFINED_OBJECT)
@@ -147,7 +149,7 @@ smk_bu_tsk_to_obj(struct task_struct *tsk, const struct task_smack *tsp,
 
 	pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc],
 		smk_of_task(tsp)->smk_known, oskp->smk_known,
-		acc, get_task_comm(comm, tsk), note);
+		acc, comm, note);
 	return 0;
 #else
 	return rc;

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm()
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
  2026-10-30 21:38 ` [PATCH v8 1/6] treewide: Get rid of get_task_comm() André Almeida
@ 2026-10-30 21:38 ` André Almeida
  2026-10-30 22:34   ` David Laight
  2026-10-30 21:38 ` [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm() André Almeida
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

In order to increase the size of current->comm[] and to avoid breaking any
existing code, replace memcpy() with copy_task_comm(). This new function
makes sure that the copy is NUL terminated. This is crucial given that the
source buffer might be larger than the destination buffer and could
truncate the NUL character out of it.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
---
Changes from v4:
 - Remove copy_task_comm() calls for structs other than struct task_struct
 - Add checks for len > TASK_COMM_LEN and len < 0

Changes from v3:
 - Simplify copy_task_comm() to a memcpy + NUL char at the end of buffer

Changes from v2:
 - Bring back custom function.

Changes from v1:
 - New patch, dropped strtostr() from last version
---
 include/linux/coredump.h                                  |  2 +-
 include/linux/sched.h                                     | 15 +++++++++++++++
 include/linux/tracepoint.h                                |  4 ++--
 include/trace/events/block.h                              | 10 +++++-----
 include/trace/events/coredump.h                           |  2 +-
 include/trace/events/f2fs.h                               |  4 ++--
 include/trace/events/oom.h                                |  2 +-
 include/trace/events/osnoise.h                            |  2 +-
 include/trace/events/sched.h                              | 10 +++++-----
 include/trace/events/signal.h                             |  2 +-
 include/trace/events/task.h                               |  4 ++--
 .../testing/selftests/bpf/test_kmods/bpf_testmod-events.h |  2 +-
 12 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 8e857770dd21..c3009edc2595 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -79,7 +79,7 @@ void vfs_coredump(const kernel_siginfo_t *siginfo);
 	do {	\
 		char comm[TASK_COMM_LEN];	\
 		/* This will always be NUL terminated. */ \
-		memcpy(comm, current->comm, sizeof(comm)); \
+		copy_task_comm(comm, current, sizeof(comm)); \
 		printk_ratelimited(Level "coredump: %d(%*pE): " Format "\n",	\
 			task_tgid_vnr(current), (int)strlen(comm), comm, ##__VA_ARGS__);	\
 	} while (0)	\
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0564aabb1393..db529a93525d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2042,6 +2042,21 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
 	__set_task_comm(tsk, from, false);		\
 })
 
+/*
+ * Copy task name to a buffer. Final result is always a NUL-terminated string.
+ */
+static __always_inline void copy_task_comm(char *dst, struct task_struct *tsk, size_t len)
+{
+	const char *_src = tsk->comm;
+	size_t _len = min(len, TASK_COMM_LEN);
+
+	if (!_len)
+		return;
+
+	memcpy(dst, _src, _len);
+	dst[_len - 1] = '\0';
+}
+
 static __always_inline void scheduler_ipi(void)
 {
 	/*
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index e0d838c9ce93..9b0094fa44c6 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -637,10 +637,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
  *	*
  *
  *	TP_fast_assign(
- *		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ *		copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
  *		__entry->prev_pid	= prev->pid;
  *		__entry->prev_prio	= prev->prio;
- *		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ *		copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
  *		__entry->next_pid	= next->pid;
  *		__entry->next_prio	= next->prio;
  *	),
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 9c97a16850b9..1e3a9ded03bd 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -213,7 +213,7 @@ DECLARE_EVENT_CLASS(block_rq,
 
 		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags);
 		__get_str(cmd)[0] = '\0';
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("%d,%d %s %u (%s) %llu + %u %s,%u,%u [%s]",
@@ -410,7 +410,7 @@ DECLARE_EVENT_CLASS(block_bio,
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio_sectors(bio);
 		blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("%d,%d %s %llu + %u [%s]",
@@ -493,7 +493,7 @@ TRACE_EVENT(block_plug,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("[%s]", __entry->comm)
@@ -512,7 +512,7 @@ DECLARE_EVENT_CLASS(block_unplug,
 
 	TP_fast_assign(
 		__entry->nr_rq = depth;
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
@@ -563,7 +563,7 @@ TRACE_EVENT(block_split,
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->new_sector	= new_sector;
 		blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("%d,%d %s %llu / %llu [%s]",
diff --git a/include/trace/events/coredump.h b/include/trace/events/coredump.h
index c7b9c53fc498..fdd20bc46bb0 100644
--- a/include/trace/events/coredump.h
+++ b/include/trace/events/coredump.h
@@ -32,7 +32,7 @@ TRACE_EVENT(coredump,
 
 	TP_fast_assign(
 		__entry->sig = sig;
-		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
 	),
 
 	TP_printk("sig=%d comm=%s",
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index df4cd346ae72..e3f2047f9de8 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -2589,7 +2589,7 @@ TRACE_EVENT(f2fs_lock_elapsed_time,
 
 	TP_fast_assign(
 		__entry->dev		= sbi->sb->s_dev;
-		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
 		__entry->pid		= p->pid;
 		__entry->prio		= p->prio;
 		__entry->ioprio_class	= IOPRIO_PRIO_CLASS(ioprio);
@@ -2642,7 +2642,7 @@ DECLARE_EVENT_CLASS(f2fs_priority_update,
 
 	TP_fast_assign(
 		__entry->dev		= sbi->sb->s_dev;
-		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
 		__entry->pid		= p->pid;
 		__entry->lock_name	= lock_name;
 		__entry->is_write	= is_write;
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 9f0a5d1482c4..8bcdc4ffc8d3 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -23,7 +23,7 @@ TRACE_EVENT(oom_score_adj_update,
 
 	TP_fast_assign(
 		__entry->pid = task->pid;
-		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
 		__entry->oom_score_adj = task->signal->oom_score_adj;
 	),
 
diff --git a/include/trace/events/osnoise.h b/include/trace/events/osnoise.h
index 3f4273623801..2cf047bb9fb7 100644
--- a/include/trace/events/osnoise.h
+++ b/include/trace/events/osnoise.h
@@ -116,7 +116,7 @@ TRACE_EVENT(thread_noise,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, t, TASK_COMM_LEN);
 		__entry->pid = t->pid;
 		__entry->start = start;
 		__entry->duration = duration;
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 535860581f15..afb24e9dac91 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -152,7 +152,7 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
 		__entry->pid		= p->pid;
 		__entry->prio		= p->prio; /* XXX SCHED_DEADLINE */
 		__entry->target_cpu	= task_cpu(p);
@@ -237,11 +237,11 @@ TRACE_EVENT(sched_switch,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
 		__entry->prev_pid	= prev->pid;
 		__entry->prev_prio	= prev->prio;
 		__entry->prev_state	= __trace_sched_switch_state(preempt, prev_state, prev);
-		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
 		__entry->next_pid	= next->pid;
 		__entry->next_prio	= next->prio;
 		/* XXX SCHED_DEADLINE */
@@ -346,7 +346,7 @@ TRACE_EVENT(sched_process_exit,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
 		__entry->pid		= p->pid;
 		__entry->prio		= p->prio; /* XXX SCHED_DEADLINE */
 		__entry->group_dead	= group_dead;
@@ -787,7 +787,7 @@ TRACE_EVENT(sched_skip_cpuset_numa,
 	),
 
 	TP_fast_assign(
-		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, tsk, TASK_COMM_LEN);
 		__entry->pid		 = task_pid_nr(tsk);
 		__entry->tgid		 = task_tgid_nr(tsk);
 		__entry->ngid		 = task_numa_group_id(tsk);
diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h
index 1db7e4b07c01..8fffe6d9bdcc 100644
--- a/include/trace/events/signal.h
+++ b/include/trace/events/signal.h
@@ -67,7 +67,7 @@ TRACE_EVENT(signal_generate,
 	TP_fast_assign(
 		__entry->sig	= sig;
 		TP_STORE_SIGINFO(__entry, info);
-		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
 		__entry->pid	= task->pid;
 		__entry->group	= group;
 		__entry->result	= result;
diff --git a/include/trace/events/task.h b/include/trace/events/task.h
index b9a129eb54d9..e3faaeb997ef 100644
--- a/include/trace/events/task.h
+++ b/include/trace/events/task.h
@@ -21,7 +21,7 @@ TRACE_EVENT(task_newtask,
 
 	TP_fast_assign(
 		__entry->pid = task->pid;
-		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
 		__entry->clone_flags = clone_flags;
 		__entry->oom_score_adj = task->signal->oom_score_adj;
 	),
@@ -46,7 +46,7 @@ TRACE_EVENT(task_rename,
 
 	TP_fast_assign(
 		__entry->pid = task->pid;
-		memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN);
+		copy_task_comm(entry->oldcomm, task, TASK_COMM_LEN);
 		strscpy(entry->newcomm, comm, TASK_COMM_LEN);
 		__entry->oom_score_adj = task->signal->oom_score_adj;
 	),
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
index 45a5e41f3a92..a197622e113c 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
@@ -20,7 +20,7 @@ TRACE_EVENT(bpf_testmod_test_read,
 	),
 	TP_fast_assign(
 		__entry->pid = task->pid;
-		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
 		__entry->off = ctx->off;
 		__entry->len = ctx->len;
 	),

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm()
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
  2026-10-30 21:38 ` [PATCH v8 1/6] treewide: Get rid of get_task_comm() André Almeida
  2026-10-30 21:38 ` [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm() André Almeida
@ 2026-10-30 21:38 ` André Almeida
  2026-10-31 21:39   ` sashiko-bot
  2026-10-30 21:38 ` [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN André Almeida
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

Add a new test for copy_task_comm(). Check if a copy from a task_struct
works, and special cases when the size of source and destination buffer
mismatches.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
 lib/tests/string_kunit.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index 0819ace5b027..66c3398f2317 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -881,6 +881,43 @@ static void string_bench_strrchr(struct kunit *test)
 	STRING_BENCH_BUF(test, buf, len, strrchr, buf, '\0');
 }
 
+#define TASK_NAME "task_name"
+#define TASK_NAME_LEN 9
+#define TASK_MAX_LEN TASK_COMM_LEN
+#define SMALLER_LEN (TASK_NAME_LEN - 3)
+#define BIGGER_LEN (TASK_MAX_LEN + 3)
+
+static void string_copy_task_comm(struct kunit *test)
+{
+	char str[TASK_MAX_LEN] = TASK_NAME, copy[TASK_MAX_LEN],
+	     smaller_buf[SMALLER_LEN], bigger_buf[BIGGER_LEN];
+	static struct task_struct task, *tsk = &task;
+	int len1, len2, i;
+
+	/* set and get task name */
+	strscpy_pad(tsk->comm, str);
+	copy_task_comm(copy, tsk, TASK_COMM_LEN);
+
+	len1 = strlen(str);
+	len2 = strlen(copy);
+
+	KUNIT_ASSERT_EQ(test, len1, len2);
+	KUNIT_ASSERT_EQ(test, len2, TASK_NAME_LEN);
+	KUNIT_ASSERT_EQ(test, copy[len2], '\0');
+	KUNIT_ASSERT_TRUE(test, !strcmp(str, copy));
+
+	/* copy to a smaller dst buffer */
+	copy_task_comm(smaller_buf, tsk, sizeof(smaller_buf));
+	KUNIT_ASSERT_TRUE(test, !strncmp(str, smaller_buf, SMALLER_LEN - 1));
+	KUNIT_ASSERT_EQ(test, smaller_buf[SMALLER_LEN - 1], '\0');
+
+	/* copy to a bigger dst buffer */
+	copy_task_comm(bigger_buf, tsk, sizeof(bigger_buf));
+	KUNIT_ASSERT_TRUE(test, !strncmp(str, bigger_buf, TASK_NAME_LEN));
+	for (i = TASK_NAME_LEN; i < BIGGER_LEN; i++)
+		KUNIT_ASSERT_EQ(test, bigger_buf[i], '\0');
+}
+
 static struct kunit_case string_test_cases[] = {
 	KUNIT_CASE(string_test_memset16),
 	KUNIT_CASE(string_test_memset32),
@@ -910,6 +947,7 @@ static struct kunit_case string_test_cases[] = {
 	KUNIT_CASE(string_bench_strnlen),
 	KUNIT_CASE(string_bench_strchr),
 	KUNIT_CASE(string_bench_strrchr),
+	KUNIT_CASE(string_copy_task_comm),
 	{}
 };
 

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
                   ` (2 preceding siblings ...)
  2026-10-30 21:38 ` [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm() André Almeida
@ 2026-10-30 21:38 ` André Almeida
  2026-10-31 21:39   ` sashiko-bot
  2026-11-01  0:10   ` kernel test robot
  2026-10-30 21:38 ` [PATCH v8 5/6] prctl: Add support for long user thread names André Almeida
  2026-10-30 21:38 ` [PATCH v8 6/6] selftests: prctl: Add test for long " André Almeida
  5 siblings, 2 replies; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

Command name has been restrict to only 16 bytes, which is too limiting,
specially when debugging and tracing complex software with thousands of
threads and the need to differentiate them.

Just as it was done with kthreads in commit 6b59808bfe48 ("workqueue:
Show the latest workqueue name in /proc/PID/{comm,stat,status}"), support
long names for userspace threads as well.

To avoid buffer overflows, cap all existing userspace APIs to
TASK_COMM_LEN, and leave the full extended name for a new interface.

Callers of set_task_comm() are responsible of having a valid string in
their argument buffers. A caller of set_task_comm() that passes a string
shorter than TASK_COMM_EXT_LEN without a null terminator will cause a
out-of-bounds read in set_task_comm().

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes from v5:
 - Fix blktrace buffer size
 - Fix i915 buffer size
---
 drivers/gpu/drm/i915/display/intel_display_driver.c |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_context.c         |  4 ++--
 fs/proc/array.c                                     |  2 +-
 include/linux/sched.h                               |  5 +++--
 kernel/sys.c                                        | 10 +++++-----
 kernel/trace/blktrace.c                             |  6 ++++--
 6 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 204810a11e46..005c49902259 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -436,8 +436,8 @@ void intel_display_driver_resume_access(struct intel_display *display)
  */
 bool intel_display_driver_check_access(struct intel_display *display)
 {
-	char current_task[TASK_COMM_LEN + 16];
-	char allowed_task[TASK_COMM_LEN + 16] = "none";
+	char current_task[TASK_COMM_EXT_LEN + 16];
+	char allowed_task[TASK_COMM_EXT_LEN + 16] = "none";
 
 	if (display->access.any_task_allowed ||
 	    display->access.allowed_task == current)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index c58ffa5a8fa6..b62b82c6de04 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1730,8 +1730,8 @@ static void gem_context_register(struct i915_gem_context *ctx,
 	ctx->pid = get_task_pid(current, PIDTYPE_PID);
 	ctx->client = i915_drm_client_get(fpriv->client);
 
-	snprintf(ctx->name, sizeof(ctx->name), "%s[%d]",
-		 current->comm, pid_nr(ctx->pid));
+	snprintf(ctx->name, sizeof(ctx->name), "%.*s[%d]",
+		 TASK_COMM_LEN - 1, current->comm, pid_nr(ctx->pid));
 
 	spin_lock(&ctx->client->ctx_lock);
 	list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list);
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 8ebb7cf1a7b0..0d70b21c803c 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -110,7 +110,7 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
 	else if (p->flags & PF_KTHREAD)
 		get_kthread_comm(tcomm, sizeof(tcomm), p);
 	else
-		strscpy_pad(tcomm, p->comm);
+		strscpy_pad(tcomm, p->comm, TASK_COMM_LEN);
 
 	if (escape)
 		seq_escape_str(m, tcomm, ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
diff --git a/include/linux/sched.h b/include/linux/sched.h
index db529a93525d..5e02bce749b8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -323,6 +323,7 @@ struct user_event_mm;
  */
 enum {
 	TASK_COMM_LEN = 16,
+	TASK_COMM_EXT_LEN = 64,
 };
 
 extern void sched_tick(void);
@@ -1192,7 +1193,7 @@ struct task_struct {
 	 * - set it with set_task_comm() to ensure it is always
 	 *   NUL-terminated and zero-padded
 	 */
-	char				comm[TASK_COMM_LEN];
+	char				comm[TASK_COMM_EXT_LEN];
 
 	struct nameidata		*nameidata;
 
@@ -2048,7 +2049,7 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
 static __always_inline void copy_task_comm(char *dst, struct task_struct *tsk, size_t len)
 {
 	const char *_src = tsk->comm;
-	size_t _len = min(len, TASK_COMM_LEN);
+	size_t _len = min(len, TASK_COMM_EXT_LEN);
 
 	if (!_len)
 		return;
diff --git a/kernel/sys.c b/kernel/sys.c
index 31eef656dbd6..6a72c7e644e7 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2538,7 +2538,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		unsigned long, arg4, unsigned long, arg5)
 {
 	struct task_struct *me = current;
-	unsigned char comm[sizeof(me->comm)];
+	unsigned char comm[TASK_COMM_LEN];
 	long error;
 
 	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
@@ -2604,16 +2604,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			error = -EINVAL;
 		break;
 	case PR_SET_NAME:
-		comm[sizeof(me->comm) - 1] = 0;
+		comm[TASK_COMM_LEN - 1] = 0;
 		if (strncpy_from_user(comm, (char __user *)arg2,
-				      sizeof(me->comm) - 1) < 0)
+				      TASK_COMM_LEN - 1) < 0)
 			return -EFAULT;
 		set_task_comm(me, comm);
 		proc_comm_connector(me);
 		break;
 	case PR_GET_NAME:
-		strscpy_pad(comm, me->comm);
-		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
+		strscpy_pad(comm, me->comm, TASK_COMM_LEN);
+		if (copy_to_user((char __user *)arg2, comm, TASK_COMM_LEN))
 			return -EFAULT;
 		break;
 	case PR_GET_ENDIAN:
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 8cd2520b4c99..edc1377c3e3c 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -214,12 +214,14 @@ static void trace_note_tsk(struct task_struct *tsk)
 {
 	unsigned long flags;
 	struct blk_trace *bt;
+	char comm[TASK_COMM_LEN];
 
 	tsk->btrace_seq = blktrace_seq;
 	raw_spin_lock_irqsave(&running_trace_lock, flags);
 	list_for_each_entry(bt, &running_trace_list, running_list) {
-		trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm,
-			   sizeof(tsk->comm), 0);
+		strscpy_pad(comm, tsk->comm);
+		trace_note(bt, tsk->pid, BLK_TN_PROCESS, comm,
+			   sizeof(comm), 0);
 	}
 	raw_spin_unlock_irqrestore(&running_trace_lock, flags);
 }

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 5/6] prctl: Add support for long user thread names
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
                   ` (3 preceding siblings ...)
  2026-10-30 21:38 ` [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN André Almeida
@ 2026-10-30 21:38 ` André Almeida
  2026-10-31 21:39   ` sashiko-bot
  2026-10-30 21:38 ` [PATCH v8 6/6] selftests: prctl: Add test for long " André Almeida
  5 siblings, 1 reply; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

Add support for getting and setting long user thread names with
PR_{SET,GET}_EXT_NAME.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
 include/linux/sched.h      |  2 +-
 include/uapi/linux/prctl.h |  3 +++
 kernel/sys.c               | 15 ++++++++++++++-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5e02bce749b8..c9477ba674f1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2039,7 +2039,7 @@ extern void kick_process(struct task_struct *tsk);
 
 extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec);
 #define set_task_comm(tsk, from) ({			\
-	BUILD_BUG_ON(sizeof(from) != TASK_COMM_LEN);	\
+	BUILD_BUG_ON(sizeof(from) < TASK_COMM_LEN);	\
 	__set_task_comm(tsk, from, false);		\
 })
 
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index b6ec6f693719..a07f8edadd65 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -56,6 +56,9 @@
 #define PR_SET_NAME    15		/* Set process name */
 #define PR_GET_NAME    16		/* Get process name */
 
+#define PR_SET_EXT_NAME    17		/* Set extended process name */
+#define PR_GET_EXT_NAME    18		/* Get extended process name */
+
 /* Get/set process endian */
 #define PR_GET_ENDIAN	19
 #define PR_SET_ENDIAN	20
diff --git a/kernel/sys.c b/kernel/sys.c
index 6a72c7e644e7..fc9e3c5a9135 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2538,7 +2538,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		unsigned long, arg4, unsigned long, arg5)
 {
 	struct task_struct *me = current;
-	unsigned char comm[TASK_COMM_LEN];
+	unsigned char comm[TASK_COMM_EXT_LEN];
 	long error;
 
 	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
@@ -2616,6 +2616,19 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		if (copy_to_user((char __user *)arg2, comm, TASK_COMM_LEN))
 			return -EFAULT;
 		break;
+	case PR_SET_EXT_NAME:
+		comm[TASK_COMM_EXT_LEN - 1] = 0;
+		if (strncpy_from_user(comm, (char __user *)arg2,
+				      TASK_COMM_EXT_LEN - 1) < 0)
+			return -EFAULT;
+		set_task_comm(me, comm);
+		proc_comm_connector(me);
+		break;
+	case PR_GET_EXT_NAME:
+		strscpy_pad(comm, me->comm, TASK_COMM_EXT_LEN);
+		if (copy_to_user((char __user *)arg2, comm, TASK_COMM_EXT_LEN))
+			return -EFAULT;
+		break;
 	case PR_GET_ENDIAN:
 		error = GET_ENDIAN(me, arg2);
 		break;

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 6/6] selftests: prctl: Add test for long thread names
  2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
                   ` (4 preceding siblings ...)
  2026-10-30 21:38 ` [PATCH v8 5/6] prctl: Add support for long user thread names André Almeida
@ 2026-10-30 21:38 ` André Almeida
  5 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-10-30 21:38 UTC (permalink / raw)
  To: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: linux-kernel, kernel-dev, linux-mm, linux-api, linux-trace-kernel,
	André Almeida

Add tests for the new interface to set and get long thread names. The
kernel should accept the LONG_NAME and returning it accordingly. For the
old PR_GET_NAME interface, the kernel should truncate the name up to 16
chars. /proc/<task>/comm should return the same string ad PR_GET_NAME.

While here, fix the check_is_name_correct() logic. It currently returns 1
for success, or a negative number for error. EXPECT_TRUE() evaluates any
non-zero value as true, so the error will be evaluated as a success. Make
the logic more robust and straightforward by returning the results of
strcmp() and expecting zero as success.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes in v5:
 - fix check_is_name_correct() return logic
---
 tools/testing/selftests/prctl/set-process-name.c | 57 +++++++++++++++++++++---
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/prctl/set-process-name.c b/tools/testing/selftests/prctl/set-process-name.c
index 3f7b146d36df..f05053aaba85 100644
--- a/tools/testing/selftests/prctl/set-process-name.c
+++ b/tools/testing/selftests/prctl/set-process-name.c
@@ -9,9 +9,17 @@
 
 #include "kselftest_harness.h"
 
+#ifndef PR_SET_EXT_NAME
+# define PR_SET_EXT_NAME 17
+# define PR_GET_EXT_NAME 18
+#endif
+
 #define CHANGE_NAME "changename"
+#define LONG_NAME	"change_to_very_long_extended_name"
+#define LONG_NAME_CAP	"change_to_very_"
 #define EMPTY_NAME ""
 #define TASK_COMM_LEN 16
+#define TASK_COMM_EXT_LEN 64
 #define MAX_PATH_LEN 50
 
 int set_name(char *name)
@@ -25,6 +33,20 @@ int set_name(char *name)
 	return res;
 }
 
+int set_ext_name(char *name)
+{
+	int res;
+
+	res = prctl(PR_SET_EXT_NAME, name, NULL, NULL, NULL);
+
+	if (res < 0)
+		return -errno;
+	return res;
+}
+
+/*
+ * Return 0 if strings match
+ */
 int check_is_name_correct(char *check_name)
 {
 	char name[TASK_COMM_LEN];
@@ -35,7 +57,23 @@ int check_is_name_correct(char *check_name)
 	if (res < 0)
 		return -errno;
 
-	return !strcmp(name, check_name);
+	return strcmp(name, check_name);
+}
+
+/*
+ * Return 0 if strings match
+ */
+int check_is_ext_name_correct(char *check_name)
+{
+	char name[TASK_COMM_EXT_LEN];
+	int res;
+
+	res = prctl(PR_GET_EXT_NAME, name, NULL, NULL, NULL);
+
+	if (res < 0)
+		return -errno;
+
+	return strcmp(name, check_name);
 }
 
 int check_null_pointer(char *check_name)
@@ -56,8 +94,8 @@ int check_name(void)
 	pid = getpid();
 	FILE *fptr = NULL;
 	char path[MAX_PATH_LEN] = {};
-	char name[TASK_COMM_LEN] = {};
-	char output[TASK_COMM_LEN] = {};
+	char name[TASK_COMM_EXT_LEN] = {};
+	char output[TASK_COMM_EXT_LEN] = {};
 	int j;
 
 	j = snprintf(path, MAX_PATH_LEN, "/proc/self/task/%d/comm", pid);
@@ -74,21 +112,26 @@ int check_name(void)
 	if (res < 0)
 		return -errno;
 
-	return !strcmp(output, name);
+	return strcmp(output, name);
 }
 
 TEST(rename_process) {
 
 	EXPECT_GE(set_name(CHANGE_NAME), 0);
-	EXPECT_TRUE(check_is_name_correct(CHANGE_NAME));
+	EXPECT_FALSE(check_is_name_correct(CHANGE_NAME));
+
+	EXPECT_GE(set_ext_name(LONG_NAME), 0);
+	EXPECT_FALSE(check_is_ext_name_correct(LONG_NAME));
+	EXPECT_FALSE(check_is_name_correct(LONG_NAME_CAP));
+	EXPECT_FALSE(check_name());
 
 	EXPECT_GE(set_name(EMPTY_NAME), 0);
-	EXPECT_TRUE(check_is_name_correct(EMPTY_NAME));
+	EXPECT_FALSE(check_is_name_correct(EMPTY_NAME));
 
 	EXPECT_GE(set_name(CHANGE_NAME), 0);
 	EXPECT_LT(check_null_pointer(CHANGE_NAME), 0);
 
-	EXPECT_TRUE(check_name());
+	EXPECT_FALSE(check_name());
 }
 
 TEST_HARNESS_MAIN

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm()
  2026-10-30 21:38 ` [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm() André Almeida
@ 2026-10-30 22:34   ` David Laight
  2026-10-31 14:30     ` Steven Rostedt
  0 siblings, 1 reply; 13+ messages in thread
From: David Laight @ 2026-10-30 22:34 UTC (permalink / raw)
  To: André Almeida
  Cc: Peter Zijlstra, Juri Lelli, Vincent Guittot, Steven Rostedt,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, Linus Torvalds, akpm, Yafang Shao,
	andrii.nakryiko, arnaldo.melo, Petr Mladek, linux-kernel,
	kernel-dev, linux-mm, linux-api, linux-trace-kernel

On Fri, 30 Oct 2026 18:38:33 -0300
André Almeida <andrealmeid@igalia.com> wrote:

> In order to increase the size of current->comm[] and to avoid breaking any
> existing code, replace memcpy() with copy_task_comm(). This new function
> makes sure that the copy is NUL terminated. This is crucial given that the
> source buffer might be larger than the destination buffer and could
> truncate the NUL character out of it.

I suspect the trace code would be faster it is just copied the (first)
16 characters and worried about whether it was terminated later on.
It does far more 'saves' than trace reads and their performance is
much more important.

David

> 
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> ---
> Changes from v4:
>  - Remove copy_task_comm() calls for structs other than struct task_struct
>  - Add checks for len > TASK_COMM_LEN and len < 0
> 
> Changes from v3:
>  - Simplify copy_task_comm() to a memcpy + NUL char at the end of buffer
> 
> Changes from v2:
>  - Bring back custom function.
> 
> Changes from v1:
>  - New patch, dropped strtostr() from last version
> ---
>  include/linux/coredump.h                                  |  2 +-
>  include/linux/sched.h                                     | 15 +++++++++++++++
>  include/linux/tracepoint.h                                |  4 ++--
>  include/trace/events/block.h                              | 10 +++++-----
>  include/trace/events/coredump.h                           |  2 +-
>  include/trace/events/f2fs.h                               |  4 ++--
>  include/trace/events/oom.h                                |  2 +-
>  include/trace/events/osnoise.h                            |  2 +-
>  include/trace/events/sched.h                              | 10 +++++-----
>  include/trace/events/signal.h                             |  2 +-
>  include/trace/events/task.h                               |  4 ++--
>  .../testing/selftests/bpf/test_kmods/bpf_testmod-events.h |  2 +-
>  12 files changed, 37 insertions(+), 22 deletions(-)
> 
> diff --git a/include/linux/coredump.h b/include/linux/coredump.h
> index 8e857770dd21..c3009edc2595 100644
> --- a/include/linux/coredump.h
> +++ b/include/linux/coredump.h
> @@ -79,7 +79,7 @@ void vfs_coredump(const kernel_siginfo_t *siginfo);
>  	do {	\
>  		char comm[TASK_COMM_LEN];	\
>  		/* This will always be NUL terminated. */ \
> -		memcpy(comm, current->comm, sizeof(comm)); \
> +		copy_task_comm(comm, current, sizeof(comm)); \
>  		printk_ratelimited(Level "coredump: %d(%*pE): " Format "\n",	\
>  			task_tgid_vnr(current), (int)strlen(comm), comm, ##__VA_ARGS__);	\
>  	} while (0)	\
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 0564aabb1393..db529a93525d 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -2042,6 +2042,21 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
>  	__set_task_comm(tsk, from, false);		\
>  })
>  
> +/*
> + * Copy task name to a buffer. Final result is always a NUL-terminated string.
> + */
> +static __always_inline void copy_task_comm(char *dst, struct task_struct *tsk, size_t len)
> +{
> +	const char *_src = tsk->comm;
> +	size_t _len = min(len, TASK_COMM_LEN);
> +
> +	if (!_len)
> +		return;
> +
> +	memcpy(dst, _src, _len);
> +	dst[_len - 1] = '\0';
> +}
> +
>  static __always_inline void scheduler_ipi(void)
>  {
>  	/*
> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
> index e0d838c9ce93..9b0094fa44c6 100644
> --- a/include/linux/tracepoint.h
> +++ b/include/linux/tracepoint.h
> @@ -637,10 +637,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
>   *	*
>   *
>   *	TP_fast_assign(
> - *		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
> + *		copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
>   *		__entry->prev_pid	= prev->pid;
>   *		__entry->prev_prio	= prev->prio;
> - *		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
> + *		copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
>   *		__entry->next_pid	= next->pid;
>   *		__entry->next_prio	= next->prio;
>   *	),
> diff --git a/include/trace/events/block.h b/include/trace/events/block.h
> index 9c97a16850b9..1e3a9ded03bd 100644
> --- a/include/trace/events/block.h
> +++ b/include/trace/events/block.h
> @@ -213,7 +213,7 @@ DECLARE_EVENT_CLASS(block_rq,
>  
>  		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags);
>  		__get_str(cmd)[0] = '\0';
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("%d,%d %s %u (%s) %llu + %u %s,%u,%u [%s]",
> @@ -410,7 +410,7 @@ DECLARE_EVENT_CLASS(block_bio,
>  		__entry->sector		= bio->bi_iter.bi_sector;
>  		__entry->nr_sector	= bio_sectors(bio);
>  		blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("%d,%d %s %llu + %u [%s]",
> @@ -493,7 +493,7 @@ TRACE_EVENT(block_plug,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("[%s]", __entry->comm)
> @@ -512,7 +512,7 @@ DECLARE_EVENT_CLASS(block_unplug,
>  
>  	TP_fast_assign(
>  		__entry->nr_rq = depth;
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
> @@ -563,7 +563,7 @@ TRACE_EVENT(block_split,
>  		__entry->sector		= bio->bi_iter.bi_sector;
>  		__entry->new_sector	= new_sector;
>  		blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("%d,%d %s %llu / %llu [%s]",
> diff --git a/include/trace/events/coredump.h b/include/trace/events/coredump.h
> index c7b9c53fc498..fdd20bc46bb0 100644
> --- a/include/trace/events/coredump.h
> +++ b/include/trace/events/coredump.h
> @@ -32,7 +32,7 @@ TRACE_EVENT(coredump,
>  
>  	TP_fast_assign(
>  		__entry->sig = sig;
> -		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
>  	),
>  
>  	TP_printk("sig=%d comm=%s",
> diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
> index df4cd346ae72..e3f2047f9de8 100644
> --- a/include/trace/events/f2fs.h
> +++ b/include/trace/events/f2fs.h
> @@ -2589,7 +2589,7 @@ TRACE_EVENT(f2fs_lock_elapsed_time,
>  
>  	TP_fast_assign(
>  		__entry->dev		= sbi->sb->s_dev;
> -		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
>  		__entry->pid		= p->pid;
>  		__entry->prio		= p->prio;
>  		__entry->ioprio_class	= IOPRIO_PRIO_CLASS(ioprio);
> @@ -2642,7 +2642,7 @@ DECLARE_EVENT_CLASS(f2fs_priority_update,
>  
>  	TP_fast_assign(
>  		__entry->dev		= sbi->sb->s_dev;
> -		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
>  		__entry->pid		= p->pid;
>  		__entry->lock_name	= lock_name;
>  		__entry->is_write	= is_write;
> diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
> index 9f0a5d1482c4..8bcdc4ffc8d3 100644
> --- a/include/trace/events/oom.h
> +++ b/include/trace/events/oom.h
> @@ -23,7 +23,7 @@ TRACE_EVENT(oom_score_adj_update,
>  
>  	TP_fast_assign(
>  		__entry->pid = task->pid;
> -		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
>  		__entry->oom_score_adj = task->signal->oom_score_adj;
>  	),
>  
> diff --git a/include/trace/events/osnoise.h b/include/trace/events/osnoise.h
> index 3f4273623801..2cf047bb9fb7 100644
> --- a/include/trace/events/osnoise.h
> +++ b/include/trace/events/osnoise.h
> @@ -116,7 +116,7 @@ TRACE_EVENT(thread_noise,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, t, TASK_COMM_LEN);
>  		__entry->pid = t->pid;
>  		__entry->start = start;
>  		__entry->duration = duration;
> diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
> index 535860581f15..afb24e9dac91 100644
> --- a/include/trace/events/sched.h
> +++ b/include/trace/events/sched.h
> @@ -152,7 +152,7 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
>  		__entry->pid		= p->pid;
>  		__entry->prio		= p->prio; /* XXX SCHED_DEADLINE */
>  		__entry->target_cpu	= task_cpu(p);
> @@ -237,11 +237,11 @@ TRACE_EVENT(sched_switch,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
>  		__entry->prev_pid	= prev->pid;
>  		__entry->prev_prio	= prev->prio;
>  		__entry->prev_state	= __trace_sched_switch_state(preempt, prev_state, prev);
> -		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
>  		__entry->next_pid	= next->pid;
>  		__entry->next_prio	= next->prio;
>  		/* XXX SCHED_DEADLINE */
> @@ -346,7 +346,7 @@ TRACE_EVENT(sched_process_exit,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
>  		__entry->pid		= p->pid;
>  		__entry->prio		= p->prio; /* XXX SCHED_DEADLINE */
>  		__entry->group_dead	= group_dead;
> @@ -787,7 +787,7 @@ TRACE_EVENT(sched_skip_cpuset_numa,
>  	),
>  
>  	TP_fast_assign(
> -		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, tsk, TASK_COMM_LEN);
>  		__entry->pid		 = task_pid_nr(tsk);
>  		__entry->tgid		 = task_tgid_nr(tsk);
>  		__entry->ngid		 = task_numa_group_id(tsk);
> diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h
> index 1db7e4b07c01..8fffe6d9bdcc 100644
> --- a/include/trace/events/signal.h
> +++ b/include/trace/events/signal.h
> @@ -67,7 +67,7 @@ TRACE_EVENT(signal_generate,
>  	TP_fast_assign(
>  		__entry->sig	= sig;
>  		TP_STORE_SIGINFO(__entry, info);
> -		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
>  		__entry->pid	= task->pid;
>  		__entry->group	= group;
>  		__entry->result	= result;
> diff --git a/include/trace/events/task.h b/include/trace/events/task.h
> index b9a129eb54d9..e3faaeb997ef 100644
> --- a/include/trace/events/task.h
> +++ b/include/trace/events/task.h
> @@ -21,7 +21,7 @@ TRACE_EVENT(task_newtask,
>  
>  	TP_fast_assign(
>  		__entry->pid = task->pid;
> -		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
>  		__entry->clone_flags = clone_flags;
>  		__entry->oom_score_adj = task->signal->oom_score_adj;
>  	),
> @@ -46,7 +46,7 @@ TRACE_EVENT(task_rename,
>  
>  	TP_fast_assign(
>  		__entry->pid = task->pid;
> -		memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN);
> +		copy_task_comm(entry->oldcomm, task, TASK_COMM_LEN);
>  		strscpy(entry->newcomm, comm, TASK_COMM_LEN);
>  		__entry->oom_score_adj = task->signal->oom_score_adj;
>  	),
> diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
> index 45a5e41f3a92..a197622e113c 100644
> --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
> +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
> @@ -20,7 +20,7 @@ TRACE_EVENT(bpf_testmod_test_read,
>  	),
>  	TP_fast_assign(
>  		__entry->pid = task->pid;
> -		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
> +		copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
>  		__entry->off = ctx->off;
>  		__entry->len = ctx->len;
>  	),
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm()
  2026-10-30 22:34   ` David Laight
@ 2026-10-31 14:30     ` Steven Rostedt
  0 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2026-10-31 14:30 UTC (permalink / raw)
  To: David Laight
  Cc: André Almeida, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, Linus Torvalds, akpm, Yafang Shao,
	andrii.nakryiko, arnaldo.melo, Petr Mladek, linux-kernel,
	kernel-dev, linux-mm, linux-api, linux-trace-kernel

On Fri, 30 Oct 2026 22:34:35 +0000
David Laight <david.laight.linux@gmail.com> wrote:

> I suspect the trace code would be faster it is just copied the (first)
> 16 characters and worried about whether it was terminated later on.
> It does far more 'saves' than trace reads and their performance is
> much more important.

I'm assuming that the compiler would optimize:

+/*
+ * Copy task name to a buffer. Final result is always a NUL-terminated string.
+ */
+static __always_inline void copy_task_comm(char *dst, struct task_struct *tsk, size_t len)
+{
+	const char *_src = tsk->comm;
+	size_t _len = min(len, TASK_COMM_LEN);
+
+	if (!_len)
+		return;
+
+	memcpy(dst, _src, _len);
+	dst[_len - 1] = '\0';
+}
+

to basically:

	memcpy(dst, src, _len);
	dst[_len - 1] = '\0';

Where it already figured out _len at build time. Adding a single write of
the nul byte without any branches would likely be a couple of cycles at
max. It's all hot cache (from the memcpy) and writing a immediate.

I'm not worried that one line will cause any measurable overhead to the
tracing.

-- Steve

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm()
  2026-10-30 21:38 ` [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm() André Almeida
@ 2026-10-31 21:39   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-10-31 21:39 UTC (permalink / raw)
  To: André Almeida, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Steven Rostedt, Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: kernel-dev, linux-mm, linux-trace-kernel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] lib/string_kunit: uninitialized stack read in string_copy_task_comm()
--

commit 0d3a01595d2cc8a60f5d8a8716e5935db351758d
Author: André Almeida <andrealmeid@igalia.com>

lib/string_kunit: Add test for copy_task_comm()

This commit adds a KUnit test case for copy_task_comm() in
lib/tests/string_kunit.c to verify copying a task command name into buffers
of equal, smaller, and larger sizes.

> diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
> index 0819ace5b0275..66c3398f23174 100644
> --- a/lib/tests/string_kunit.c
> +++ b/lib/tests/string_kunit.c
> @@ -881,6 +881,43 @@ static void string_bench_strrchr(struct kunit *test)
>  	STRING_BENCH_BUF(test, buf, len, strrchr, buf, '\0');
>  }
>  
> +#define TASK_NAME "task_name"
> +#define TASK_NAME_LEN 9
> +#define TASK_MAX_LEN TASK_COMM_LEN
> +#define SMALLER_LEN (TASK_NAME_LEN - 3)
> +#define BIGGER_LEN (TASK_MAX_LEN + 3)
> +
> +static void string_copy_task_comm(struct kunit *test)
> +{
> +	char str[TASK_MAX_LEN] = TASK_NAME, copy[TASK_MAX_LEN],
> +	     smaller_buf[SMALLER_LEN], bigger_buf[BIGGER_LEN];
> +	static struct task_struct task, *tsk = &task;
> +	int len1, len2, i;
> +
> +	/* set and get task name */
> +	strscpy_pad(tsk->comm, str);
> +	copy_task_comm(copy, tsk, TASK_COMM_LEN);
> +
> +	len1 = strlen(str);
> +	len2 = strlen(copy);
> +
> +	KUNIT_ASSERT_EQ(test, len1, len2);
> +	KUNIT_ASSERT_EQ(test, len2, TASK_NAME_LEN);
> +	KUNIT_ASSERT_EQ(test, copy[len2], '\0');
> +	KUNIT_ASSERT_TRUE(test, !strcmp(str, copy));
> +
> +	/* copy to a smaller dst buffer */
> +	copy_task_comm(smaller_buf, tsk, sizeof(smaller_buf));
> +	KUNIT_ASSERT_TRUE(test, !strncmp(str, smaller_buf, SMALLER_LEN - 1));
> +	KUNIT_ASSERT_EQ(test, smaller_buf[SMALLER_LEN - 1], '\0');
> +
> +	/* copy to a bigger dst buffer */
> +	copy_task_comm(bigger_buf, tsk, sizeof(bigger_buf));
> +	KUNIT_ASSERT_TRUE(test, !strncmp(str, bigger_buf, TASK_NAME_LEN));
> +	for (i = TASK_NAME_LEN; i < BIGGER_LEN; i++)
> +		KUNIT_ASSERT_EQ(test, bigger_buf[i], '\0');
> +}

[Severity: Medium]
Does this loop in string_copy_task_comm() read uninitialized stack memory at
 the end of bigger_buf[]?

In string_copy_task_comm(), bigger_buf is declared on the stack without an
initializer and sized to BIGGER_LEN (TASK_MAX_LEN + 3, where TASK_MAX_LEN is
TASK_COMM_LEN).

However, copy_task_comm() in include/linux/sched.h clamps the copy length to
TASK_COMM_LEN and does not zero-pad dst beyond _len:

include/linux/sched.h:copy_task_comm() {
	const char *_src = tsk->comm;
	size_t _len = min(len, TASK_COMM_LEN);

	if (!_len)
		return;

	memcpy(dst, _src, _len);
	dst[_len - 1] = '\0';
}

Because copy_task_comm() only writes TASK_MAX_LEN bytes into bigger_buf, the
trailing 3 bytes from TASK_MAX_LEN to BIGGER_LEN - 1 are never written. When
the loop iterates i up to BIGGER_LEN, won't KUNIT_ASSERT_EQ() read those 3
uninitialized stack bytes and fail the test (or trigger a KMSAN report) when
stack variables are not zero-initialized?

Note that in the later commit de6fdb508944 ("sched: Extend task command name
with TASK_COMM_EXT_LEN"), tsk->comm and the clamp in copy_task_comm() are
increased to TASK_COMM_EXT_LEN (64) while TASK_MAX_LEN here remains
TASK_COMM_LEN (16). That masks the uninitialized read only because
bigger_buf (19 bytes) ceases to be larger than tsk->comm (64 bytes), which
leaves this commit broken during bisection and means the bigger_buf test
case is no longer testing a buffer larger than tsk->comm after that commit.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261030-tonyk-long_name-v8-0-c9b030332254@igalia.com?part=3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN
  2026-10-30 21:38 ` [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN André Almeida
@ 2026-10-31 21:39   ` sashiko-bot
  2026-11-01  0:10   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-10-31 21:39 UTC (permalink / raw)
  To: André Almeida, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Steven Rostedt, Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: kernel-dev, linux-mm, linux-trace-kernel

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [Medium] drm/tests: drm_test_framebuffer_init() fails due to extended current->comm
- [Medium] drm/amdgpu: amdgpu_ras_check_bad_page_unlock() fails for >=16-char comm
- [Medium] selftests/bpf: verifier negative tests fail with 64-byte task_struct::comm
- [Medium] drm/nouveau: format truncation in nouveau_channel_ctor() and nouveau_drm_open()
- [Medium] tracing: broken comm event filtering in filter_pred_comm() for long names
- [Medium] lib/string_kunit: string_copy_task_comm() uses TASK_COMM_LEN for TASK_MAX_LEN
- [Low] ipv6: ndisc_warn_deprecated_sysctl() fails to deduplicate long comm names
--

commit de6fdb5089442d5e041310e67345e77eafd17cb9
Author: André Almeida <andrealmeid@igalia.com>

sched: Extend task command name with TASK_COMM_EXT_LEN

This commit introduces TASK_COMM_EXT_LEN (64 bytes) and expands
task_struct::comm to allow longer command names for userspace and kernel
threads while capping existing userspace interfaces to TASK_COMM_LEN.

[ ... ]

> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index db529a93525d3..5e02bce749b82 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -323,6 +323,7 @@ struct user_event_mm;
>   */
>  enum {
>  	TASK_COMM_LEN = 16,
> +	TASK_COMM_EXT_LEN = 64,
>  };
>  
>  extern void sched_tick(void);
> @@ -1192,7 +1193,7 @@ struct task_struct {
>  	 * - set it with set_task_comm() to ensure it is always
>  	 *   NUL-terminated and zero-padded
>  	 */
> -	char				comm[TASK_COMM_LEN];
> +	char				comm[TASK_COMM_EXT_LEN];

[Severity: Medium]
Does enlarging task_struct::comm to TASK_COMM_EXT_LEN cause the
drm_test_framebuffer_init() KUnit test to fail?

KUnit runs each test case inside a kthread created by kunit_try_catch_run()
in lib/kunit/try-catch.c:

	task_struct = kthread_create(kunit_generic_run_threadfn_adapter,
				     try_catch, "kunit_try_catch_thread");

During kthread creation, copy_process() in kernel/fork.c copies args->name
into p->comm:

	if (args->name)
		strscpy_pad(p->comm, args->name, sizeof(p->comm));

With p->comm enlarged to 64 bytes, current->comm now holds the full
22-character "kunit_try_catch_thread" instead of being truncated to
"kunit_try_catch".

However, struct drm_framebuffer still defines comm as char comm[TASK_COMM_LEN],
so drm_framebuffer_init() in drivers/gpu/drm/drm_framebuffer.c truncates it
to 15 characters:

	fb->funcs = funcs;
	strscpy(fb->comm, current->comm);

When drm_test_framebuffer_init() in
drivers/gpu/drm/tests/drm_framebuffer_test.c checks:

	/* The fb->comm must be set to the current running process */
	KUNIT_EXPECT_STREQ(test, fb1.comm, current->comm);

won't this compare "kunit_try_catch" against "kunit_try_catch_thread" and
fail on every run?

[Severity: Medium]
Can this also cause amdgpu_ras_check_bad_page_unlock() to reject the owning
process with -EACCES when its command name is 16 or more characters long?

In drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c, amdgpu_vram_mgr_new() saves
the allocating task's comm into vres->task.comm (which is sized to
TASK_COMM_LEN):

	vres->task.pid = task_pid_nr(current);
	strscpy_pad(vres->task.comm, current->comm);

This truncates names of 16 or more characters to 15 characters and places a
NUL byte at index 15.

Later, amdgpu_ras_check_bad_page_unlock() in
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c verifies the caller against the
stored task info:

	if ((flags == BYPASS_ALLOCATED_ADDRESS) &&
	    ((blk_info.task.pid != task_pid_nr(current)) ||
		strncmp(blk_info.task.comm, current->comm, TASK_COMM_LEN))) {
		ret = -EACCES;
		goto out;
	}

When current->comm has 16 or more characters (for example from execve() via
begin_new_exec() -> __set_task_comm()), current->comm[15] is non-NUL while
blk_info.task.comm[15] is NUL, causing strncmp(..., TASK_COMM_LEN) to mismatch
at index 15. Should that comparison use TASK_COMM_LEN - 1?

[Severity: Medium]
Will changing task_struct::comm to 64 bytes in vmlinux BTF break the BPF
verifier negative selftests that test out-of-bounds accesses against
task->comm?

In tools/testing/selftests/bpf/progs/task_kfunc_failure.c, task_access_comm1
and task_access_comm2 expect a 17-byte access to exceed task->comm:

	SEC("tp_btf/task_newtask")
	__failure __msg("access beyond the end of member comm")
	int BPF_PROG(task_access_comm1, struct task_struct *task, u64 clone_flags)
	{
		bpf_strncmp(task->comm, 17, "foo");
		return 0;
	}

	SEC("tp_btf/task_newtask")
	__failure __msg("access beyond the end of member comm")
	int BPF_PROG(task_access_comm2, struct task_struct *task, u64 clone_flags)
	{
		bpf_strncmp(task->comm + 1, 16, "foo");
		return 0;
	}

And in tools/testing/selftests/bpf/progs/verifier_btf_array_access.c,
kernel_btf_array_out_of_bounds expects offsets in [0, 31] to run past the
end of task->comm:

	/* task->comm[i], i in [0, 31]: max offset runs past comm. */
	SEC("syscall")
	__failure
	__msg("invalid variable offset access into struct task_struct")
	int kernel_btf_array_out_of_bounds(void *ctx)

With task_struct::comm enlarged to 64 bytes, the verifier accepts all three
programs instead of rejecting them. Should these selftests be updated to match
TASK_COMM_EXT_LEN?

[Severity: Medium]
Could enlarging current->comm to 64 bytes trigger -Wformat-truncation build
warnings under W=1 and truncate the PID suffix in Nouveau?

Similar to the i915 places updated in this patch, nouveau_channel_ctor() in
drivers/gpu/drm/nouveau/nouveau_chan.c formats current->comm and the PID into
a 32-byte buffer:

	DEFINE_RAW_FLEX(struct nvif_chan_v0, args, name, TASK_COMM_LEN + 16);
	...
	snprintf(args->name, __member_size(args->name), "%s[%d]",
		 current->comm, task_pid_nr(current));

And nouveau_drm_open() in drivers/gpu/drm/nouveau/nouveau_drm.c does the same
into a 32-byte stack buffer:

	char name[32];
	...
	rcu_read_lock();
	snprintf(name, sizeof(name), "%s[%d]",
		 current->comm, pid_nr(rcu_dereference(fpriv->pid)));
	rcu_read_unlock();

Should these two callers also be updated so W=1 builds do not fail with
-Wformat-truncation and long command names do not drop the "[%d]" suffix?

[Severity: Medium]
How does ftrace event filtering on comm behave when current->comm is longer
than 15 characters?

In kernel/trace/trace_events_filter.c, filter_pred_comm() passes TASK_COMM_LEN
(16) as the buffer length of current->comm:

	static int filter_pred_comm(struct filter_pred *pred, void *event)
	{
		int cmp;

		cmp = pred->regex->match(current->comm, pred->regex,
					TASK_COMM_LEN);
		return cmp ^ pred->not;
	}

When a task has a command name of 16 or more characters in current->comm,
current->comm[15] is non-NUL. In regex_match_full():

	if (len < r->len)
		return 0;

	return strncmp(str, r->pattern, len) == 0;

filtering by the 15-character truncated name (r->len == 15) compares 16 bytes
and fails because str[15] is non-NUL while r->pattern[15] is NUL, whereas
filtering by a full name longer than 16 characters is rejected by len < r->len.
Likewise, regex_match_end() computes strlen = len - 1 (15) and checks for the
suffix at offset 15 - r->len rather than the end of current->comm:

	static int regex_match_end(char *str, struct regex *r, int len)
	{
		int strlen = len - 1;

		if (strlen >= r->len &&
		    memcmp(str + strlen - r->len, r->pattern, r->len) == 0)

Should filter_pred_comm() and the regex match helpers be updated to handle
TASK_COMM_EXT_LEN?

[Severity: Low]
In net/ipv6/ndisc.c, does ndisc_warn_deprecated_sysctl() fail to deduplicate
warnings when current->comm is 16 or more characters long?

	static char warncomm[TASK_COMM_LEN];
	static int warned;
	if (strcmp(warncomm, current->comm) && warned < 5) {
		strscpy(warncomm, current->comm);

Because warncomm is sized to TASK_COMM_LEN, strscpy() truncates current->comm
to 15 characters, so subsequent calls from the same process (such as
systemd-networkd) will see strcmp(warncomm, current->comm) != 0 and repeat
the warning up to 5 times. Should warncomm use TASK_COMM_EXT_LEN (or compare
with strncmp(warncomm, current->comm, TASK_COMM_LEN - 1))?

>  
>  	struct nameidata		*nameidata;
>  
> @@ -2048,7 +2049,7 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
>  static __always_inline void copy_task_comm(char *dst, struct task_struct *tsk, size_t len)
>  {
>  	const char *_src = tsk->comm;
> -	size_t _len = min(len, TASK_COMM_LEN);
> +	size_t _len = min(len, TASK_COMM_EXT_LEN);
>  
>  	if (!_len)
>  		return;

[Severity: Medium]
In lib/tests/string_kunit.c, should string_copy_task_comm() also be updated
from TASK_COMM_LEN to TASK_COMM_EXT_LEN?

Currently, string_copy_task_comm() defines:

	#define TASK_MAX_LEN TASK_COMM_LEN
	#define SMALLER_LEN (TASK_NAME_LEN - 3)
	#define BIGGER_LEN (TASK_MAX_LEN + 3)

	static void string_copy_task_comm(struct kunit *test)
	{
		...
		/* copy to a bigger dst buffer */
		copy_task_comm(bigger_buf, tsk, sizeof(bigger_buf));
		KUNIT_ASSERT_TRUE(test, !strncmp(str, bigger_buf, TASK_NAME_LEN));
		for (i = TASK_NAME_LEN; i < BIGGER_LEN; i++)
			KUNIT_ASSERT_EQ(test, bigger_buf[i], '\0');

Because TASK_MAX_LEN is still TASK_COMM_LEN (16), BIGGER_LEN is 19, which is
smaller than sizeof(tsk->comm) (64), so the test no longer exercises copying
into a destination buffer larger than tsk->comm. Additionally, if TASK_MAX_LEN
is updated to TASK_COMM_EXT_LEN, copy_task_comm() only writes _len (64) bytes
and does not zero-pad dst[_len .. len - 1], which would leave the trailing
bytes of bigger_buf uninitialized when the test asserts they are '\0'.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261030-tonyk-long_name-v8-0-c9b030332254@igalia.com?part=4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 5/6] prctl: Add support for long user thread names
  2026-10-30 21:38 ` [PATCH v8 5/6] prctl: Add support for long user thread names André Almeida
@ 2026-10-31 21:39   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-10-31 21:39 UTC (permalink / raw)
  To: André Almeida, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Steven Rostedt, Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: kernel-dev, linux-mm, linux-trace-kernel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] prctl: missing arg validation and buffer size UAPI in PR_{SET,GET}_EXT_NAME
--

commit d86849bc61de6aa30e004f18202851c2e72d0d41
Author: André Almeida <andrealmeid@igalia.com>

prctl: Add support for long user thread names

This commit adds the PR_SET_EXT_NAME and PR_GET_EXT_NAME prctl() options to
support getting and setting extended user thread names up to
TASK_COMM_EXT_LEN bytes.

> diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
> index b6ec6f6937195..a07f8edadd652 100644
> --- a/include/uapi/linux/prctl.h
> +++ b/include/uapi/linux/prctl.h
> @@ -56,6 +56,9 @@
>  #define PR_SET_NAME    15		/* Set process name */
>  #define PR_GET_NAME    16		/* Get process name */
>  
> +#define PR_SET_EXT_NAME    17		/* Set extended process name */
> +#define PR_GET_EXT_NAME    18		/* Get extended process name */
> +
>  /* Get/set process endian */
>  #define PR_GET_ENDIAN	19
>  #define PR_SET_ENDIAN	20
> diff --git a/kernel/sys.c b/kernel/sys.c
> index 6a72c7e644e70..fc9e3c5a91353 100644
> --- a/kernel/sys.c
> +++ b/kernel/sys.c

[ ... ]

> @@ -2616,6 +2616,19 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
>  		if (copy_to_user((char __user *)arg2, comm, TASK_COMM_LEN))
>  			return -EFAULT;
>  		break;
> +	case PR_SET_EXT_NAME:
> +		comm[TASK_COMM_EXT_LEN - 1] = 0;
> +		if (strncpy_from_user(comm, (char __user *)arg2,
> +				      TASK_COMM_EXT_LEN - 1) < 0)
> +			return -EFAULT;
> +		set_task_comm(me, comm);
> +		proc_comm_connector(me);
> +		break;
> +	case PR_GET_EXT_NAME:
> +		strscpy_pad(comm, me->comm, TASK_COMM_EXT_LEN);
> +		if (copy_to_user((char __user *)arg2, comm, TASK_COMM_EXT_LEN))
> +			return -EFAULT;
> +		break;

[Severity: Medium]
Should PR_SET_EXT_NAME and PR_GET_EXT_NAME in SYSCALL_DEFINE5(prctl) validate
that the unused arguments (arg3, arg4, and arg5) are zero and return -EINVAL
otherwise? Because libc's prctl() wrapper is variadic, 2-argument calls from
userspace can pass arbitrary register values in arg3..arg5, which prevents
extending these options with flags or length parameters in the future.

In addition, PR_GET_EXT_NAME unconditionally copies TASK_COMM_EXT_LEN (64)
bytes to the userspace buffer at arg2, but TASK_COMM_EXT_LEN is only defined
in include/linux/sched.h and is not exposed in include/uapi/linux/prctl.h:

include/linux/sched.h:
    enum {
        TASK_COMM_LEN = 16,
        TASK_COMM_EXT_LEN = 64,
    };

Without a UAPI constant or a buffer size argument in PR_GET_EXT_NAME, could a
userspace caller passing a smaller buffer (or passing a buffer length in arg3)
have 64 bytes written past the end of its buffer, or break if
TASK_COMM_EXT_LEN is ever increased?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261030-tonyk-long_name-v8-0-c9b030332254@igalia.com?part=5

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN
  2026-10-30 21:38 ` [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN André Almeida
  2026-10-31 21:39   ` sashiko-bot
@ 2026-11-01  0:10   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2026-11-01  0:10 UTC (permalink / raw)
  To: André Almeida, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Steven Rostedt, Christian Brauner, Kees Cook, Shuah Khan, willy,
	mathieu.desnoyers, David Laight, Linus Torvalds, akpm,
	Yafang Shao, andrii.nakryiko, arnaldo.melo, Petr Mladek
  Cc: oe-kbuild-all, LKML, kernel-dev, linux-mm, linux-api,
	linux-trace-kernel, André Almeida

Hi André,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4dd16e31135ea8437a720222df34e8745f385d6d]

url:    https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/treewide-Get-rid-of-get_task_comm/20261030-183832
base:   4dd16e31135ea8437a720222df34e8745f385d6d
patch link:    https://lore.kernel.org/r/20261030-tonyk-long_name-v8-4-c9b030332254%40igalia.com
patch subject: [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20261101/202611010746.Qs8jUny8-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261101/202611010746.Qs8jUny8-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202611010746.Qs8jUny8-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/nouveau/nouveau_chan.c: In function 'nouveau_channel_ctor':
>> drivers/gpu/drm/nouveau/nouveau_chan.c:343:58: warning: '%s' directive output may be truncated writing up to 63 bytes into a region of size 32 [-Wformat-truncation=]
     343 |         snprintf(args->name, __member_size(args->name), "%s[%d]",
         |                                                          ^~
   drivers/gpu/drm/nouveau/nouveau_chan.c:343:9: note: 'snprintf' output between 4 and 77 bytes into a destination of size 32
     343 |         snprintf(args->name, __member_size(args->name), "%s[%d]",
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     344 |                  current->comm, task_pid_nr(current));
         |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +343 drivers/gpu/drm/nouveau/nouveau_chan.c

ebb945a94bba2ce Ben Skeggs          2012-07-20  253  
5b8a43aeb9cbf6b Marcin Slusarz      2012-08-19  254  static int
5cca41ac70e5877 Ben Skeggs          2024-07-26  255  nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm,
06db7fded6dec88 Ben Skeggs          2022-06-01  256  		     struct nouveau_channel **pchan)
ebb945a94bba2ce Ben Skeggs          2012-07-20  257  {
152be54224de182 Danilo Krummrich    2023-10-02  258  	const struct nvif_mclass hosts[] = {
284ad706ad2f509 Ben Skeggs          2025-02-04  259  		{ BLACKWELL_CHANNEL_GPFIFO_B, 0 },
32cb1cc358ffed2 Ben Skeggs          2024-11-25  260  		{ BLACKWELL_CHANNEL_GPFIFO_A, 0 },
44f93b209e2afde Ben Skeggs          2024-11-25  261  		{    HOPPER_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  262  		{    AMPERE_CHANNEL_GPFIFO_B, 0 },
7f4f35ea5b080e6 Ben Skeggs          2022-06-01  263  		{    AMPERE_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  264  		{    TURING_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  265  		{     VOLTA_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  266  		{    PASCAL_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  267  		{   MAXWELL_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  268  		{    KEPLER_CHANNEL_GPFIFO_B, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  269  		{    KEPLER_CHANNEL_GPFIFO_A, 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  270  		{     FERMI_CHANNEL_GPFIFO  , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  271  		{       G82_CHANNEL_GPFIFO  , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  272  		{      NV50_CHANNEL_GPFIFO  , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  273  		{      NV40_CHANNEL_DMA     , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  274  		{      NV17_CHANNEL_DMA     , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  275  		{      NV10_CHANNEL_DMA     , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  276  		{      NV03_CHANNEL_DMA     , 0 },
06db7fded6dec88 Ben Skeggs          2022-06-01  277  		{}
06db7fded6dec88 Ben Skeggs          2022-06-01  278  	};
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  279  	DEFINE_RAW_FLEX(struct nvif_chan_v0, args, name, TASK_COMM_LEN + 16);
5cca41ac70e5877 Ben Skeggs          2024-07-26  280  	struct nvif_device *device = &cli->device;
ebb945a94bba2ce Ben Skeggs          2012-07-20  281  	struct nouveau_channel *chan;
06db7fded6dec88 Ben Skeggs          2022-06-01  282  	const u64 plength = 0x10000;
06db7fded6dec88 Ben Skeggs          2022-06-01  283  	const u64 ioffset = plength;
06db7fded6dec88 Ben Skeggs          2022-06-01  284  	const u64 ilength = 0x02000;
06db7fded6dec88 Ben Skeggs          2022-06-01  285  	int cid, ret;
06db7fded6dec88 Ben Skeggs          2022-06-01  286  	u64 size;
06db7fded6dec88 Ben Skeggs          2022-06-01  287  
06db7fded6dec88 Ben Skeggs          2022-06-01  288  	cid = nvif_mclass(&device->object, hosts);
06db7fded6dec88 Ben Skeggs          2022-06-01  289  	if (cid < 0)
06db7fded6dec88 Ben Skeggs          2022-06-01  290  		return cid;
06db7fded6dec88 Ben Skeggs          2022-06-01  291  
06db7fded6dec88 Ben Skeggs          2022-06-01  292  	if (hosts[cid].oclass < NV50_CHANNEL_GPFIFO)
06db7fded6dec88 Ben Skeggs          2022-06-01  293  		size = plength;
06db7fded6dec88 Ben Skeggs          2022-06-01  294  	else
06db7fded6dec88 Ben Skeggs          2022-06-01  295  		size = ioffset + ilength;
ebb945a94bba2ce Ben Skeggs          2012-07-20  296  
ebb945a94bba2ce Ben Skeggs          2012-07-20  297  	/* allocate dma push buffer */
5cca41ac70e5877 Ben Skeggs          2024-07-26  298  	ret = nouveau_channel_prep(cli, size, &chan);
ebb945a94bba2ce Ben Skeggs          2012-07-20  299  	*pchan = chan;
ebb945a94bba2ce Ben Skeggs          2012-07-20  300  	if (ret)
ebb945a94bba2ce Ben Skeggs          2012-07-20  301  		return ret;
ebb945a94bba2ce Ben Skeggs          2012-07-20  302  
ebb945a94bba2ce Ben Skeggs          2012-07-20  303  	/* create channel object */
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  304  	args->version = 0;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  305  	args->namelen = __member_size(args->name);
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  306  	args->runlist = __ffs64(runm);
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  307  	args->runq = 0;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  308  	args->priv = priv;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  309  	args->devm = BIT(0);
06db7fded6dec88 Ben Skeggs          2022-06-01  310  	if (hosts[cid].oclass < NV50_CHANNEL_GPFIFO) {
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  311  		args->vmm = 0;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  312  		args->ctxdma = nvif_handle(&chan->push.ctxdma);
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  313  		args->offset = chan->push.addr;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  314  		args->length = 0;
bbf8906b2cad17c Ben Skeggs          2014-08-10  315  	} else {
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  316  		args->vmm = nvif_handle(&chan->vmm->vmm.object);
06db7fded6dec88 Ben Skeggs          2022-06-01  317  		if (hosts[cid].oclass < FERMI_CHANNEL_GPFIFO)
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  318  			args->ctxdma = nvif_handle(&chan->push.ctxdma);
06db7fded6dec88 Ben Skeggs          2022-06-01  319  		else
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  320  			args->ctxdma = 0;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  321  		args->offset = ioffset + chan->push.addr;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  322  		args->length = ilength;
06db7fded6dec88 Ben Skeggs          2022-06-01  323  	}
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  324  	args->huserd = 0;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  325  	args->ouserd = 0;
06db7fded6dec88 Ben Skeggs          2022-06-01  326  
06db7fded6dec88 Ben Skeggs          2022-06-01  327  	/* allocate userd */
06db7fded6dec88 Ben Skeggs          2022-06-01  328  	if (hosts[cid].oclass >= VOLTA_CHANNEL_GPFIFO_A) {
06db7fded6dec88 Ben Skeggs          2022-06-01  329  		ret = nvif_mem_ctor(&cli->mmu, "abi16ChanUSERD", NVIF_CLASS_MEM_GF100,
06db7fded6dec88 Ben Skeggs          2022-06-01  330  				    NVIF_MEM_VRAM | NVIF_MEM_COHERENT | NVIF_MEM_MAPPABLE,
06db7fded6dec88 Ben Skeggs          2022-06-01  331  				    0, PAGE_SIZE, NULL, 0, &chan->mem_userd);
06db7fded6dec88 Ben Skeggs          2022-06-01  332  		if (ret)
ebb945a94bba2ce Ben Skeggs          2012-07-20  333  			return ret;
ebb945a94bba2ce Ben Skeggs          2012-07-20  334  
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  335  		args->huserd = nvif_handle(&chan->mem_userd.object);
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  336  		args->ouserd = 0;
ebb945a94bba2ce Ben Skeggs          2012-07-20  337  
06db7fded6dec88 Ben Skeggs          2022-06-01  338  		chan->userd = &chan->mem_userd.object;
06db7fded6dec88 Ben Skeggs          2022-06-01  339  	} else {
06db7fded6dec88 Ben Skeggs          2022-06-01  340  		chan->userd = &chan->user;
06db7fded6dec88 Ben Skeggs          2022-06-01  341  	}
ebb945a94bba2ce Ben Skeggs          2012-07-20  342  
e270b3665f8321c Gustavo A. R. Silva 2025-04-16 @343  	snprintf(args->name, __member_size(args->name), "%s[%d]",
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  344  		 current->comm, task_pid_nr(current));
ebb945a94bba2ce Ben Skeggs          2012-07-20  345  
06db7fded6dec88 Ben Skeggs          2022-06-01  346  	ret = nvif_object_ctor(&device->object, "abi16ChanUser", 0, hosts[cid].oclass,
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  347  			       args, __struct_size(args), &chan->user);
06db7fded6dec88 Ben Skeggs          2022-06-01  348  	if (ret) {
06db7fded6dec88 Ben Skeggs          2022-06-01  349  		nouveau_channel_del(pchan);
ebb945a94bba2ce Ben Skeggs          2012-07-20  350  		return ret;
bbf8906b2cad17c Ben Skeggs          2014-08-10  351  	}
ebb945a94bba2ce Ben Skeggs          2012-07-20  352  
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  353  	chan->runlist = args->runlist;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  354  	chan->chid = args->chid;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  355  	chan->inst = args->inst;
e270b3665f8321c Gustavo A. R. Silva 2025-04-16  356  	chan->token = args->token;
06db7fded6dec88 Ben Skeggs          2022-06-01  357  	return 0;
ebb945a94bba2ce Ben Skeggs          2012-07-20  358  }
ebb945a94bba2ce Ben Skeggs          2012-07-20  359  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-11-01  0:11 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 21:38 [PATCH v8 0/6] sched: Add support for long task name André Almeida
2026-10-30 21:38 ` [PATCH v8 1/6] treewide: Get rid of get_task_comm() André Almeida
2026-10-30 21:38 ` [PATCH v8 2/6] treewide: Replace memcpy(..., current->comm) with copy_task_comm() André Almeida
2026-10-30 22:34   ` David Laight
2026-10-31 14:30     ` Steven Rostedt
2026-10-30 21:38 ` [PATCH v8 3/6] lib/string_kunit: Add test for copy_task_comm() André Almeida
2026-10-31 21:39   ` sashiko-bot
2026-10-30 21:38 ` [PATCH v8 4/6] sched: Extend task command name with TASK_COMM_EXT_LEN André Almeida
2026-10-31 21:39   ` sashiko-bot
2026-11-01  0:10   ` kernel test robot
2026-10-30 21:38 ` [PATCH v8 5/6] prctl: Add support for long user thread names André Almeida
2026-10-31 21:39   ` sashiko-bot
2026-10-30 21:38 ` [PATCH v8 6/6] selftests: prctl: Add test for long " André Almeida

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox