Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 May 2011 07:05:36 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r221678 - in user/avg/xcpu/sys: amd64/amd64 kern sys
Message-ID:  <201105090705.p4975ai0080480@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Mon May  9 07:05:36 2011
New Revision: 221678
URL: http://svn.freebsd.org/changeset/base/221678

Log:
  change generic_stop_cpus to use the same approach hard_stop_cpus

Modified:
  user/avg/xcpu/sys/amd64/amd64/mp_machdep.c
  user/avg/xcpu/sys/kern/subr_smp.c
  user/avg/xcpu/sys/sys/smp.h

Modified: user/avg/xcpu/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- user/avg/xcpu/sys/amd64/amd64/mp_machdep.c	Mon May  9 07:05:06 2011	(r221677)
+++ user/avg/xcpu/sys/amd64/amd64/mp_machdep.c	Mon May  9 07:05:36 2011	(r221678)
@@ -1422,9 +1422,13 @@ cpustop_handler(void)
 	cpumask_t cpumask;
 	u_int cpu;
 
-	cpu = PCPU_GET(cpuid);
 	cpumask = PCPU_GET(cpumask);
 
+	/* Just return if this is a belated NMI */
+	if ((stopping_cpus & cpumask) == 0)
+		return;
+
+	cpu = PCPU_GET(cpuid);
 	savectx(&stoppcbs[cpu]);
 
 	/* Indicate that we are stopped */

Modified: user/avg/xcpu/sys/kern/subr_smp.c
==============================================================================
--- user/avg/xcpu/sys/kern/subr_smp.c	Mon May  9 07:05:06 2011	(r221677)
+++ user/avg/xcpu/sys/kern/subr_smp.c	Mon May  9 07:05:36 2011	(r221678)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #ifdef SMP
 volatile cpumask_t stopped_cpus;
 volatile cpumask_t started_cpus;
+volatile cpumask_t stopping_cpus;
 volatile cpumask_t hard_stopped_cpus;
 volatile cpumask_t hard_started_cpus;
 volatile cpumask_t hard_stopping_cpus;
@@ -205,7 +206,9 @@ forward_signal(struct thread *td)
 static int
 generic_stop_cpus(cpumask_t map, u_int type)
 {
-	static volatile u_int stopping_cpu = NOCPU;
+	static volatile u_int stopper_cpu = NOCPU;
+	cpumask_t mask;
+	int cpu;
 	int i;
 
 	KASSERT(
@@ -221,13 +224,29 @@ generic_stop_cpus(cpumask_t map, u_int t
 
 	CTR2(KTR_SMP, "stop_cpus(%x) with %u type", map, type);
 
-	if (stopping_cpu != PCPU_GET(cpuid))
-		while (atomic_cmpset_int(&stopping_cpu, NOCPU,
-		    PCPU_GET(cpuid)) == 0)
-			while (stopping_cpu != NOCPU)
-				cpu_spinwait(); /* spin */
+	/* Ensure non-preemtable context, just in case. */
+	spinlock_enter();
+
+	mask = PCPU_GET(cpumask);
+	cpu = PCPU_GET(cpuid);
+
+	if (cpu != stopper_cpu) {
+		while (atomic_cmpset_int(&stopper_cpu, NOCPU, cpu) == 0)
+			while (stopper_cpu != NOCPU) {
+				if ((mask & stopping_cpus) != 0)
+					cpustop_handler();
+				else
+					cpu_spinwait();
+			}
+	} else {
+		/*
+		 * Recursion here is not expected.
+		 */
+		panic("cpu stop recursion\n");
+	}
 
 	/* send the stop IPI to all CPUs in map */
+	stopping_cpus = map;
 	ipi_selected(map, type);
 
 	i = 0;
@@ -241,7 +260,7 @@ generic_stop_cpus(cpumask_t map, u_int t
 		}
 	}
 
-	stopping_cpu = NOCPU;
+	spinlock_exit();
 	return (1);
 }
 

Modified: user/avg/xcpu/sys/sys/smp.h
==============================================================================
--- user/avg/xcpu/sys/sys/smp.h	Mon May  9 07:05:06 2011	(r221677)
+++ user/avg/xcpu/sys/sys/smp.h	Mon May  9 07:05:36 2011	(r221678)
@@ -73,6 +73,7 @@ extern int smp_active;
 extern int smp_cpus;
 extern volatile cpumask_t started_cpus;
 extern volatile cpumask_t stopped_cpus;
+extern volatile cpumask_t stopping_cpus;
 extern volatile cpumask_t hard_started_cpus;
 extern volatile cpumask_t hard_stopped_cpus;
 extern volatile cpumask_t hard_stopping_cpus;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105090705.p4975ai0080480>