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>