Name: kthread creation simplification Author: Rusty Russell Status: Experimental Linus says: > Hmm. Your kthread creation code is ugly as sin, though. > > You should make "kernel_thread()" return a (nonstarted) "struct > task_struct *", by changing the "do_fork()" to "copy_process()". > > So I'd suggest: > - rename all architectures "kernel_thread()" to "create_kernel_thread()". > - make them all call "copy_process()" instead of "do_fork()", and make > them return the struct task_struct pointer instead of the pid. > - create a (generic) "kernel_thread()" function to take care of existing > users: ... > - now you don't need all that "wait_task_inactive()" crap. So now I can break 20 architectures, because I can say "Linus told me to!" diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/arm/kernel/armksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/arm/kernel/armksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/arm/kernel/armksyms.c 2004-02-29 19:10:46.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/arm/kernel/armksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -101,7 +101,6 @@ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(udelay); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(__iounmap); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(system_rev); EXPORT_SYMBOL(system_serial_low); EXPORT_SYMBOL(system_serial_high); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/arm/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/arm/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/arm/kernel/process.c 2004-02-18 23:54:11.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/arm/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -396,7 +396,8 @@ asm( ".align\n" /* * Create a kernel thread. */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), void *arg, + unsigned long flags) { struct pt_regs regs; @@ -408,7 +409,8 @@ pid_t kernel_thread(int (*fn)(void *), v regs.ARM_pc = (unsigned long)kernel_thread_helper; regs.ARM_cpsr = SVC_MODE; - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return copy_process(flags|CLONE_VM|CLONE_UNTRACED, + 0, ®s, 0, NULL, NULL); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/cris/arch-v10/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/cris/arch-v10/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/cris/arch-v10/kernel/process.c 2003-09-22 10:23:07.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/cris/arch-v10/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -80,7 +80,8 @@ static void kernel_thread_helper(void* d /* * Create a kernel thread */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), + void * arg, unsigned long flags) { struct pt_regs regs; @@ -92,7 +93,8 @@ int kernel_thread(int (*fn)(void *), voi regs.irp = (unsigned long)kernel_thread_helper; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return copy_process(flags | CLONE_VM | CLONE_UNTRACED, + 0, ®s, 0, NULL, NULL); } /* setup the child's kernel stack with a pt_regs and switch_stack on it. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/cris/kernel/ksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/cris/kernel/ksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/cris/kernel/ksyms.c 2003-09-22 10:23:07.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/cris/kernel/ksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -34,7 +34,6 @@ extern void iounmap(void *addr); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(get_cmos_time); EXPORT_SYMBOL(loops_per_usec); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/i386/kernel/i386_ksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/i386/kernel/i386_ksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/i386/kernel/i386_ksyms.c 2004-02-18 23:54:12.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/i386/kernel/i386_ksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -81,7 +81,6 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(probe_irq_mask); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(get_cmos_time); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/i386/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/i386/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/i386/kernel/process.c 2004-02-29 19:10:47.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/i386/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -263,7 +263,8 @@ __asm__(".section .text\n" /* * Create a kernel thread */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), void *arg, + unsigned long flags) { struct pt_regs regs; @@ -280,7 +281,7 @@ int kernel_thread(int (*fn)(void *), voi regs.eflags = 0x286; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return copy_process(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/ia64/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/ia64/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/ia64/kernel/process.c 2004-02-29 19:11:48.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/ia64/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -571,8 +571,8 @@ ia64_set_personality (struct elf64_hdr * current->thread.flags &= ~IA64_THREAD_XSTACK; } -pid_t -kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) +struct task_struct * +create_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) { extern void ia64_invoke_kernel_thread_helper (void); unsigned long *helper_fptr = (unsigned long *) &ia64_invoke_kernel_thread_helper; @@ -592,9 +592,9 @@ kernel_thread (int (*fn)(void *), void * regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); + return copy_process(flags | CLONE_VM | CLONE_UNTRACED, + 0, ®s.pt, 0, NULL, NULL); } -EXPORT_SYMBOL(kernel_thread); /* This gets called from kernel_thread() via ia64_invoke_thread_helper(). */ int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/s390/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/s390/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/s390/kernel/process.c 2004-02-29 19:10:57.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/s390/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -172,7 +172,8 @@ __asm__(".align 4\n" #endif /* CONFIG_ARCH_S390X */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), void *arg, + unsigned long flags) { struct pt_regs regs; @@ -187,8 +188,8 @@ int kernel_thread(int (*fn)(void *), voi regs.orig_gpr2 = -1; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, - 0, ®s, 0, NULL, NULL); + return copy_process(flags | CLONE_VM | CLONE_UNTRACED, + 0, ®s, 0, NULL, NULL); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/s390/kernel/s390_ksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/s390/kernel/s390_ksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/s390/kernel/s390_ksyms.c 2004-02-29 19:10:57.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/s390/kernel/s390_ksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -85,7 +85,6 @@ EXPORT_SYMBOL(del_virt_timer); */ EXPORT_SYMBOL(machine_flags); EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(csum_fold); EXPORT_SYMBOL(console_mode); EXPORT_SYMBOL(console_device); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/sh/kernel/process.c .20940-linux-2.6.4-rc1-bk1.updated/arch/sh/kernel/process.c --- .20940-linux-2.6.4-rc1-bk1/arch/sh/kernel/process.c 2004-02-18 23:54:15.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/sh/kernel/process.c 2004-03-01 14:08:54.000000000 +1100 @@ -144,7 +144,8 @@ __asm__(".align 5\n" ".align 2\n\t" "1:.long do_exit"); -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), void *arg, + unsigned long flags) { /* Don't use this in BL=1(cli). Or else, CPU resets! */ struct pt_regs regs; @@ -156,7 +157,8 @@ int kernel_thread(int (*fn)(void *), voi regs.sr = (1 << 30); /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return copy_process(flags | CLONE_VM | CLONE_UNTRACED, + 0, ®s, 0, NULL, NULL); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/sh/kernel/sh_ksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/sh/kernel/sh_ksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/sh/kernel/sh_ksyms.c 2004-02-04 15:38:41.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/sh/kernel/sh_ksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -33,7 +33,6 @@ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(no_irq_type); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/um/kernel/ksyms.c .20940-linux-2.6.4-rc1-bk1.updated/arch/um/kernel/ksyms.c --- .20940-linux-2.6.4-rc1-bk1/arch/um/kernel/ksyms.c 2003-09-22 09:48:05.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/um/kernel/ksyms.c 2004-03-01 14:08:54.000000000 +1100 @@ -26,7 +26,6 @@ EXPORT_SYMBOL(stop); EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(__const_udelay); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(sys_waitpid); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/arch/um/kernel/process_kern.c .20940-linux-2.6.4-rc1-bk1.updated/arch/um/kernel/process_kern.c --- .20940-linux-2.6.4-rc1-bk1/arch/um/kernel/process_kern.c 2003-10-09 18:02:50.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/arch/um/kernel/process_kern.c 2004-03-01 14:08:54.000000000 +1100 @@ -101,15 +101,12 @@ unsigned long alloc_stack(int order, int return(page); } -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +struct task_struct *create_kernel_thread(int (*fn)(void *), void *arg, + unsigned long flags) { - struct task_struct *p; - current->thread.request.u.thread.proc = fn; current->thread.request.u.thread.arg = arg; - p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL); - if(IS_ERR(p)) panic("do_fork failed in kernel_thread"); - return(p->pid); + return copy_process(CLONE_VM | flags, 0, NULL, 0, NULL, NULL); } void switch_mm(struct mm_struct *prev, struct mm_struct *next, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-arm/processor.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-arm/processor.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-arm/processor.h 2003-09-29 10:25:56.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-arm/processor.h 2004-03-01 14:08:54.000000000 +1100 @@ -90,7 +90,9 @@ unsigned long get_wchan(struct task_stru /* * Create a new kernel thread */ -extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019]) #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017]) diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-cris/processor.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-cris/processor.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-cris/processor.h 2003-09-22 10:23:13.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-cris/processor.h 2004-03-01 14:08:54.000000000 +1100 @@ -49,7 +49,9 @@ extern inline void prepare_to_copy(struc { } -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); unsigned long get_wchan(struct task_struct *p); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-i386/processor.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-i386/processor.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-i386/processor.h 2004-02-29 19:11:26.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-i386/processor.h 2004-03-01 14:08:54.000000000 +1100 @@ -483,7 +483,9 @@ extern void prepare_to_copy(struct task_ /* * create a kernel thread without removing it from tasklists */ -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); extern unsigned long thread_saved_pc(struct task_struct *tsk); void show_trace(struct task_struct *task, unsigned long *stack); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-s390/processor.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-s390/processor.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-s390/processor.h 2004-02-04 15:39:12.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-s390/processor.h 2004-03-01 14:08:54.000000000 +1100 @@ -147,7 +147,9 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); /* Prepare to copy thread state - unlazy all lazy status */ #define prepare_to_copy(tsk) do { } while (0) diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-sh/processor.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-sh/processor.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-sh/processor.h 2004-02-18 23:54:33.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-sh/processor.h 2004-03-01 14:08:54.000000000 +1100 @@ -185,7 +185,9 @@ extern void release_thread(struct task_s /* * create a kernel thread without removing it from tasklists */ -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); /* * Bus types diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/include/asm-um/processor-generic.h .20940-linux-2.6.4-rc1-bk1.updated/include/asm-um/processor-generic.h --- .20940-linux-2.6.4-rc1-bk1/include/asm-um/processor-generic.h 2003-09-22 09:48:16.000000000 +1000 +++ .20940-linux-2.6.4-rc1-bk1.updated/include/asm-um/processor-generic.h 2004-03-01 14:08:54.000000000 +1100 @@ -104,7 +104,9 @@ extern struct task_struct *alloc_task_st extern void free_task_struct(struct task_struct *task); extern void release_thread(struct task_struct *); -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern struct task_struct *create_kernel_thread(int (*fn)(void *), + void *arg, + unsigned long flags); extern void dump_thread(struct pt_regs *regs, struct user *u); extern unsigned long thread_saved_pc(struct task_struct *t); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/kernel/fork.c .20940-linux-2.6.4-rc1-bk1.updated/kernel/fork.c --- .20940-linux-2.6.4-rc1-bk1/kernel/fork.c 2004-02-29 19:11:33.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/kernel/fork.c 2004-03-01 14:08:54.000000000 +1100 @@ -1182,6 +1182,20 @@ long do_fork(unsigned long clone_flags, return pid; } +/* Note: kthread_run is a friendly wrapper for this, you might want that. */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct task_struct *p = create_kernel_thread(fn, arg, flags); + int pid; + + pid = PTR_ERR(p); + if (!IS_ERR(p)) { + pid = p->pid; + wake_up_forked_process(p); + } + return pid; +} + /* SLAB cache for signal_struct structures (tsk->signal) */ kmem_cache_t *signal_cachep; diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .20940-linux-2.6.4-rc1-bk1/kernel/sched.c .20940-linux-2.6.4-rc1-bk1.updated/kernel/sched.c --- .20940-linux-2.6.4-rc1-bk1/kernel/sched.c 2004-02-29 19:11:33.000000000 +1100 +++ .20940-linux-2.6.4-rc1-bk1.updated/kernel/sched.c 2004-03-01 14:08:54.000000000 +1100 @@ -767,6 +767,39 @@ void sched_fork(task_t *p) local_irq_enable(); } + +/* We decrease the sleep average of forking parents and children as + * well, to keep max-interactive tasks from forking tasks that are + * max-interactive. + */ +static void adjust_child_prio(task_t *p) +{ + current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) * + PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); + + p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) * + CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); + + p->interactive_credit = 0; + + p->prio = effective_prio(p); +} + +/* Tidy up forked process, but let it stay asleep. */ +void let_sleep_forked_process(task_t *p) +{ + unsigned long flags; + runqueue_t *rq = task_rq_lock(current, &flags); + + /* This was copied from parent. */ + BUG_ON(p->state != TASK_RUNNING); + p->state = TASK_INTERRUPTIBLE; + + adjust_child_prio(p); + p->array = NULL; + task_rq_unlock(rq, &flags); +} + /* * wake_up_forked_process - wake up a freshly forked process. * @@ -780,20 +813,7 @@ void wake_up_forked_process(task_t * p) BUG_ON(p->state != TASK_RUNNING); - /* - * We decrease the sleep average of forking parents - * and children as well, to keep max-interactive tasks - * from forking tasks that are max-interactive. - */ - current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) * - PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); - - p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) * - CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); - - p->interactive_credit = 0; - - p->prio = effective_prio(p); + adjust_child_prio(p); set_task_cpu(p, smp_processor_id()); if (unlikely(!current->array)) @@ -808,6 +828,8 @@ void wake_up_forked_process(task_t * p) task_rq_unlock(rq, &flags); } + + /* * Potentially available exiting-child timeslices are * retrieved here - this way the parent does not get