Skip to content

Commit 11e31f6

Browse files
committed
watchdog/softlockup: Enforce that timestamp is valid on boot
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 <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 3a51449 commit 11e31f6

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

kernel/watchdog.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ static void lockup_detector_update_enable(void)
161161

162162
#ifdef CONFIG_SOFTLOCKUP_DETECTOR
163163

164+
#define SOFTLOCKUP_RESET ULONG_MAX
165+
164166
/* Global variables, exported for sysctl */
165167
unsigned int __read_mostly softlockup_panic =
166168
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
@@ -272,7 +274,7 @@ notrace void touch_softlockup_watchdog_sched(void)
272274
* Preemption can be enabled. It doesn't matter which CPU's timestamp
273275
* gets zeroed here, so use the raw_ operation.
274276
*/
275-
raw_cpu_write(watchdog_touch_ts, 0);
277+
raw_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET);
276278
}
277279

278280
notrace void touch_softlockup_watchdog(void)
@@ -296,14 +298,14 @@ void touch_all_softlockup_watchdogs(void)
296298
* the softlockup check.
297299
*/
298300
for_each_cpu(cpu, &watchdog_allowed_mask)
299-
per_cpu(watchdog_touch_ts, cpu) = 0;
301+
per_cpu(watchdog_touch_ts, cpu) = SOFTLOCKUP_RESET;
300302
wq_watchdog_touch(-1);
301303
}
302304

303305
void touch_softlockup_watchdog_sync(void)
304306
{
305307
__this_cpu_write(softlockup_touch_sync, true);
306-
__this_cpu_write(watchdog_touch_ts, 0);
308+
__this_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET);
307309
}
308310

309311
static int is_softlockup(unsigned long touch_ts)
@@ -379,7 +381,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
379381
/* .. and repeat */
380382
hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));
381383

382-
if (touch_ts == 0) {
384+
if (touch_ts == SOFTLOCKUP_RESET) {
383385
if (unlikely(__this_cpu_read(softlockup_touch_sync))) {
384386
/*
385387
* If the time stamp was touched atomically

0 commit comments

Comments
 (0)