aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-12-02 04:53:54 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-12-20 10:08:26 -0500
commit28e18293cf0f8d23a0950d7b1d2212d11af494dc (patch)
treefbd27f23bbd1b85ef7b06cf4b5f733f46a929044 /arch/arm/kernel/smp.c
parent0eb0511d176534674600a1986c3c766756288908 (diff)
ARM: SMP: ensure smp_send_stop() waits for CPUs to stop
Wait for CPUs to indicate that they've stopped, after sending the stop IPI, rather than blindly continuing on and hoping that they've stopped in time. Print a warning if we fail to stop the other CPUs. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 1de3e13a42a1..64f2d198c764 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -575,10 +575,22 @@ void smp_send_reschedule(int cpu)
575 575
576void smp_send_stop(void) 576void smp_send_stop(void)
577{ 577{
578 cpumask_t mask = cpu_online_map; 578 unsigned long timeout;
579 cpu_clear(smp_processor_id(), mask); 579
580 if (!cpus_empty(mask)) 580 if (num_online_cpus() > 1) {
581 cpumask_t mask = cpu_online_map;
582 cpu_clear(smp_processor_id(), mask);
583
581 smp_cross_call(&mask, IPI_CPU_STOP); 584 smp_cross_call(&mask, IPI_CPU_STOP);
585 }
586
587 /* Wait up to one second for other CPUs to stop */
588 timeout = USEC_PER_SEC;
589 while (num_online_cpus() > 1 && timeout--)
590 udelay(1);
591
592 if (num_online_cpus() > 1)
593 pr_warning("SMP: failed to stop secondary CPUs\n");
582} 594}
583 595
584/* 596/*