@@ -386,7 +386,7 @@ EXPORT_SYMBOL_GPL(clocksource_verify_percpu);
386386
387387static 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