]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
a7ef482b851ce8cef6cf56ffe840438e415f0606
[thirdparty/kernel/stable-queue.git] /
1 From 62c1256d544747b38e77ca9b5bfe3a26f9592576 Mon Sep 17 00:00:00 2001
2 From: Nicholas Piggin <npiggin@gmail.com>
3 Date: Sat, 23 Apr 2022 00:14:46 +1000
4 Subject: timers/nohz: Switch to ONESHOT_STOPPED in the low-res handler when the tick is stopped
5
6 From: Nicholas Piggin <npiggin@gmail.com>
7
8 commit 62c1256d544747b38e77ca9b5bfe3a26f9592576 upstream.
9
10 When tick_nohz_stop_tick() stops the tick and high resolution timers are
11 disabled, then the clock event device is not put into ONESHOT_STOPPED
12 mode. This can lead to spurious timer interrupts with some clock event
13 device drivers that don't shut down entirely after firing.
14
15 Eliminate these by putting the device into ONESHOT_STOPPED mode at points
16 where it is not being reprogrammed. When there are no timers active, then
17 tick_program_event() with KTIME_MAX can be used to stop the device. When
18 there is a timer active, the device can be stopped at the next tick (any
19 new timer added by timers will reprogram the tick).
20
21 Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
22 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
23 Link: https://lore.kernel.org/r/20220422141446.915024-1-npiggin@gmail.com
24 Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26 ---
27 kernel/time/tick-sched.c | 12 ++++++++++--
28 1 file changed, 10 insertions(+), 2 deletions(-)
29
30 --- a/kernel/time/tick-sched.c
31 +++ b/kernel/time/tick-sched.c
32 @@ -884,6 +884,8 @@ static void tick_nohz_stop_tick(struct t
33 if (unlikely(expires == KTIME_MAX)) {
34 if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
35 hrtimer_cancel(&ts->sched_timer);
36 + else
37 + tick_program_event(KTIME_MAX, 1);
38 return;
39 }
40
41 @@ -1274,9 +1276,15 @@ static void tick_nohz_handler(struct clo
42 tick_sched_do_timer(ts, now);
43 tick_sched_handle(ts, regs);
44
45 - /* No need to reprogram if we are running tickless */
46 - if (unlikely(ts->tick_stopped))
47 + if (unlikely(ts->tick_stopped)) {
48 + /*
49 + * The clockevent device is not reprogrammed, so change the
50 + * clock event device to ONESHOT_STOPPED to avoid spurious
51 + * interrupts on devices which might not be truly one shot.
52 + */
53 + tick_program_event(KTIME_MAX, 1);
54 return;
55 + }
56
57 hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
58 tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);