Commit f4205a53 authored by William Lee Irwin III's avatar William Lee Irwin III Committed by Linus Torvalds

[PATCH] sched: consolidate CLONE_IDLETASK masking

Every arch now bears the burden of sanitizing CLONE_IDLETASK out of the
clone_flags passed to do_fork() by userspace.  This patch hoists the
masking of CLONE_IDLETASK out of the system call entrypoints into
do_fork(), and thereby removes some small overheads from do_fork(), as
do_fork() may now assume that CLONE_IDLETASK has been cleared.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent fe92ebf3
......@@ -246,8 +246,7 @@ alpha_clone(unsigned long clone_flags, unsigned long usp,
if (!usp)
usp = rdusp();
return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0,
parent_tid, child_tid);
return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid);
}
int
......
......@@ -257,7 +257,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct
if (!newsp)
newsp = regs->ARM_sp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
asmlinkage int sys_vfork(struct pt_regs *regs)
......
......@@ -256,7 +256,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct
if (!newsp)
newsp = regs->ARM_sp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
asmlinkage int sys_vfork(struct pt_regs *regs)
......
......@@ -180,7 +180,7 @@ asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
{
if (!newusp)
newusp = rdusp();
return do_fork(flags & ~CLONE_IDLETASK, newusp, regs, 0, parent_tid, child_tid);
return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
}
/* vfork is a system call in i386 because of register-pressure - maybe
......
......@@ -189,7 +189,7 @@ asmlinkage int h8300_clone(struct pt_regs *regs)
newsp = regs->er2;
if (!newsp)
newsp = rdusp();
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
......
......@@ -595,7 +595,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
child_tidptr = (int __user *)regs.edi;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, parent_tidptr, child_tidptr);
return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
}
/*
......
......@@ -41,7 +41,7 @@ ENTRY(ia32_clone)
zxt4 out1=in1 // newsp
mov out3=16 // stacksize (compensates for 16-byte scratch area)
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
dep out0=0,in0,CLONE_IDLETASK_BIT,1 // out0 = clone_flags & ~CLONE_IDLETASK
mov out0=in0 // out0 = clone_flags
zxt4 out4=in2 // out4 = parent_tidptr
zxt4 out5=in4 // out5 = child_tidptr
br.call.sptk.many rp=do_fork
......
......@@ -195,11 +195,6 @@ void foo(void)
DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
DEFINE(CLONE_IDLETASK_BIT, 12);
#if CLONE_IDLETASK != (1 << 12)
# error "CLONE_IDLETASK_BIT incorrect, please fix"
#endif
DEFINE(CLONE_SETTLS_BIT, 19);
#if CLONE_SETTLS != (1<<19)
# error "CLONE_SETTLS_BIT incorrect, please fix"
......
......@@ -128,7 +128,7 @@ GLOBAL_ENTRY(sys_clone2)
(p6) st8 [r2]=in5 // store TLS in r16 for copy_thread()
mov out5=in4 // child_tidptr: valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
dep out0=0,in0,CLONE_IDLETASK_BIT,1 // out0 = clone_flags & ~CLONE_IDLETASK
mov out0=in0 // out0 = clone_flags
br.call.sptk.many rp=do_fork
.ret1: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
......@@ -157,7 +157,7 @@ GLOBAL_ENTRY(sys_clone)
(p6) st8 [r2]=in4 // store TLS in r13 (tp)
mov out5=in3 // child_tidptr: valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
dep out0=0,in0,CLONE_IDLETASK_BIT,1 // out0 = clone_flags & ~CLONE_IDLETASK
mov out0=in0 // out0 = clone_flags
br.call.sptk.many rp=do_fork
.ret2: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
......
......@@ -232,7 +232,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
child_tidptr = (int *)regs->d4;
if (!newsp)
newsp = rdusp();
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0,
return do_fork(clone_flags, newsp, regs, 0,
parent_tidptr, child_tidptr);
}
......
......@@ -188,7 +188,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
newsp = regs->d2;
if (!newsp)
newsp = rdusp();
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
int copy_thread(int nr, unsigned long clone_flags,
......
......@@ -180,7 +180,7 @@ static_unused int _sys_clone(nabi_no_regargs struct pt_regs regs)
newsp = regs.regs[29];
parent_tidptr = (int *) regs.regs[6];
child_tidptr = (int *) regs.regs[7];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
......
......@@ -262,7 +262,7 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
if(usp == 0)
usp = regs->gr[30];
return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL);
return do_fork(clone_flags, usp, regs, 0, user_tid, NULL);
}
int
......
......@@ -555,8 +555,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
CHECK_FULL_REGS(regs);
if (usp == 0)
usp = regs->gpr[1]; /* stack pointer for child */
return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0,
parent_tidp, child_tidp);
return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
}
int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
......
......@@ -458,7 +458,7 @@ int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
}
}
return do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,
return do_fork(clone_flags, p2, regs, 0,
(int __user *)parent_tidptr, (int __user *)child_tidptr);
}
......
......@@ -1219,7 +1219,7 @@ asmlinkage long sys32_clone(struct pt_regs regs)
child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
if (!newsp)
newsp = regs.gprs[15];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
......
......@@ -336,7 +336,7 @@ asmlinkage long sys_clone(struct pt_regs regs)
child_tidptr = (int __user *) regs.gprs[5];
if (!newsp)
newsp = regs.gprs[15];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
......
......@@ -440,7 +440,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
{
if (!newsp)
newsp = regs.regs[15];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
return do_fork(clone_flags, newsp, &regs, 0,
(int __user *)parent_tidptr, (int __user *)child_tidptr);
}
......
......@@ -820,7 +820,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
{
if (!newsp)
newsp = pregs->regs[15];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, pregs, 0, 0, 0);
return do_fork(clone_flags, newsp, pregs, 0, 0, 0);
}
/*
......
......@@ -435,8 +435,6 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
{
unsigned long parent_tid_ptr, child_tid_ptr;
clone_flags &= ~CLONE_IDLETASK;
parent_tid_ptr = regs->u_regs[UREG_I2];
child_tid_ptr = regs->u_regs[UREG_I4];
......
......@@ -588,8 +588,6 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
{
int __user *parent_tid_ptr, *child_tid_ptr;
clone_flags &= ~CLONE_IDLETASK;
#ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_32BIT)) {
parent_tid_ptr = compat_ptr(regs->u_regs[UREG_I2]);
......
......@@ -1148,8 +1148,7 @@ asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
void __user *child_tid = (void __user *)regs->rdi;
if (!newsp)
newsp = regs->rsp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0,
parent_tid, child_tid);
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
}
/*
......
......@@ -555,8 +555,7 @@ asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void _
{
if (!newsp)
newsp = regs->rsp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0,
parent_tid, child_tid);
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
}
/*
......
......@@ -40,7 +40,6 @@ struct exec_domain;
#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
#define CLONE_IDLETASK 0x00001000 /* set if new pid should be 0 (kernel only)*/
#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
......
......@@ -45,6 +45,9 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
/* set if new pid should be 0 (kernel only)*/
#define CLONE_IDLETASK 0x00001000
/* The idle threads do not count..
* Protected by write_lock_irq(&tasklist_lock)
*/
......@@ -1194,7 +1197,7 @@ task_t * __init fork_idle(int cpu)
static inline int fork_traceflag (unsigned clone_flags)
{
if (clone_flags & (CLONE_UNTRACED | CLONE_IDLETASK))
if (clone_flags & CLONE_UNTRACED)
return 0;
else if (clone_flags & CLONE_VFORK) {
if (current->ptrace & PT_TRACE_VFORK)
......@@ -1225,6 +1228,7 @@ long do_fork(unsigned long clone_flags,
int trace = 0;
long pid;
clone_flags &= ~CLONE_IDLETASK;
if (unlikely(current->ptrace)) {
trace = fork_traceflag (clone_flags);
if (trace)
......@@ -1254,13 +1258,11 @@ long do_fork(unsigned long clone_flags,
set_tsk_thread_flag(p, TIF_SIGPENDING);
}
if (likely(!(clone_flags & CLONE_IDLETASK))) {
if (!(clone_flags & CLONE_STOPPED))
wake_up_new_task(p, clone_flags);
else
p->state = TASK_STOPPED;
++total_forks;
}
if (!(clone_flags & CLONE_STOPPED))
wake_up_new_task(p, clone_flags);
else
p->state = TASK_STOPPED;
++total_forks;
if (unlikely (trace)) {
current->ptrace_message = pid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment