linux/kernel/time
Thomas Gleixner 5d62c183f9 nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick()
The conditions in irq_exit() to invoke tick_nohz_irq_exit() which
subsequently invokes tick_nohz_stop_sched_tick() are:

  if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu))

If need_resched() is not set, but a timer softirq is pending then this is
an indication that the softirq code punted and delegated the execution to
softirqd. need_resched() is not true because the current interrupted task
takes precedence over softirqd.

Invoking tick_nohz_irq_exit() in this case can cause an endless loop of
timer interrupts because the timer wheel contains an expired timer, but
softirqs are not yet executed. So it returns an immediate expiry request,
which causes the timer to fire immediately again. Lather, rinse and
repeat....

Prevent that by adding a check for a pending timer soft interrupt to the
conditions in tick_nohz_stop_sched_tick() which avoid calling
get_next_timer_interrupt(). That keeps the tick sched timer on the tick and
prevents a repetitive programming of an already expired timer.

Reported-by: Sebastian Siewior <bigeasy@linutronix.d>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Cc: Anna-Maria Gleixner <anna-maria@linutronix.de>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/alpine.DEB.2.20.1712272156050.2431@nanos
2017-12-29 23:13:10 +01:00
..
alarmtimer.c alarmtimer: Ensure RTC module is not unloaded 2017-08-31 21:36:45 +02:00
clockevents.c clockevents: Retry programming min delta up to 10 times 2017-10-19 16:29:15 +02:00
clocksource.c treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
hrtimer.c timers/hrtimer: Use lockdep to assert IRQs are disabled/enabled 2017-11-08 11:13:49 +01:00
itimer.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
jiffies.c jiffies: Revert bogus conversion of NSEC_PER_SEC to TICK_NSEC 2017-03-07 11:03:28 +01:00
Kconfig timekeeping: Remove CONFIG_GENERIC_TIME_VSYSCALL_OLD 2017-11-14 11:20:25 +01:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ntp_internal.h Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:56:58 -08:00
ntp.c Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:56:58 -08:00
posix-clock.c posix-timers: Move posix-timer internals to core 2017-06-04 15:40:23 +02:00
posix-cpu-timers.c timers/posix-cpu-timers: Use lockdep to assert IRQs are disabled/enabled 2017-11-08 11:13:54 +01:00
posix-stubs.c posix-stubs: Use get_timespec64() and put_timespec64() 2017-10-17 17:22:27 +02:00
posix-timers.c posix-timer: Properly check sigevent->sigev_notify 2017-12-15 11:08:40 +01:00
posix-timers.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sched_clock.c timers, sched_clock: Update timeout for clock wrap 2017-03-23 12:30:27 -07:00
test_udelay.c time: Avoid timespec in udelay_test 2016-06-20 12:47:26 -07:00
tick-broadcast-hrtimer.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tick-broadcast.c tick/broadcast: Make tick_broadcast_setup_oneshot() static 2017-06-12 18:56:01 +02:00
tick-common.c ktime: Cleanup ktime_set() usage 2016-12-25 17:21:22 +01:00
tick-internal.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tick-oneshot.c clockevents: Update clockevents device next_event on stop 2017-11-01 18:20:17 +01:00
tick-sched.c nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick() 2017-12-29 23:13:10 +01:00
tick-sched.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
time.c Merge branch 'fortglx/4.15/time' of https://git.linaro.org/people/john.stultz/linux into timers/core 2017-10-31 23:17:28 +01:00
timeconst.bc time: Introduce jiffies64_to_nsecs() 2017-02-01 09:13:45 +01:00
timeconv.c time: Add time64_to_tm() 2016-06-20 12:47:15 -07:00
timecounter.c clocksource: Use a plain u64 instead of cycle_t 2016-12-25 11:04:12 +01:00
timekeeping_debug.c PM / timekeeping: Print debug messages when requested 2017-07-23 00:03:43 +02:00
timekeeping_internal.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
timekeeping.c timekeeping: Remove CONFIG_GENERIC_TIME_VSYSCALL_OLD 2017-11-14 11:20:25 +01:00
timekeeping.h Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:56:58 -08:00
timer_list.c timer/debug: Change /proc/timer_list from 0444 to 0400 2017-11-13 16:04:06 +01:00
timer.c timers: Reinitialize per cpu bases on hotplug 2017-12-29 23:13:09 +01:00