diff options
author | Donghan Ryu <dryu@nvidia.com> | 2011-04-11 12:14:55 +0900 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-04-14 21:28:55 -0700 |
commit | 196834caab117848884980aab67576e85340f00a (patch) | |
tree | 7a584667215c8be2f04047c28c274a1b4f1d909c | |
parent | 3eabf0949204e0b658e57a662abbc326835c89b6 (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.
Bug 810939
(cherry picked from commit 28e18293cf0f8d23a0950d7b1d2212d11af494dc)
Change-Id: I87fbaad50a50789dc9a12b1f27d51372ffd6aaf1
Reviewed-on: http://git-master/r/27828
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r-- | arch/arm/kernel/smp.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7c5ddb111897..2a3288701bae 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -518,9 +518,22 @@ void smp_send_reschedule(int cpu) void smp_send_stop(void) { - cpumask_t mask = cpu_online_map; - cpu_clear(smp_processor_id(), mask); - send_ipi_message(&mask, IPI_CPU_STOP); + unsigned long timeout; + + if (num_online_cpus() > 1) { + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); + + send_ipi_message(&mask, IPI_CPU_STOP); + } + + /* Wait up to one second for other CPUs to stop */ + timeout = USEC_PER_SEC; + while (num_online_cpus() > 1 && timeout--) + udelay(1); + + if (num_online_cpus() > 1) + pr_warning("SMP: failed to stop secondary CPUs "); } /* |