svn commit: r221678 - in user/avg/xcpu/sys: amd64/amd64 kern sys
Andriy Gapon
avg at FreeBSD.org
Mon May 9 07:05:36 UTC 2011
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;
More information about the svn-src-user
mailing list