@@ -225,6 +225,7 @@ int __cpu_disable(void)
}
static DECLARE_COMPLETION(cpu_died);
+static DEFINE_RAW_SPINLOCK(stop_lock);
/*
* called on the thread which is asking for a CPU to be shutdown -
@@ -232,10 +233,13 @@ static DECLARE_COMPLETION(cpu_died);
*/
void __cpu_die(unsigned int cpu)
{
+ unsigned long flags;
if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
pr_err("CPU%u: cpu didn't die\n", cpu);
return;
}
+ raw_spin_lock_irqsave(&stop_lock, flags);
+ raw_spin_unlock_irqrestore(&stop_lock, flags);
pr_notice("CPU%u: shutdown\n", cpu);
/*
@@ -280,7 +284,17 @@ void __ref cpu_die(void)
* has been sent, power and/or clocks can be removed at any point
* from this CPU and its cache by platform_cpu_kill().
*/
+ raw_spin_lock(&stop_lock);
__smp_cross_call(cpumask_of(cpumask_any(cpu_online_mask)), IPI_CPU_DEAD);
+ raw_spin_unlock(&stop_lock);
+
+ /*
+ * Ensure that the cache lines associated with the stop_lock are
+ * written out. This covers the case where _this_ CPU is doing the
+ * powering down, to ensure that the lock is visible to the
+ * CPU waiting for this one.
+ */
+ flush_cache_louis();
/*
* The actual CPU shutdown procedure is at least platform (if not
@@ -517,8 +531,6 @@ void tick_broadcast(const struct cpumask *mask)
}
#endif
-static DEFINE_RAW_SPINLOCK(stop_lock);
-
/*
* ipi_cpu_stop - handle IPI from smp_send_stop()
*/