summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonghan Ryu <dryu@nvidia.com>2011-04-11 12:14:55 +0900
committerVarun Colbert <vcolbert@nvidia.com>2011-04-14 21:28:55 -0700
commit196834caab117848884980aab67576e85340f00a (patch)
tree7a584667215c8be2f04047c28c274a1b4f1d909c
parent3eabf0949204e0b658e57a662abbc326835c89b6 (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.c19
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 ");
}
/*