Merge branches 'misc', 'sa1100-for-next' and 'spectre' into for-linus
[linux-block.git] / arch / arm / kernel / smp.c
index 82b879db32ee4ca8d07454da7c2a0f7d73e9de85..3bf82232b1bed4bce829749ce6af885bbc43c191 100644 (file)
@@ -266,8 +266,6 @@ int __cpu_disable(void)
        flush_cache_louis();
        local_flush_tlb_all();
 
-       clear_tasks_mm_cpumask(cpu);
-
        return 0;
 }
 
@@ -285,6 +283,7 @@ void __cpu_die(unsigned int cpu)
        }
        pr_debug("CPU%u: shutdown\n", cpu);
 
+       clear_tasks_mm_cpumask(cpu);
        /*
         * platform_cpu_kill() is generally expected to do the powering off
         * and/or cutting of clocks to the dying CPU.  Optionally, this may
@@ -725,6 +724,21 @@ void smp_send_stop(void)
                pr_warn("SMP: failed to stop secondary CPUs\n");
 }
 
+/* In case panic() and panic() called at the same time on CPU1 and CPU2,
+ * and CPU 1 calls panic_smp_self_stop() before crash_smp_send_stop()
+ * CPU1 can't receive the ipi irqs from CPU2, CPU1 will be always online,
+ * kdump fails. So split out the panic_smp_self_stop() and add
+ * set_cpu_online(smp_processor_id(), false).
+ */
+void panic_smp_self_stop(void)
+{
+       pr_debug("CPU %u will stop doing anything useful since another CPU has paniced\n",
+                smp_processor_id());
+       set_cpu_online(smp_processor_id(), false);
+       while (1)
+               cpu_relax();
+}
+
 /*
  * not supported here
  */