Skip to content

Commit f944ffc

Browse files
KAGA-KOKOakpm00
authored andcommitted
watchdog/perf: properly initialize the turbo mode timestamp and rearm counter
For systems on which the performance counter can expire early due to turbo modes the watchdog handler has a safety net in place which validates that since the last watchdog event there has at least 4/5th of the watchdog period elapsed. This works reliably only after the first watchdog event because the per CPU variable which holds the timestamp of the last event is never initialized. So a first spurious event will validate against a timestamp of 0 which results in a delta which is likely to be way over the 4/5 threshold of the period. As this might happen before the first watchdog hrtimer event increments the watchdog counter, this can lead to false positives. Fix this by initializing the timestamp before enabling the hardware event. Reset the rearm counter as well, as that might be non zero after the watchdog was disabled and reenabled. Link: https://lkml.kernel.org/r/87frsfu15a.ffs@tglx Fixes: 7edaeb6 ("kernel/watchdog: Prevent false positives with turbo modes") Signed-off-by: Thomas Gleixner <[email protected]> Cc: Arjan van de Ven <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 0fe2356 commit f944ffc

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

kernel/watchdog_perf.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,15 @@ static bool watchdog_check_timestamp(void)
7575
__this_cpu_write(last_timestamp, now);
7676
return true;
7777
}
78-
#else
79-
static inline bool watchdog_check_timestamp(void)
78+
79+
static void watchdog_init_timestamp(void)
8080
{
81-
return true;
81+
__this_cpu_write(nmi_rearmed, 0);
82+
__this_cpu_write(last_timestamp, ktime_get_mono_fast_ns());
8283
}
84+
#else
85+
static inline bool watchdog_check_timestamp(void) { return true; }
86+
static inline void watchdog_init_timestamp(void) { }
8387
#endif
8488

8589
static struct perf_event_attr wd_hw_attr = {
@@ -161,6 +165,7 @@ void watchdog_hardlockup_enable(unsigned int cpu)
161165
if (!atomic_fetch_inc(&watchdog_cpus))
162166
pr_info("Enabled. Permanently consumes one hw-PMU counter.\n");
163167

168+
watchdog_init_timestamp();
164169
perf_event_enable(this_cpu_read(watchdog_ev));
165170
}
166171

0 commit comments

Comments
 (0)