Skip to content

Commit 2d89891

Browse files
Frederic Weisbeckergregkh
authored andcommitted
nohz: Fix missing tick reprogram when interrupting an inline softirq
commit 0a0e082 upstream. The full nohz tick is reprogrammed in irq_exit() only if the exit is not in a nesting interrupt. This stands as an optimization: whether a hardirq or a softirq is interrupted, the tick is going to be reprogrammed when necessary at the end of the inner interrupt, with even potential new updates on the timer queue. When soft interrupts are interrupted, it's assumed that they are executing on the tail of an interrupt return. In that case tick_nohz_irq_exit() is called after softirq processing to take care of the tick reprogramming. But the assumption is wrong: softirqs can be processed inline as well, ie: outside of an interrupt, like in a call to local_bh_enable() or from ksoftirqd. Inline softirqs don't reprogram the tick once they are done, as opposed to interrupt tail softirq processing. So if a tick interrupts an inline softirq processing, the next timer will neither be reprogrammed from the interrupting tick's irq_exit() nor after the interrupted softirq processing. This situation may leave the tick unprogrammed while timers are armed. To fix this, simply keep reprogramming the tick even if a softirq has been interrupted. That can be optimized further, but for now correctness is more important. Note that new timers enqueued in nohz_full mode after a softirq gets interrupted will still be handled just fine through self-IPIs triggered by the timer code. Reported-by: Anna-Maria Gleixner <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Anna-Maria Gleixner <[email protected]> Cc: [email protected] # 4.14+ Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e5bcbed commit 2d89891

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

kernel/softirq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ static inline void tick_irq_exit(void)
382382

383383
/* Make sure that timer wheel updates are propagated */
384384
if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) {
385-
if (!in_interrupt())
385+
if (!in_irq())
386386
tick_nohz_irq_exit();
387387
}
388388
#endif

0 commit comments

Comments
 (0)