[PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct

Mike Christie posted 5 patches 2 years, 7 months ago
[PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
Posted by Mike Christie 2 years, 7 months ago
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 <michael.christie@oracle.com>
---
 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(&current->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
Re: [PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
Posted by Linus Torvalds 2 years, 7 months ago
On Sun, Feb 12, 2023 at 5:00 PM Mike Christie
<michael.christie@oracle.com> 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
Re: [PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
Posted by kernel test robot 2 years, 7 months ago
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/202302131343.whX9lCGw-lkp@intel.com/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 <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202302131343.whX9lCGw-lkp@intel.com/

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
Re: [PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
Posted by kernel test robot 2 years, 7 months ago
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/202302131159.c56w5Bln-lkp@intel.com/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 <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202302131159.c56w5Bln-lkp@intel.com/

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(&current->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