diff options
-rw-r--r-- | sys/compat/linux/linux_sched.c | 5 | ||||
-rw-r--r-- | sys/compat/netbsd/netbsd_misc.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/usb_port.h | 5 | ||||
-rw-r--r-- | sys/kern/init_main.c | 88 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 25 | ||||
-rw-r--r-- | sys/kern/kern_kthread.c | 9 | ||||
-rw-r--r-- | sys/kern/subr_autoconf.c | 30 | ||||
-rw-r--r-- | sys/sys/device.h | 5 | ||||
-rw-r--r-- | sys/sys/proc.h | 4 |
9 files changed, 128 insertions, 47 deletions
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c index c5b1b008db9..4521fee96e6 100644 --- a/sys/compat/linux/linux_sched.c +++ b/sys/compat/linux/linux_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_sched.c,v 1.4 2004/06/13 21:49:23 niklas Exp $ */ +/* $OpenBSD: linux_sched.c,v 1.5 2004/11/23 19:08:52 miod Exp $ */ /* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */ /*- @@ -96,7 +96,8 @@ linux_sys_clone(p, v, retval) * or down. So, we pass a stack size of 0, so that the code * that makes this adjustment is a noop. */ - return (fork1(p, sig, flags, SCARG(uap, stack), 0, NULL, NULL, retval)); + return (fork1(p, sig, flags, SCARG(uap, stack), 0, NULL, NULL, retval, + NULL)); } int diff --git a/sys/compat/netbsd/netbsd_misc.c b/sys/compat/netbsd/netbsd_misc.c index b8a7b984103..627c5cb1d83 100644 --- a/sys/compat/netbsd/netbsd_misc.c +++ b/sys/compat/netbsd/netbsd_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netbsd_misc.c,v 1.13 2003/06/02 23:28:00 millert Exp $ */ +/* $OpenBSD: netbsd_misc.c,v 1.14 2004/11/23 19:08:54 miod Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -57,7 +57,7 @@ netbsd_sys___vfork14(p, v, retval) register_t *retval; { return (fork1(p, SIGCHLD, FORK_PPWAIT|FORK_SHAREVM, NULL, 0, NULL, - NULL, retval)); + NULL, retval, NULL)); } /* XXX syncs whole file */ diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index c830e6e1820..dab4ad72e3a 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_port.h,v 1.52 2004/11/08 22:01:02 dlg Exp $ */ +/* $OpenBSD: usb_port.h,v 1.53 2004/11/23 19:08:54 miod Exp $ */ /* $NetBSD: usb_port.h,v 1.62 2003/02/15 18:33:30 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */ @@ -279,9 +279,6 @@ typedef struct proc *usb_proc_ptr; #define usb_kthread_create1 kthread_create #define usb_kthread_create kthread_create_deferred -#define config_pending_incr() -#define config_pending_decr() - typedef int usb_malloc_type; #define Ether_ifattach(ifp, eaddr) ether_ifattach(ifp) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 196065727d4..119bcecce17 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.119 2004/07/28 17:15:12 tholo Exp $ */ +/* $OpenBSD: init_main.c,v 1.120 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -126,6 +126,7 @@ struct timeval boottime; struct timeval runtime; #endif int ncpus = 1; +__volatile int start_init_exec; /* semaphore for start_init() */ #if !defined(NO_PROPOLICE) long __guard[8]; @@ -185,7 +186,6 @@ main(framep) struct timeval rtv; quad_t lim; int s, i; - register_t rval[2]; extern struct pdevinit pdevinit[]; extern void scheduler_start(void); extern void disk_init(void); @@ -399,6 +399,34 @@ main(framep) /* Start the scheduler */ scheduler_start(); + /* + * Create process 1 (init(8)). We do this now, as Unix has + * historically had init be process 1, and changing this would + * probably upset a lot of people. + * + * Note that process 1 won't immediately exec init(8), but will + * wait for us to inform it that the root file system has been + * mounted. + */ + if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, NULL, + &initproc)) + panic("fork init"); + + /* + * Create any kernel threads who's creation was deferred because + * initproc had not yet been created. + */ + kthread_run_deferred_queue(); + + /* + * Now that device driver threads have been created, wait for + * them to finish any deferred autoconfiguration. Note we don't + * need to lock this semaphore, since we haven't booted any + * secondary processors, yet. + */ + while (config_pending) + (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0); + dostartuphooks(); /* Configure root/swap devices */ @@ -419,6 +447,15 @@ main(framep) p->p_fd->fd_rdir = NULL; /* + * Now that root is mounted, we can fixup initproc's CWD + * info. All other processes are kthreads, which merely + * share proc0's CWD info. + */ + initproc->p_fd->fd_cdir = rootvnode; + VREF(initproc->p_fd->fd_cdir); + initproc->p_fd->fd_rdir = NULL; + + /* * Now can look at time, having had a chance to verify the time * from the file system. Reset p->p_rtime as it may have been * munched in mi_switch() after the time got set. @@ -428,49 +465,45 @@ main(framep) #else boottime = mono_time = time; #endif - p->p_stats->p_start = boottime; -#ifdef __HAVE_CPUINFO - microuptime(&p->p_cpu->ci_schedstate.spc_runtime); -#else +#ifndef __HAVE_CPUINFO microuptime(&runtime); #endif - p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; + LIST_FOREACH(p, &allproc, p_list) { + p->p_stats->p_start = boottime; +#ifdef __HAVE_CPUINFO + microuptime(&p->p_cpu->ci_schedstate.spc_runtime); +#endif + p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; + } uvm_swap_init(); - /* Create process 1 (init(8)). */ - if (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, start_init, NULL, rval)) - panic("fork init"); - - /* Create process 2, the pageout daemon kernel thread. */ + /* Create the pageout daemon kernel thread. */ if (kthread_create(uvm_pageout, NULL, NULL, "pagedaemon")) panic("fork pagedaemon"); - /* Create process 3, the reaper daemon kernel thread. */ + /* Create the reaper daemon kernel thread. */ if (kthread_create(start_reaper, NULL, NULL, "reaper")) panic("fork reaper"); - /* Create process 4, the cleaner daemon kernel thread. */ + /* Create the cleaner daemon kernel thread. */ if (kthread_create(start_cleaner, NULL, NULL, "cleaner")) panic("fork cleaner"); - /* Create process 5, the update daemon kernel thread. */ + /* Create the update daemon kernel thread. */ if (kthread_create(start_update, NULL, NULL, "update")) panic("fork update"); - /* Create process 6, the aiodone daemon kernel thread. */ + /* Create the aiodone daemon kernel thread. */ if (kthread_create(uvm_aiodone_daemon, NULL, NULL, "aiodoned")) panic("fork aiodoned"); #ifdef CRYPTO - /* Create process 7, the crypto kernel thread. */ + /* Create the crypto kernel thread. */ if (kthread_create(start_crypto, NULL, NULL, "crypto")) panic("crypto thread"); #endif /* CRYPTO */ - /* Create any other deferred kernel threads. */ - kthread_run_deferred_queue(); - microtime(&rtv); srandom((u_long)(rtv.tv_sec ^ rtv.tv_usec)); @@ -481,6 +514,12 @@ main(framep) cpu_boot_secondary_processors(); #endif + /* + * Okay, now we can let init(8) exec! It's off to userland! + */ + start_init_exec = 1; + wakeup((void *)&start_init_exec); + /* The scheduler is an infinite loop. */ uvm_scheduler(); /* NOTREACHED */ @@ -535,11 +574,16 @@ start_init(arg) char flags[4], *flagsp; char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL; - initproc = p; - /* * Now in process 1. */ + + /* + * Wait for main() to tell us that it's safe to exec. + */ + while (start_init_exec == 0) + (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0); + check_console(p); /* diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 4fc2dd5c8f0..eee21a8231c 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.72 2004/08/06 22:31:30 mickey Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.73 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -75,7 +75,8 @@ int pidtaken(pid_t); int sys_fork(struct proc *p, void *v, register_t *retval) { - return (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, NULL, NULL, retval)); + return (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, NULL, + NULL, retval, NULL)); } /*ARGSUSED*/ @@ -83,7 +84,7 @@ int sys_vfork(struct proc *p, void *v, register_t *retval) { return (fork1(p, SIGCHLD, FORK_VFORK|FORK_PPWAIT, NULL, 0, NULL, - NULL, retval)); + NULL, retval, NULL)); } int @@ -121,7 +122,7 @@ sys_rfork(struct proc *p, void *v, register_t *retval) if (rforkflags & RFMEM) flags |= FORK_SHAREVM; - return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval)); + return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval, NULL)); } /* print the 'table full' message once per 10 seconds */ @@ -129,7 +130,8 @@ struct timeval fork_tfmrate = { 10, 0 }; int fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, - void (*func)(void *), void *arg, register_t *retval) + void (*func)(void *), void *arg, register_t *retval, + struct proc **rnewprocp) { struct proc *p2; uid_t uid; @@ -354,6 +356,14 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, */ PRELE(p1); + /* + * Notify any interested parties about the new process. + */ + KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid); + + /* + * Update stats now that we know the fork was successfull. + */ uvmexp.forks++; if (flags & FORK_PPWAIT) uvmexp.forks_ppwait++; @@ -361,9 +371,10 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, uvmexp.forks_sharevm++; /* - * tell any interested parties about the new process + * Pass a pointer to the new process to the caller. */ - KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid); + if (rnewprocp != NULL) + *rnewprocp = p2; /* * Preserve synchronization semantics of vfork. If waiting for diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 44c85d176a3..721c440c999 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_kthread.c,v 1.22 2004/05/04 16:59:32 grange Exp $ */ +/* $OpenBSD: kern_kthread.c,v 1.23 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */ /*- @@ -65,7 +65,6 @@ kthread_create(void (*func)(void *), void *arg, struct proc **newpp, const char *fmt, ...) { struct proc *p2; - register_t rv[2]; int error; va_list ap; @@ -74,13 +73,11 @@ kthread_create(void (*func)(void *), void *arg, * descriptors and don't leave the exit status around for the * parent to wait for. */ - error = fork1(&proc0, 0, - FORK_SHAREVM|FORK_NOZOMBIE|FORK_SIGHAND, NULL, 0, func, arg, rv); + error = fork1(&proc0, 0, FORK_SHAREVM |FORK_NOZOMBIE |FORK_SIGHAND, + NULL, 0, func, arg, NULL, &p2); if (error) return (error); - p2 = pfind(rv[0]); - /* * Mark it as a system process and not a candidate for * swapping. diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c index c378eac10e2..9cb03dbf82d 100644 --- a/sys/kern/subr_autoconf.c +++ b/sys/kern/subr_autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_autoconf.c,v 1.38 2004/08/03 17:49:04 pefo Exp $ */ +/* $OpenBSD: subr_autoconf.c,v 1.39 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: subr_autoconf.c,v 1.21 1996/04/04 06:06:18 cgd Exp $ */ /* @@ -51,6 +51,7 @@ #include <sys/systm.h> /* Extra stuff from Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de> */ #include <sys/queue.h> +#include <sys/proc.h> #include "hotplug.h" @@ -101,6 +102,8 @@ void config_process_deferred_children(struct device *); struct devicelist alldevs; /* list of all devices */ struct evcntlist allevents; /* list of all event counters */ +__volatile int config_pending; /* semaphore for mountroot */ + /* * Initialize autoconfiguration data structures. This occurs before console * initialization as that might require use of this subsystem. Furthermore @@ -691,6 +694,7 @@ config_defer(dev, func) dc->dc_dev = dev; dc->dc_func = func; TAILQ_INSERT_TAIL(&deferred_config_queue, dc, dc_queue); + config_pending_incr(); } /* @@ -709,10 +713,34 @@ config_process_deferred_children(parent) TAILQ_REMOVE(&deferred_config_queue, dc, dc_queue); (*dc->dc_func)(dc->dc_dev); free(dc, M_DEVBUF); + config_pending_decr(); } } } +/* + * Manipulate the config_pending semaphore. + */ +void +config_pending_incr(void) +{ + + config_pending++; +} + +void +config_pending_decr(void) +{ + +#ifdef DIAGNOSTIC + if (config_pending == 0) + panic("config_pending_decr: config_pending == 0"); +#endif + config_pending--; + if (config_pending == 0) + wakeup((void *)&config_pending); +} + int config_detach_children(parent, flags) struct device *parent; diff --git a/sys/sys/device.h b/sys/sys/device.h index c06c4bc2831..95ea9f12939 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -1,4 +1,4 @@ -/* $OpenBSD: device.h,v 1.28 2004/11/17 14:12:59 deraadt Exp $ */ +/* $OpenBSD: device.h,v 1.29 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */ /* @@ -185,6 +185,7 @@ extern struct devicelist alldevs; /* list of all devices */ extern struct evcntlist allevents; /* list of all event counters */ extern int autoconf_verbose; +extern __volatile int config_pending; /* semaphore for mountroot */ void config_init(void); void *config_search(cfmatch_t, struct device *, void *); @@ -203,6 +204,8 @@ struct device *config_make_softc(struct device *parent, struct cfdata *cf); void config_defer(struct device *, void (*)(struct device *)); void evcnt_attach(struct device *, const char *, struct evcnt *); +void config_pending_incr(void); +void config_pending_decr(void); struct device *device_lookup(struct cfdriver *, int unit); void device_ref(struct device *); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 4ab6cfe9c9c..a8746d3eecf 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.75 2004/07/22 15:42:11 art Exp $ */ +/* $OpenBSD: proc.h,v 1.76 2004/11/23 19:08:55 miod Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -421,7 +421,7 @@ void reaper(void); void exit1(struct proc *, int); void exit2(struct proc *); int fork1(struct proc *, int, int, void *, size_t, void (*)(void *), - void *, register_t *); + void *, register_t *, struct proc **); void rqinit(void); int groupmember(gid_t, struct ucred *); #if !defined(cpu_switch) |