Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Rather than starting init and creating kthreads by forki...



details:   https://anonhg.NetBSD.org/src/rev/8bfd2c8e9131
branches:  trunk
changeset: 486749:8bfd2c8e9131
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun May 28 05:48:59 2000 +0000

description:
Rather than starting init and creating kthreads by forking and then
doing a cpu_set_kpc(), just pass the entry point and argument all
the way down the fork path starting with fork1().  In order to
avoid special-casing the normal fork in every cpu_fork(), MI code
passes down child_return() and the child process pointer explicitly.

This fixes a race condition on multiprocessor systems; a CPU could
grab the newly created processes (which has been placed on a run queue)
before cpu_set_kpc() would be performed.

diffstat:

 sys/arch/alpha/alpha/vm_machdep.c     |  51 ++++----------------------
 sys/arch/amiga/amiga/vm_machdep.c     |  42 ++++-----------------
 sys/arch/arm26/arm26/except.c         |   9 ++--
 sys/arch/arm26/arm26/vm_machdep.c     |  30 +++------------
 sys/arch/arm32/arm32/vm_machdep.c     |  28 ++++----------
 sys/arch/atari/atari/vm_machdep.c     |  42 ++++-----------------
 sys/arch/hp300/hp300/vm_machdep.c     |  35 ++++--------------
 sys/arch/i386/i386/vm_machdep.c       |  31 ++++-----------
 sys/arch/luna68k/luna68k/vm_machdep.c |  39 +++++---------------
 sys/arch/mac68k/mac68k/vm_machdep.c   |  35 ++++--------------
 sys/arch/mips/mips/vm_machdep.c       |  35 ++++--------------
 sys/arch/mvme68k/mvme68k/vm_machdep.c |  35 ++++--------------
 sys/arch/news68k/news68k/vm_machdep.c |  35 ++++--------------
 sys/arch/next68k/next68k/vm_machdep.c |  16 ++++---
 sys/arch/pc532/pc532/vm_machdep.c     |  42 ++++-----------------
 sys/arch/powerpc/powerpc/vm_machdep.c |  31 ++++------------
 sys/arch/sh3/sh3/vm_machdep.c         |  33 ++++------------
 sys/arch/sparc/sparc/vm_machdep.c     |  52 ++++-----------------------
 sys/arch/sparc64/sparc64/vm_machdep.c |  65 ++++------------------------------
 sys/arch/sun3/sun3/vm_machdep.c       |  16 +++++--
 sys/arch/vax/vax/vm_machdep.c         |  37 ++++---------------
 sys/arch/x68k/x68k/vm_machdep.c       |  35 ++++--------------
 sys/compat/linux/common/linux_sched.c |   5 +-
 sys/compat/svr4/svr4_lwp.c            |   6 +-
 sys/kern/init_main.c                  |   5 +-
 sys/kern/kern_fork.c                  |  17 +++++---
 sys/kern/kern_kthread.c               |   7 +--
 sys/sys/proc.h                        |  11 ++++-
 sys/sys/systm.h                       |   4 +-
 sys/uvm/uvm_extern.h                  |   4 +-
 sys/uvm/uvm_glue.c                    |  16 +++++---
 sys/vm/vm_extern.h                    |   3 +-
 32 files changed, 232 insertions(+), 620 deletions(-)

diffs (truncated from 1935 to 300 lines):

diff -r 73c18e63abeb -r 8bfd2c8e9131 sys/arch/alpha/alpha/vm_machdep.c
--- a/sys/arch/alpha/alpha/vm_machdep.c Sun May 28 05:23:41 2000 +0000
+++ b/sys/arch/alpha/alpha/vm_machdep.c Sun May 28 05:48:59 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.56 2000/05/27 06:29:35 thorpej Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.57 2000/05/28 05:48:59 thorpej Exp $ */
 
 /*
  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.56 2000/05/27 06:29:35 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.57 2000/05/28 05:48:59 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -140,17 +140,20 @@
  * fork(), while the parent process returns normally.
  *
  * p1 is the process being forked; if p1 == &proc0, we are creating
- * a kernel thread, and the return path will later be changed in cpu_set_kpc.
+ * a kernel thread, and the return path and argument are specified with
+ * `func' and `arg'.
  *
  * If an alternate user-level stack is requested (with non-zero values
  * in both the stack and stacksize args), set up the user stack pointer
  * accordingly.
  */
 void
-cpu_fork(p1, p2, stack, stacksize)
+cpu_fork(p1, p2, stack, stacksize, func, arg)
        register struct proc *p1, *p2;
        void *stack;
        size_t stacksize;
+       void (*func) __P((void *));
+       void *arg;
 {
        struct user *up = p2->p_addr;
 
@@ -223,55 +226,19 @@
                if (stack != NULL)
                        p2tf->tf_regs[FRAME_SP] = (u_long)stack + stacksize;
 
-               /*
-                * Arrange for continuation at child_return(), which
-                * will return to exception_return().  Note that the child
-                * process doesn't stay in the kernel for long!
-                * 
-                * This is an inlined version of cpu_set_kpc.
-                */
                up->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)p2tf;    
                up->u_pcb.pcb_context[0] =
-                   (u_int64_t)child_return;            /* s0: pc */
+                   (u_int64_t)func;                    /* s0: pc */
                up->u_pcb.pcb_context[1] =
                    (u_int64_t)exception_return;        /* s1: ra */
                up->u_pcb.pcb_context[2] =
-                   (u_int64_t)p2;                      /* s2: arg */
+                   (u_int64_t)arg;                     /* s2: arg */
                up->u_pcb.pcb_context[7] =
                    (u_int64_t)switch_trampoline;       /* ra: assembly magic */
        }
 }
 
 /*
- * cpu_set_kpc:
- *
- * Arrange for in-kernel execution of a process to continue at the
- * named pc, as if the code at that address were called as a function
- * with argument, the current process's process pointer.
- *
- * Note that it's assumed that when the named process returns,
- * exception_return() should be invoked, to return to user mode.
- *
- * (Note that cpu_fork(), above, uses an open-coded version of this.)
- */
-void
-cpu_set_kpc(p, pc, arg)
-       struct proc *p;
-       void (*pc) __P((void *));
-       void *arg;
-{
-       struct pcb *pcbp;
-
-       pcbp = &p->p_addr->u_pcb;
-       pcbp->pcb_context[0] = (u_int64_t)pc;   /* s0 - pc to invoke */
-       pcbp->pcb_context[1] =
-           (u_int64_t)exception_return;        /* s1 - return address */
-       pcbp->pcb_context[2] = (u_int64_t)arg;  /* s2 - arg */
-       pcbp->pcb_context[7] =
-           (u_int64_t)switch_trampoline;       /* ra - assembly magic */
-}
-
-/*
  * Finish a swapin operation.
  *
  * We need to cache the physical address of the PCB, so we can
diff -r 73c18e63abeb -r 8bfd2c8e9131 sys/arch/amiga/amiga/vm_machdep.c
--- a/sys/arch/amiga/amiga/vm_machdep.c Sun May 28 05:23:41 2000 +0000
+++ b/sys/arch/amiga/amiga/vm_machdep.c Sun May 28 05:48:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm_machdep.c,v 1.53 2000/01/20 22:18:55 sommerfeld Exp $       */
+/*     $NetBSD: vm_machdep.c,v 1.54 2000/05/28 05:49:00 thorpej Exp $  */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -74,17 +74,20 @@
  * fork(), while the parent process returns normally.
  *
  * p1 is the process being forked; if p1 == &proc0, we are creating
- * a kernel thread, and the return path will later be changed in cpu_set_kpc.
+ * a kernel thread, and the return path and argument are specified with
+ * `func' and `arg'.
  *
  * If an alternate user-level stack is requested (with non-zero values
  * in both the stack and stacksize args), set up the user stack pointer
  * accordingly.
  */
 void
-cpu_fork(p1, p2, stack, stacksize)
+cpu_fork(p1, p2, stack, stacksize, func, arg)
        register struct proc *p1, *p2;
        void *stack;
        size_t stacksize;
+       void (*func) __P((void *));
+       void *arg;
 {
        register struct pcb *pcb = &p2->p_addr->u_pcb;
        register struct trapframe *tf;
@@ -105,8 +108,7 @@
        *pcb = p1->p_addr->u_pcb;
 
        /*
-        * Copy the trap frame, and arrange for the child to return directly
-        * through child_return().  Note the in-line cpu_set_kpc().
+        * Copy the trap frame.
         */
        tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1;
        p2->p_md.md_regs = (int *)tf;
@@ -120,38 +122,12 @@
 
        sf = (struct switchframe *)tf - 1;
        sf->sf_pc = (u_int)proc_trampoline;
-       pcb->pcb_regs[6] = (int)child_return;   /* A2 */
-       pcb->pcb_regs[7] = (int)p2;             /* A3 */
+       pcb->pcb_regs[6] = (int)func;           /* A2 */
+       pcb->pcb_regs[7] = (int)arg;            /* A3 */
        pcb->pcb_regs[11] = (int)sf;            /* SSP */
 }
 
 /*
- * cpu_set_kpc:
- *
- * Arrange for in-kernel execution of a process to continue at the
- * named pc, as if the code at that address were called as a function
- * with the supplied argument.
- *
- * Note that it's assumed that when the named process returns, rei()
- * should be invoked, to return to user mode.
- */
-void
-cpu_set_kpc(p, pc, arg)
-       struct proc     *p;
-       void            (*pc) __P((void *));
-       void            *arg;
-{
-       struct pcb *pcbp;
-       struct switchframe *sf;
-
-       pcbp = &p->p_addr->u_pcb;
-       sf = (struct switchframe *)pcbp->pcb_regs[11];
-       sf->sf_pc = (u_int)proc_trampoline;
-       pcbp->pcb_regs[6] = (int)pc;            /* A2 */
-       pcbp->pcb_regs[7] = (int)arg;           /* A3 */
-}
-
-/*
  * cpu_exit is called as the last action during exit.
  *
  * Block context switches and then call switch_exit() which will
diff -r 73c18e63abeb -r 8bfd2c8e9131 sys/arch/arm26/arm26/except.c
--- a/sys/arch/arm26/arm26/except.c     Sun May 28 05:23:41 2000 +0000
+++ b/sys/arch/arm26/arm26/except.c     Sun May 28 05:48:59 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: except.c,v 1.5 2000/05/27 00:40:31 sommerfeld Exp $ */
+/* $NetBSD: except.c,v 1.6 2000/05/28 05:49:00 thorpej Exp $ */
 /*-
  * Copyright (c) 1998, 1999, 2000 Ben Harris
  * All rights reserved.
@@ -32,7 +32,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.5 2000/05/27 00:40:31 sommerfeld Exp $");
+__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.6 2000/05/28 05:49:00 thorpej Exp $");
 
 #include "opt_cputypes.h"
 #include "opt_ddb.h"
@@ -299,12 +299,11 @@
  * a normal successful syscall return.
  */
 void
-child_return(void* ignore)
+child_return(void *arg)
 {
-       struct proc *p;
+       struct proc *p = arg;
        struct trapframe *tf;
 
-       p = curproc;
        tf = p->p_addr->u_pcb.pcb_tf;
        tf->tf_r0 = 0;
        tf->tf_r15 &= ~R15_FLAG_C;
diff -r 73c18e63abeb -r 8bfd2c8e9131 sys/arch/arm26/arm26/vm_machdep.c
--- a/sys/arch/arm26/arm26/vm_machdep.c Sun May 28 05:23:41 2000 +0000
+++ b/sys/arch/arm26/arm26/vm_machdep.c Sun May 28 05:48:59 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.2 2000/05/13 17:57:14 bjh21 Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.3 2000/05/28 05:49:00 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2000 Ben Harris
@@ -66,7 +66,7 @@
 
 #include <sys/param.h>
 
-__RCSID("$NetBSD: vm_machdep.c,v 1.2 2000/05/13 17:57:14 bjh21 Exp $");
+__RCSID("$NetBSD: vm_machdep.c,v 1.3 2000/05/28 05:49:00 thorpej Exp $");
 
 #include <sys/buf.h>
 #include <sys/exec.h>
@@ -88,7 +88,8 @@
  * Copy and update the pcb and trap frame, making the child ready to run.
  *
  * p1 is the process being forked; if p1 == &proc0, we are creating
- * a kernel thread, and the return path will later be changed in cpu_set_kpc.
+ * a kernel thread, and the return path and argument are specified with
+ * `func' and `arg'.
  *
  * If an alternate user-level stack is requested (with non-zero values
  * in both the stack and stacksize args), set up the user stack pointer
@@ -104,7 +105,8 @@
  */
 
 void
-cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize)
+cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize,
+    void (*func)(void *), void *arg)
 {
        struct pcb *pcb;
        struct trapframe *tf;
@@ -138,25 +140,7 @@
        pcb->pcb_tf = tf;
        pcb->pcb_sf = sf;
        pcb->pcb_onfault = NULL;
-       cpu_set_kpc(p2, child_return, NULL);
-}
-
-/*
- * Change the initial entry point of a process that's been created by
- * cpu_fork() but hasn't run yet.  It will still start up through
- * proc_trampoline, but will call pc instead of child_return().
- */
-void
-cpu_set_kpc(struct proc *p, void (*pc)(void *), void *arg)
-{
-       struct switchframe *sf;
-
-       sf = p->p_addr->u_pcb.pcb_sf;
-#ifdef DIAGNOSTIC
-       if (sf->sf_r14 != ((register_t)proc_trampoline | R15_MODE_SVC))
-               panic("cpu_set_kpc");
-#endif
-       sf->sf_r4 = (register_t)pc;
+       sf->sf_r4 = (register_t)func;
        sf->sf_r5 = (register_t)arg;
 }
 
diff -r 73c18e63abeb -r 8bfd2c8e9131 sys/arch/arm32/arm32/vm_machdep.c
--- a/sys/arch/arm32/arm32/vm_machdep.c Sun May 28 05:23:41 2000 +0000
+++ b/sys/arch/arm32/arm32/vm_machdep.c Sun May 28 05:48:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm_machdep.c,v 1.49 2000/03/26 20:42:26 kleink Exp $   */
+/*     $NetBSD: vm_machdep.c,v 1.50 2000/05/28 05:49:01 thorpej Exp $  */
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -105,19 +105,21 @@
  * fork(), while the parent process returns normally.
  *
  * p1 is the process being forked; if p1 == &proc0, we are creating
- * a kernel thread, and the return path will later be changed in cpu_set_kpc.
+ * a kernel thread, and the return path and argument are specified with
+ * `func' and `arg'.
  *
  * If an alternate user-level stack is requested (with non-zero values
  * in both the stack and stacksize args), set up the user stack pointer
  * accordingly.



Home | Main Index | Thread Index | Old Index