On Fri, 2010-11-12 at 13:31 -0800, john stultz wrote:
Here's a rough and untested attempt at adding just #3.
thanks
-john
Improve watchdog hursitics to avoid false positives caused by the
watchdog being delayed.
Signed-off-by: John Stultz <johnstul@us.ibm.com>
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index c18d7ef..d63f6f8 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -247,6 +247,7 @@ static void clocksource_watchdog(unsigned long data)
struct clocksource *cs;
cycle_t csnow, wdnow;
int64_t wd_nsec, cs_nsec;
+ int64_t wd_max_nsec;
int next_cpu;
spin_lock(&watchdog_lock);
@@ -257,6 +258,8 @@ static void clocksource_watchdog(unsigned long data)
wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask,
watchdog->mult, watchdog->shift);
watchdog_last = wdnow;
+ wd_max_nsec = clocksource_cyc2ns(watchdog->mask, watchdog->mult,
+ watchdog->shift);
list_for_each_entry(cs, &watchdog_list, wd_list) {
@@ -280,6 +283,14 @@ static void clocksource_watchdog(unsigned long data)
cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) &
cs->mask, cs->mult, cs->shift);
cs->wd_last = csnow;
+
+ /* Check to make sure the watchdog wasn't delayed */
+ if (cs_nsec > wd_max_nsec) {
+ WARN_ONCE(1,
+ "clocksource_watchdog: watchdog delayed?\n");
+ continue;
+ }
+
if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
clocksource_unstable(cs, cs_nsec - wd_nsec);
continue;
--