svn commit: r235502 - in stable/8/sys: cddl/contrib/opensolaris/uts/common/dtrace dev/usb geom i386/conf kern security/mac sys

Andriy Gapon avg at FreeBSD.org
Wed May 16 09:03:31 UTC 2012


Author: avg
Date: Wed May 16 09:03:29 2012
New Revision: 235502
URL: http://svn.freebsd.org/changeset/base/235502

Log:
  MFC r228424,228448,230643: panic: add a switch and infrastructure for
  stopping other CPUs in SMP case

Modified:
  stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  stable/8/sys/dev/usb/usb_transfer.c
  stable/8/sys/geom/geom_bsd.c
  stable/8/sys/geom/geom_mbr.c
  stable/8/sys/geom/geom_pc98.c
  stable/8/sys/kern/kern_lock.c
  stable/8/sys/kern/kern_mutex.c
  stable/8/sys/kern/kern_rmlock.c
  stable/8/sys/kern/kern_rwlock.c
  stable/8/sys/kern/kern_shutdown.c
  stable/8/sys/kern/kern_sx.c
  stable/8/sys/kern/kern_synch.c
  stable/8/sys/kern/subr_kdb.c
  stable/8/sys/kern/subr_lock.c
  stable/8/sys/kern/subr_witness.c
  stable/8/sys/security/mac/mac_priv.c
  stable/8/sys/sys/mutex.h
  stable/8/sys/sys/proc.h
  stable/8/sys/sys/systm.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/sys/i386/conf/XENHVM   (props changed)

Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Wed May 16 09:03:29 2012	(r235502)
@@ -5877,6 +5877,9 @@ dtrace_probe(dtrace_id_t id, uintptr_t a
 	volatile uint16_t *flags;
 	hrtime_t now;
 
+	if (panicstr != NULL)
+		return;
+
 #if defined(sun)
 	/*
 	 * Kick out immediately if this CPU is still being born (in which case

Modified: stable/8/sys/dev/usb/usb_transfer.c
==============================================================================
--- stable/8/sys/dev/usb/usb_transfer.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/dev/usb/usb_transfer.c	Wed May 16 09:03:29 2012	(r235502)
@@ -42,6 +42,7 @@
 #include <sys/callout.h>
 #include <sys/malloc.h>
 #include <sys/priv.h>
+#include <sys/proc.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>

Modified: stable/8/sys/geom/geom_bsd.c
==============================================================================
--- stable/8/sys/geom/geom_bsd.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/geom/geom_bsd.c	Wed May 16 09:03:29 2012	(r235502)
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/errno.h>
 #include <sys/disklabel.h>
 #include <sys/gpt.h>
+#include <sys/proc.h>
 #include <sys/uuid.h>
 #include <geom/geom.h>
 #include <geom/geom_slice.h>

Modified: stable/8/sys/geom/geom_mbr.c
==============================================================================
--- stable/8/sys/geom/geom_mbr.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/geom/geom_mbr.c	Wed May 16 09:03:29 2012	(r235502)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/md5.h>
+#include <sys/proc.h>
 
 #include <sys/diskmbr.h>
 #include <sys/sbuf.h>

Modified: stable/8/sys/geom/geom_pc98.c
==============================================================================
--- stable/8/sys/geom/geom_pc98.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/geom/geom_pc98.c	Wed May 16 09:03:29 2012	(r235502)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bio.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 
 #include <sys/diskpc98.h>
 #include <geom/geom.h>

Modified: stable/8/sys/kern/kern_lock.c
==============================================================================
--- stable/8/sys/kern/kern_lock.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_lock.c	Wed May 16 09:03:29 2012	(r235502)
@@ -1207,6 +1207,9 @@ _lockmgr_disown(struct lock *lk, const c
 {
 	uintptr_t tid, x;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	tid = (uintptr_t)curthread;
 	_lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED, file, line);
 

Modified: stable/8/sys/kern/kern_mutex.c
==============================================================================
--- stable/8/sys/kern/kern_mutex.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_mutex.c	Wed May 16 09:03:29 2012	(r235502)
@@ -191,6 +191,8 @@ void
 _mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(m->mtx_lock != MTX_DESTROYED,
 	    ("mtx_lock() of destroyed mutex @ %s:%d", file, line));
@@ -210,6 +212,9 @@ _mtx_lock_flags(struct mtx *m, int opts,
 void
 _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
 {
+
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(m->mtx_lock != MTX_DESTROYED,
 	    ("mtx_unlock() of destroyed mutex @ %s:%d", file, line));
@@ -231,6 +236,8 @@ void
 _mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(m->mtx_lock != MTX_DESTROYED,
 	    ("mtx_lock_spin() of destroyed mutex @ %s:%d", file, line));
@@ -253,6 +260,8 @@ void
 _mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(m->mtx_lock != MTX_DESTROYED,
 	    ("mtx_unlock_spin() of destroyed mutex @ %s:%d", file, line));
@@ -281,6 +290,9 @@ _mtx_trylock(struct mtx *m, int opts, co
 #endif
 	int rval;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	MPASS(curthread != NULL);
 	KASSERT(m->mtx_lock != MTX_DESTROYED,
 	    ("mtx_trylock() of destroyed mutex @ %s:%d", file, line));
@@ -337,6 +349,9 @@ _mtx_lock_sleep(struct mtx *m, uintptr_t
 	int64_t sleep_time = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	if (mtx_owned(m)) {
 		KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
 	    ("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
@@ -507,6 +522,9 @@ _mtx_lock_spin(struct mtx *m, uintptr_t 
 	uint64_t waittime = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	if (LOCK_LOG_TEST(&m->lock_object, opts))
 		CTR1(KTR_LOCK, "_mtx_lock_spin: %p spinning", m);
 
@@ -554,6 +572,10 @@ _thread_lock_flags(struct thread *td, in
 
 	i = 0;
 	tid = (uintptr_t)curthread;
+
+	if (SCHEDULER_STOPPED())
+		return;
+
 	for (;;) {
 retry:
 		spinlock_enter();
@@ -655,6 +677,9 @@ _mtx_unlock_sleep(struct mtx *m, int opt
 {
 	struct turnstile *ts;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	if (mtx_recursed(m)) {
 		if (--(m->mtx_recurse) == 0)
 			atomic_clear_ptr(&m->mtx_lock, MTX_RECURSED);

Modified: stable/8/sys/kern/kern_rmlock.c
==============================================================================
--- stable/8/sys/kern/kern_rmlock.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_rmlock.c	Wed May 16 09:03:29 2012	(r235502)
@@ -315,6 +315,9 @@ _rm_rlock(struct rmlock *rm, struct rm_p
 	struct thread *td = curthread;
 	struct pcpu *pc;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	tracker->rmp_flags  = 0;
 	tracker->rmp_thread = td;
 	tracker->rmp_rmlock = rm;
@@ -383,6 +386,9 @@ _rm_runlock(struct rmlock *rm, struct rm
 	struct pcpu *pc;
 	struct thread *td = tracker->rmp_thread;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	td->td_critnest++;	/* critical_enter(); */
 	pc = cpuid_to_pcpu[td->td_oncpu]; /* pcpu_find(td->td_oncpu); */
 	rm_tracker_remove(pc, tracker);
@@ -401,6 +407,9 @@ _rm_wlock(struct rmlock *rm)
 	struct rm_priotracker *prio;
 	struct turnstile *ts;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	mtx_lock(&rm->rm_lock);
 
 	if (rm->rm_noreadtoken == 0) {
@@ -447,6 +456,9 @@ _rm_wunlock(struct rmlock *rm)
 void _rm_wlock_debug(struct rmlock *rm, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	WITNESS_CHECKORDER(&rm->lock_object, LOP_NEWORDER | LOP_EXCLUSIVE,
 	    file, line, NULL);
 
@@ -464,6 +476,9 @@ void
 _rm_wunlock_debug(struct rmlock *rm, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	curthread->td_locks--;
 	WITNESS_UNLOCK(&rm->lock_object, LOP_EXCLUSIVE, file, line);
 	LOCK_LOG_LOCK("RMWUNLOCK", &rm->lock_object, 0, 0, file, line);
@@ -475,6 +490,9 @@ _rm_rlock_debug(struct rmlock *rm, struc
     const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	WITNESS_CHECKORDER(&rm->lock_object, LOP_NEWORDER, file, line, NULL);
 
 	_rm_rlock(rm, tracker);
@@ -491,6 +509,9 @@ _rm_runlock_debug(struct rmlock *rm, str
     const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	curthread->td_locks--;
 	WITNESS_UNLOCK(&rm->lock_object, 0, file, line);
 	LOCK_LOG_LOCK("RMRUNLOCK", &rm->lock_object, 0, 0, file, line);

Modified: stable/8/sys/kern/kern_rwlock.c
==============================================================================
--- stable/8/sys/kern/kern_rwlock.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_rwlock.c	Wed May 16 09:03:29 2012	(r235502)
@@ -229,6 +229,8 @@ void
 _rw_wlock(struct rwlock *rw, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_wlock() of destroyed rwlock @ %s:%d", file, line));
@@ -245,6 +247,9 @@ _rw_try_wlock(struct rwlock *rw, const c
 {
 	int rval;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_try_wlock() of destroyed rwlock @ %s:%d", file, line));
 
@@ -269,6 +274,8 @@ void
 _rw_wunlock(struct rwlock *rw, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_wunlock() of destroyed rwlock @ %s:%d", file, line));
@@ -313,6 +320,9 @@ _rw_rlock(struct rwlock *rw, const char 
 	int64_t sleep_time = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_rlock() of destroyed rwlock @ %s:%d", file, line));
 	KASSERT(rw_wowner(rw) != curthread,
@@ -495,6 +505,9 @@ _rw_try_rlock(struct rwlock *rw, const c
 {
 	uintptr_t x;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	for (;;) {
 		x = rw->rw_lock;
 		KASSERT(rw->rw_lock != RW_DESTROYED,
@@ -521,6 +534,9 @@ _rw_runlock(struct rwlock *rw, const cha
 	struct turnstile *ts;
 	uintptr_t x, v, queue;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_runlock() of destroyed rwlock @ %s:%d", file, line));
 	_rw_assert(rw, RA_RLOCKED, file, line);
@@ -646,6 +662,9 @@ _rw_wlock_hard(struct rwlock *rw, uintpt
 	int64_t sleep_time = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	if (rw_wlocked(rw)) {
 		KASSERT(rw->lock_object.lo_flags & LO_RECURSABLE,
 		    ("%s: recursing but non-recursive rw %s @ %s:%d\n",
@@ -810,6 +829,9 @@ _rw_wunlock_hard(struct rwlock *rw, uint
 	uintptr_t v;
 	int queue;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	if (rw_wlocked(rw) && rw_recursed(rw)) {
 		rw->rw_recurse--;
 		if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -872,6 +894,9 @@ _rw_try_upgrade(struct rwlock *rw, const
 	struct turnstile *ts;
 	int success;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_try_upgrade() of destroyed rwlock @ %s:%d", file, line));
 	_rw_assert(rw, RA_RLOCKED, file, line);
@@ -942,6 +967,9 @@ _rw_downgrade(struct rwlock *rw, const c
 	uintptr_t tid, v;
 	int rwait, wwait;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	KASSERT(rw->rw_lock != RW_DESTROYED,
 	    ("rw_downgrade() of destroyed rwlock @ %s:%d", file, line));
 	_rw_assert(rw, RA_WLOCKED | RA_NOTRECURSED, file, line);

Modified: stable/8/sys/kern/kern_shutdown.c
==============================================================================
--- stable/8/sys/kern/kern_shutdown.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_shutdown.c	Wed May 16 09:03:29 2012	(r235502)
@@ -121,6 +121,11 @@ SYSCTL_INT(_kern, OID_AUTO, sync_on_pani
 	&sync_on_panic, 0, "Do a sync before rebooting from a panic");
 TUNABLE_INT("kern.sync_on_panic", &sync_on_panic);
 
+static int stop_scheduler_on_panic = 0;
+SYSCTL_INT(_kern, OID_AUTO, stop_scheduler_on_panic, CTLFLAG_RW | CTLFLAG_TUN,
+    &stop_scheduler_on_panic, 0, "stop scheduler upon entering panic");
+TUNABLE_INT("kern.stop_scheduler_on_panic", &stop_scheduler_on_panic);
+
 SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW, 0, "Shutdown environment");
 
 #ifndef DIAGNOSTIC
@@ -292,10 +297,12 @@ boot(int howto)
 	 * systems don't shutdown properly (i.e., ACPI power off) if we
 	 * run on another processor.
 	 */
-	thread_lock(curthread);
-	sched_bind(curthread, 0);
-	thread_unlock(curthread);
-	KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0"));
+	if (!SCHEDULER_STOPPED()) {
+		thread_lock(curthread);
+		sched_bind(curthread, 0);
+		thread_unlock(curthread);
+		KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0"));
+	}
 #endif
 	/* We're in the process of rebooting. */
 	rebooting = 1;
@@ -551,7 +558,11 @@ panic(const char *fmt, ...)
 	va_list ap;
 	static char buf[256];
 
-	critical_enter();
+	if (stop_scheduler_on_panic)
+		spinlock_enter();
+	else
+		critical_enter();
+
 #ifdef SMP
 	/*
 	 * We don't want multiple CPU's to panic at the same time, so we
@@ -564,6 +575,19 @@ panic(const char *fmt, ...)
 		    PCPU_GET(cpuid)) == 0)
 			while (panic_cpu != NOCPU)
 				; /* nothing */
+
+	if (stop_scheduler_on_panic) {
+		if (panicstr == NULL && !kdb_active)
+			stop_cpus_hard(PCPU_GET(other_cpus));
+
+		/*
+		 * We set stop_scheduler here and not in the block above,
+		 * because we want to ensure that if panic has been called and
+		 * stop_scheduler_on_panic is true, then stop_scheduler will
+		 * always be set.  Even if panic has been entered from kdb.
+		 */
+		td->td_stopsched = 1;
+	}
 #endif
 
 	bootopt = RB_AUTOBOOT | RB_DUMP;
@@ -610,7 +634,8 @@ panic(const char *fmt, ...)
 	/* thread_unlock(td); */
 	if (!sync_on_panic)
 		bootopt |= RB_NOSYNC;
-	critical_exit();
+	if (!stop_scheduler_on_panic)
+		critical_exit();
 	boot(bootopt);
 }
 

Modified: stable/8/sys/kern/kern_sx.c
==============================================================================
--- stable/8/sys/kern/kern_sx.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_sx.c	Wed May 16 09:03:29 2012	(r235502)
@@ -238,6 +238,8 @@ _sx_slock(struct sx *sx, int opts, const
 {
 	int error = 0;
 
+	if (SCHEDULER_STOPPED())
+		return (0);
 	MPASS(curthread != NULL);
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_slock() of destroyed sx @ %s:%d", file, line));
@@ -257,6 +259,9 @@ _sx_try_slock(struct sx *sx, const char 
 {
 	uintptr_t x;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	for (;;) {
 		x = sx->sx_lock;
 		KASSERT(x != SX_LOCK_DESTROYED,
@@ -280,6 +285,8 @@ _sx_xlock(struct sx *sx, int opts, const
 {
 	int error = 0;
 
+	if (SCHEDULER_STOPPED())
+		return (0);
 	MPASS(curthread != NULL);
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_xlock() of destroyed sx @ %s:%d", file, line));
@@ -301,6 +308,9 @@ _sx_try_xlock(struct sx *sx, const char 
 {
 	int rval;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	MPASS(curthread != NULL);
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_try_xlock() of destroyed sx @ %s:%d", file, line));
@@ -327,6 +337,8 @@ void
 _sx_sunlock(struct sx *sx, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_sunlock() of destroyed sx @ %s:%d", file, line));
@@ -342,6 +354,8 @@ void
 _sx_xunlock(struct sx *sx, const char *file, int line)
 {
 
+	if (SCHEDULER_STOPPED())
+		return;
 	MPASS(curthread != NULL);
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_xunlock() of destroyed sx @ %s:%d", file, line));
@@ -366,6 +380,9 @@ _sx_try_upgrade(struct sx *sx, const cha
 	uintptr_t x;
 	int success;
 
+	if (SCHEDULER_STOPPED())
+		return (1);
+
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_try_upgrade() of destroyed sx @ %s:%d", file, line));
 	_sx_assert(sx, SA_SLOCKED, file, line);
@@ -396,6 +413,9 @@ _sx_downgrade(struct sx *sx, const char 
 	uintptr_t x;
 	int wakeup_swapper;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
 	    ("sx_downgrade() of destroyed sx @ %s:%d", file, line));
 	_sx_assert(sx, SA_XLOCKED | SA_NOTRECURSED, file, line);
@@ -478,6 +498,9 @@ _sx_xlock_hard(struct sx *sx, uintptr_t 
 	int64_t sleep_time = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return (0);
+
 	/* If we already hold an exclusive lock, then recurse. */
 	if (sx_xlocked(sx)) {
 		KASSERT((sx->lock_object.lo_flags & LO_RECURSABLE) != 0,
@@ -678,6 +701,9 @@ _sx_xunlock_hard(struct sx *sx, uintptr_
 	uintptr_t x;
 	int queue, wakeup_swapper;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	MPASS(!(sx->sx_lock & SX_LOCK_SHARED));
 
 	/* If the lock is recursed, then unrecurse one level. */
@@ -750,6 +776,9 @@ _sx_slock_hard(struct sx *sx, int opts, 
 	int64_t sleep_time = 0;
 #endif
 
+	if (SCHEDULER_STOPPED())
+		return (0);
+
 	/*
 	 * As with rwlocks, we don't make any attempt to try to block
 	 * shared locks once there is an exclusive waiter.
@@ -916,6 +945,9 @@ _sx_sunlock_hard(struct sx *sx, const ch
 	uintptr_t x;
 	int wakeup_swapper;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	for (;;) {
 		x = sx->sx_lock;
 

Modified: stable/8/sys/kern/kern_synch.c
==============================================================================
--- stable/8/sys/kern/kern_synch.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/kern_synch.c	Wed May 16 09:03:29 2012	(r235502)
@@ -158,7 +158,7 @@ _sleep(void *ident, struct lock_object *
 	else
 		class = NULL;
 
-	if (cold) {
+	if (cold || SCHEDULER_STOPPED()) {
 		/*
 		 * During autoconfiguration, just return;
 		 * don't run any other threads or panic below,
@@ -260,7 +260,7 @@ msleep_spin(void *ident, struct mtx *mtx
 	KASSERT(p != NULL, ("msleep1"));
 	KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
 
-	if (cold) {
+	if (cold || SCHEDULER_STOPPED()) {
 		/*
 		 * During autoconfiguration, just return;
 		 * don't run any other threads or panic below,
@@ -411,6 +411,8 @@ mi_switch(int flags, struct thread *newt
 	 */
 	if (kdb_active)
 		kdb_switch();
+	if (SCHEDULER_STOPPED())
+		return;
 	if (flags & SW_VOL)
 		td->td_ru.ru_nvcsw++;
 	else

Modified: stable/8/sys/kern/subr_kdb.c
==============================================================================
--- stable/8/sys/kern/subr_kdb.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/subr_kdb.c	Wed May 16 09:03:29 2012	(r235502)
@@ -250,10 +250,7 @@ kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS
 void
 kdb_panic(const char *msg)
 {
-	
-#ifdef SMP
-	stop_cpus_hard(PCPU_GET(other_cpus));
-#endif
+
 	printf("KDB: panic\n");
 	panic("%s", msg);
 }
@@ -611,8 +608,11 @@ kdb_trap(int type, int code, struct trap
 	intr = intr_disable();
 
 #ifdef SMP
-	if ((did_stop_cpus = kdb_stop_cpus) != 0)
-		stop_cpus_hard(PCPU_GET(other_cpus));
+	if (!SCHEDULER_STOPPED()) {
+		if ((did_stop_cpus = kdb_stop_cpus) != 0)
+			stop_cpus_hard(PCPU_GET(other_cpus));
+	} else
+		did_stop_cpus = 0;
 #endif
 
 	kdb_active++;

Modified: stable/8/sys/kern/subr_lock.c
==============================================================================
--- stable/8/sys/kern/subr_lock.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/subr_lock.c	Wed May 16 09:03:29 2012	(r235502)
@@ -537,6 +537,9 @@ lock_profile_obtain_lock_success(struct 
 	struct lock_profile_object *l;
 	int spin;
 
+	if (SCHEDULER_STOPPED())
+		return;
+
 	/* don't reset the timer when/if recursing */
 	if (!lock_prof_enable || (lo->lo_flags & LO_NOPROFILE))
 		return;
@@ -601,6 +604,8 @@ lock_profile_release_lock(struct lock_ob
 	struct lpohead *head;
 	int spin;
 
+	if (SCHEDULER_STOPPED())
+		return;
 	if (lo->lo_flags & LO_NOPROFILE)
 		return;
 	spin = (LOCK_CLASS(lo)->lc_flags & LC_SPINLOCK) ? 1 : 0;

Modified: stable/8/sys/kern/subr_witness.c
==============================================================================
--- stable/8/sys/kern/subr_witness.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/kern/subr_witness.c	Wed May 16 09:03:29 2012	(r235502)
@@ -2144,6 +2144,13 @@ witness_save(struct lock_object *lock, c
 	struct lock_instance *instance;
 	struct lock_class *class;
 
+	/*
+	 * This function is used independently in locking code to deal with
+	 * Giant, SCHEDULER_STOPPED() check can be removed here after Giant
+	 * is gone.
+	 */
+	if (SCHEDULER_STOPPED())
+		return;
 	KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
 	if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
 		return;
@@ -2170,6 +2177,13 @@ witness_restore(struct lock_object *lock
 	struct lock_instance *instance;
 	struct lock_class *class;
 
+	/*
+	 * This function is used independently in locking code to deal with
+	 * Giant, SCHEDULER_STOPPED() check can be removed here after Giant
+	 * is gone.
+	 */
+	if (SCHEDULER_STOPPED())
+		return;
 	KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
 	if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
 		return;

Modified: stable/8/sys/security/mac/mac_priv.c
==============================================================================
--- stable/8/sys/security/mac/mac_priv.c	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/security/mac/mac_priv.c	Wed May 16 09:03:29 2012	(r235502)
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
 #include "opt_mac.h"
 
 #include <sys/param.h>
-#include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/priv.h>
 #include <sys/sdt.h>

Modified: stable/8/sys/sys/mutex.h
==============================================================================
--- stable/8/sys/sys/mutex.h	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/sys/mutex.h	Wed May 16 09:03:29 2012	(r235502)
@@ -380,7 +380,8 @@ do {									\
 									\
 	if (mtx_owned(&Giant)) {					\
 		WITNESS_SAVE(&Giant.lock_object, Giant);		\
-		for (_giantcnt = 0; mtx_owned(&Giant); _giantcnt++)	\
+		for (_giantcnt = 0; mtx_owned(&Giant) &&		\
+		    !SCHEDULER_STOPPED(); _giantcnt++)			\
 			mtx_unlock(&Giant);				\
 	}
 

Modified: stable/8/sys/sys/proc.h
==============================================================================
--- stable/8/sys/sys/proc.h	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/sys/proc.h	Wed May 16 09:03:29 2012	(r235502)
@@ -229,6 +229,7 @@ struct thread {
 	short		td_locks;	/* (k) Count of non-spin locks. */
 	short		td_rw_rlocks;	/* (k) Count of rwlock read locks. */
 	short		td_lk_slocks;	/* (k) Count of lockmgr shared locks. */
+	short		td_stopsched;	/* (k) Scheduler stopped. */
 	struct turnstile *td_blocked;	/* (t) Lock thread is blocked on. */
 	const char	*td_lockname;	/* (t) Name of lock blocked on. */
 	LIST_HEAD(, turnstile) td_contested;	/* (q) Contested locks. */

Modified: stable/8/sys/sys/systm.h
==============================================================================
--- stable/8/sys/sys/systm.h	Wed May 16 07:18:56 2012	(r235501)
+++ stable/8/sys/sys/systm.h	Wed May 16 09:03:29 2012	(r235502)
@@ -111,6 +111,14 @@ enum VM_GUEST { VM_GUEST_NO = 0, VM_GUES
 	    ((uintptr_t)&(var) & (sizeof(void *) - 1)) == 0, msg)
 
 /*
+ * If we have already panic'd and this is the thread that called
+ * panic(), then don't block on any mutexes but silently succeed.
+ * Otherwise, the kernel will deadlock since the scheduler isn't
+ * going to run the thread that holds any lock we need.
+ */
+#define	SCHEDULER_STOPPED() __predict_false(curthread->td_stopsched)
+
+/*
  * XXX the hints declarations are even more misplaced than most declarations
  * in this file, since they are needed in one file (per arch) and only used
  * in two files.


More information about the svn-src-all mailing list