diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-05-29 03:20:44 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-05-29 03:20:44 +0000 |
commit | 93c77ad51e4fcc28584bb93f63dd48a4a6c771ec (patch) | |
tree | 0198ee58bab354860cf7d00f461d33143ff1aa7f | |
parent | 171f684dab1e3ccc2da4ee86219e9396e8e38e55 (diff) |
sched work by niklas and art backed out; causes panics
-rw-r--r-- | sys/arch/amd64/amd64/ioapic.c | 8 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore.S | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 6 | ||||
-rw-r--r-- | sys/arch/amd64/include/pic.h | 4 | ||||
-rw-r--r-- | sys/arch/hppa64/include/cpu.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/i386/locore.s | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/trap.c | 11 | ||||
-rw-r--r-- | sys/arch/i386/include/intrdefs.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/interrupt.c | 17 | ||||
-rw-r--r-- | sys/arch/sparc64/include/psl.h | 4 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_lock.c | 70 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 63 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 75 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 6 | ||||
-rw-r--r-- | sys/kern/sched_bsd.c | 81 | ||||
-rw-r--r-- | sys/kern/vfs_sync.c | 7 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_ctl.c | 9 | ||||
-rw-r--r-- | sys/sys/lock.h | 35 | ||||
-rw-r--r-- | sys/sys/mplock.h | 10 | ||||
-rw-r--r-- | sys/sys/proc.h | 6 | ||||
-rw-r--r-- | sys/sys/sched.h | 66 | ||||
-rw-r--r-- | sys/sys/signalvar.h | 6 | ||||
-rw-r--r-- | sys/uvm/uvm_glue.c | 13 |
25 files changed, 348 insertions, 173 deletions
diff --git a/sys/arch/amd64/amd64/ioapic.c b/sys/arch/amd64/amd64/ioapic.c index 21c4b38ddab..6ee5bf11a1b 100644 --- a/sys/arch/amd64/amd64/ioapic.c +++ b/sys/arch/amd64/amd64/ioapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioapic.c,v 1.4 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: ioapic.c,v 1.5 2005/05/29 03:20:36 deraadt Exp $ */ /* $NetBSD: ioapic.c,v 1.6 2003/05/15 13:30:31 fvdl Exp $ */ /*- @@ -127,14 +127,14 @@ ioapic_lock(struct ioapic_softc *sc) flags = read_psl(); disable_intr(); - mtx_enter(&sc->sc_pic.pic_mutex); + SIMPLE_LOCK(&sc->sc_pic.pic_lock); return flags; } static __inline void ioapic_unlock(struct ioapic_softc *sc, u_long flags) { - mtx_leave(&sc->sc_pic.pic_mutex); + SIMPLE_UNLOCK(&sc->sc_pic.pic_lock); write_psl(flags); } @@ -294,7 +294,7 @@ ioapic_attach(struct device *parent, struct device *self, void *aux) sc->sc_data = (volatile u_int32_t *)(bh + IOAPIC_DATA); sc->sc_pic.pic_type = PIC_IOAPIC; - mtx_init(&sc->sc_pic.pic_mutex, IPL_NONE); + SIMPLE_LOCK_INIT(&sc->sc_pic.pic_lock); sc->sc_pic.pic_hwmask = ioapic_hwmask; sc->sc_pic.pic_hwunmask = ioapic_hwunmask; sc->sc_pic.pic_addroute = ioapic_addroute; diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index a73047353d6..46583605655 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.18 2005/05/27 19:32:39 art Exp $ */ +/* $OpenBSD: locore.S,v 1.19 2005/05/29 03:20:36 deraadt Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -846,8 +846,9 @@ idle_start: cmpl $0,_C_LABEL(whichqs)(%rip) jz idle_loop idle_exit: + movl $IPL_HIGH,CPUVAR(ILEVEL) sti -#if defined(MULTIPROCESSOR) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_lock_idle) #endif switch_search: diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index 0bc830b1c7b..05289bfe2ed 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.5 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: trap.c,v 1.6 2005/05/29 03:20:36 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */ /*- @@ -386,6 +386,10 @@ copyfault: case T_PAGEFLT: /* allow page faults in kernel mode */ if (p == NULL) goto we_re_toast; +#ifdef LOCKDEBUG + if (simple_lock_held(&sched_lock)) + goto we_re_toast; +#endif #ifdef MULTIPROCESSOR if ((p->p_flag & P_BIGLOCK) == 0) goto we_re_toast; diff --git a/sys/arch/amd64/include/pic.h b/sys/arch/amd64/include/pic.h index 0ef3a8fa4ca..0859288542f 100644 --- a/sys/arch/amd64/include/pic.h +++ b/sys/arch/amd64/include/pic.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pic.h,v 1.3 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: pic.h,v 1.4 2005/05/29 03:20:36 deraadt Exp $ */ /* $NetBSD: pic.h,v 1.1 2003/02/26 21:26:11 fvdl Exp $ */ #ifndef _X86_PIC_H @@ -20,7 +20,7 @@ struct pic { struct device pic_dev; int pic_type; #ifdef MULTIPROCESSOR - struct mutex pic_mutex; + struct SIMPLE_LOCK pic_lock; #endif void (*pic_hwmask)(struct pic *, int); void (*pic_hwunmask)(struct pic *, int); diff --git a/sys/arch/hppa64/include/cpu.h b/sys/arch/hppa64/include/cpu.h index e4054861dab..11f8d9e16ae 100644 --- a/sys/arch/hppa64/include/cpu.h +++ b/sys/arch/hppa64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.3 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: cpu.h,v 1.4 2005/05/29 03:20:37 deraadt Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -83,8 +83,8 @@ #define IPL_VM 7 #define IPL_AUDIO 8 #define IPL_CLOCK 9 +#define IPL_SCHED 9 #define IPL_STATCLOCK 10 -#define IPL_SCHED IPL_STATCLOCK #define IPL_HIGH 11 #define NIPL 12 diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index f27a00a8c3a..724f4325bdb 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.89 2005/05/26 04:29:06 mickey Exp $ */ +/* $OpenBSD: locore.s,v 1.90 2005/05/29 03:20:38 deraadt Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -1617,6 +1617,7 @@ ENTRY(idle_start) jz _C_LABEL(idle_loop) ENTRY(idle_exit) + movl $IPL_HIGH,CPL # splhigh sti #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_lock_idle) diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index 98d21021725..960753234ab 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.68 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: trap.c,v 1.69 2005/05/29 03:20:38 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ /*- @@ -451,6 +451,15 @@ trap(frame) case T_PAGEFLT: /* allow page faults in kernel mode */ if (p == 0 || p->p_addr == 0) goto we_re_toast; +#ifdef LOCKDEBUG + /* If we page-fault while in scheduler, we're doomed. */ +#ifdef notyet + if (simple_lock_held(&sched_lock)) +#else + if (__mp_lock_held(&sched_lock)) +#endif + goto we_re_toast; +#endif pcb = &p->p_addr->u_pcb; #if 0 diff --git a/sys/arch/i386/include/intrdefs.h b/sys/arch/i386/include/intrdefs.h index 2cf218fc765..6b7b1762430 100644 --- a/sys/arch/i386/include/intrdefs.h +++ b/sys/arch/i386/include/intrdefs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intrdefs.h,v 1.3 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: intrdefs.h,v 1.4 2005/05/29 03:20:39 deraadt Exp $ */ /* $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */ #ifndef _i386_INTRDEFS_H @@ -66,8 +66,8 @@ #define IPL_IMP IPL_VM /* XXX - should not be here. */ #define IPL_AUDIO MAKEIPL(7) /* audio */ #define IPL_CLOCK MAKEIPL(8) /* clock */ +#define IPL_SCHED IPL_CLOCK #define IPL_STATCLOCK MAKEIPL(9) /* statclock */ -#define IPL_SCHED IPL_STATCLOCK #define IPL_HIGH MAKEIPL(9) /* everything */ #define IPL_IPI MAKEIPL(10) /* interprocessor interrupt */ diff --git a/sys/arch/mips64/mips64/interrupt.c b/sys/arch/mips64/mips64/interrupt.c index 95ea6c0ef8f..a8a748fd2de 100644 --- a/sys/arch/mips64/mips64/interrupt.c +++ b/sys/arch/mips64/mips64/interrupt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interrupt.c,v 1.12 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: interrupt.c,v 1.13 2005/05/29 03:20:40 deraadt Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -282,10 +282,21 @@ softintr() ADDUPROF(p); } if (want_resched) { + int s; + /* - * We're being preempted. + * Since we are curproc, clock will normally just change + * our priority without moving us from one queue to another + * (since the running process is not on a queue.) + * If that happened after we put ourselves on the run queue + * but before we switched, we might not be on the queue + * indicated by our priority. */ - preempt(NULL); + s = splstatclock(); + setrunqueue(p); + p->p_stats->p_ru.ru_nivcsw++; + mi_switch(); + splx(s); while ((sig = CURSIG(p)) != 0) postsig(sig); } diff --git a/sys/arch/sparc64/include/psl.h b/sys/arch/sparc64/include/psl.h index 633a97467a9..ef4ef42008f 100644 --- a/sys/arch/sparc64/include/psl.h +++ b/sys/arch/sparc64/include/psl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psl.h,v 1.14 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: psl.h,v 1.15 2005/05/29 03:20:40 deraadt Exp $ */ /* $NetBSD: psl.h,v 1.20 2001/04/13 23:30:05 thorpej Exp $ */ /* @@ -90,7 +90,7 @@ #define PIL_SER 12 #define PIL_STATCLOCK 14 #define PIL_HIGH 15 -#define PIL_SCHED PIL_STATCLOCK +#define PIL_SCHED PIL_CLOCK #define PIL_LOCK PIL_HIGH /* diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 05ba79f3399..5e0d1273538 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.75 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.76 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -341,9 +341,9 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, /* * Make child runnable, set start time, and add to run queue. */ + SCHED_LOCK(s); getmicrotime(&p2->p_stats->p_start); p2->p_acflag = AFORK; - SCHED_LOCK(s); p2->p_stat = SRUN; setrunqueue(p2); SCHED_UNLOCK(s); diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index d36c6d14ec6..3bcb5928023 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_lock.c,v 1.18 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_lock.c,v 1.19 2005/05/29 03:20:41 deraadt Exp $ */ /* * Copyright (c) 1995 @@ -1121,6 +1121,18 @@ simple_lock_freecheck(void *start, void *end) splx(s); } +/* + * We must be holding exactly one lock: the sched_lock. + */ + +#ifdef notyet +void +simple_lock_switchcheck(void) +{ + + simple_lock_only_held(&sched_lock, "switching"); +} +#endif void simple_lock_only_held(volatile struct simplelock *lp, const char *where) @@ -1160,6 +1172,60 @@ simple_lock_only_held(volatile struct simplelock *lp, const char *where) * so that they show up in profiles. */ +/* + * XXX Instead of using struct lock for the kernel lock and thus requiring us + * XXX to implement simplelocks, causing all sorts of fine-grained locks all + * XXX over our tree getting activated consuming both time and potentially + * XXX introducing locking protocol bugs. + */ +#ifdef notyet + +struct lock kernel_lock; + +void +_kernel_lock_init(void) +{ + spinlockinit(&kernel_lock, "klock", 0); +} + +/* + * Acquire/release the kernel lock. Intended for use in the scheduler + * and the lower half of the kernel. + */ +void +_kernel_lock(int flag) +{ + SCHED_ASSERT_UNLOCKED(); + spinlockmgr(&kernel_lock, flag, 0); +} + +void +_kernel_unlock(void) +{ + spinlockmgr(&kernel_lock, LK_RELEASE, 0); +} + +/* + * Acquire/release the kernel_lock on behalf of a process. Intended for + * use in the top half of the kernel. + */ +void +_kernel_proc_lock(struct proc *p) +{ + SCHED_ASSERT_UNLOCKED(); + spinlockmgr(&kernel_lock, LK_EXCLUSIVE, 0); + p->p_flag |= P_BIGLOCK; +} + +void +_kernel_proc_unlock(struct proc *p) +{ + p->p_flag &= ~P_BIGLOCK; + spinlockmgr(&kernel_lock, LK_RELEASE, 0); +} + +#else + struct __mp_lock kernel_lock; void @@ -1206,6 +1272,8 @@ _kernel_proc_unlock(struct proc *p) __mp_unlock(&kernel_lock); } +#endif + #ifdef MP_LOCKDEBUG /* CPU-dependent timing, needs this to be settable from ddb. */ int __mp_lock_spinout = 200000000; diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index d770a3858af..5f33e7b55a1 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_resource.c,v 1.29 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_resource.c,v 1.30 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_resource.c,v 1.38 1996/10/23 07:19:38 matthias Exp $ */ /*- @@ -199,7 +199,7 @@ donice(curp, chgp, n) return (EACCES); chgp->p_nice = n; SCHED_LOCK(s); - resetpriority(chgp); + (void)resetpriority(chgp); SCHED_UNLOCK(s); return (0); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index d228b218db6..a8092d7bcb1 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.74 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.75 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -805,19 +805,29 @@ trapsignal(p, signum, code, type, sigval) * regardless of the signal action (eg, blocked or ignored). * * Other ignored signals are discarded immediately. + * + * XXXSMP: Invoked as psignal() or sched_psignal(). */ void -psignal(struct proc *p, int signum) +psignal1(p, signum, dolock) + register struct proc *p; + register int signum; + int dolock; /* XXXSMP: works, but icky */ { - int s, prop; - sig_t action; + register int s, prop; + register sig_t action; int mask; #ifdef DIAGNOSTIC if ((u_int)signum >= NSIG || signum == 0) panic("psignal signal number"); + + /* XXXSMP: works, but icky */ + if (dolock) + SCHED_ASSERT_UNLOCKED(); + else + SCHED_ASSERT_LOCKED(); #endif - SCHED_ASSERT_UNLOCKED(); /* Ignore signal if we are exiting */ if (p->p_flag & P_WEXIT) @@ -880,8 +890,10 @@ psignal(struct proc *p, int signum) */ if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP)) return; + /* XXXSMP: works, but icky */ + if (dolock) + SCHED_LOCK(s); - SCHED_LOCK(s); switch (p->p_stat) { case SSLEEP: @@ -922,11 +934,12 @@ psignal(struct proc *p, int signum) goto out; p->p_siglist &= ~mask; p->p_xstat = signum; - if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) { - SCHED_UNLOCK(s); - psignal(p->p_pptr, SIGCHLD); - SCHED_LOCK(s); - } + if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) + /* + * XXXSMP: recursive call; don't lock + * the second time around. + */ + sched_psignal(p->p_pptr, SIGCHLD); proc_stop(p); goto out; } @@ -963,7 +976,7 @@ psignal(struct proc *p, int signum) * Otherwise, process goes back to sleep state. */ p->p_flag |= P_CONTINUED; - sched_wakeup(p->p_pptr); + wakeup(p->p_pptr); if (action == SIG_DFL) p->p_siglist &= ~mask; if (action == SIG_CATCH) @@ -1014,7 +1027,9 @@ runfast: run: setrunnable(p); out: - SCHED_UNLOCK(s); + /* XXXSMP: works, but icky */ + if (dolock) + SCHED_UNLOCK(s); } /* @@ -1059,23 +1074,24 @@ issignal(struct proc *p) */ p->p_xstat = signum; + SCHED_LOCK(s); /* protect mi_switch */ if (p->p_flag & P_FSTRACE) { #ifdef PROCFS - SCHED_LOCK(s); /* procfs debugging */ p->p_stat = SSTOP; - sched_wakeup(p); - mi_switch(s); + wakeup(p); + mi_switch(); #else panic("procfs debugging"); #endif } else { /* ptrace debugging */ psignal(p->p_pptr, SIGCHLD); - SCHED_LOCK(s); proc_stop(p); - mi_switch(s); + mi_switch(); } + SCHED_ASSERT_UNLOCKED(); + splx(s); /* * If we are no longer being traced, or the parent @@ -1136,7 +1152,9 @@ issignal(struct proc *p) psignal(p->p_pptr, SIGCHLD); SCHED_LOCK(s); proc_stop(p); - mi_switch(s); + mi_switch(); + SCHED_ASSERT_UNLOCKED(); + splx(s); break; } else if (prop & SA_IGNORE) { /* @@ -1180,13 +1198,16 @@ keep: * on the run queue. */ void -proc_stop(struct proc *p) +proc_stop(p) + struct proc *p; { +#ifdef MULTIPROCESSOR SCHED_ASSERT_LOCKED(); +#endif p->p_stat = SSTOP; p->p_flag &= ~P_WAITED; - sched_wakeup(p->p_pptr); + wakeup(p->p_pptr); } /* diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 9d887083455..16fc2d6f8ae 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.62 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.63 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -145,12 +145,8 @@ ltsleep(ident, priority, wmesg, timo, interlock) else *qp->sq_tailp = p; *(qp->sq_tailp = &p->p_forw) = 0; - - p->p_stat = SSLEEP; - if (timo) timeout_add(&p->p_sleep_to, timo); - /* * We can now release the interlock; the scheduler_slock * is held, so a thread can't get in to do wakeup() before @@ -174,16 +170,13 @@ ltsleep(ident, priority, wmesg, timo, interlock) */ if (catch) { p->p_flag |= P_SINTR; - SCHED_UNLOCK(s); /* XXX - must unlock for CURSIG */ if ((sig = CURSIG(p)) != 0) { - SCHED_LOCK(s); if (p->p_wchan) unsleep(p); p->p_stat = SONPROC; SCHED_UNLOCK(s); goto resume; } - SCHED_LOCK(s); if (p->p_wchan == 0) { catch = 0; SCHED_UNLOCK(s); @@ -191,14 +184,22 @@ ltsleep(ident, priority, wmesg, timo, interlock) } } else sig = 0; + p->p_stat = SSLEEP; p->p_stats->p_ru.ru_nvcsw++; SCHED_ASSERT_LOCKED(); - mi_switch(s); + mi_switch(); #ifdef DDB /* handy breakpoint location after process "wakes" */ __asm(".globl bpendtsleep\nbpendtsleep:"); #endif + SCHED_ASSERT_UNLOCKED(); + /* + * Note! this splx belongs to the SCHED_LOCK(s) above, mi_switch + * releases the scheduler lock, but does not lower the spl. + */ + splx(s); + resume: #ifdef __HAVE_CPUINFO p->p_cpu->ci_schedstate.spc_curpriority = p->p_usrpri; @@ -269,13 +270,20 @@ endtsleep(arg) * Remove a process from its wait queue */ void -unsleep(struct proc *p) +unsleep(p) + register struct proc *p; { - struct slpque *qp; - struct proc **hp; - - SCHED_ASSERT_LOCKED(); + register struct slpque *qp; + register struct proc **hp; +#if 0 + int s; + /* + * XXX we cannot do recursive SCHED_LOCKing yet. All callers lock + * anyhow. + */ + SCHED_LOCK(s); +#endif if (p->p_wchan) { hp = &(qp = &slpque[LOOKUP(p->p_wchan)])->sq_head; while (*hp != p) @@ -285,39 +293,24 @@ unsleep(struct proc *p) qp->sq_tailp = hp; p->p_wchan = 0; } -} - -void -wakeup(void *ident) -{ - int s; - - SCHED_LOCK(s); - sched_wakeup(ident); - SCHED_UNLOCK(s); -} - -void -wakeup_n(void *ident, int n) -{ - int s; - - SCHED_LOCK(s); - sched_wakeup_n(ident, n); +#if 0 SCHED_UNLOCK(s); +#endif } /* * Make all processes sleeping on the specified identifier runnable. */ void -sched_wakeup_n(void *ident, int n) +wakeup_n(ident, n) + void *ident; + int n; { struct slpque *qp; struct proc *p, **q; + int s; - SCHED_ASSERT_LOCKED(); - + SCHED_LOCK(s); qp = &slpque[LOOKUP(ident)]; restart: for (q = &qp->sq_head; (p = *q) != NULL; ) { @@ -356,7 +349,7 @@ restart: need_resched(0); #endif } else { - sched_wakeup((caddr_t)&proc0); + wakeup((caddr_t)&proc0); } /* END INLINE EXPANSION */ @@ -368,4 +361,12 @@ restart: } else q = &p->p_forw; } + SCHED_UNLOCK(s); +} + +void +wakeup(chan) + void *chan; +{ + wakeup_n(chan, -1); } diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index d5e29b55362..237b20a2f09 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.46 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: kern_time.c,v 1.47 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -560,12 +560,8 @@ sys_setitimer(p, v, retval) } p->p_realtimer = aitv; } else { - int s; - itimerround(&aitv.it_interval); - s = splclock(); p->p_stats->p_timer[SCARG(uap, which)] = aitv; - splx(s); } return (0); diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c index 3bfe54b9bcd..854ff074573 100644 --- a/sys/kern/sched_bsd.c +++ b/sys/kern/sched_bsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sched_bsd.c,v 1.3 2005/05/26 18:10:40 art Exp $ */ +/* $OpenBSD: sched_bsd.c,v 1.4 2005/05/29 03:20:41 deraadt Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -65,9 +65,7 @@ int rrticks_init; /* # of hardclock ticks per roundrobin() */ int whichqs; /* Bit mask summary of non-empty Q's. */ struct prochd qs[NQS]; -#ifdef MULTIPROCESSOR -struct mutex sched_mutex = MUTEX_INITIALIZER(IPL_SCHED); -#endif +struct SIMPLELOCK sched_lock; void scheduler_start(void); @@ -262,7 +260,7 @@ schedcpu(arg) struct timeout *to = (struct timeout *)arg; fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); struct proc *p; - int s, t; + int s; unsigned int newcpu; int phz; @@ -276,7 +274,6 @@ schedcpu(arg) KASSERT(phz); for (p = LIST_FIRST(&allproc); p != 0; p = LIST_NEXT(p, p_list)) { - SCHED_LOCK(s); /* * Increment time in/out of memory and sleep time * (if sleeping). We ignore overflow; with 16-bit int's @@ -290,11 +287,9 @@ schedcpu(arg) * If the process has slept the entire second, * stop recalculating its priority until it wakes up. */ - if (p->p_slptime > 1) { - SCHED_UNLOCK(s); + if (p->p_slptime > 1) continue; - } - t = splstatclock(); + s = splstatclock(); /* prevent state changes */ /* * p_pctcpu is only for ps. */ @@ -310,7 +305,8 @@ schedcpu(arg) p->p_cpticks = 0; newcpu = (u_int) decay_cpu(loadfac, p->p_estcpu); p->p_estcpu = newcpu; - splx(t); + splx(s); + SCHED_LOCK(s); resetpriority(p); if (p->p_priority >= PUSER) { if ((p != curproc) && @@ -359,13 +355,13 @@ updatepri(p) void sched_unlock_idle(void) { - mtx_leave(&sched_mutex); + SIMPLE_UNLOCK(&sched_lock); } void sched_lock_idle(void) { - mtx_enter(&sched_mutex); + SIMPLE_LOCK(&sched_lock); } #endif /* MULTIPROCESSOR || LOCKDEBUG */ @@ -384,7 +380,9 @@ yield() p->p_stat = SRUN; setrunqueue(p); p->p_stats->p_ru.ru_nvcsw++; - mi_switch(s); + mi_switch(); + SCHED_ASSERT_UNLOCKED(); + splx(s); } /* @@ -411,17 +409,19 @@ preempt(newp) p->p_stat = SRUN; setrunqueue(p); p->p_stats->p_ru.ru_nivcsw++; - mi_switch(s); + mi_switch(); + SCHED_ASSERT_UNLOCKED(); + splx(s); } /* - * Must be called at splsched() or higher. + * Must be called at splstatclock() or higher. */ void -mi_switch(int s) +mi_switch() { - struct proc *p = curproc; + struct proc *p = curproc; /* XXX */ struct rlimit *rlim; struct timeval tv; #if defined(MULTIPROCESSOR) @@ -433,6 +433,20 @@ mi_switch(int s) SCHED_ASSERT_LOCKED(); +#if defined(MULTIPROCESSOR) + /* + * Release the kernel_lock, as we are about to yield the CPU. + * The scheduler lock is still held until cpu_switch() + * selects a new process and removes it from the run queue. + */ + if (p->p_flag & P_BIGLOCK) +#ifdef notyet + hold_count = spinlock_release_all(&kernel_lock); +#else + hold_count = __mp_release_all(&kernel_lock); +#endif +#endif + /* * Compute the amount of time during which the current * process was running, and add that to its total so far. @@ -470,7 +484,6 @@ mi_switch(int s) */ rlim = &p->p_rlimit[RLIMIT_CPU]; if ((rlim_t)p->p_rtime.tv_sec >= rlim->rlim_cur) { - SCHED_UNLOCK(s); if ((rlim_t)p->p_rtime.tv_sec >= rlim->rlim_max) { psignal(p, SIGKILL); } else { @@ -478,23 +491,8 @@ mi_switch(int s) if (rlim->rlim_cur < rlim->rlim_max) rlim->rlim_cur += 5; } - SCHED_LOCK(s); } -#if defined(MULTIPROCESSOR) - /* - * Release the kernel_lock, as we are about to yield the CPU. - * The scheduler lock is still held until cpu_switch() - * selects a new process and removes it from the run queue. - */ - if (p->p_flag & P_BIGLOCK) -#ifdef notyet - hold_count = spinlock_release_all(&kernel_lock); -#else - hold_count = __mp_release_all(&kernel_lock); -#endif -#endif - /* * Process is about to yield the CPU; clear the appropriate * scheduling flags. @@ -537,9 +535,12 @@ mi_switch(int s) * we reacquire the interlock. */ if (p->p_flag & P_BIGLOCK) +#ifdef notyet + spinlock_acquire_count(&kernel_lock, hold_count); +#else __mp_acquire_count(&kernel_lock, hold_count); #endif - splx(s); +#endif } /* @@ -553,6 +554,7 @@ rqinit() for (i = 0; i < NQS; i++) qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i]; + SIMPLE_LOCK_INIT(&sched_lock); } static __inline void @@ -600,7 +602,8 @@ resched_proc(struct proc *p, u_char pri) * and awakening the swapper if it isn't in memory. */ void -setrunnable(struct proc *p) +setrunnable(p) + register struct proc *p; { SCHED_ASSERT_LOCKED(); @@ -632,7 +635,7 @@ setrunnable(struct proc *p) updatepri(p); p->p_slptime = 0; if ((p->p_flag & P_INMEM) == 0) - sched_wakeup((caddr_t)&proc0); + wakeup((caddr_t)&proc0); else resched_proc(p, p->p_priority); } @@ -677,10 +680,10 @@ schedclock(p) { int s; - SCHED_LOCK(s); p->p_estcpu = ESTCPULIM(p->p_estcpu + 1); + SCHED_LOCK(s); resetpriority(p); + SCHED_UNLOCK(s); if (p->p_priority >= PUSER) p->p_priority = p->p_usrpri; - SCHED_UNLOCK(s); } diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c index 549962182f6..4d74da6a3b2 100644 --- a/sys/kern/vfs_sync.c +++ b/sys/kern/vfs_sync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_sync.c,v 1.30 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: vfs_sync.c,v 1.31 2005/05/29 03:20:42 deraadt Exp $ */ /* * Portions of this code are: @@ -50,7 +50,6 @@ #include <sys/malloc.h> #include <sys/kernel.h> -#include <sys/sched.h> #ifdef FFS_SOFTUPDATES int softdep_process_worklist(struct mount *); @@ -245,10 +244,10 @@ speedup_syncer() { int s; - SCHED_LOCK(s); + s = splhigh(); if (syncerproc && syncerproc->p_wchan == &lbolt) setrunnable(syncerproc); - SCHED_UNLOCK(s); + splx(s); if (rushjob < syncdelay / 2) { rushjob += 1; stat_rush_requests += 1; diff --git a/sys/miscfs/procfs/procfs_ctl.c b/sys/miscfs/procfs/procfs_ctl.c index 7a1c92b0bb3..7f7be3b522b 100644 --- a/sys/miscfs/procfs/procfs_ctl.c +++ b/sys/miscfs/procfs/procfs_ctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_ctl.c,v 1.14 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: procfs_ctl.c,v 1.15 2005/05/29 03:20:35 deraadt Exp $ */ /* $NetBSD: procfs_ctl.c,v 1.14 1996/02/09 22:40:48 christos Exp $ */ /* @@ -48,7 +48,6 @@ #include <sys/resourcevar.h> #include <sys/signalvar.h> #include <sys/ptrace.h> -#include <sys/sched.h> #include <miscfs/procfs/procfs.h> /* @@ -111,7 +110,6 @@ procfs_control(curp, p, op) int op; { int error; - int s; /* * Attach - attaches the target process for debugging @@ -250,10 +248,8 @@ procfs_control(curp, p, op) #endif } - SCHED_LOCK(s); if (p->p_stat == SSTOP) setrunnable(p); - SCHED_UNLOCK(s); return (0); } #endif @@ -269,7 +265,6 @@ procfs_doctl(curp, p, pfs, uio) int error; char msg[PROCFS_CTLLEN+1]; const vfs_namemap_t *nm; - int s; if (uio->uio_rw != UIO_WRITE) return (EOPNOTSUPP); @@ -302,9 +297,7 @@ procfs_doctl(curp, p, pfs, uio) if (TRACE_WAIT_P(curp, p)) { p->p_xstat = nm->nm_val; FIX_SSTEP(p); - SCHED_LOCK(s); setrunnable(p); - SCHED_UNLOCK(s); } else { psignal(p, nm->nm_val); } diff --git a/sys/sys/lock.h b/sys/sys/lock.h index 31c1614ed0e..09bbe8573b9 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lock.h,v 1.13 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: lock.h,v 1.14 2005/05/29 03:20:42 deraadt Exp $ */ /* * Copyright (c) 1995 @@ -239,4 +239,37 @@ void spinlock_acquire_count(__volatile struct lock *, int); #define LOCK_ASSERT(x) /* nothing */ #endif +#if defined(MULTIPROCESSOR) +/* + * XXX Instead of using struct lock for the kernel lock and thus requiring us + * XXX to implement simplelocks, causing all sorts of fine-grained locks all + * XXX over our tree getting activated consuming both time and potentially + * XXX introducing locking protocol bugs. + */ +#ifdef notyet + +extern struct lock kernel_lock; + +/* + * XXX Simplelock macros used at "trusted" places. + */ +#define SIMPLELOCK simplelock +#define SIMPLE_LOCK_INIT simple_lock_init +#define SIMPLE_LOCK simple_lock +#define SIMPLE_UNLOCK simple_unlock + +#endif + +#else + +/* + * XXX Simplelock macros used at "trusted" places. + */ +#define SIMPLELOCK simplelock +#define SIMPLE_LOCK_INIT simple_lock_init +#define SIMPLE_LOCK simple_lock +#define SIMPLE_UNLOCK simple_unlock + +#endif + #endif /* !_LOCK_H_ */ diff --git a/sys/sys/mplock.h b/sys/sys/mplock.h index cd816a8fc2d..3d17ede906a 100644 --- a/sys/sys/mplock.h +++ b/sys/sys/mplock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mplock.h,v 1.6 2005/05/27 20:46:59 niklas Exp $ */ +/* $OpenBSD: mplock.h,v 1.7 2005/05/29 03:20:42 deraadt Exp $ */ /* * Copyright (c) 2004 Niklas Hallqvist. All rights reserved. @@ -45,6 +45,14 @@ static __inline int __mp_release_all(struct __mp_lock *); static __inline void __mp_acquire_count(struct __mp_lock *, int); static __inline int __mp_lock_held(struct __mp_lock *); +/* + * XXX Simplelocks macros used at "trusted" places. + */ +#define SIMPLELOCK __mp_lock +#define SIMPLE_LOCK_INIT __mp_lock_init +#define SIMPLE_LOCK __mp_lock +#define SIMPLE_UNLOCK __mp_unlock + static __inline void __mp_lock_init(struct __mp_lock *lock) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index e22d922e262..2d804b9c84f 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.78 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: proc.h,v 1.79 2005/05/29 03:20:42 deraadt Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -408,7 +408,7 @@ int inferior(struct proc *p); int leavepgrp(struct proc *p); void yield(void); void preempt(struct proc *); -void mi_switch(int); +void mi_switch(void); void pgdelete(struct pgrp *pgrp); void procinit(void); #if !defined(remrunqueue) @@ -424,8 +424,6 @@ int ltsleep(void *chan, int pri, const char *wmesg, int timo, volatile struct simplelock *); #define tsleep(chan, pri, wmesg, timo) ltsleep(chan, pri, wmesg, timo, NULL) void unsleep(struct proc *); -void sched_wakeup_n(void *, int); -#define sched_wakeup(c) sched_wakeup_n((c), -1) void wakeup_n(void *chan, int); void wakeup(void *chan); #define wakeup_one(c) wakeup_n((c), 1) diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 6bac76e9e33..7be5d0161ab 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.11 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: sched.h,v 1.12 2005/05/29 03:20:42 deraadt Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -145,31 +145,59 @@ void roundrobin(struct cpu_info *); #define IPL_SCHED IPL_HIGH #endif -#if defined(MULTIPROCESSOR) -#include <sys/mutex.h> - -extern struct mutex sched_mutex; - -#define SCHED_ASSERT_LOCKED() MUTEX_ASSERT_LOCKED(&sched_mutex) -#define SCHED_ASSERT_UNLOCKED() MUTEX_ASSERT_UNLOCKED(&sched_mutex) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +#include <sys/lock.h> /* - * We need this MUTEX_OLDIPL hack to be able to properly restore the old - * ipl after all the ipl juggling in cpu_switch. + * XXX Instead of using struct lock for the kernel lock and thus requiring us + * XXX to implement simplelocks, causing all sorts of fine-grained locks all + * XXX over our tree getting activated consuming both time and potentially + * XXX introducing locking protocol bugs. */ -#define SCHED_LOCK(s) do { \ - mtx_enter(&sched_mutex); \ - s = MUTEX_OLDIPL(&sched_mutex); \ -} while (0) +#ifdef notyet -#define SCHED_UNLOCK(s) do { \ - mtx_leave(&sched_mutex); \ -} while (0) +extern struct simplelock sched_lock; + +#define SCHED_ASSERT_LOCKED() LOCK_ASSERT(simple_lock_held(&sched_lock)) +#define SCHED_ASSERT_UNLOCKED() LOCK_ASSERT(simple_lock_held(&sched_lock) == 0) + +#define SCHED_LOCK(s) \ +do { \ + s = splsched(); \ + simple_lock(&sched_lock); \ +} while (/* CONSTCOND */ 0) + +#define SCHED_UNLOCK(s) \ +do { \ + simple_unlock(&sched_lock); \ + splx(s); \ +} while (/* CONSTCOND */ 0) + +#else + +extern struct __mp_lock sched_lock; + +#define SCHED_ASSERT_LOCKED() LOCK_ASSERT(__mp_lock_held(&sched_lock)) +#define SCHED_ASSERT_UNLOCKED() LOCK_ASSERT(__mp_lock_held(&sched_lock) == 0) + +#define SCHED_LOCK(s) \ +do { \ + s = splsched(); \ + __mp_lock(&sched_lock); \ +} while (/* CONSTCOND */ 0) + +#define SCHED_UNLOCK(s) \ +do { \ + __mp_unlock(&sched_lock); \ + splx(s); \ +} while (/* CONSTCOND */ 0) + +#endif void sched_lock_idle(void); void sched_unlock_idle(void); -#else /* ! MULTIPROCESSOR */ +#else /* ! MULTIPROCESSOR || LOCKDEBUG */ #define SCHED_ASSERT_LOCKED() splassert(IPL_SCHED); #define SCHED_ASSERT_UNLOCKED() /* nothing */ @@ -177,7 +205,7 @@ void sched_unlock_idle(void); #define SCHED_LOCK(s) s = splsched() #define SCHED_UNLOCK(s) splx(s) -#endif /* MULTIPROCESSOR */ +#endif /* MULTIPROCESSOR || LOCKDEBUG */ #endif /* _KERNEL */ #endif /* _SYS_SCHED_H_ */ diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 27bcd0b10c7..fbc8a7286fe 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signalvar.h,v 1.13 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: signalvar.h,v 1.14 2005/05/29 03:20:43 deraadt Exp $ */ /* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */ /* @@ -159,7 +159,9 @@ void csignal(pid_t pgid, int signum, uid_t uid, uid_t euid); int issignal(struct proc *p); void pgsignal(struct pgrp *pgrp, int sig, int checkctty); void postsig(int sig); -void psignal(struct proc *p, int sig); +void psignal1(struct proc *p, int sig, int dolock); +#define psignal(p, sig) psignal1((p), (sig), 1) +#define sched_psignal(p, sig) psignal1((p), (sig), 0) void siginit(struct proc *p); void trapsignal(struct proc *p, int sig, u_long code, int type, union sigval val); diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c index c2e331eb087..6c4f00e6e71 100644 --- a/sys/uvm/uvm_glue.c +++ b/sys/uvm/uvm_glue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_glue.c,v 1.40 2005/05/25 23:17:47 niklas Exp $ */ +/* $OpenBSD: uvm_glue.c,v 1.41 2005/05/29 03:20:43 deraadt Exp $ */ /* $NetBSD: uvm_glue.c,v 1.44 2001/02/06 19:54:44 eeh Exp $ */ /* @@ -80,7 +80,6 @@ #ifdef SYSVSHM #include <sys/shm.h> #endif -#include <sys/sched.h> #include <uvm/uvm.h> @@ -381,13 +380,13 @@ uvm_swapin(p) * moved to new physical page(s) (e.g. see mips/mips/vm_machdep.c). */ cpu_swapin(p); - SCHED_LOCK(s); + s = splstatclock(); if (p->p_stat == SRUN) setrunqueue(p); p->p_flag |= P_INMEM; p->p_flag &= ~P_SWAPIN; + splx(s); p->p_swtime = 0; - SCHED_UNLOCK(s); ++uvmexp.swapins; } @@ -578,16 +577,16 @@ uvm_swapout(p) /* * Mark it as (potentially) swapped out. */ - SCHED_LOCK(s); + s = splstatclock(); if (!(p->p_flag & P_INMEM)) { - SCHED_UNLOCK(s); + splx(s); return; } p->p_flag &= ~P_INMEM; if (p->p_stat == SRUN) remrunqueue(p); + splx(s); p->p_swtime = 0; - SCHED_UNLOCK(s); ++uvmexp.swapouts; /* |