Index: kern/kern_switch.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_switch.c,v retrieving revision 1.97 diff -u -r1.97 kern_switch.c --- kern/kern_switch.c 5 Oct 2004 22:03:10 -0000 1.97 +++ kern/kern_switch.c 12 Oct 2004 14:14:59 -0000 @@ -449,6 +449,10 @@ KASSERT(td->td_critnest != 0, ("critical_exit: td_critnest == 0")); if (td->td_critnest == 1) { + if (PCPU_GET(wakeproc0)) { + PCPU_SET(wakeproc0, 0); + wakeup(&proc0); + } #ifdef PREEMPTION mtx_assert(&sched_lock, MA_NOTOWNED); if (td->td_pflags & TDP_OWEPREEMPT) { Index: kern/kern_synch.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v retrieving revision 1.262 diff -u -r1.262 kern_synch.c --- kern/kern_synch.c 5 Oct 2004 18:51:11 -0000 1.262 +++ kern/kern_synch.c 12 Oct 2004 14:14:59 -0000 @@ -390,13 +390,12 @@ if ((p->p_sflag & PS_INMEM) == 0) { if ((p->p_sflag & PS_SWAPPINGIN) == 0) { p->p_sflag |= PS_SWAPINREQ; -#ifndef SMP /* - * XXX: Disabled on SMP due to a LOR between - * sched_lock and the sleepqueue chain locks. + * Schedule a wakeup of the swapper when the + * CPU leaves its current critical section so + * that 'td' can be swapped on as soon as possible. */ - wakeup(&proc0); -#endif + PCPU_SET(wakeproc0, 1); } } else sched_wakeup(td); Index: sys/pcpu.h =================================================================== RCS file: /home/ncvs/src/sys/sys/pcpu.h,v retrieving revision 1.13 diff -u -r1.13 pcpu.h --- sys/pcpu.h 27 Mar 2004 18:21:24 -0000 1.13 +++ sys/pcpu.h 12 Oct 2004 14:15:04 -0000 @@ -65,6 +65,7 @@ u_int pc_cpuid; /* This cpu number */ cpumask_t pc_cpumask; /* This cpu mask */ cpumask_t pc_other_cpus; /* Mask of all other cpus */ + int pc_wakeproc0; SLIST_ENTRY(pcpu) pc_allcpu; struct lock_list_entry *pc_spinlocks; #ifdef KTR_PERCPU