]> git.hungrycats.org Git - linux/commitdiff
[PATCH] clone-cleanup 2.5.32-BK
authorIngo Molnar <mingo@elte.hu>
Fri, 30 Aug 2002 08:55:56 +0000 (01:55 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 30 Aug 2002 08:55:56 +0000 (01:55 -0700)
This 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.

arch/i386/kernel/process.c
arch/i386/kernel/smpboot.c
include/linux/sched.h
kernel/fork.c

index 11356352f4058bb3a6ce6f33f3c4d2fa266b1f81..d0f33f6ed49f11605d34e01376599e666c636dfc 100644 (file)
@@ -504,7 +504,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        regs.eflags = 0x286;
 
        /* Ok, create the new process.. */
-       p = do_fork(flags | CLONE_VM, 0, &regs, 0);
+       p = do_fork(flags | CLONE_VM, 0, &regs, 0, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -587,11 +587,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
                        IO_BITMAP_BYTES);
        }
 
-       /*
-        * The common fastpath:
-        */
-       if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_CLEARTID)))
-               return 0;
        /*
         * Set a new TLS for the child thread?
         */
@@ -613,19 +608,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
                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 @@ asmlinkage int sys_fork(struct pt_regs regs)
 {
        struct task_struct *p;
 
-       p = do_fork(SIGCHLD, regs.esp, &regs, 0);
+       p = do_fork(SIGCHLD, regs.esp, &regs, 0, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -788,12 +770,14 @@ asmlinkage int sys_clone(struct pt_regs regs)
        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, &regs, 0);
+       p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, user_tid);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -811,7 +795,7 @@ asmlinkage int sys_vfork(struct pt_regs regs)
 {
        struct task_struct *p;
 
-       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0);
+       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
index 5ce52c87d7ef036c0aa6e21e5033ae52e52159e5..936ee9e5fbb20d45225610ebf8191e2b588a488e 100644 (file)
@@ -495,7 +495,7 @@ static struct task_struct * __init fork_by_hand(void)
         * 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, &regs, 0);
+       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
 }
 
 /* which physical APIC ID maps to which logical CPU number */
index e8251036b026db059902bb0319ccc166627fd4f2..77db4acdfdcd3190badcfef1c5391115f3bd0f2d 100644 (file)
@@ -660,7 +660,7 @@ extern void daemonize(void);
 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));
index 491079bcf5cc4730bcd4f84989ed00290b57f928..f06b869ba95827781a0b1e14ffae555548151804 100644 (file)
@@ -649,7 +649,8 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
 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 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        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 @@ bad_fork_free:
 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;