svn commit: r208055 - stable/8/sys/kern

Attilio Rao attilio at FreeBSD.org
Fri May 14 01:43:13 UTC 2010


Author: attilio
Date: Fri May 14 01:43:13 2010
New Revision: 208055
URL: http://svn.freebsd.org/changeset/base/208055

Log:
  MFC r206878, r206897, r207921:
  Fix a deadlock in the shutdown code when some CPUs are performing
  smp_rendezvous() (or smp_tlb_shootdown()) and are waiting for
  acknowledgment.

Modified:
  stable/8/sys/kern/kern_shutdown.c
  stable/8/sys/kern/subr_smp.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (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/xen/xenpci/   (props changed)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sys/kern/kern_shutdown.c
==============================================================================
--- stable/8/sys/kern/kern_shutdown.c	Fri May 14 01:25:30 2010	(r208054)
+++ stable/8/sys/kern/kern_shutdown.c	Fri May 14 01:43:13 2010	(r208055)
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/reboot.h>
 #include <sys/resourcevar.h>
 #include <sys/sched.h>
-#include <sys/smp.h>		/* smp_active */
+#include <sys/smp.h>
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
 
@@ -485,15 +485,26 @@ static void
 shutdown_reset(void *junk, int howto)
 {
 
+	printf("Rebooting...\n");
+	DELAY(1000000);	/* wait 1 sec for printf's to complete and be read */
+
 	/*
-	 * Disable interrupts on CPU0 in order to avoid fast handlers
-	 * to preempt the stopping process and to deadlock against other
-	 * CPUs.
+	 * Acquiring smp_ipi_mtx here has a double effect:
+	 * - it disables interrupts avoiding CPU0 preemption
+	 *   by fast handlers (thus deadlocking  against other CPUs)
+	 * - it avoids deadlocks against smp_rendezvous() or, more 
+	 *   generally, threads busy-waiting, with this spinlock held,
+	 *   and waiting for responses by threads on other CPUs
+	 *   (ie. smp_tlb_shootdown()).
+	 *
+	 * For the !SMP case it just needs to handle the former problem.
 	 */
+#ifdef SMP
+	mtx_lock_spin(&smp_ipi_mtx);
+#else
 	spinlock_enter();
+#endif
 
-	printf("Rebooting...\n");
-	DELAY(1000000);	/* wait 1 sec for printf's to complete and be read */
 	/* cpu_boot(howto); */ /* doesn't do anything at the moment */
 	cpu_reset();
 	/* NOTREACHED */ /* assuming reset worked */

Modified: stable/8/sys/kern/subr_smp.c
==============================================================================
--- stable/8/sys/kern/subr_smp.c	Fri May 14 01:25:30 2010	(r208054)
+++ stable/8/sys/kern/subr_smp.c	Fri May 14 01:43:13 2010	(r208055)
@@ -137,6 +137,8 @@ static void
 mp_start(void *dummy)
 {
 
+	mtx_init(&smp_ipi_mtx, "smp rendezvous", NULL, MTX_SPIN);
+
 	/* Probe for MP hardware. */
 	if (smp_disabled != 0 || cpu_mp_probe() == 0) {
 		mp_ncpus = 1;
@@ -144,7 +146,6 @@ mp_start(void *dummy)
 		return;
 	}
 
-	mtx_init(&smp_ipi_mtx, "smp rendezvous", NULL, MTX_SPIN);
 	cpu_mp_start();
 	printf("FreeBSD/SMP: Multiprocessor System Detected: %d CPUs\n",
 	    mp_ncpus);


More information about the svn-src-all mailing list