lkml.org 
[lkml]   [2023]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/5] kernel: Move kernel_clone_args's fn to new struct
    Date
    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
    \
     
     \ /
      Last update: 2023-03-27 00:19    [W:3.385 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site