Skip to content

Commit ec68deb

Browse files
committed
clocksource: Reject bogus watchdog clocksource measurements
One remaining clocksource-skew issue involves extreme CPU overcommit, which can cause the clocksource watchdog measurements to be delayed by tens of seconds. This in turn means that a clock-skew criterion that is appropriate for a 500-millisecond interval will instead give lots of false positives. Therefore, check for the watchdog clocksource reporting much larger or much less than the time specified by WATCHDOG_INTERVAL. In these cases, print a pr_warn() warning and refrain from marking the clocksource under test as being unstable. Reported-by: Chris Mason <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> Cc: John Stultz <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: Feng Tang <[email protected]> Cc: Waiman Long <[email protected]>
1 parent c69f94b commit ec68deb

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

kernel/time/clocksource.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ EXPORT_SYMBOL_GPL(clocksource_verify_percpu);
386386

387387
static void clocksource_watchdog(struct timer_list *unused)
388388
{
389-
u64 csnow, wdnow, cslast, wdlast, delta;
389+
u64 csnow, wdnow, cslast, wdlast, delta, wdi;
390390
int next_cpu, reset_pending;
391391
int64_t wd_nsec, cs_nsec;
392392
struct clocksource *cs;
@@ -440,6 +440,17 @@ static void clocksource_watchdog(struct timer_list *unused)
440440
if (atomic_read(&watchdog_reset_pending))
441441
continue;
442442

443+
/* Check for bogus measurements. */
444+
wdi = jiffies_to_nsecs(WATCHDOG_INTERVAL);
445+
if (wd_nsec < (wdi >> 2)) {
446+
pr_warn("timekeeping watchdog on CPU%d: Watchdog clocksource '%s' advanced only %lld ns during %d-jiffy time interval, skipping watchdog check.\n", smp_processor_id(), watchdog->name, wd_nsec, WATCHDOG_INTERVAL);
447+
continue;
448+
}
449+
if (wd_nsec > (wdi << 2)) {
450+
pr_warn("timekeeping watchdog on CPU%d: Watchdog clocksource '%s' advanced an excessive %lld ns during %d-jiffy time interval, probable CPU overutilization, skipping watchdog check.\n", smp_processor_id(), watchdog->name, wd_nsec, WATCHDOG_INTERVAL);
451+
continue;
452+
}
453+
443454
/* Check the deviation from the watchdog clocksource. */
444455
md = cs->uncertainty_margin + watchdog->uncertainty_margin;
445456
if (abs(cs_nsec - wd_nsec) > md) {

0 commit comments

Comments
 (0)