|
@@ -565,17 +565,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static void stop_this_cpu(void *dummy)
|
|
|
-{
|
|
|
- /* Remove this CPU */
|
|
|
- set_cpu_online(smp_processor_id(), false);
|
|
|
-
|
|
|
- hard_irq_disable();
|
|
|
- spin_begin();
|
|
|
- while (1)
|
|
|
- spin_cpu_relax();
|
|
|
-}
|
|
|
-
|
|
|
#ifdef CONFIG_NMI_IPI
|
|
|
static void nmi_stop_this_cpu(struct pt_regs *regs)
|
|
|
{
|
|
@@ -583,23 +572,57 @@ static void nmi_stop_this_cpu(struct pt_regs *regs)
|
|
|
* This is a special case because it never returns, so the NMI IPI
|
|
|
* handling would never mark it as done, which makes any later
|
|
|
* smp_send_nmi_ipi() call spin forever. Mark it done now.
|
|
|
+ *
|
|
|
+ * IRQs are already hard disabled by the smp_handle_nmi_ipi.
|
|
|
*/
|
|
|
nmi_ipi_lock();
|
|
|
nmi_ipi_busy_count--;
|
|
|
nmi_ipi_unlock();
|
|
|
|
|
|
- stop_this_cpu(NULL);
|
|
|
+ /* Remove this CPU */
|
|
|
+ set_cpu_online(smp_processor_id(), false);
|
|
|
+
|
|
|
+ spin_begin();
|
|
|
+ while (1)
|
|
|
+ spin_cpu_relax();
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
void smp_send_stop(void)
|
|
|
{
|
|
|
-#ifdef CONFIG_NMI_IPI
|
|
|
smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, nmi_stop_this_cpu, 1000000);
|
|
|
-#else
|
|
|
+}
|
|
|
+
|
|
|
+#else /* CONFIG_NMI_IPI */
|
|
|
+
|
|
|
+static void stop_this_cpu(void *dummy)
|
|
|
+{
|
|
|
+ /* Remove this CPU */
|
|
|
+ set_cpu_online(smp_processor_id(), false);
|
|
|
+
|
|
|
+ hard_irq_disable();
|
|
|
+ spin_begin();
|
|
|
+ while (1)
|
|
|
+ spin_cpu_relax();
|
|
|
+}
|
|
|
+
|
|
|
+void smp_send_stop(void)
|
|
|
+{
|
|
|
+ static bool stopped = false;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Prevent waiting on csd lock from a previous smp_send_stop.
|
|
|
+ * This is racy, but in general callers try to do the right
|
|
|
+ * thing and only fire off one smp_send_stop (e.g., see
|
|
|
+ * kernel/panic.c)
|
|
|
+ */
|
|
|
+ if (stopped)
|
|
|
+ return;
|
|
|
+
|
|
|
+ stopped = true;
|
|
|
+
|
|
|
smp_call_function(stop_this_cpu, NULL, 0);
|
|
|
-#endif
|
|
|
}
|
|
|
+#endif /* CONFIG_NMI_IPI */
|
|
|
|
|
|
struct thread_info *current_set[NR_CPUS];
|
|
|
|