Index: amd64/amd64/cpu_switch.S =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/amd64/cpu_switch.S,v retrieving revision 1.158 diff -u -p -r1.158 cpu_switch.S --- amd64/amd64/cpu_switch.S 6 Jun 2007 07:35:07 -0000 1.158 +++ amd64/amd64/cpu_switch.S 7 Jun 2007 03:06:05 -0000 @@ -69,6 +69,9 @@ ENTRY(cpu_throw) movq TD_PROC(%rdi), %rdx /* oldtd->td_proc */ movq P_VMSPACE(%rdx), %rdx /* proc->p_vmspace */ LK btrl %eax, VM_PMAP+PM_ACTIVE(%rdx) /* clear old */ + movq TD_LOCK(%rdi), %rdx + movq $MTX_UNOWNED, %rdi + xchgq %rdi, MTX_LOCK(%rdx) /* Release lock */ 1: movq TD_PCB(%rsi),%rdx /* newtd->td_proc */ movq PCB_CR3(%rdx),%rdx Index: amd64/amd64/genassym.c =================================================================== RCS file: /usr/home/ncvs/src/sys/amd64/amd64/genassym.c,v retrieving revision 1.163 diff -u -p -r1.163 genassym.c --- amd64/amd64/genassym.c 6 Jun 2007 07:35:07 -0000 1.163 +++ amd64/amd64/genassym.c 7 Jun 2007 03:06:05 -0000 @@ -210,6 +210,7 @@ ASSYM(KUDSEL, GSEL(GUDATA_SEL, SEL_UPL)) ASSYM(KUC32SEL, GSEL(GUCODE32_SEL, SEL_UPL)); ASSYM(SEL_RPL_MASK, SEL_RPL_MASK); +ASSYM(MTX_UNOWNED, MTX_UNOWNED); ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); Index: conf/NOTES =================================================================== RCS file: /usr/home/ncvs/src/sys/conf/NOTES,v retrieving revision 1.1428 diff -u -p -r1.1428 NOTES --- conf/NOTES 5 Jun 2007 00:12:36 -0000 1.1428 +++ conf/NOTES 7 Jun 2007 03:06:05 -0000 @@ -186,6 +186,7 @@ options ROOTDEVNAME=\"ufs:da0s2e\" # options SCHED_4BSD #options SCHED_ULE +#options SCHED_SMP ##################################################################### # SMP OPTIONS: Index: conf/files =================================================================== RCS file: /usr/home/ncvs/src/sys/conf/files,v retrieving revision 1.1214 diff -u -p -r1.1214 files --- conf/files 5 Jun 2007 00:12:36 -0000 1.1214 +++ conf/files 7 Jun 2007 03:06:05 -0000 @@ -1428,6 +1428,7 @@ kern/md5c.c standard kern/p1003_1b.c standard kern/posix4_mib.c standard kern/sched_4bsd.c optional sched_4bsd +kern/sched_smp.c optional sched_smp kern/sched_ule.c optional sched_ule kern/serdev_if.m standard kern/subr_acl_posix1e.c standard Index: conf/options =================================================================== RCS file: /usr/home/ncvs/src/sys/conf/options,v retrieving revision 1.590 diff -u -p -r1.590 options --- conf/options 5 Jun 2007 00:12:36 -0000 1.590 +++ conf/options 7 Jun 2007 03:06:05 -0000 @@ -135,6 +135,7 @@ PPS_SYNC opt_ntp.h PREEMPTION opt_sched.h QUOTA SCHED_4BSD opt_sched.h +SCHED_SMP opt_sched.h SCHED_ULE opt_sched.h SHOW_BUSYBUFS SLEEPQUEUE_PROFILING Index: kern/kern_synch.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/kern_synch.c,v retrieving revision 1.300 diff -u -p -r1.300 kern_synch.c --- kern/kern_synch.c 4 Jun 2007 23:50:56 -0000 1.300 +++ kern/kern_synch.c 7 Jun 2007 03:06:05 -0000 @@ -414,8 +414,6 @@ mi_switch(int flags, struct thread *newt td->td_generation++; /* bump preempt-detect counter */ PCPU_INC(cnt.v_swtch); PCPU_SET(switchticks, ticks); - CTR4(KTR_PROC, "mi_switch: old thread %ld (kse %p, pid %ld, %s)", - td->td_tid, td->td_sched, p->p_pid, p->p_comm); #if (KTR_COMPILE & KTR_SCHED) != 0 if (TD_IS_IDLETHREAD(td)) CTR3(KTR_SCHED, "mi_switch: %p(%s) prio %d idle", @@ -443,9 +441,6 @@ mi_switch(int flags, struct thread *newt CTR3(KTR_SCHED, "mi_switch: running %p(%s) prio %d", td, td->td_proc->p_comm, td->td_priority); - CTR4(KTR_PROC, "mi_switch: new thread %ld (kse %p, pid %ld, %s)", - td->td_tid, td->td_sched, p->p_pid, p->p_comm); - /* * If the last thread was exiting, finish cleaning it up. */ Index: kern/kern_thread.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.247 diff -u -p -r1.247 kern_thread.c --- kern/kern_thread.c 4 Jun 2007 23:52:24 -0000 1.247 +++ kern/kern_thread.c 7 Jun 2007 03:06:05 -0000 @@ -348,6 +348,7 @@ thread_exit(void) struct thread *td; struct thread *td2; struct proc *p; + struct mtx *m; td = curthread; p = td->td_proc; @@ -464,7 +465,12 @@ thread_exit(void) thread_lock(td); /* Aggregate our tick statistics into our parents rux. */ ruxagg(&p->p_rux, td); - PROC_SUNLOCK(p); + m = &p->p_slock; + thread_lock_set(td, m); + KASSERT(m->mtx_recurse == 0, ("thread_exit: proc slock recursed")); + WITNESS_UNLOCK(&m->lock_object, LOP_EXCLUSIVE, __FILE__, __LINE__); + LOCK_LOG_LOCK("UNLOCK", &m->lock_object, 0, m->mtx_recurse, + __FILE__, __LINE__); td->td_state = TDS_INACTIVE; CTR1(KTR_PROC, "thread_exit: cpu_throw() thread %p", td); sched_throw(td); Index: kern/sched_4bsd.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/sched_4bsd.c,v retrieving revision 1.101 diff -u -p -r1.101 sched_4bsd.c --- kern/sched_4bsd.c 6 Jun 2007 03:40:46 -0000 1.101 +++ kern/sched_4bsd.c 7 Jun 2007 03:06:05 -0000 @@ -1387,22 +1387,20 @@ sched_idletd(void *dummy) void sched_throw(struct thread *td) { + + mtx_lock_spin(&sched_lock); /* - * Correct spinlock nesting. The idle thread context that we are - * borrowing was created so that it would start out with a single - * spin lock (sched_lock) held in fork_trampoline(). Since we've - * explicitly acquired locks in this function, the nesting count - * is now 2 rather than 1. Since we are nested, calling - * spinlock_exit() will simply adjust the counts without allowing - * spin lock using code to interrupt us. + * Correct spinlock nesting. Two cases: + * 1) The idle thread context that we are borrowing was created so that it would + * start out with a single spin lock held in fork_trampoline(). + * 2) The exiting thread holds the per-process spinlock and this is pointed at + * by td_lock. + * + * Since we've explicitly acquired locks in this function, the nesting count + * is now 2 rather than 1. Since we are nested, calling spinlock_exit() will + * simply adjust the counts without allowing interrupts. */ - if (td == NULL) { - mtx_lock_spin(&sched_lock); - spinlock_exit(); - } else { - MPASS(td->td_lock == &sched_lock); - } - mtx_assert(&sched_lock, MA_OWNED); + spinlock_exit(); KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); PCPU_SET(switchtime, cpu_ticks()); PCPU_SET(switchticks, ticks); Index: kern/sched_ule.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/sched_ule.c,v retrieving revision 1.197 diff -u -p -r1.197 sched_ule.c --- kern/sched_ule.c 6 Jun 2007 03:40:46 -0000 1.197 +++ kern/sched_ule.c 7 Jun 2007 03:06:05 -0000 @@ -2122,22 +2122,20 @@ sched_idletd(void *dummy) void sched_throw(struct thread *td) { + + mtx_lock_spin(&sched_lock); /* - * Correct spinlock nesting. The idle thread context that we are - * borrowing was created so that it would start out with a single - * spin lock (sched_lock) held in fork_trampoline(). Since we've - * explicitly acquired locks in this function, the nesting count - * is now 2 rather than 1. Since we are nested, calling - * spinlock_exit() will simply adjust the counts without allowing - * spin lock using code to interrupt us. + * Correct spinlock nesting. Two cases: + * 1) The idle thread context that we are borrowing was created so that it would + * start out with a single spin lock held in fork_trampoline(). + * 2) The exiting thread holds the per-process spinlock and this is pointed at + * by td_lock. + * + * Since we've explicitly acquired locks in this function, the nesting count + * is now 2 rather than 1. Since we are nested, calling spinlock_exit() will + * simply adjust the counts without allowing interrupts. */ - if (td == NULL) { - mtx_lock_spin(&sched_lock); - spinlock_exit(); - } else { - MPASS(td->td_lock == &sched_lock); - } - mtx_assert(&sched_lock, MA_OWNED); + spinlock_exit(); KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); PCPU_SET(switchtime, cpu_ticks()); PCPU_SET(switchticks, ticks);