]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/arm64/kernel/smp.c
arm64: smp: fix crash_smp_send_stop() behaviour
[linux.git] / arch / arm64 / kernel / smp.c
index d4ed9a19d8fe7f8a63946edbfb934bbe8d58a442..5407bf5d98ac5ec4a0a19be90bb638525b0d2325 100644 (file)
@@ -958,11 +958,22 @@ void tick_broadcast(const struct cpumask *mask)
 }
 #endif
 
+/*
+ * The number of CPUs online, not counting this CPU (which may not be
+ * fully online and so not counted in num_online_cpus()).
+ */
+static inline unsigned int num_other_online_cpus(void)
+{
+       unsigned int this_cpu_online = cpu_online(smp_processor_id());
+
+       return num_online_cpus() - this_cpu_online;
+}
+
 void smp_send_stop(void)
 {
        unsigned long timeout;
 
-       if (num_online_cpus() > 1) {
+       if (num_other_online_cpus()) {
                cpumask_t mask;
 
                cpumask_copy(&mask, cpu_online_mask);
@@ -975,10 +986,10 @@ void smp_send_stop(void)
 
        /* Wait up to one second for other CPUs to stop */
        timeout = USEC_PER_SEC;
-       while (num_online_cpus() > 1 && timeout--)
+       while (num_other_online_cpus() && timeout--)
                udelay(1);
 
-       if (num_online_cpus() > 1)
+       if (num_other_online_cpus())
                pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
                        cpumask_pr_args(cpu_online_mask));
 
@@ -1001,7 +1012,11 @@ void crash_smp_send_stop(void)
 
        cpus_stopped = 1;
 
-       if (num_online_cpus() == 1) {
+       /*
+        * If this cpu is the only one alive at this point in time, online or
+        * not, there are no stop messages to be sent around, so just back out.
+        */
+       if (num_other_online_cpus() == 0) {
                sdei_mask_local_cpu();
                return;
        }
@@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void)
        cpumask_copy(&mask, cpu_online_mask);
        cpumask_clear_cpu(smp_processor_id(), &mask);
 
-       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+       atomic_set(&waiting_for_crash_ipi, num_other_online_cpus());
 
        pr_crit("SMP: stopping secondary CPUs\n");
        smp_cross_call(&mask, IPI_CPU_CRASH_STOP);