| From 8ea2cc4b4791cd026185e0830e6e93b08c3b89a6 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Thu, 16 Jan 2020 19:17:02 +0100 |
| Subject: [PATCH] watchdog/softlockup: Enforce that timestamp is valid on boot |
| |
| commit 11e31f608b499f044f24b20be73f1dcab3e43f8a upstream. |
| |
| Robert reported that during boot the watchdog timestamp is set to 0 for one |
| second which is the indicator for a watchdog reset. |
| |
| The reason for this is that the timestamp is in seconds and the time is |
| taken from sched clock and divided by ~1e9. sched clock starts at 0 which |
| means that for the first second during boot the watchdog timestamp is 0, |
| i.e. reset. |
| |
| Use ULONG_MAX as the reset indicator value so the watchdog works correctly |
| right from the start. ULONG_MAX would only conflict with a real timestamp |
| if the system reaches an uptime of 136 years on 32bit and almost eternity |
| on 64bit. |
| |
| Reported-by: Robert Richter <rrichter@marvell.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Link: https://lore.kernel.org/r/87o8v3uuzl.fsf@nanos.tec.linutronix.de |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/watchdog.c b/kernel/watchdog.c |
| index 7f9e7b9306fe..c1853aea4c14 100644 |
| --- a/kernel/watchdog.c |
| +++ b/kernel/watchdog.c |
| @@ -161,6 +161,8 @@ static void lockup_detector_update_enable(void) |
| |
| #ifdef CONFIG_SOFTLOCKUP_DETECTOR |
| |
| +#define SOFTLOCKUP_RESET ULONG_MAX |
| + |
| /* Global variables, exported for sysctl */ |
| unsigned int __read_mostly softlockup_panic = |
| CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; |
| @@ -274,7 +276,7 @@ notrace void touch_softlockup_watchdog_sched(void) |
| * Preemption can be enabled. It doesn't matter which CPU's timestamp |
| * gets zeroed here, so use the raw_ operation. |
| */ |
| - raw_cpu_write(watchdog_touch_ts, 0); |
| + raw_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET); |
| } |
| |
| notrace void touch_softlockup_watchdog(void) |
| @@ -298,14 +300,14 @@ void touch_all_softlockup_watchdogs(void) |
| * the softlockup check. |
| */ |
| for_each_cpu(cpu, &watchdog_allowed_mask) |
| - per_cpu(watchdog_touch_ts, cpu) = 0; |
| + per_cpu(watchdog_touch_ts, cpu) = SOFTLOCKUP_RESET; |
| wq_watchdog_touch(-1); |
| } |
| |
| void touch_softlockup_watchdog_sync(void) |
| { |
| __this_cpu_write(softlockup_touch_sync, true); |
| - __this_cpu_write(watchdog_touch_ts, 0); |
| + __this_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET); |
| } |
| |
| static int is_softlockup(unsigned long touch_ts) |
| @@ -383,7 +385,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) |
| /* .. and repeat */ |
| hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period)); |
| |
| - if (touch_ts == 0) { |
| + if (touch_ts == SOFTLOCKUP_RESET) { |
| if (unlikely(__this_cpu_read(softlockup_touch_sync))) { |
| /* |
| * If the time stamp was touched atomically |
| -- |
| 2.7.4 |
| |