aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@au1.ibm.com>2014-04-22 17:34:40 +1000
committerEli Qiao <taget@linux.vnet.ibm.com>2014-04-22 16:55:28 +0800
commit8b60dedf326e7dcae6ec3f4721fa30a1ecd98c24 (patch)
treedd295aa4d649b7bf76d0ebb4f8db6797223fe700
parent0a99a22d8216bd20712fc12a0796a7e70eaff125 (diff)
downloadpowerkvm-8b60dedf326e7dcae6ec3f4721fa30a1ecd98c24.tar.gz
tick-broadcast/cpuidle: Fix the demuxing of PPC_MSG_TIMER IPI message
The PPC_MSG_TIMER IPI message slot was introduced for the tick broadcast IPIs which are required to wakeup sleeping CPUs. The decrementer of the CPUs that enter fast sleep stops as a consequence of entering the idle state. Therefore such CPUs have to be woken up in time to handle their timers by a broadcast CPU which sends the PPC_MSG_TIMER IPIs to them. This IPI message is being parsed wrongly in smp_ipi_demux(). Thus the tick broadcast interrupt handler is never executed on the sleeping CPU. This could have led to unpleasant side effects like not handling timers in time on the sleeping cpus. But since the sleeping CPUs still receive the tick broadcast IPI, they are awoken from the idle state and their decrementers are back in action. As a result, its possible that they are managing to handle timers before they go to sleep again. Hence timers are being handled on the sleeping cpus although the tick broadcast interrupt handler, which is actually supposed to ensure that is never being called today due to the wrong number of shift bits while parsing the tick broadcast IPI. However we need to note that as a result of this discrepency, timer handling on the sleeping cpus may be unstable. This could be one of the reasons we are observing some softlockups in the cpuidle wakeup path. Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/smp.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 668e67e391e7a5..33738113914480 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -227,7 +227,7 @@ irqreturn_t smp_ipi_demux(void)
generic_smp_call_function_interrupt();
if (all & (1 << (24 - 8 * PPC_MSG_RESCHEDULE)))
scheduler_ipi();
- if (all & (1 << (24 - 9 * PPC_MSG_TIMER)))
+ if (all & (1 << (24 - 8 * PPC_MSG_TIMER)))
decrementer_timer_interrupt();
if (all & (1 << (24 - 8 * PPC_MSG_DEBUGGER_BREAK)))
debug_ipi_action(0, NULL);