diff options
author | Benjamin Herrenschmidt <benh@au1.ibm.com> | 2014-04-22 17:34:40 +1000 |
---|---|---|
committer | Eli Qiao <taget@linux.vnet.ibm.com> | 2014-04-22 16:55:28 +0800 |
commit | 8b60dedf326e7dcae6ec3f4721fa30a1ecd98c24 (patch) | |
tree | dd295aa4d649b7bf76d0ebb4f8db6797223fe700 | |
parent | 0a99a22d8216bd20712fc12a0796a7e70eaff125 (diff) | |
download | powerkvm-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.c | 2 |
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); |