The following patches were made over Linus's tree. They standardize the
task->comm initialization. Currently, kthreads will set it up after a
successful kthread_thread call in the calling function. io_uring will
set it from the thread fn. And the vhost task patches added it's own
helper.
This patchset adds a new kernel clone args callout, setup_thread_fn,
which can be used to setup an internal struct, like is needed by
kthreads, and can also be used to set the task->comm like is needed
by kthread, io_uring and vhost.
Note that I have not yet compile tested all the archs in the first
patch. I was not sure if Linus was going to prefer this patchset's
approach to setting the comm or would like to leave it as it is now.
So this more of a RFC.
The next patches will add callouts to set the task's comm, and create
internal resources. This adds a new struct to for these callouts to
organize them and reduce the args passed into kernel_thread and
create_io_thread.
Signed-off-by: Mike Christie <[email protected]>
---
arch/alpha/kernel/process.c | 4 ++--
arch/arc/kernel/process.c | 4 ++--
arch/arm/kernel/process.c | 4 ++--
arch/arm64/kernel/process.c | 4 ++--
arch/csky/kernel/process.c | 4 ++--
arch/hexagon/kernel/process.c | 4 ++--
arch/ia64/kernel/process.c | 4 ++--
arch/loongarch/kernel/process.c | 4 ++--
arch/m68k/kernel/process.c | 4 ++--
arch/microblaze/kernel/process.c | 4 ++--
arch/mips/kernel/process.c | 4 ++--
arch/nios2/kernel/process.c | 4 ++--
arch/openrisc/kernel/process.c | 4 ++--
arch/parisc/kernel/process.c | 8 ++++----
arch/powerpc/kernel/process.c | 5 ++---
arch/riscv/kernel/process.c | 4 ++--
arch/s390/kernel/process.c | 4 ++--
arch/sh/kernel/process_32.c | 4 ++--
arch/sparc/kernel/process_32.c | 4 ++--
arch/sparc/kernel/process_64.c | 4 ++--
arch/um/kernel/process.c | 4 ++--
arch/x86/kernel/process.c | 9 +++++----
arch/xtensa/kernel/process.c | 6 +++---
include/linux/sched/task.h | 12 +++++++++---
init/main.c | 6 +++++-
io_uring/io-wq.c | 8 ++++++--
io_uring/sqpoll.c | 6 +++++-
kernel/fork.c | 24 ++++++++++++++++--------
kernel/kthread.c | 7 ++++++-
29 files changed, 99 insertions(+), 68 deletions(-)
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 65fdae9e48f3..3008c9d39b0f 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -245,12 +245,12 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childti->pcb.ksp = (unsigned long) childstack;
childti->pcb.flags = 1; /* set FEN, clear everything else */
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
memset(childstack, 0,
sizeof(struct switch_stack) + sizeof(struct pt_regs));
childstack->r26 = (unsigned long) ret_from_kernel_thread;
- childstack->r9 = (unsigned long) args->fn;
+ childstack->r9 = (unsigned long) args->fns->thread_fn;
childstack->r10 = (unsigned long) args->fn_arg;
childregs->hae = alpha_mv.hae_cache;
childti->pcb.usp = 0;
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 3369f0700702..edda86c54634 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -192,11 +192,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childksp[0] = 0; /* fp */
childksp[1] = (unsigned long)ret_from_fork; /* blink */
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(c_regs, 0, sizeof(struct pt_regs));
c_callee->r13 = (unsigned long)args->fn_arg;
- c_callee->r14 = (unsigned long)args->fn;
+ c_callee->r14 = (unsigned long)args->fns->thread_fn;
return 0;
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f811733a8fc5..a1b28921f351 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -254,7 +254,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
thread->cpu_domain = get_domain();
#endif
- if (likely(!args->fn)) {
+ if (likely(!args->fns || !args->fns->thread_fn)) {
*childregs = *current_pt_regs();
childregs->ARM_r0 = 0;
if (stack_start)
@@ -262,7 +262,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
} else {
memset(childregs, 0, sizeof(struct pt_regs));
thread->cpu_context.r4 = (unsigned long)args->fn_arg;
- thread->cpu_context.r5 = (unsigned long)args->fn;
+ thread->cpu_context.r5 = (unsigned long)args->fns->thread_fn;
childregs->ARM_cpsr = SVC_MODE;
}
thread->cpu_context.pc = (unsigned long)ret_from_fork;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 269ac1c25ae2..499aab54d56d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -361,7 +361,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
ptrauth_thread_init_kernel(p);
- if (likely(!args->fn)) {
+ if (likely(!args->fns || !args->fns->thread_fn)) {
*childregs = *current_pt_regs();
childregs->regs[0] = 0;
@@ -399,7 +399,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h | PSR_IL_BIT;
- p->thread.cpu_context.x19 = (unsigned long)args->fn;
+ p->thread.cpu_context.x19 = (unsigned long)args->fns->thread_fn;
p->thread.cpu_context.x20 = (unsigned long)args->fn_arg;
}
p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c
index 2b0ed515a88e..50b417cca6be 100644
--- a/arch/csky/kernel/process.c
+++ b/arch/csky/kernel/process.c
@@ -48,11 +48,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* setup thread.sp for switch_to !!! */
p->thread.sp = (unsigned long)childstack;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(childregs, 0, sizeof(struct pt_regs));
childstack->r15 = (unsigned long) ret_from_kernel_thread;
childstack->r10 = (unsigned long) args->fn_arg;
- childstack->r9 = (unsigned long) args->fn;
+ childstack->r9 = (unsigned long) args->fns->thread_fn;
childregs->sr = mfcr("psr");
} else {
*childregs = *(current_pt_regs());
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index e15eeaebd785..8c57762202e8 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -75,10 +75,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
sizeof(*ss));
ss->lr = (unsigned long)ret_from_fork;
p->thread.switch_sp = ss;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(childregs, 0, sizeof(struct pt_regs));
/* r24 <- fn, r25 <- arg */
- ss->r24 = (unsigned long)args->fn;
+ ss->r24 = (unsigned long)args->fns->thread_fn;
ss->r25 = (unsigned long)args->fn_arg;
pt_set_kmode(childregs);
return 0;
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 416305e550e2..22b3c75b895a 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -342,13 +342,13 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
if (unlikely(args->idle)) {
/* fork_idle() called us */
return 0;
}
memset(child_stack, 0, sizeof(*child_ptregs) + sizeof(*child_stack));
- child_stack->r4 = (unsigned long) args->fn;
+ child_stack->r4 = (unsigned long) args->fns->thread_fn;
child_stack->r5 = (unsigned long) args->fn_arg;
/*
* Preserve PSR bits, except for bits 32-34 and 37-45,
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index edfd220a3737..b5022c0defd2 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -146,10 +146,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.csr_crmd = csr_read32(LOONGARCH_CSR_CRMD);
p->thread.csr_prmd = csr_read32(LOONGARCH_CSR_PRMD);
p->thread.csr_ecfg = csr_read32(LOONGARCH_CSR_ECFG);
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
p->thread.reg03 = childksp;
- p->thread.reg23 = (unsigned long)args->fn;
+ p->thread.reg23 = (unsigned long)args->fns->thread_fn;
p->thread.reg24 = (unsigned long)args->fn_arg;
p->thread.reg01 = (unsigned long)ret_from_kernel_thread;
p->thread.sched_ra = (unsigned long)ret_from_kernel_thread;
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index e06ce147c0b7..550a75b3d36d 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -159,11 +159,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
*/
p->thread.fc = USER_DATA;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
memset(frame, 0, sizeof(struct fork_frame));
frame->regs.sr = PS_S;
- frame->sw.a3 = (unsigned long)args->fn;
+ frame->sw.a3 = (unsigned long)args->fns->thread_fn;
frame->sw.d7 = (unsigned long)args->fn_arg;
frame->sw.retpc = (unsigned long)ret_from_kernel_thread;
p->thread.usp = 0;
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 1f802aab2b96..94138f7aec4c 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -60,13 +60,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
struct pt_regs *childregs = task_pt_regs(p);
struct thread_info *ti = task_thread_info(p);
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* if we're creating a new kernel thread then just zeroing all
* the registers. That's OK for a brand new thread.*/
memset(childregs, 0, sizeof(struct pt_regs));
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
ti->cpu_context.r1 = (unsigned long)childregs;
- ti->cpu_context.r20 = (unsigned long)args->fn;
+ ti->cpu_context.r20 = (unsigned long)args->fns->thread_fn;
ti->cpu_context.r19 = (unsigned long)args->fn_arg;
childregs->pt_mode = 1;
local_save_flags(childregs->msr);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 093dbbd6b843..45bc4bac3ba2 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -121,11 +121,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* Put the stack after the struct pt_regs. */
childksp = (unsigned long) childregs;
p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
unsigned long status = p->thread.cp0_status;
memset(childregs, 0, sizeof(struct pt_regs));
- p->thread.reg16 = (unsigned long)args->fn;
+ p->thread.reg16 = (unsigned long)args->fns->thread_fn;
p->thread.reg17 = (unsigned long)args->fn_arg;
p->thread.reg29 = childksp;
p->thread.reg31 = (unsigned long) ret_from_kernel_thread;
diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c
index 29593b98567d..87135a1b64af 100644
--- a/arch/nios2/kernel/process.c
+++ b/arch/nios2/kernel/process.c
@@ -111,11 +111,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
struct switch_stack *childstack =
((struct switch_stack *)childregs) - 1;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(childstack, 0,
sizeof(struct switch_stack) + sizeof(struct pt_regs));
- childstack->r16 = (unsigned long) args->fn;
+ childstack->r16 = (unsigned long) args->fns->thread_fn;
childstack->r17 = (unsigned long) args->fn_arg;
childstack->ra = (unsigned long) ret_from_kernel_thread;
childregs->estatus = STATUS_PIE;
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index f94b5ec06786..cfd377832c2c 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -185,9 +185,9 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
sp -= sizeof(struct pt_regs);
kregs = (struct pt_regs *)sp;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(kregs, 0, sizeof(struct pt_regs));
- kregs->gpr[20] = (unsigned long)args->fn;
+ kregs->gpr[20] = (unsigned long)args->fns->thread_fn;
kregs->gpr[22] = (unsigned long)args->fn_arg;
} else {
*userregs = *current_pt_regs();
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index c4f8374c7018..a1f028dbb2d1 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -216,7 +216,7 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
extern void * const ret_from_kernel_thread;
extern void * const child_return;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
memset(cregs, 0, sizeof(struct pt_regs));
if (args->idle) /* idle thread */
@@ -231,10 +231,10 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
* ret_from_kernel_thread.
*/
#ifdef CONFIG_64BIT
- cregs->gr[27] = ((unsigned long *)args->fn)[3];
- cregs->gr[26] = ((unsigned long *)args->fn)[2];
+ cregs->gr[27] = ((unsigned long *)args->fns->thread_fn)[3];
+ cregs->gr[26] = ((unsigned long *)args->fns->thread_fn)[2];
#else
- cregs->gr[26] = (unsigned long) args->fn;
+ cregs->gr[26] = (unsigned long) args->fns->thread_fn;
#endif
cregs->gr[25] = (unsigned long) args->fn_arg;
} else {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c22cc234672f..627efd7a5179 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1761,14 +1761,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* Copy registers */
childregs = (struct pt_regs *)(sp + STACK_INT_FRAME_REGS);
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
((unsigned long *)sp)[0] = 0;
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gpr[1] = sp + STACK_USER_INT_FRAME_SIZE;
/* function */
- if (args->fn)
- childregs->gpr[14] = ppc_function_entry((void *)args->fn);
+ childregs->gpr[14] = ppc_function_entry((void *)args->fns->thread_fn);
#ifdef CONFIG_PPC64
clear_tsk_thread_flag(p, TIF_32BIT);
childregs->softe = IRQS_ENABLED;
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 8955f2432c2d..2b8cf2f8ac4b 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -167,7 +167,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
memset(&p->thread.s, 0, sizeof(p->thread.s));
/* p->thread holds context to be restored by __switch_to() */
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* Kernel thread */
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gp = gp_in_global;
@@ -175,7 +175,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs->status = SR_PP | SR_PIE;
p->thread.ra = (unsigned long)ret_from_kernel_thread;
- p->thread.s[0] = (unsigned long)args->fn;
+ p->thread.s[0] = (unsigned long)args->fns->thread_fn;
p->thread.s[1] = (unsigned long)args->fn_arg;
} else {
*childregs = *(current_pt_regs());
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 3f5d2db0b854..b4cda7f71488 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -144,14 +144,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
frame->sf.gprs[9] = (unsigned long)frame;
/* Store access registers to kernel stack of new process. */
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
/* kernel thread */
memset(&frame->childregs, 0, sizeof(struct pt_regs));
frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
frame->childregs.psw.addr =
(unsigned long)__ret_from_fork;
- frame->childregs.gprs[9] = (unsigned long)args->fn;
+ frame->childregs.gprs[9] = (unsigned long)args->fns->thread_fn;
frame->childregs.gprs[10] = (unsigned long)args->fn_arg;
frame->childregs.orig_gpr2 = -1;
frame->childregs.last_break = 1;
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 92b6649d4929..ef7d7fd6a78c 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -111,11 +111,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs = task_pt_regs(p);
p->thread.sp = (unsigned long) childregs;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(childregs, 0, sizeof(struct pt_regs));
p->thread.pc = (unsigned long) ret_from_kernel_thread;
childregs->regs[4] = (unsigned long) args->fn_arg;
- childregs->regs[5] = (unsigned long) args->fn;
+ childregs->regs[5] = (unsigned long) args->fns->thread_fn;
childregs->sr = SR_MD;
#if defined(CONFIG_SH_FPU)
childregs->sr |= SR_FD;
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 33b0215a4182..a035775c47d5 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -298,12 +298,12 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
ti->ksp = (unsigned long) new_stack;
p->thread.kregs = childregs;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
extern int nwindows;
unsigned long psr;
memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
- childregs->u_regs[UREG_G1] = (unsigned long) args->fn;
+ childregs->u_regs[UREG_G1] = (unsigned long) args->fns->thread_fn;
childregs->u_regs[UREG_G2] = (unsigned long) args->fn_arg;
psr = childregs->psr = get_psr();
ti->kpsr = psr | PSR_PIL;
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 6335b698a4b4..332253a742c9 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -586,11 +586,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
sizeof(struct sparc_stackf));
t->fpsaved[0] = 0;
- if (unlikely(args->fn)) {
+ if (unlikely(args->fns && args->fns->thread_fn)) {
memset(child_trap_frame, 0, child_stack_sz);
__thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(current_pt_regs()->tstate + 1) & TSTATE_CWP;
- t->kregs->u_regs[UREG_G1] = (unsigned long) args->fn;
+ t->kregs->u_regs[UREG_G1] = (unsigned long) args->fns->thread_fn;
t->kregs->u_regs[UREG_G2] = (unsigned long) args->fn_arg;
return 0;
}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 47830ade35ed..8e56c8c85707 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -165,7 +165,7 @@ int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
p->thread = (struct thread_struct) INIT_THREAD;
- if (!args->fn) {
+ if (!args->fns || !args->fns->thread_fn) {
memcpy(&p->thread.regs.regs, current_pt_regs(),
sizeof(p->thread.regs.regs));
PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
@@ -177,7 +177,7 @@ int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
arch_copy_thread(¤t->thread.arch, &p->thread.arch);
} else {
get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
- p->thread.request.u.thread.proc = args->fn;
+ p->thread.request.u.thread.proc = args->fns->thread_fn;
p->thread.request.u.thread.arg = args->fn_arg;
handler = new_thread_handler;
}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 40d156a31676..0bbf55b90c0e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -134,6 +134,7 @@ static int set_new_tls(struct task_struct *p, unsigned long tls)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
unsigned long clone_flags = args->flags;
+ int (*thread_fn)(void *) = args->fns ? args->fns->thread_fn : NULL;
unsigned long sp = args->stack;
unsigned long tls = args->tls;
struct inactive_task_frame *frame;
@@ -173,13 +174,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
frame->flags = X86_EFLAGS_FIXED;
#endif
- fpu_clone(p, clone_flags, args->fn);
+ fpu_clone(p, clone_flags, thread_fn);
/* Kernel thread ? */
if (unlikely(p->flags & PF_KTHREAD)) {
p->thread.pkru = pkru_get_init_value();
memset(childregs, 0, sizeof(struct pt_regs));
- kthread_frame_init(frame, args->fn, args->fn_arg);
+ kthread_frame_init(frame, thread_fn, args->fn_arg);
return 0;
}
@@ -195,7 +196,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
if (sp)
childregs->sp = sp;
- if (unlikely(args->fn)) {
+ if (unlikely(thread_fn)) {
/*
* A user space thread, but it doesn't return to
* ret_after_fork().
@@ -208,7 +209,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
*/
childregs->sp = 0;
childregs->ip = 0;
- kthread_frame_init(frame, args->fn, args->fn_arg);
+ kthread_frame_init(frame, thread_fn, args->fn_arg);
return 0;
}
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 68e0e2f06d66..015720ce6e19 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -287,7 +287,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
#error Unsupported Xtensa ABI
#endif
- if (!args->fn) {
+ if (!args->fns || !args->fns->thread_fn) {
struct pt_regs *regs = current_pt_regs();
unsigned long usp = usp_thread_fn ?
usp_thread_fn : regs->areg[1];
@@ -339,14 +339,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
* Window underflow will load registers from the
* spill slots on the stack on return from _switch_to.
*/
- SPILL_SLOT(childregs, 2) = (unsigned long)args->fn;
+ SPILL_SLOT(childregs, 2) = (unsigned long)args->fns->thread_fn;
SPILL_SLOT(childregs, 3) = (unsigned long)args->fn_arg;
#elif defined(__XTENSA_CALL0_ABI__)
/*
* a12 = thread_fn, a13 = thread_fn arg.
* _switch_to epilogue will load registers from the stack.
*/
- ((unsigned long *)p->thread.sp)[0] = (unsigned long)args->fn;
+ ((unsigned long *)p->thread.sp)[0] = (unsigned long)args->fns->thread_fn;
((unsigned long *)p->thread.sp)[1] = (unsigned long)args->fn_arg;
#else
#error Unsupported Xtensa ABI
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 357e0068497c..7a61ebbcdfe0 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -18,6 +18,10 @@ struct css_set;
/* All the bits taken by the old clone syscall. */
#define CLONE_LEGACY_FLAGS 0xffffffffULL
+struct kernel_clone_fns {
+ int (*thread_fn)(void *fn_arg);
+};
+
struct kernel_clone_args {
u64 flags;
int __user *pidfd;
@@ -34,7 +38,7 @@ struct kernel_clone_args {
int io_thread;
int kthread;
int idle;
- int (*fn)(void *);
+ struct kernel_clone_fns *fns;
void *fn_arg;
struct cgroup *cgrp;
struct css_set *cset;
@@ -89,9 +93,11 @@ extern void exit_files(struct task_struct *);
extern void exit_itimers(struct task_struct *);
extern pid_t kernel_clone(struct kernel_clone_args *kargs);
-struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
+struct task_struct *create_io_thread(struct kernel_clone_fns *fns, void *fn_arg,
+ int node);
struct task_struct *fork_idle(int);
-extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
+ unsigned long flags);
extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags);
extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
int kernel_wait(pid_t pid, int *stat);
diff --git a/init/main.c b/init/main.c
index e1c3911d7c70..d9889b67d9ee 100644
--- a/init/main.c
+++ b/init/main.c
@@ -683,6 +683,10 @@ static void __init setup_command_line(char *command_line)
static __initdata DECLARE_COMPLETION(kthreadd_done);
+static struct kernel_clone_fns kthread_fns = {
+ .thread_fn = kthreadd,
+};
+
noinline void __ref rest_init(void)
{
struct task_struct *tsk;
@@ -707,7 +711,7 @@ noinline void __ref rest_init(void)
rcu_read_unlock();
numa_default_policy();
- pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
+ pid = kernel_thread(&kthread_fns, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 411bb2d1acd4..455df0c0deb5 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -739,6 +739,10 @@ static inline bool io_should_retry_thread(long err)
}
}
+static struct kernel_clone_fns io_wqe_clone_fns = {
+ .thread_fn = io_wqe_worker,
+};
+
static void create_worker_cont(struct callback_head *cb)
{
struct io_worker *worker;
@@ -748,7 +752,7 @@ static void create_worker_cont(struct callback_head *cb)
worker = container_of(cb, struct io_worker, create_work);
clear_bit_unlock(0, &worker->create_state);
wqe = worker->wqe;
- tsk = create_io_thread(io_wqe_worker, worker, wqe->node);
+ tsk = create_io_thread(&io_wqe_clone_fns, worker, wqe->node);
if (!IS_ERR(tsk)) {
io_init_new_worker(wqe, worker, tsk);
io_worker_release(worker);
@@ -817,7 +821,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
if (index == IO_WQ_ACCT_BOUND)
worker->flags |= IO_WORKER_F_BOUND;
- tsk = create_io_thread(io_wqe_worker, worker, wqe->node);
+ tsk = create_io_thread(&io_wqe_clone_fns, worker, wqe->node);
if (!IS_ERR(tsk)) {
io_init_new_worker(wqe, worker, tsk);
} else if (!io_should_retry_thread(PTR_ERR(tsk))) {
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index 559652380672..8d60b9775798 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -312,6 +312,10 @@ static int io_sq_thread(void *data)
do_exit(0);
}
+static struct kernel_clone_fns io_sq_clone_fns = {
+ .thread_fn = io_sq_thread,
+};
+
int io_sqpoll_wait_sq(struct io_ring_ctx *ctx)
{
DEFINE_WAIT(wait);
@@ -395,7 +399,7 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
sqd->task_pid = current->pid;
sqd->task_tgid = current->tgid;
- tsk = create_io_thread(io_sq_thread, sqd, NUMA_NO_NODE);
+ tsk = create_io_thread(&io_sq_clone_fns, sqd, NUMA_NO_NODE);
if (IS_ERR(tsk)) {
ret = PTR_ERR(tsk);
goto err_sqpoll;
diff --git a/kernel/fork.c b/kernel/fork.c
index 9f7fe3541897..f308a5ae0ed3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2590,9 +2590,12 @@ static int idle_dummy(void *dummy)
struct task_struct * __init fork_idle(int cpu)
{
struct task_struct *task;
+ struct kernel_clone_fns fns = {
+ .thread_fn = &idle_dummy,
+ };
struct kernel_clone_args args = {
.flags = CLONE_VM,
- .fn = &idle_dummy,
+ .fns = &fns,
.fn_arg = NULL,
.kthread = 1,
.idle = 1,
@@ -2613,7 +2616,8 @@ struct task_struct * __init fork_idle(int cpu)
* The returned task is inactive, and the caller must fire it up through
* wake_up_new_task(p). All signals are blocked in the created task.
*/
-struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+struct task_struct *create_io_thread(struct kernel_clone_fns *fns, void *fn_arg,
+ int node)
{
unsigned long flags = CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|
CLONE_IO;
@@ -2621,8 +2625,8 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
.flags = ((lower_32_bits(flags) | CLONE_VM |
CLONE_UNTRACED) & ~CSIGNAL),
.exit_signal = (lower_32_bits(flags) & CSIGNAL),
- .fn = fn,
- .fn_arg = arg,
+ .fns = fns,
+ .fn_arg = fn_arg,
.io_thread = 1,
};
@@ -2727,14 +2731,15 @@ pid_t kernel_clone(struct kernel_clone_args *args)
/*
* Create a kernel thread.
*/
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
+ unsigned long flags)
{
struct kernel_clone_args args = {
.flags = ((lower_32_bits(flags) | CLONE_VM |
CLONE_UNTRACED) & ~CSIGNAL),
.exit_signal = (lower_32_bits(flags) & CSIGNAL),
- .fn = fn,
- .fn_arg = arg,
+ .fns = fns,
+ .fn_arg = fn_arg,
.kthread = 1,
};
@@ -2746,11 +2751,14 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
*/
pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
+ struct kernel_clone_fns clone_fns = {
+ .thread_fn = fn,
+ };
struct kernel_clone_args args = {
.flags = ((lower_32_bits(flags) | CLONE_VM |
CLONE_UNTRACED) & ~CSIGNAL),
.exit_signal = (lower_32_bits(flags) & CSIGNAL),
- .fn = fn,
+ .fns = &clone_fns,
.fn_arg = arg,
};
diff --git a/kernel/kthread.c b/kernel/kthread.c
index f97fd01a2932..5e7c8f3f184f 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -388,6 +388,10 @@ int tsk_fork_get_node(struct task_struct *tsk)
return NUMA_NO_NODE;
}
+static struct kernel_clone_fns thread_clone_fns = {
+ .thread_fn = kthread,
+};
+
static void create_kthread(struct kthread_create_info *create)
{
int pid;
@@ -396,7 +400,8 @@ static void create_kthread(struct kthread_create_info *create)
current->pref_node_fork = create->node;
#endif
/* We want our own signal handler (we take no signals by default). */
- pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
+ pid = kernel_thread(&thread_clone_fns, create,
+ CLONE_FS | CLONE_FILES | SIGCHLD);
if (pid < 0) {
/* Release the structure when caller killed by a fatal signal. */
struct completion *done = xchg(&create->done, NULL);
--
2.25.1
This converts io_uring to use the setup_thread_fn callout so it can set
the task's name during copy_process. It then doesn't need the temp buffer
and will work like kthread and vhost.
Signed-off-by: Mike Christie <[email protected]>
---
io_uring/io-wq.c | 11 +++++++----
io_uring/sqpoll.c | 13 +++++++++----
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 455df0c0deb5..4981bfd5581f 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -617,13 +617,9 @@ static int io_wqe_worker(void *data)
struct io_wqe *wqe = worker->wqe;
struct io_wq *wq = wqe->wq;
bool last_timeout = false;
- char buf[TASK_COMM_LEN];
worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
- snprintf(buf, sizeof(buf), "iou-wrk-%d", wq->task->pid);
- set_task_comm(current, buf);
-
while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
long ret;
@@ -739,8 +735,15 @@ static inline bool io_should_retry_thread(long err)
}
}
+static int io_wqe_setup_thread(struct task_struct *tsk, void *data)
+{
+ snprintf(tsk->comm, TASK_COMM_LEN, "iou-wrk-%d", tsk->pid);
+ return 0;
+}
+
static struct kernel_clone_fns io_wqe_clone_fns = {
.thread_fn = io_wqe_worker,
+ .setup_thread_fn = io_wqe_setup_thread,
};
static void create_worker_cont(struct callback_head *cb)
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index 8d60b9775798..373067a714dc 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -223,12 +223,8 @@ static int io_sq_thread(void *data)
struct io_sq_data *sqd = data;
struct io_ring_ctx *ctx;
unsigned long timeout = 0;
- char buf[TASK_COMM_LEN];
DEFINE_WAIT(wait);
- snprintf(buf, sizeof(buf), "iou-sqp-%d", sqd->task_pid);
- set_task_comm(current, buf);
-
if (sqd->sq_cpu != -1)
set_cpus_allowed_ptr(current, cpumask_of(sqd->sq_cpu));
else
@@ -312,8 +308,17 @@ static int io_sq_thread(void *data)
do_exit(0);
}
+static int io_sq_setup_thread(struct task_struct *tsk, void *data)
+{
+ struct io_sq_data *sqd = data;
+
+ snprintf(tsk->comm, TASK_COMM_LEN, "iou-sqp-%d", sqd->task_pid);
+ return 0;
+}
+
static struct kernel_clone_fns io_sq_clone_fns = {
.thread_fn = io_sq_thread,
+ .setup_thread_fn = io_sq_setup_thread,
};
int io_sqpoll_wait_sq(struct io_ring_ctx *ctx)
--
2.25.1
The io_uring code will set it's worker threads's name with a
iou-sqd/iou-wrk prefix and then either the task's pid or the task's
parent's pid. The kthread code will set the name to whatever the caller
decides. To set these names they have come up with different approaches.
This patch adds a callout to setup a kthread or io_uring worker's
internal struct and/or set the task's coomm.
Signed-off-by: Mike Christie <[email protected]>
---
include/linux/sched.h | 2 ++
include/linux/sched/task.h | 1 +
kernel/fork.c | 6 ++++++
3 files changed, 9 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 853d08f7562b..09bdc71c0523 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1066,6 +1066,8 @@ struct task_struct {
* executable name, excluding path.
*
* - normally initialized setup_new_exec()
+ * - can be initialized in copy_process if
+ * kernel_clone_args.fns.setup_thread_fn() is set.
* - access it with [gs]et_task_comm()
* - lock it with task_lock()
*/
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 7a61ebbcdfe0..844824e0023c 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -20,6 +20,7 @@ struct css_set;
struct kernel_clone_fns {
int (*thread_fn)(void *fn_arg);
+ int (*setup_thread_fn)(struct task_struct *tsk, void *fn_arg);
};
struct kernel_clone_args {
diff --git a/kernel/fork.c b/kernel/fork.c
index f308a5ae0ed3..057274da64fb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2345,6 +2345,12 @@ static __latent_entropy struct task_struct *copy_process(
p->tgid = p->pid;
}
+ if (args->fns && args->fns->setup_thread_fn) {
+ retval = args->fns->setup_thread_fn(p, args->fn_arg);
+ if (retval)
+ goto bad_fork_put_pidfd;
+ }
+
p->nr_dirtied = 0;
p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
p->dirty_paused_when = 0;
--
2.25.1
This preps set_kthread_struct to be used for a setup_thread_fn callback
by having it set the task's comm and also returning an int instead of a
bool.
Signed-off-by: Mike Christie <[email protected]>
---
include/linux/kthread.h | 2 +-
kernel/fork.c | 2 +-
kernel/kthread.c | 89 ++++++++++++++++++++++++++++-------------
kernel/sched/core.c | 2 +-
4 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 30e5bec81d2b..94dffdfa17df 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -34,7 +34,7 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
const char *namefmt);
void get_kthread_comm(char *buf, size_t buf_size, struct task_struct *tsk);
-bool set_kthread_struct(struct task_struct *p);
+int kthread_setup_struct(struct task_struct *p, void *data);
void kthread_set_per_cpu(struct task_struct *k, int cpu);
bool kthread_is_per_cpu(struct task_struct *k);
diff --git a/kernel/fork.c b/kernel/fork.c
index 057274da64fb..bd60ecc6b29c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2190,7 +2190,7 @@ static __latent_entropy struct task_struct *copy_process(
audit_set_context(p, NULL);
cgroup_fork(p);
if (args->kthread) {
- if (!set_kthread_struct(p))
+ if (kthread_setup_struct(p, args->fn_arg))
goto bad_fork_cleanup_delayacct;
}
#ifdef CONFIG_NUMA
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 5e7c8f3f184f..b67c2caf2ccb 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -46,6 +46,10 @@ struct kthread_create_info
struct task_struct *result;
struct completion *done;
+ struct mutex name_mutex;
+ const char *name_fmt;
+ va_list *name_args;
+
struct list_head list;
};
@@ -107,23 +111,58 @@ void get_kthread_comm(char *buf, size_t buf_size, struct task_struct *tsk)
strscpy_pad(buf, kthread->full_name, buf_size);
}
-bool set_kthread_struct(struct task_struct *p)
+static int set_kthread_comm(struct task_struct *tsk, struct kthread *kthread,
+ struct kthread_create_info *create)
+{
+ va_list name_args;
+ int len;
+
+ mutex_lock(&create->name_mutex);
+ if (!create->name_args) {
+ mutex_unlock(&create->name_mutex);
+ return -EINTR;
+ }
+
+ va_copy(name_args, *create->name_args);
+ len = vsnprintf(tsk->comm, TASK_COMM_LEN, create->name_fmt, name_args);
+ va_end(name_args);
+ if (len >= TASK_COMM_LEN) {
+ /* leave it truncated when out of memory. */
+ kthread->full_name = kvasprintf(GFP_KERNEL, create->name_fmt,
+ *create->name_args);
+ }
+ mutex_unlock(&create->name_mutex);
+ return 0;
+}
+
+int kthread_setup_struct(struct task_struct *p, void *data)
{
struct kthread *kthread;
+ int ret;
if (WARN_ON_ONCE(to_kthread(p)))
- return false;
+ return -EINVAL;
kthread = kzalloc(sizeof(*kthread), GFP_KERNEL);
if (!kthread)
- return false;
+ return -ENOMEM;
+
+ if (data) {
+ ret = set_kthread_comm(p, kthread, data);
+ if (ret)
+ goto free_kthread;
+ }
init_completion(&kthread->exited);
init_completion(&kthread->parked);
p->vfork_done = &kthread->exited;
p->worker_private = kthread;
- return true;
+ return 0;
+
+free_kthread:
+ kfree(kthread);
+ return ret;
}
void free_kthread_struct(struct task_struct *k)
@@ -131,7 +170,7 @@ void free_kthread_struct(struct task_struct *k)
struct kthread *kthread;
/*
- * Can be NULL if kmalloc() in set_kthread_struct() failed.
+ * Can be NULL if kmalloc() in kthread_setup_struct() failed.
*/
kthread = to_kthread(k);
if (!kthread)
@@ -423,6 +462,8 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
{
DECLARE_COMPLETION_ONSTACK(done);
struct task_struct *task;
+ va_list name_args;
+ int ret;
struct kthread_create_info *create = kmalloc(sizeof(*create),
GFP_KERNEL);
@@ -432,6 +473,10 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
create->data = data;
create->node = node;
create->done = &done;
+ mutex_init(&create->name_mutex);
+ create->name_fmt = namefmt;
+ va_copy(name_args, args);
+ create->name_args = &name_args;
spin_lock(&kthread_create_lock);
list_add_tail(&create->list, &kthread_create_list);
@@ -443,14 +488,20 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
* the OOM killer while kthreadd is trying to allocate memory for
* new kernel thread.
*/
- if (unlikely(wait_for_completion_killable(&done))) {
+ ret = wait_for_completion_killable(&done);
+ if (unlikely(ret)) {
+ mutex_lock(&create->name_mutex);
+ create->name_args = NULL;
+ mutex_unlock(&create->name_mutex);
/*
* If I was killed by a fatal signal before kthreadd (or new
* kernel thread) calls complete(), leave the cleanup of this
* structure to that thread.
*/
- if (xchg(&create->done, NULL))
- return ERR_PTR(-EINTR);
+ if (xchg(&create->done, NULL)) {
+ task = ERR_PTR(-EINTR);
+ goto end_args;
+ }
/*
* kthreadd (or new kernel thread) will call complete()
* shortly.
@@ -458,27 +509,9 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
wait_for_completion(&done);
}
task = create->result;
- if (!IS_ERR(task)) {
- char name[TASK_COMM_LEN];
- va_list aq;
- int len;
-
- /*
- * task is already visible to other tasks, so updating
- * COMM must be protected.
- */
- va_copy(aq, args);
- len = vsnprintf(name, sizeof(name), namefmt, aq);
- va_end(aq);
- if (len >= TASK_COMM_LEN) {
- struct kthread *kthread = to_kthread(task);
-
- /* leave it truncated when out of memory. */
- kthread->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
- }
- set_task_comm(task, name);
- }
kfree(create);
+end_args:
+ va_end(name_args);
return task;
}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e838feb6adc5..289b9941b58d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -9925,7 +9925,7 @@ void __init sched_init(void)
* if we want to avoid special-casing it in code that deals with per-CPU
* kthreads.
*/
- WARN_ON(!set_kthread_struct(current));
+ WARN_ON(kthread_setup_struct(current, NULL));
/*
* Make us the idle thread. Technically, schedule() should not be
--
2.25.1
kthread_setup_struct can now setup the kthread struct and setup the
comm, so remove the call to kthread_setup_struct in copy_process and
have kthread.c set the setup_thread_fn callback, so it works like
io_uring.
Signed-off-by: Mike Christie <[email protected]>
---
kernel/fork.c | 5 +----
kernel/kthread.c | 1 +
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index bd60ecc6b29c..7cdd85befa41 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2189,10 +2189,6 @@ static __latent_entropy struct task_struct *copy_process(
p->io_context = NULL;
audit_set_context(p, NULL);
cgroup_fork(p);
- if (args->kthread) {
- if (kthread_setup_struct(p, args->fn_arg))
- goto bad_fork_cleanup_delayacct;
- }
#ifdef CONFIG_NUMA
p->mempolicy = mpol_dup(p->mempolicy);
if (IS_ERR(p->mempolicy)) {
@@ -2598,6 +2594,7 @@ struct task_struct * __init fork_idle(int cpu)
struct task_struct *task;
struct kernel_clone_fns fns = {
.thread_fn = &idle_dummy,
+ .setup_thread_fn = kthread_setup_struct,
};
struct kernel_clone_args args = {
.flags = CLONE_VM,
diff --git a/kernel/kthread.c b/kernel/kthread.c
index b67c2caf2ccb..7776d19789f6 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -429,6 +429,7 @@ int tsk_fork_get_node(struct task_struct *tsk)
static struct kernel_clone_fns thread_clone_fns = {
.thread_fn = kthread,
+ .setup_thread_fn = kthread_setup_struct,
};
static void create_kthread(struct kthread_create_info *create)
--
2.25.1
Hi Mike,
I love your patch! Yet something to improve:
[auto build test ERROR on tip/sched/core]
[also build test ERROR on vfs-idmapping/for-next linus/master v6.2-rc8]
[cannot apply to davem-sparc/master next-20230210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
patch link: https://lore.kernel.org/r/20230213010020.1813-2-michael.christie%40oracle.com
patch subject: [PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20230213/[email protected]/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/3eb77c0672cdc93fa577d5feb91b79f272d883b7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
git checkout 3eb77c0672cdc93fa577d5feb91b79f272d883b7
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=um SUBARCH=i386 olddefconfig
make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
arch/um/kernel/process.c:51:5: warning: no previous prototype for 'pid_to_processor_id' [-Wmissing-prototypes]
51 | int pid_to_processor_id(int pid)
| ^~~~~~~~~~~~~~~~~~~
arch/um/kernel/process.c:87:7: warning: no previous prototype for '__switch_to' [-Wmissing-prototypes]
87 | void *__switch_to(struct task_struct *from, struct task_struct *to)
| ^~~~~~~~~~~
arch/um/kernel/process.c: In function 'new_thread_handler':
arch/um/kernel/process.c:122:28: warning: variable 'n' set but not used [-Wunused-but-set-variable]
122 | int (*fn)(void *), n;
| ^
arch/um/kernel/process.c: At top level:
arch/um/kernel/process.c:140:6: warning: no previous prototype for 'fork_handler' [-Wmissing-prototypes]
140 | void fork_handler(void)
| ^~~~~~~~~~~~
arch/um/kernel/process.c: In function 'copy_thread':
>> arch/um/kernel/process.c:187:20: error: 'const struct kernel_clone_args' has no member named 'fn'; did you mean 'fns'?
187 | if (!args->fn) {
| ^~
| fns
arch/um/kernel/process.c: At top level:
arch/um/kernel/process.c:217:6: warning: no previous prototype for 'arch_cpu_idle' [-Wmissing-prototypes]
217 | void arch_cpu_idle(void)
| ^~~~~~~~~~~~~
arch/um/kernel/process.c:253:5: warning: no previous prototype for 'copy_to_user_proc' [-Wmissing-prototypes]
253 | int copy_to_user_proc(void __user *to, void *from, int size)
| ^~~~~~~~~~~~~~~~~
arch/um/kernel/process.c:263:5: warning: no previous prototype for 'clear_user_proc' [-Wmissing-prototypes]
263 | int clear_user_proc(void __user *buf, int size)
| ^~~~~~~~~~~~~~~
arch/um/kernel/process.c:316:12: warning: no previous prototype for 'make_proc_sysemu' [-Wmissing-prototypes]
316 | int __init make_proc_sysemu(void)
| ^~~~~~~~~~~~~~~~
arch/um/kernel/process.c:356:15: warning: no previous prototype for 'arch_align_stack' [-Wmissing-prototypes]
356 | unsigned long arch_align_stack(unsigned long sp)
| ^~~~~~~~~~~~~~~~
vim +187 arch/um/kernel/process.c
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 157
c5febea0956fd3 arch/um/kernel/process.c Eric W. Biederman 2022-04-08 158 int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
^1da177e4c3f41 arch/um/kernel/process_kern.c Linus Torvalds 2005-04-16 159 {
c5febea0956fd3 arch/um/kernel/process.c Eric W. Biederman 2022-04-08 160 unsigned long clone_flags = args->flags;
c5febea0956fd3 arch/um/kernel/process.c Eric W. Biederman 2022-04-08 161 unsigned long sp = args->stack;
c5febea0956fd3 arch/um/kernel/process.c Eric W. Biederman 2022-04-08 162 unsigned long tls = args->tls;
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 163 void (*handler)(void);
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 164 int ret = 0;
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 165
^1da177e4c3f41 arch/um/kernel/process_kern.c Linus Torvalds 2005-04-16 166 p->thread = (struct thread_struct) INIT_THREAD;
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 167
3eb77c0672cdc9 arch/um/kernel/process.c Mike Christie 2023-02-12 168 if (!args->fns || !args->fns->thread_fn) {
2b067fc9dd143b arch/um/kernel/process.c Al Viro 2012-10-29 169 memcpy(&p->thread.regs.regs, current_pt_regs(),
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 170 sizeof(p->thread.regs.regs));
a3170d2ec25f84 arch/um/kernel/process.c Al Viro 2012-05-22 171 PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 172 if (sp != 0)
18badddaa84e13 arch/um/kernel/process.c Jeff Dike 2007-10-16 173 REGS_SP(p->thread.regs.regs.gp) = sp;
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 174
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 175 handler = fork_handler;
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 176
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 177 arch_copy_thread(¤t->thread.arch, &p->thread.arch);
d2ce4e92fa4f79 arch/um/kernel/process.c Al Viro 2012-09-20 178 } else {
fbfe9c847edf57 arch/um/kernel/process.c Ingo van Lil 2011-09-14 179 get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
3eb77c0672cdc9 arch/um/kernel/process.c Mike Christie 2023-02-12 180 p->thread.request.u.thread.proc = args->fns->thread_fn;
5bd2e97c868a8a arch/um/kernel/process.c Eric W. Biederman 2022-04-12 181 p->thread.request.u.thread.arg = args->fn_arg;
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 182 handler = new_thread_handler;
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 183 }
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 184
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 185 new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 186
5bd2e97c868a8a arch/um/kernel/process.c Eric W. Biederman 2022-04-12 @187 if (!args->fn) {
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 188 clear_flushed_tls(p);
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 189
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 190 /*
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 191 * Set a new TLS for the child thread?
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 192 */
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 193 if (clone_flags & CLONE_SETTLS)
457677c70c7672 arch/um/kernel/process.c Amanieu d'Antras 2020-01-04 194 ret = arch_set_tls(p, tls);
77bf4400319db9 arch/um/kernel/process.c Jeff Dike 2007-10-16 195 }
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 196
aa6758d4867cd0 arch/um/kernel/process_kern.c Paolo 'Blaisorblade' Giarrusso 2006-03-31 197 return ret;
^1da177e4c3f41 arch/um/kernel/process_kern.c Linus Torvalds 2005-04-16 198 }
^1da177e4c3f41 arch/um/kernel/process_kern.c Linus Torvalds 2005-04-16 199
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
Hi Mike,
I love your patch! Perhaps something to improve:
[auto build test WARNING on tip/sched/core]
[also build test WARNING on vfs-idmapping/for-next linus/master]
[cannot apply to davem-sparc/master next-20230210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
patch link: https://lore.kernel.org/r/20230213010020.1813-6-michael.christie%40oracle.com
patch subject: [PATCH 5/5] kernel: Convert kthread to use setup_thread_fn
config: mips-randconfig-r021-20230213 (https://download.01.org/0day-ci/archive/20230213/[email protected]/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project db0e6591612b53910a1b366863348bdb9d7d2fb1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install mips cross compiling tool for clang build
# apt-get install binutils-mipsel-linux-gnu
# https://github.com/intel-lab-lkp/linux/commit/9b34e5869b059d529620a0144a93c7437411cca0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
git checkout 9b34e5869b059d529620a0144a93c7437411cca0
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
kernel/fork.c:162:13: warning: no previous prototype for function 'arch_release_task_struct' [-Wmissing-prototypes]
void __weak arch_release_task_struct(struct task_struct *tsk)
^
kernel/fork.c:162:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void __weak arch_release_task_struct(struct task_struct *tsk)
^
static
kernel/fork.c:862:20: warning: no previous prototype for function 'arch_task_cache_init' [-Wmissing-prototypes]
void __init __weak arch_task_cache_init(void) { }
^
kernel/fork.c:862:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void __init __weak arch_task_cache_init(void) { }
^
static
>> kernel/fork.c:2565:1: warning: unused label 'bad_fork_cleanup_delayacct' [-Wunused-label]
bad_fork_cleanup_delayacct:
^~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
vim +/bad_fork_cleanup_delayacct +2565 kernel/fork.c
d741bf41d7c7db Peter Zijlstra 2020-08-29 2371
7e47682ea555e7 Aleksa Sarai 2015-06-09 2372 /*
7e47682ea555e7 Aleksa Sarai 2015-06-09 2373 * Ensure that the cgroup subsystem policies allow the new process to be
7b7b8a2c9560ef Randy Dunlap 2020-10-15 2374 * forked. It should be noted that the new process's css_set can be changed
7e47682ea555e7 Aleksa Sarai 2015-06-09 2375 * between here and cgroup_post_fork() if an organisation operation is in
7e47682ea555e7 Aleksa Sarai 2015-06-09 2376 * progress.
7e47682ea555e7 Aleksa Sarai 2015-06-09 2377 */
ef2c41cf38a755 Christian Brauner 2020-02-05 2378 retval = cgroup_can_fork(p, args);
7e47682ea555e7 Aleksa Sarai 2015-06-09 2379 if (retval)
5a5cf5cb30d781 Christian Brauner 2020-02-05 2380 goto bad_fork_put_pidfd;
7e47682ea555e7 Aleksa Sarai 2015-06-09 2381
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2382 /*
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2383 * Now that the cgroups are pinned, re-clone the parent cgroup and put
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2384 * the new task on the correct runqueue. All this *before* the task
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2385 * becomes visible.
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2386 *
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2387 * This isn't part of ->can_fork() because while the re-cloning is
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2388 * cgroup specific, it unconditionally needs to place the task on a
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2389 * runqueue.
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2390 */
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2391 sched_cgroup_fork(p, args);
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2392
7b55851367136b David Herrmann 2019-01-08 2393 /*
7b55851367136b David Herrmann 2019-01-08 2394 * From this point on we must avoid any synchronous user-space
7b55851367136b David Herrmann 2019-01-08 2395 * communication until we take the tasklist-lock. In particular, we do
7b55851367136b David Herrmann 2019-01-08 2396 * not want user-space to be able to predict the process start-time by
7b55851367136b David Herrmann 2019-01-08 2397 * stalling fork(2) after we recorded the start_time but before it is
7b55851367136b David Herrmann 2019-01-08 2398 * visible to the system.
7b55851367136b David Herrmann 2019-01-08 2399 */
7b55851367136b David Herrmann 2019-01-08 2400
7b55851367136b David Herrmann 2019-01-08 2401 p->start_time = ktime_get_ns();
cf25e24db61cc9 Peter Zijlstra 2019-11-07 2402 p->start_boottime = ktime_get_boottime_ns();
7b55851367136b David Herrmann 2019-01-08 2403
18c830df771f2b Oleg Nesterov 2013-07-03 2404 /*
18c830df771f2b Oleg Nesterov 2013-07-03 2405 * Make it visible to the rest of the system, but dont wake it up yet.
18c830df771f2b Oleg Nesterov 2013-07-03 2406 * Need tasklist lock for parent etc handling!
18c830df771f2b Oleg Nesterov 2013-07-03 2407 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2408 write_lock_irq(&tasklist_lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2409
^1da177e4c3f41 Linus Torvalds 2005-04-16 2410 /* CLONE_PARENT re-uses the old parent */
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2411 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2412 p->real_parent = current->real_parent;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2413 p->parent_exec_id = current->parent_exec_id;
b4e00444cab4c3 Eddy Wu 2020-11-07 2414 if (clone_flags & CLONE_THREAD)
b4e00444cab4c3 Eddy Wu 2020-11-07 2415 p->exit_signal = -1;
b4e00444cab4c3 Eddy Wu 2020-11-07 2416 else
b4e00444cab4c3 Eddy Wu 2020-11-07 2417 p->exit_signal = current->group_leader->exit_signal;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2418 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2419 p->real_parent = current;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2420 p->parent_exec_id = current->self_exec_id;
b4e00444cab4c3 Eddy Wu 2020-11-07 2421 p->exit_signal = args->exit_signal;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2422 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2423
d83a7cb375eec2 Josh Poimboeuf 2017-02-13 2424 klp_copy_process(p);
d83a7cb375eec2 Josh Poimboeuf 2017-02-13 2425
85dd3f61203c5c Peter Zijlstra 2021-03-29 2426 sched_core_fork(p);
85dd3f61203c5c Peter Zijlstra 2021-03-29 2427
^1da177e4c3f41 Linus Torvalds 2005-04-16 2428 spin_lock(¤t->sighand->siglock);
4a2c7a7837da1b Oleg Nesterov 2006-03-28 2429
792575348ff70e Daniel Bristot de Oliveira 2022-07-29 2430 rv_task_fork(p);
792575348ff70e Daniel Bristot de Oliveira 2022-07-29 2431
d7822b1e24f2df Mathieu Desnoyers 2018-06-02 2432 rseq_fork(p, clone_flags);
d7822b1e24f2df Mathieu Desnoyers 2018-06-02 2433
4ca1d3ee46130e Eric W. Biederman 2018-07-13 2434 /* Don't start children in a dying pid namespace */
e8cfbc245e2488 Gargi Sharma 2017-11-17 2435 if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
3fd37226216620 Kirill Tkhai 2017-05-12 2436 retval = -ENOMEM;
3fd37226216620 Kirill Tkhai 2017-05-12 2437 goto bad_fork_cancel_cgroup;
3fd37226216620 Kirill Tkhai 2017-05-12 2438 }
4a2c7a7837da1b Oleg Nesterov 2006-03-28 2439
7673bf553b2732 Eric W. Biederman 2018-07-23 2440 /* Let kill terminate clone/fork in the middle */
7673bf553b2732 Eric W. Biederman 2018-07-23 2441 if (fatal_signal_pending(current)) {
7673bf553b2732 Eric W. Biederman 2018-07-23 2442 retval = -EINTR;
7673bf553b2732 Eric W. Biederman 2018-07-23 2443 goto bad_fork_cancel_cgroup;
7673bf553b2732 Eric W. Biederman 2018-07-23 2444 }
7673bf553b2732 Eric W. Biederman 2018-07-23 2445
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2446 /* No more failure paths after this point. */
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2447
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2448 /*
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2449 * Copy seccomp details explicitly here, in case they were changed
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2450 * before holding sighand lock.
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2451 */
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2452 copy_seccomp(p);
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2453
2c4704756cab7c Eric W. Biederman 2017-09-26 2454 init_task_pid_links(p);
73b9ebfe126a4a Oleg Nesterov 2006-03-28 2455 if (likely(p->pid)) {
4b9d33e6d83cc0 Tejun Heo 2011-06-17 2456 ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2457
8190773985141f Oleg Nesterov 2013-07-03 2458 init_task_pid(p, PIDTYPE_PID, pid);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2459 if (thread_group_leader(p)) {
6883f81aac6f44 Eric W. Biederman 2017-06-04 2460 init_task_pid(p, PIDTYPE_TGID, pid);
8190773985141f Oleg Nesterov 2013-07-03 2461 init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
8190773985141f Oleg Nesterov 2013-07-03 2462 init_task_pid(p, PIDTYPE_SID, task_session(current));
8190773985141f Oleg Nesterov 2013-07-03 2463
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2464 if (is_child_reaper(pid)) {
17cf22c33e1f1b Eric W. Biederman 2010-03-02 2465 ns_of_pid(pid)->child_reaper = p;
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2466 p->signal->flags |= SIGNAL_UNKILLABLE;
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2467 }
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2468 p->signal->shared_pending.signal = delayed.signal;
9c9f4ded90a59e Alan Cox 2008-10-13 2469 p->signal->tty = tty_kref_get(current->signal->tty);
749860ce242798 Pavel Tikhomirov 2017-01-30 2470 /*
749860ce242798 Pavel Tikhomirov 2017-01-30 2471 * Inherit has_child_subreaper flag under the same
749860ce242798 Pavel Tikhomirov 2017-01-30 2472 * tasklist_lock with adding child to the process tree
749860ce242798 Pavel Tikhomirov 2017-01-30 2473 * for propagate_has_child_subreaper optimization.
749860ce242798 Pavel Tikhomirov 2017-01-30 2474 */
749860ce242798 Pavel Tikhomirov 2017-01-30 2475 p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
749860ce242798 Pavel Tikhomirov 2017-01-30 2476 p->real_parent->signal->is_child_subreaper;
9cd80bbb07fcd6 Oleg Nesterov 2009-12-17 2477 list_add_tail(&p->sibling, &p->real_parent->children);
5e85d4abe3f43b Eric W. Biederman 2006-04-18 2478 list_add_tail_rcu(&p->tasks, &init_task.tasks);
6883f81aac6f44 Eric W. Biederman 2017-06-04 2479 attach_pid(p, PIDTYPE_TGID);
8190773985141f Oleg Nesterov 2013-07-03 2480 attach_pid(p, PIDTYPE_PGID);
8190773985141f Oleg Nesterov 2013-07-03 2481 attach_pid(p, PIDTYPE_SID);
909ea96468096b Christoph Lameter 2010-12-08 2482 __this_cpu_inc(process_counts);
80628ca06c5d42 Oleg Nesterov 2013-07-03 2483 } else {
80628ca06c5d42 Oleg Nesterov 2013-07-03 2484 current->signal->nr_threads++;
d80f7d7b2c75c5 Eric W. Biederman 2022-06-21 2485 current->signal->quick_threads++;
80628ca06c5d42 Oleg Nesterov 2013-07-03 2486 atomic_inc(¤t->signal->live);
60d4de3ff7f775 Elena Reshetova 2019-01-18 2487 refcount_inc(¤t->signal->sigcnt);
924de3b8c9410c Eric W. Biederman 2018-07-23 2488 task_join_group_stop(p);
80628ca06c5d42 Oleg Nesterov 2013-07-03 2489 list_add_tail_rcu(&p->thread_group,
80628ca06c5d42 Oleg Nesterov 2013-07-03 2490 &p->group_leader->thread_group);
0c740d0afc3bff Oleg Nesterov 2014-01-21 2491 list_add_tail_rcu(&p->thread_node,
0c740d0afc3bff Oleg Nesterov 2014-01-21 2492 &p->signal->thread_head);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2493 }
8190773985141f Oleg Nesterov 2013-07-03 2494 attach_pid(p, PIDTYPE_PID);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2495 nr_threads++;
73b9ebfe126a4a Oleg Nesterov 2006-03-28 2496 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2497 total_forks++;
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2498 hlist_del_init(&delayed.node);
3f17da699431ec Oleg Nesterov 2006-02-15 2499 spin_unlock(¤t->sighand->siglock);
4af4206be2bd19 Oleg Nesterov 2014-04-13 2500 syscall_tracepoint_update(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2501 write_unlock_irq(&tasklist_lock);
4af4206be2bd19 Oleg Nesterov 2014-04-13 2502
ddc204b517e60a Waiman Long 2022-02-08 2503 if (pidfile)
ddc204b517e60a Waiman Long 2022-02-08 2504 fd_install(pidfd, pidfile);
ddc204b517e60a Waiman Long 2022-02-08 2505
c13cf856cbe16a Andrew Morton 2005-11-28 2506 proc_fork_connector(p);
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2507 sched_post_fork(p);
ef2c41cf38a755 Christian Brauner 2020-02-05 2508 cgroup_post_fork(p, args);
cdd6c482c9ff9c Ingo Molnar 2009-09-21 2509 perf_event_fork(p);
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2510
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2511 trace_task_newtask(p, clone_flags);
3ab679661721b1 Oleg Nesterov 2013-10-16 2512 uprobe_copy_process(p, clone_flags);
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2513
67197a4f28d28d Suren Baghdasaryan 2020-10-13 2514 copy_oom_score_adj(clone_flags, p);
67197a4f28d28d Suren Baghdasaryan 2020-10-13 2515
^1da177e4c3f41 Linus Torvalds 2005-04-16 2516 return p;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2517
7e47682ea555e7 Aleksa Sarai 2015-06-09 2518 bad_fork_cancel_cgroup:
85dd3f61203c5c Peter Zijlstra 2021-03-29 2519 sched_core_free(p);
3fd37226216620 Kirill Tkhai 2017-05-12 2520 spin_unlock(¤t->sighand->siglock);
3fd37226216620 Kirill Tkhai 2017-05-12 2521 write_unlock_irq(&tasklist_lock);
ef2c41cf38a755 Christian Brauner 2020-02-05 2522 cgroup_cancel_fork(p, args);
b3e5838252665e Christian Brauner 2019-03-27 2523 bad_fork_put_pidfd:
6fd2fe494b17bf Al Viro 2019-06-26 2524 if (clone_flags & CLONE_PIDFD) {
6fd2fe494b17bf Al Viro 2019-06-26 2525 fput(pidfile);
6fd2fe494b17bf Al Viro 2019-06-26 2526 put_unused_fd(pidfd);
6fd2fe494b17bf Al Viro 2019-06-26 2527 }
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2528 bad_fork_free_pid:
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2529 if (pid != &init_struct_pid)
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2530 free_pid(pid);
0740aa5f637568 Jiri Slaby 2016-05-20 2531 bad_fork_cleanup_thread:
0740aa5f637568 Jiri Slaby 2016-05-20 2532 exit_thread(p);
fd0928df98b957 Jens Axboe 2008-01-24 2533 bad_fork_cleanup_io:
b69f2292063d2c Louis Rilling 2009-12-04 2534 if (p->io_context)
b69f2292063d2c Louis Rilling 2009-12-04 2535 exit_io_context(p);
ab516013ad9ca4 Serge E. Hallyn 2006-10-02 2536 bad_fork_cleanup_namespaces:
444f378b237a0f Linus Torvalds 2007-01-30 2537 exit_task_namespaces(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2538 bad_fork_cleanup_mm:
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2539 if (p->mm) {
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2540 mm_clear_owner(p->mm, p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2541 mmput(p->mm);
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2542 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2543 bad_fork_cleanup_signal:
4ab6c08336535f Oleg Nesterov 2009-08-26 2544 if (!(clone_flags & CLONE_THREAD))
1c5354de90c900 Mike Galbraith 2011-01-05 2545 free_signal_struct(p->signal);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2546 bad_fork_cleanup_sighand:
a7e5328a06a2be Oleg Nesterov 2006-03-28 2547 __cleanup_sighand(p->sighand);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2548 bad_fork_cleanup_fs:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2549 exit_fs(p); /* blocking */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2550 bad_fork_cleanup_files:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2551 exit_files(p); /* blocking */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2552 bad_fork_cleanup_semundo:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2553 exit_sem(p);
e4e55b47ed9ae2 Tetsuo Handa 2017-03-24 2554 bad_fork_cleanup_security:
e4e55b47ed9ae2 Tetsuo Handa 2017-03-24 2555 security_task_free(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2556 bad_fork_cleanup_audit:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2557 audit_free(p);
6c72e3501d0d62 Peter Zijlstra 2014-10-02 2558 bad_fork_cleanup_perf:
cdd6c482c9ff9c Ingo Molnar 2009-09-21 2559 perf_event_free_task(p);
6c72e3501d0d62 Peter Zijlstra 2014-10-02 2560 bad_fork_cleanup_policy:
b09be676e0ff25 Byungchul Park 2017-08-07 2561 lockdep_free_task(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2562 #ifdef CONFIG_NUMA
f0be3d32b05d3f Lee Schermerhorn 2008-04-28 2563 mpol_put(p->mempolicy);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2564 #endif
ff8288ff475e47 Eric W. Biederman 2021-12-20 @2565 bad_fork_cleanup_delayacct:
35df17c57cecb0 Shailabh Nagar 2006-08-31 2566 delayacct_tsk_free(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2567 bad_fork_cleanup_count:
21d1c5e386bc75 Alexey Gladkov 2021-04-22 2568 dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
e0e817392b9acf David Howells 2009-09-02 2569 exit_creds(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2570 bad_fork_free:
2f064a59a11ff9 Peter Zijlstra 2021-06-11 2571 WRITE_ONCE(p->__state, TASK_DEAD);
1a03d3f13ffe5d Sebastian Andrzej Siewior 2022-02-17 2572 exit_task_stack_account(p);
68f24b08ee892d Andy Lutomirski 2016-09-15 2573 put_task_stack(p);
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2574 delayed_free_task(p);
fe7d37d1fbf8ff Oleg Nesterov 2006-01-08 2575 fork_out:
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2576 spin_lock_irq(¤t->sighand->siglock);
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2577 hlist_del_init(&delayed.node);
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2578 spin_unlock_irq(¤t->sighand->siglock);
fe7d37d1fbf8ff Oleg Nesterov 2006-01-08 2579 return ERR_PTR(retval);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2580 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2581
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
Hi Mike,
I love your patch! Perhaps something to improve:
[auto build test WARNING on tip/sched/core]
[also build test WARNING on vfs-idmapping/for-next linus/master v6.2-rc8]
[cannot apply to next-20230210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
patch link: https://lore.kernel.org/r/20230213010020.1813-6-michael.christie%40oracle.com
patch subject: [PATCH 5/5] kernel: Convert kthread to use setup_thread_fn
config: i386-defconfig (https://download.01.org/0day-ci/archive/20230213/[email protected]/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/9b34e5869b059d529620a0144a93c7437411cca0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
git checkout 9b34e5869b059d529620a0144a93c7437411cca0
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 olddefconfig
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
kernel/fork.c: In function 'copy_process':
>> kernel/fork.c:2565:1: warning: label 'bad_fork_cleanup_delayacct' defined but not used [-Wunused-label]
2565 | bad_fork_cleanup_delayacct:
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/bad_fork_cleanup_delayacct +2565 kernel/fork.c
d741bf41d7c7db Peter Zijlstra 2020-08-29 2371
7e47682ea555e7 Aleksa Sarai 2015-06-09 2372 /*
7e47682ea555e7 Aleksa Sarai 2015-06-09 2373 * Ensure that the cgroup subsystem policies allow the new process to be
7b7b8a2c9560ef Randy Dunlap 2020-10-15 2374 * forked. It should be noted that the new process's css_set can be changed
7e47682ea555e7 Aleksa Sarai 2015-06-09 2375 * between here and cgroup_post_fork() if an organisation operation is in
7e47682ea555e7 Aleksa Sarai 2015-06-09 2376 * progress.
7e47682ea555e7 Aleksa Sarai 2015-06-09 2377 */
ef2c41cf38a755 Christian Brauner 2020-02-05 2378 retval = cgroup_can_fork(p, args);
7e47682ea555e7 Aleksa Sarai 2015-06-09 2379 if (retval)
5a5cf5cb30d781 Christian Brauner 2020-02-05 2380 goto bad_fork_put_pidfd;
7e47682ea555e7 Aleksa Sarai 2015-06-09 2381
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2382 /*
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2383 * Now that the cgroups are pinned, re-clone the parent cgroup and put
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2384 * the new task on the correct runqueue. All this *before* the task
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2385 * becomes visible.
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2386 *
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2387 * This isn't part of ->can_fork() because while the re-cloning is
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2388 * cgroup specific, it unconditionally needs to place the task on a
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2389 * runqueue.
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2390 */
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2391 sched_cgroup_fork(p, args);
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2392
7b55851367136b David Herrmann 2019-01-08 2393 /*
7b55851367136b David Herrmann 2019-01-08 2394 * From this point on we must avoid any synchronous user-space
7b55851367136b David Herrmann 2019-01-08 2395 * communication until we take the tasklist-lock. In particular, we do
7b55851367136b David Herrmann 2019-01-08 2396 * not want user-space to be able to predict the process start-time by
7b55851367136b David Herrmann 2019-01-08 2397 * stalling fork(2) after we recorded the start_time but before it is
7b55851367136b David Herrmann 2019-01-08 2398 * visible to the system.
7b55851367136b David Herrmann 2019-01-08 2399 */
7b55851367136b David Herrmann 2019-01-08 2400
7b55851367136b David Herrmann 2019-01-08 2401 p->start_time = ktime_get_ns();
cf25e24db61cc9 Peter Zijlstra 2019-11-07 2402 p->start_boottime = ktime_get_boottime_ns();
7b55851367136b David Herrmann 2019-01-08 2403
18c830df771f2b Oleg Nesterov 2013-07-03 2404 /*
18c830df771f2b Oleg Nesterov 2013-07-03 2405 * Make it visible to the rest of the system, but dont wake it up yet.
18c830df771f2b Oleg Nesterov 2013-07-03 2406 * Need tasklist lock for parent etc handling!
18c830df771f2b Oleg Nesterov 2013-07-03 2407 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2408 write_lock_irq(&tasklist_lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2409
^1da177e4c3f41 Linus Torvalds 2005-04-16 2410 /* CLONE_PARENT re-uses the old parent */
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2411 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2412 p->real_parent = current->real_parent;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2413 p->parent_exec_id = current->parent_exec_id;
b4e00444cab4c3 Eddy Wu 2020-11-07 2414 if (clone_flags & CLONE_THREAD)
b4e00444cab4c3 Eddy Wu 2020-11-07 2415 p->exit_signal = -1;
b4e00444cab4c3 Eddy Wu 2020-11-07 2416 else
b4e00444cab4c3 Eddy Wu 2020-11-07 2417 p->exit_signal = current->group_leader->exit_signal;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2418 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2419 p->real_parent = current;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2420 p->parent_exec_id = current->self_exec_id;
b4e00444cab4c3 Eddy Wu 2020-11-07 2421 p->exit_signal = args->exit_signal;
2d5516cbb9daf7 Oleg Nesterov 2009-03-02 2422 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2423
d83a7cb375eec2 Josh Poimboeuf 2017-02-13 2424 klp_copy_process(p);
d83a7cb375eec2 Josh Poimboeuf 2017-02-13 2425
85dd3f61203c5c Peter Zijlstra 2021-03-29 2426 sched_core_fork(p);
85dd3f61203c5c Peter Zijlstra 2021-03-29 2427
^1da177e4c3f41 Linus Torvalds 2005-04-16 2428 spin_lock(¤t->sighand->siglock);
4a2c7a7837da1b Oleg Nesterov 2006-03-28 2429
792575348ff70e Daniel Bristot de Oliveira 2022-07-29 2430 rv_task_fork(p);
792575348ff70e Daniel Bristot de Oliveira 2022-07-29 2431
d7822b1e24f2df Mathieu Desnoyers 2018-06-02 2432 rseq_fork(p, clone_flags);
d7822b1e24f2df Mathieu Desnoyers 2018-06-02 2433
4ca1d3ee46130e Eric W. Biederman 2018-07-13 2434 /* Don't start children in a dying pid namespace */
e8cfbc245e2488 Gargi Sharma 2017-11-17 2435 if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
3fd37226216620 Kirill Tkhai 2017-05-12 2436 retval = -ENOMEM;
3fd37226216620 Kirill Tkhai 2017-05-12 2437 goto bad_fork_cancel_cgroup;
3fd37226216620 Kirill Tkhai 2017-05-12 2438 }
4a2c7a7837da1b Oleg Nesterov 2006-03-28 2439
7673bf553b2732 Eric W. Biederman 2018-07-23 2440 /* Let kill terminate clone/fork in the middle */
7673bf553b2732 Eric W. Biederman 2018-07-23 2441 if (fatal_signal_pending(current)) {
7673bf553b2732 Eric W. Biederman 2018-07-23 2442 retval = -EINTR;
7673bf553b2732 Eric W. Biederman 2018-07-23 2443 goto bad_fork_cancel_cgroup;
7673bf553b2732 Eric W. Biederman 2018-07-23 2444 }
7673bf553b2732 Eric W. Biederman 2018-07-23 2445
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2446 /* No more failure paths after this point. */
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2447
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2448 /*
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2449 * Copy seccomp details explicitly here, in case they were changed
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2450 * before holding sighand lock.
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2451 */
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2452 copy_seccomp(p);
a1140cb215fa13 Kuniyuki Iwashima 2022-08-23 2453
2c4704756cab7c Eric W. Biederman 2017-09-26 2454 init_task_pid_links(p);
73b9ebfe126a4a Oleg Nesterov 2006-03-28 2455 if (likely(p->pid)) {
4b9d33e6d83cc0 Tejun Heo 2011-06-17 2456 ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2457
8190773985141f Oleg Nesterov 2013-07-03 2458 init_task_pid(p, PIDTYPE_PID, pid);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2459 if (thread_group_leader(p)) {
6883f81aac6f44 Eric W. Biederman 2017-06-04 2460 init_task_pid(p, PIDTYPE_TGID, pid);
8190773985141f Oleg Nesterov 2013-07-03 2461 init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
8190773985141f Oleg Nesterov 2013-07-03 2462 init_task_pid(p, PIDTYPE_SID, task_session(current));
8190773985141f Oleg Nesterov 2013-07-03 2463
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2464 if (is_child_reaper(pid)) {
17cf22c33e1f1b Eric W. Biederman 2010-03-02 2465 ns_of_pid(pid)->child_reaper = p;
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2466 p->signal->flags |= SIGNAL_UNKILLABLE;
1c4042c29bd2e8 Eric W. Biederman 2010-07-12 2467 }
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2468 p->signal->shared_pending.signal = delayed.signal;
9c9f4ded90a59e Alan Cox 2008-10-13 2469 p->signal->tty = tty_kref_get(current->signal->tty);
749860ce242798 Pavel Tikhomirov 2017-01-30 2470 /*
749860ce242798 Pavel Tikhomirov 2017-01-30 2471 * Inherit has_child_subreaper flag under the same
749860ce242798 Pavel Tikhomirov 2017-01-30 2472 * tasklist_lock with adding child to the process tree
749860ce242798 Pavel Tikhomirov 2017-01-30 2473 * for propagate_has_child_subreaper optimization.
749860ce242798 Pavel Tikhomirov 2017-01-30 2474 */
749860ce242798 Pavel Tikhomirov 2017-01-30 2475 p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper ||
749860ce242798 Pavel Tikhomirov 2017-01-30 2476 p->real_parent->signal->is_child_subreaper;
9cd80bbb07fcd6 Oleg Nesterov 2009-12-17 2477 list_add_tail(&p->sibling, &p->real_parent->children);
5e85d4abe3f43b Eric W. Biederman 2006-04-18 2478 list_add_tail_rcu(&p->tasks, &init_task.tasks);
6883f81aac6f44 Eric W. Biederman 2017-06-04 2479 attach_pid(p, PIDTYPE_TGID);
8190773985141f Oleg Nesterov 2013-07-03 2480 attach_pid(p, PIDTYPE_PGID);
8190773985141f Oleg Nesterov 2013-07-03 2481 attach_pid(p, PIDTYPE_SID);
909ea96468096b Christoph Lameter 2010-12-08 2482 __this_cpu_inc(process_counts);
80628ca06c5d42 Oleg Nesterov 2013-07-03 2483 } else {
80628ca06c5d42 Oleg Nesterov 2013-07-03 2484 current->signal->nr_threads++;
d80f7d7b2c75c5 Eric W. Biederman 2022-06-21 2485 current->signal->quick_threads++;
80628ca06c5d42 Oleg Nesterov 2013-07-03 2486 atomic_inc(¤t->signal->live);
60d4de3ff7f775 Elena Reshetova 2019-01-18 2487 refcount_inc(¤t->signal->sigcnt);
924de3b8c9410c Eric W. Biederman 2018-07-23 2488 task_join_group_stop(p);
80628ca06c5d42 Oleg Nesterov 2013-07-03 2489 list_add_tail_rcu(&p->thread_group,
80628ca06c5d42 Oleg Nesterov 2013-07-03 2490 &p->group_leader->thread_group);
0c740d0afc3bff Oleg Nesterov 2014-01-21 2491 list_add_tail_rcu(&p->thread_node,
0c740d0afc3bff Oleg Nesterov 2014-01-21 2492 &p->signal->thread_head);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2493 }
8190773985141f Oleg Nesterov 2013-07-03 2494 attach_pid(p, PIDTYPE_PID);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2495 nr_threads++;
73b9ebfe126a4a Oleg Nesterov 2006-03-28 2496 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2497 total_forks++;
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2498 hlist_del_init(&delayed.node);
3f17da699431ec Oleg Nesterov 2006-02-15 2499 spin_unlock(¤t->sighand->siglock);
4af4206be2bd19 Oleg Nesterov 2014-04-13 2500 syscall_tracepoint_update(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2501 write_unlock_irq(&tasklist_lock);
4af4206be2bd19 Oleg Nesterov 2014-04-13 2502
ddc204b517e60a Waiman Long 2022-02-08 2503 if (pidfile)
ddc204b517e60a Waiman Long 2022-02-08 2504 fd_install(pidfd, pidfile);
ddc204b517e60a Waiman Long 2022-02-08 2505
c13cf856cbe16a Andrew Morton 2005-11-28 2506 proc_fork_connector(p);
b1e8206582f9d6 Peter Zijlstra 2022-02-14 2507 sched_post_fork(p);
ef2c41cf38a755 Christian Brauner 2020-02-05 2508 cgroup_post_fork(p, args);
cdd6c482c9ff9c Ingo Molnar 2009-09-21 2509 perf_event_fork(p);
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2510
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2511 trace_task_newtask(p, clone_flags);
3ab679661721b1 Oleg Nesterov 2013-10-16 2512 uprobe_copy_process(p, clone_flags);
43d2b113241d67 KAMEZAWA Hiroyuki 2012-01-10 2513
67197a4f28d28d Suren Baghdasaryan 2020-10-13 2514 copy_oom_score_adj(clone_flags, p);
67197a4f28d28d Suren Baghdasaryan 2020-10-13 2515
^1da177e4c3f41 Linus Torvalds 2005-04-16 2516 return p;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2517
7e47682ea555e7 Aleksa Sarai 2015-06-09 2518 bad_fork_cancel_cgroup:
85dd3f61203c5c Peter Zijlstra 2021-03-29 2519 sched_core_free(p);
3fd37226216620 Kirill Tkhai 2017-05-12 2520 spin_unlock(¤t->sighand->siglock);
3fd37226216620 Kirill Tkhai 2017-05-12 2521 write_unlock_irq(&tasklist_lock);
ef2c41cf38a755 Christian Brauner 2020-02-05 2522 cgroup_cancel_fork(p, args);
b3e5838252665e Christian Brauner 2019-03-27 2523 bad_fork_put_pidfd:
6fd2fe494b17bf Al Viro 2019-06-26 2524 if (clone_flags & CLONE_PIDFD) {
6fd2fe494b17bf Al Viro 2019-06-26 2525 fput(pidfile);
6fd2fe494b17bf Al Viro 2019-06-26 2526 put_unused_fd(pidfd);
6fd2fe494b17bf Al Viro 2019-06-26 2527 }
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2528 bad_fork_free_pid:
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2529 if (pid != &init_struct_pid)
425fb2b4bf5dde Pavel Emelyanov 2007-10-18 2530 free_pid(pid);
0740aa5f637568 Jiri Slaby 2016-05-20 2531 bad_fork_cleanup_thread:
0740aa5f637568 Jiri Slaby 2016-05-20 2532 exit_thread(p);
fd0928df98b957 Jens Axboe 2008-01-24 2533 bad_fork_cleanup_io:
b69f2292063d2c Louis Rilling 2009-12-04 2534 if (p->io_context)
b69f2292063d2c Louis Rilling 2009-12-04 2535 exit_io_context(p);
ab516013ad9ca4 Serge E. Hallyn 2006-10-02 2536 bad_fork_cleanup_namespaces:
444f378b237a0f Linus Torvalds 2007-01-30 2537 exit_task_namespaces(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2538 bad_fork_cleanup_mm:
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2539 if (p->mm) {
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2540 mm_clear_owner(p->mm, p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2541 mmput(p->mm);
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2542 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2543 bad_fork_cleanup_signal:
4ab6c08336535f Oleg Nesterov 2009-08-26 2544 if (!(clone_flags & CLONE_THREAD))
1c5354de90c900 Mike Galbraith 2011-01-05 2545 free_signal_struct(p->signal);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2546 bad_fork_cleanup_sighand:
a7e5328a06a2be Oleg Nesterov 2006-03-28 2547 __cleanup_sighand(p->sighand);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2548 bad_fork_cleanup_fs:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2549 exit_fs(p); /* blocking */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2550 bad_fork_cleanup_files:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2551 exit_files(p); /* blocking */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2552 bad_fork_cleanup_semundo:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2553 exit_sem(p);
e4e55b47ed9ae2 Tetsuo Handa 2017-03-24 2554 bad_fork_cleanup_security:
e4e55b47ed9ae2 Tetsuo Handa 2017-03-24 2555 security_task_free(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2556 bad_fork_cleanup_audit:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2557 audit_free(p);
6c72e3501d0d62 Peter Zijlstra 2014-10-02 2558 bad_fork_cleanup_perf:
cdd6c482c9ff9c Ingo Molnar 2009-09-21 2559 perf_event_free_task(p);
6c72e3501d0d62 Peter Zijlstra 2014-10-02 2560 bad_fork_cleanup_policy:
b09be676e0ff25 Byungchul Park 2017-08-07 2561 lockdep_free_task(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2562 #ifdef CONFIG_NUMA
f0be3d32b05d3f Lee Schermerhorn 2008-04-28 2563 mpol_put(p->mempolicy);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2564 #endif
ff8288ff475e47 Eric W. Biederman 2021-12-20 @2565 bad_fork_cleanup_delayacct:
35df17c57cecb0 Shailabh Nagar 2006-08-31 2566 delayacct_tsk_free(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2567 bad_fork_cleanup_count:
21d1c5e386bc75 Alexey Gladkov 2021-04-22 2568 dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
e0e817392b9acf David Howells 2009-09-02 2569 exit_creds(p);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2570 bad_fork_free:
2f064a59a11ff9 Peter Zijlstra 2021-06-11 2571 WRITE_ONCE(p->__state, TASK_DEAD);
1a03d3f13ffe5d Sebastian Andrzej Siewior 2022-02-17 2572 exit_task_stack_account(p);
68f24b08ee892d Andy Lutomirski 2016-09-15 2573 put_task_stack(p);
c3f3ce049f7d97 Andrea Arcangeli 2019-05-14 2574 delayed_free_task(p);
fe7d37d1fbf8ff Oleg Nesterov 2006-01-08 2575 fork_out:
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2576 spin_lock_irq(¤t->sighand->siglock);
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2577 hlist_del_init(&delayed.node);
c3ad2c3b02e953 Eric W. Biederman 2018-07-23 2578 spin_unlock_irq(¤t->sighand->siglock);
fe7d37d1fbf8ff Oleg Nesterov 2006-01-08 2579 return ERR_PTR(retval);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2580 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2581
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
Hi Mike,
I love your patch! Yet something to improve:
[auto build test ERROR on tip/sched/core]
[also build test ERROR on linus/master v6.2-rc8]
[cannot apply to next-20230210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
patch link: https://lore.kernel.org/r/20230213010020.1813-2-michael.christie%40oracle.com
patch subject: [PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
config: csky-buildonly-randconfig-r004-20230212 (https://download.01.org/0day-ci/archive/20230213/[email protected]/config)
compiler: csky-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/3eb77c0672cdc93fa577d5feb91b79f272d883b7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mike-Christie/kernel-Move-kernel_clone_args-s-fn-to-new-struct/20230213-090304
git checkout 3eb77c0672cdc93fa577d5feb91b79f272d883b7
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=csky olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=csky SHELL=/bin/bash fs/ kernel/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from fs/open.c:9:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/mm.h:7:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from fs/pipe.c:8:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/mm.h:7:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
fs/pipe.c:757:15: warning: no previous prototype for 'account_pipe_buffers' [-Wmissing-prototypes]
757 | unsigned long account_pipe_buffers(struct user_struct *user,
| ^~~~~~~~~~~~~~~~~~~~
fs/pipe.c:763:6: warning: no previous prototype for 'too_many_pipe_buffers_soft' [-Wmissing-prototypes]
763 | bool too_many_pipe_buffers_soft(unsigned long user_bufs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
fs/pipe.c:770:6: warning: no previous prototype for 'too_many_pipe_buffers_hard' [-Wmissing-prototypes]
770 | bool too_many_pipe_buffers_hard(unsigned long user_bufs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
fs/pipe.c:777:6: warning: no previous prototype for 'pipe_is_unprivileged_user' [-Wmissing-prototypes]
777 | bool pipe_is_unprivileged_user(void)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
fs/pipe.c:1253:5: warning: no previous prototype for 'pipe_resize_ring' [-Wmissing-prototypes]
1253 | int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
| ^~~~~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/uapi/linux/aio_abi.h:31,
from include/linux/syscalls.h:77,
from fs/d_path.c:2:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/wait.h:9,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:6:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
fs/d_path.c:317:7: warning: no previous prototype for 'simple_dname' [-Wmissing-prototypes]
317 | char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
| ^~~~~~~~~~~~
--
In file included from kernel/fork.c:23:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/slab.h:15,
from kernel/fork.c:16:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/fork.c:162:13: warning: no previous prototype for 'arch_release_task_struct' [-Wmissing-prototypes]
162 | void __weak arch_release_task_struct(struct task_struct *tsk)
| ^~~~~~~~~~~~~~~~~~~~~~~~
kernel/fork.c:862:20: warning: no previous prototype for 'arch_task_cache_init' [-Wmissing-prototypes]
862 | void __init __weak arch_task_cache_init(void) { }
| ^~~~~~~~~~~~~~~~~~~~
kernel/fork.c:957:12: warning: no previous prototype for 'arch_dup_task_struct' [-Wmissing-prototypes]
957 | int __weak arch_dup_task_struct(struct task_struct *dst,
| ^~~~~~~~~~~~~~~~~~~~
>> kernel/fork.c:2740:7: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
2740 | pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from include/linux/kallsyms.h:13,
from include/linux/ftrace.h:13,
from include/linux/kprobes.h:28,
from include/linux/kgdb.h:19,
from kernel/panic.c:15:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/percpu.h:6,
from include/linux/context_tracking_state.h:5,
from include/linux/hardirq.h:5,
from include/linux/interrupt.h:11,
from kernel/panic.c:14:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/panic.c: In function '__warn':
kernel/panic.c:658:17: warning: function '__warn' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
658 | vprintk(args->fmt, args->args);
| ^~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from kernel/exit.c:8:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:7,
from include/linux/mm.h:7:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/exit.c:1908:13: warning: no previous prototype for 'abort' [-Wmissing-prototypes]
1908 | __weak void abort(void)
| ^~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from include/linux/kallsyms.h:13,
from kernel/kallsyms.c:15:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/kref.h:16,
from include/linux/mm_types.h:8,
from include/linux/buildid.h:5,
from include/linux/kallsyms.h:10:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/kallsyms.c:663:12: warning: no previous prototype for 'arch_get_kallsym' [-Wmissing-prototypes]
663 | int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
| ^~~~~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from include/linux/kallsyms.h:13,
from include/linux/ftrace.h:13,
from include/linux/kprobes.h:28,
from kernel/kprobes.c:23:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/current.h:5,
from ./arch/csky/include/generated/asm/current.h:1,
from include/linux/mutex.h:14,
from include/linux/notifier.h:14,
from include/linux/kprobes.h:21:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/kprobes.c:1856:12: warning: no previous prototype for 'kprobe_exceptions_notify' [-Wmissing-prototypes]
1856 | int __weak kprobe_exceptions_notify(struct notifier_block *self,
| ^~~~~~~~~~~~~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:740,
from kernel/iomem.c:5:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/current.h:5,
from ./arch/csky/include/generated/asm/current.h:1,
from include/linux/sched.h:12,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from kernel/iomem.c:2:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/iomem.c:9:22: warning: no previous prototype for 'ioremap_cache' [-Wmissing-prototypes]
9 | __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
| ^~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from fs/proc/meminfo.c:2:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/wait.h:9,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:6:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
fs/proc/meminfo.c:22:28: warning: no previous prototype for 'arch_report_meminfo' [-Wmissing-prototypes]
22 | void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
| ^~~~~~~~~~~~~~~~~~~
--
In file included from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/debugfs.h:15,
from kernel/locking/lock_events.c:19:
>> include/linux/sched/task.h:99:14: error: conflicting types for 'kernel_thread'; have 'pid_t(struct kernel_clone_fns *, void *, long unsigned int)' {aka 'int(struct kernel_clone_fns *, void *, long unsigned int)'}
99 | extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
| ^~~~~~~~~~~~~
In file included from arch/csky/include/asm/thread_info.h:10,
from include/linux/thread_info.h:60,
from include/asm-generic/preempt.h:5,
from ./arch/csky/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/wait.h:9,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:6:
arch/csky/include/asm/processor.h:75:12: note: previous declaration of 'kernel_thread' with type 'int(int (*)(void *), void *, long unsigned int)'
75 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
| ^~~~~~~~~~~~~
kernel/locking/lock_events.c:61:16: warning: no previous prototype for 'lockevent_read' [-Wmissing-prototypes]
61 | ssize_t __weak lockevent_read(struct file *file, char __user *user_buf,
| ^~~~~~~~~~~~~~
..
vim +99 include/linux/sched/task.h
94
95 extern pid_t kernel_clone(struct kernel_clone_args *kargs);
96 struct task_struct *create_io_thread(struct kernel_clone_fns *fns, void *fn_arg,
97 int node);
98 struct task_struct *fork_idle(int);
> 99 extern pid_t kernel_thread(struct kernel_clone_fns *fns, void *fn_arg,
100 unsigned long flags);
101 extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags);
102 extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
103 int kernel_wait(pid_t pid, int *stat);
104
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
On Sun, Feb 12, 2023 at 5:00 PM Mike Christie
<[email protected]> wrote:
>
> This preps set_kthread_struct to be used for a setup_thread_fn callback
> by having it set the task's comm and also returning an int instead of a
> bool.
Ok, so I like the concept, but this patch is just too ugly for words,
and very very confused.
Now, some of it is pre-exisging nasty code just moved around:
> + mutex_lock(&create->name_mutex);
> + if (!create->name_args) {
> + mutex_unlock(&create->name_mutex);
> + return -EINTR;
> + }
> +
> + va_copy(name_args, *create->name_args);
> + len = vsnprintf(tsk->comm, TASK_COMM_LEN, create->name_fmt, name_args);
> + va_end(name_args);
> + if (len >= TASK_COMM_LEN) {
> + /* leave it truncated when out of memory. */
> + kthread->full_name = kvasprintf(GFP_KERNEL, create->name_fmt,
> + *create->name_args);
> + }
> + mutex_unlock(&create->name_mutex);
The *whole* point of my suggestion was to stop having silly pointless
locking on the name, because this all should be local to that one
thread creation, so that "name_mutex" kind of makes this all
pointless,
But what the heck is this:
> + mutex_init(&create->name_mutex);
> + create->name_fmt = namefmt;
> + va_copy(name_args, args);
> + create->name_args = &name_args;
That's just crazy talk.
Please just create the name once.
And please don't think that just because it was using a "va_list", you
need to keep it in that format.
Just make it create the name in __kthread_create_on_node() and be done
with it. That code already does a
struct kthread_create_info *create = kmalloc(sizeof(*create), ..
and you can just make a sufficiently large buffer there. Don't worry
about "kthread->fuil_name" being huge, it should just be bigger than
16. Make it be 32 or something. Nobody wants a larger "full name"
anyway.
No name_mutex, no va_list that is bigger than the buffer we'd need for
the name anyway. Just "create the name once".
IOW, this patch is just being much too complicated for no good reason.
The point was to make it _simpler_ to do thread setup, not more
complicated.
Linus
On Sun, Feb 12, 2023 at 5:00 PM Mike Christie
<[email protected]> wrote:
>
> The next patches will add callouts to set the task's comm, and create
> internal resources. This adds a new struct to for these callouts to
> organize them and reduce the args passed into kernel_thread and
> create_io_thread.
This patch too seems to just make things more complicated for no reason.
When the point was to make things simpler, adding a (pointless)
indirection through another structure seems to be against the whole
idea.
The code is neither simpler not more legible. Quite the reverse.
Linus
On 2/13/23 1:54 PM, Linus Torvalds wrote:
> IOW, this patch is just being much too complicated for no good reason.
> The point was to make it _simpler_ to do thread setup, not more
> complicated.
Ah ok, I think I better understand your original question/suggestion.
I was thinking we couldn't do:
diff --git a/kernel/fork.c b/kernel/fork.c
index 9f7fe3541897..e94dd5a838d6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2109,6 +2109,11 @@ static __latent_entropy struct task_struct *copy_process(
siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
}
+
+ if (args->name)
+ snprintf(p->comm, TASK_COMM_LEN, "%s-%d", args->name,
+ current->pid);
+
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? args->child_tid : NULL;
/*
* Clear TID on mm_release()?
because it would only support vhost and io_uring's sqpoll.c case which use the
parent pid in the name. I went wild trying to support every case and also kthread's
struct setup :)
I could balance it by doing the following which would support vhost, io_uring sqpoll
and kthread's name setting:
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 357e0068497c..81179faa943d 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -23,6 +23,7 @@ struct kernel_clone_args {
int __user *pidfd;
int __user *child_tid;
int __user *parent_tid;
+ const char *name;
int exit_signal;
unsigned long stack;
unsigned long stack_size;
@@ -89,9 +90,11 @@ extern void exit_files(struct task_struct *);
extern void exit_itimers(struct task_struct *);
extern pid_t kernel_clone(struct kernel_clone_args *kargs);
-struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
+struct task_struct *create_io_thread(int (*fn)(void *), void *arg,
+ const char *name, int node);
struct task_struct *fork_idle(int);
-extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
+ unsigned long flags);
extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags);
extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
int kernel_wait(pid_t pid, int *stat);
diff --git a/init/main.c b/init/main.c
index e1c3911d7c70..9dc816aa904f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -707,7 +707,7 @@ noinline void __ref rest_init(void)
rcu_read_unlock();
numa_default_policy();
- pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
+ pid = kernel_thread(kthreadd, NULL, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 411bb2d1acd4..b399ef30882d 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -748,7 +748,7 @@ static void create_worker_cont(struct callback_head *cb)
worker = container_of(cb, struct io_worker, create_work);
clear_bit_unlock(0, &worker->create_state);
wqe = worker->wqe;
- tsk = create_io_thread(io_wqe_worker, worker, wqe->node);
+ tsk = create_io_thread(io_wqe_worker, worker, NULL, wqe->node);
if (!IS_ERR(tsk)) {
io_init_new_worker(wqe, worker, tsk);
io_worker_release(worker);
@@ -817,7 +817,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
if (index == IO_WQ_ACCT_BOUND)
worker->flags |= IO_WORKER_F_BOUND;
- tsk = create_io_thread(io_wqe_worker, worker, wqe->node);
+ tsk = create_io_thread(io_wqe_worker, worker, NULL, wqe->node);
if (!IS_ERR(tsk)) {
io_init_new_worker(wqe, worker, tsk);
} else if (!io_should_retry_thread(PTR_ERR(tsk))) {
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index 559652380672..4b0388e15671 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -223,12 +223,8 @@ static int io_sq_thread(void *data)
struct io_sq_data *sqd = data;
struct io_ring_ctx *ctx;
unsigned long timeout = 0;
- char buf[TASK_COMM_LEN];
DEFINE_WAIT(wait);
- snprintf(buf, sizeof(buf), "iou-sqp-%d", sqd->task_pid);
- set_task_comm(current, buf);
-
if (sqd->sq_cpu != -1)
set_cpus_allowed_ptr(current, cpumask_of(sqd->sq_cpu));
else
@@ -350,6 +346,7 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
fdput(f);
}
if (ctx->flags & IORING_SETUP_SQPOLL) {
+ char name[TASK_COMM_LEN];
struct task_struct *tsk;
struct io_sq_data *sqd;
bool attached;
@@ -395,7 +392,8 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
sqd->task_pid = current->pid;
sqd->task_tgid = current->tgid;
- tsk = create_io_thread(io_sq_thread, sqd, NUMA_NO_NODE);
+ snprintf(name, sizeof(name), "iou-sqp-%d", sqd->task_pid);
+ tsk = create_io_thread(io_sq_thread, sqd, name, NUMA_NO_NODE);
if (IS_ERR(tsk)) {
ret = PTR_ERR(tsk);
goto err_sqpoll;
diff --git a/kernel/fork.c b/kernel/fork.c
index 9f7fe3541897..c566512281e0 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2109,6 +2109,9 @@ static __latent_entropy struct task_struct *copy_process(
siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
}
+ if (args->name)
+ snprintf(p->comm, TASK_COMM_LEN, "%s", args->name);
+
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? args->child_tid : NULL;
/*
* Clear TID on mm_release()?
@@ -2613,7 +2616,8 @@ struct task_struct * __init fork_idle(int cpu)
* The returned task is inactive, and the caller must fire it up through
* wake_up_new_task(p). All signals are blocked in the created task.
*/
-struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+struct task_struct *create_io_thread(int (*fn)(void *), void *arg,
+ const char *name, int node)
{
unsigned long flags = CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|
CLONE_IO;
@@ -2624,6 +2628,7 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
.fn = fn,
.fn_arg = arg,
.io_thread = 1,
+ .name = name,
};
return copy_process(NULL, 0, node, &args);
@@ -2727,7 +2732,8 @@ pid_t kernel_clone(struct kernel_clone_args *args)
/*
* Create a kernel thread.
*/
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
+ unsigned long flags)
{
struct kernel_clone_args args = {
.flags = ((lower_32_bits(flags) | CLONE_VM |
@@ -2735,6 +2741,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
.exit_signal = (lower_32_bits(flags) & CSIGNAL),
.fn = fn,
.fn_arg = arg,
+ .name = name,
.kthread = 1,
};
diff --git a/kernel/kthread.c b/kernel/kthread.c
index f97fd01a2932..20fdab8c6b25 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -38,6 +38,7 @@ struct task_struct *kthreadd_task;
struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
+ char *full_name;
int (*threadfn)(void *data);
void *data;
int node;
@@ -343,10 +344,12 @@ static int kthread(void *_create)
/* Release the structure when caller killed by a fatal signal. */
done = xchg(&create->done, NULL);
if (!done) {
+ kfree(create->full_name);
kfree(create);
kthread_exit(-EINTR);
}
+ self->full_name = create->full_name;
self->threadfn = threadfn;
self->data = data;
@@ -396,12 +399,14 @@ static void create_kthread(struct kthread_create_info *create)
current->pref_node_fork = create->node;
#endif
/* We want our own signal handler (we take no signals by default). */
- pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
+ pid = kernel_thread(kthread, create, create->full_name,
+ CLONE_FS | CLONE_FILES | SIGCHLD);
if (pid < 0) {
/* Release the structure when caller killed by a fatal signal. */
struct completion *done = xchg(&create->done, NULL);
if (!done) {
+ kfree(create->full_name);
kfree(create);
return;
}
@@ -427,6 +432,11 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
create->data = data;
create->node = node;
create->done = &done;
+ create->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
+ if (!create->full_name) {
+ task = ERR_PTR(-ENOMEM);
+ goto free_create;
+ }
spin_lock(&kthread_create_lock);
list_add_tail(&create->list, &kthread_create_list);
@@ -453,26 +463,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
wait_for_completion(&done);
}
task = create->result;
- if (!IS_ERR(task)) {
- char name[TASK_COMM_LEN];
- va_list aq;
- int len;
-
- /*
- * task is already visible to other tasks, so updating
- * COMM must be protected.
- */
- va_copy(aq, args);
- len = vsnprintf(name, sizeof(name), namefmt, aq);
- va_end(aq);
- if (len >= TASK_COMM_LEN) {
- struct kthread *kthread = to_kthread(task);
-
- /* leave it truncated when out of memory. */
- kthread->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
- }
- set_task_comm(task, name);
- }
+free_create:
kfree(create);
return task;
}
On Mon, Feb 13, 2023 at 4:50 PM Mike Christie
<[email protected]> wrote:
>
> I could balance it by doing the following which would support vhost, io_uring sqpoll
> and kthread's name setting:
Yeah, so this patch looks like a real simplification to me, and avoids
the different users doing their own random task name handling.
Thanks,
Linus