Messages in this thread Patch in this message | | | Date | Fri, 30 Aug 2002 09:26:25 +0200 (CEST) | From | Ingo Molnar <> | Subject | [patch] clone-cleanup 2.5.32-BK |
| |
the attached patch moves CLONE_SETTID and CLONE_CLEARTID handling into kernel/fork.c, where it belongs. [the CLONE_SETTLS is x86-specific and thus remains in the per-arch process.c] This makes support for these two new flags much easier: architectures only have to pass in the user_tid pointer. (I tested the patch with userspace threading code and it works just fine.)
Ingo
--- linux/arch/i386/kernel/smpboot.c.orig Fri Aug 30 09:20:52 2002 +++ linux/arch/i386/kernel/smpboot.c Fri Aug 30 09:20:59 2002 @@ -495,7 +495,7 @@ * don't care about the eip and regs settings since * we'll never reschedule the forked task. */ - return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0); + return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL); } /* which physical APIC ID maps to which logical CPU number */ --- linux/arch/i386/kernel/process.c.orig Fri Aug 30 09:14:27 2002 +++ linux/arch/i386/kernel/process.c Fri Aug 30 09:20:32 2002 @@ -504,7 +504,7 @@ regs.eflags = 0x286; /* Ok, create the new process.. */ - p = do_fork(flags | CLONE_VM, 0, ®s, 0); + p = do_fork(flags | CLONE_VM, 0, ®s, 0, NULL); return IS_ERR(p) ? PTR_ERR(p) : p->pid; } @@ -588,11 +588,6 @@ } /* - * The common fastpath: - */ - if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_CLEARTID))) - return 0; - /* * Set a new TLS for the child thread? */ if (clone_flags & CLONE_SETTLS) { @@ -613,19 +608,6 @@ desc->a = LDT_entry_a(&info); desc->b = LDT_entry_b(&info); } - - /* - * Notify the child of the TID? - */ - if (clone_flags & CLONE_SETTID) - if (put_user(p->pid, (pid_t *)childregs->edx)) - return -EFAULT; - - /* - * Does the userspace VM want the TID cleared on mm_release()? - */ - if (clone_flags & CLONE_CLEARTID) - p->user_tid = (int *) childregs->edx; return 0; } @@ -779,7 +761,7 @@ { struct task_struct *p; - p = do_fork(SIGCHLD, regs.esp, ®s, 0); + p = do_fork(SIGCHLD, regs.esp, ®s, 0, NULL); return IS_ERR(p) ? PTR_ERR(p) : p->pid; } @@ -788,12 +770,14 @@ struct task_struct *p; unsigned long clone_flags; unsigned long newsp; + int *user_tid; clone_flags = regs.ebx; newsp = regs.ecx; + user_tid = (int *)regs.edx; if (!newsp) newsp = regs.esp; - p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0); + p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, user_tid); return IS_ERR(p) ? PTR_ERR(p) : p->pid; } @@ -811,7 +795,7 @@ { struct task_struct *p; - p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0); + p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL); return IS_ERR(p) ? PTR_ERR(p) : p->pid; } --- linux/include/linux/sched.h.orig Fri Aug 30 09:14:48 2002 +++ linux/include/linux/sched.h Fri Aug 30 09:17:44 2002 @@ -659,7 +659,7 @@ extern task_t *child_reaper; extern int do_execve(char *, char **, char **, struct pt_regs *); -extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long); +extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int *); extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); --- linux/kernel/fork.c.orig Fri Aug 30 09:12:13 2002 +++ linux/kernel/fork.c Fri Aug 30 09:18:58 2002 @@ -649,7 +649,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, - unsigned long stack_size) + unsigned long stack_size, + int *user_tid) { int retval; struct task_struct *p = NULL; @@ -760,7 +761,20 @@ retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); if (retval) goto bad_fork_cleanup_namespace; - + /* + * Notify the child of the TID? + */ + retval = -EFAULT; + if (clone_flags & CLONE_SETTID) + if (put_user(p->pid, user_tid)) + goto bad_fork_cleanup_namespace; + + /* + * Does the userspace VM want the TID cleared on mm_release()? + */ + if (clone_flags & CLONE_CLEARTID) + p->user_tid = user_tid; + /* Our parent execution domain becomes current domain These must match for thread signalling to apply */ @@ -876,11 +890,12 @@ struct task_struct *do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, - unsigned long stack_size) + unsigned long stack_size, + int *user_tid) { struct task_struct *p; - p = copy_process(clone_flags, stack_start, regs, stack_size); + p = copy_process(clone_flags, stack_start, regs, stack_size, user_tid); if (!IS_ERR(p)) { struct completion vfork; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |