Skip to content

Commit 8eb2312

Browse files
committed
tick/broadcast: Prevent hrtimer recursion
The hrtimer based broadcast vehicle can cause a hrtimer recursion which went unnoticed until we changed the hrtimer expiry code to keep track of the currently running timer. local_timer_interrupt() local_handler() hrtimer_interrupt() expire_hrtimers() broadcast_hrtimer() send_ipis() local_handler() hrtimer_interrupt() .... Solution is simple: Prevent the local handler call from the broadcast code when the broadcast 'device' is hrtimer based. [ Split out from a larger combo patch ] Tested-by: Sudeep Holla <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Suzuki Poulose <[email protected]> Cc: Lorenzo Pieralisi <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Rafael J. Wysocki <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Preeti U Murthy <[email protected]> Cc: Ingo Molnar <[email protected]> Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1507070929360.3916@nanos
1 parent 7c4a976 commit 8eb2312

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/time/tick-broadcast.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,22 @@ static bool tick_do_broadcast(struct cpumask *mask)
265265
* Check, if the current cpu is in the mask
266266
*/
267267
if (cpumask_test_cpu(cpu, mask)) {
268+
struct clock_event_device *bc = tick_broadcast_device.evtdev;
269+
268270
cpumask_clear_cpu(cpu, mask);
269-
local = true;
271+
/*
272+
* We only run the local handler, if the broadcast
273+
* device is not hrtimer based. Otherwise we run into
274+
* a hrtimer recursion.
275+
*
276+
* local timer_interrupt()
277+
* local_handler()
278+
* expire_hrtimers()
279+
* bc_handler()
280+
* local_handler()
281+
* expire_hrtimers()
282+
*/
283+
local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER);
270284
}
271285

272286
if (!cpumask_empty(mask)) {

0 commit comments

Comments
 (0)