diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-03-06 06:18:36 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-03-13 06:39:39 -0400 |
commit | eaa907c546f76222227dfc41784b22588af1e3d7 (patch) | |
tree | 0e23882c311bc527ae9e328c22b000ff11b85fae /include/linux/clockchips.h | |
parent | 989dcb645ca715129c5a2b39102c8334a20d9615 (diff) |
tick: Provide a check for a forced broadcast pending
On the CPU which gets woken along with the target CPU of the broadcast
the following happens:
deep_idle()
<-- spurious wakeup
broadcast_exit()
set forced bit
enable interrupts
<-- Nothing happens
disable interrupts
broadcast_enter()
<-- Here we observe the forced bit is set
deep_idle()
Now after that the target CPU of the broadcast runs the broadcast
handler and finds the other CPU in both the broadcast and the forced
mask, sends the IPI and stuff gets back to normal.
So it's not actually harmful, just more evidence for the theory, that
hardware designers have access to very special drug supplies.
Now there is no point in going back to deep idle just to wake up again
right away via an IPI. Provide a check which allows the idle code to
avoid the deep idle transition.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: LAK <linux-arm-kernel@lists.infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Arjan van de Veen <arjan@infradead.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Jason Liu <liu.h.jason@gmail.com>
Link: http://lkml.kernel.org/r/20130306111537.565418308@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux/clockchips.h')
-rw-r--r-- | include/linux/clockchips.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 494d33ea78f8..646aac136eed 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h | |||
@@ -175,6 +175,12 @@ extern void tick_broadcast(const struct cpumask *mask); | |||
175 | extern int tick_receive_broadcast(void); | 175 | extern int tick_receive_broadcast(void); |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT) | ||
179 | extern int tick_check_broadcast_expired(void); | ||
180 | #else | ||
181 | static inline int tick_check_broadcast_expired(void) { return 0; } | ||
182 | #endif | ||
183 | |||
178 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | 184 | #ifdef CONFIG_GENERIC_CLOCKEVENTS |
179 | extern void clockevents_notify(unsigned long reason, void *arg); | 185 | extern void clockevents_notify(unsigned long reason, void *arg); |
180 | #else | 186 | #else |