diff options
| -rw-r--r-- | include/linux/clocksource.h | 1 | ||||
| -rw-r--r-- | kernel/time/clocksource.c | 24 |
2 files changed, 14 insertions, 11 deletions
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index d4646b48dc4a..18a1baf31f2d 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
| @@ -188,6 +188,7 @@ struct clocksource { | |||
| 188 | #ifdef CONFIG_CLOCKSOURCE_WATCHDOG | 188 | #ifdef CONFIG_CLOCKSOURCE_WATCHDOG |
| 189 | /* Watchdog related data, used by the framework */ | 189 | /* Watchdog related data, used by the framework */ |
| 190 | struct list_head wd_list; | 190 | struct list_head wd_list; |
| 191 | cycle_t cs_last; | ||
| 191 | cycle_t wd_last; | 192 | cycle_t wd_last; |
| 192 | #endif | 193 | #endif |
| 193 | } ____cacheline_aligned; | 194 | } ____cacheline_aligned; |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 1c95fd677328..e0980f0d9a0a 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -185,7 +185,6 @@ static struct clocksource *watchdog; | |||
| 185 | static struct timer_list watchdog_timer; | 185 | static struct timer_list watchdog_timer; |
| 186 | static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); | 186 | static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); |
| 187 | static DEFINE_SPINLOCK(watchdog_lock); | 187 | static DEFINE_SPINLOCK(watchdog_lock); |
| 188 | static cycle_t watchdog_last; | ||
| 189 | static int watchdog_running; | 188 | static int watchdog_running; |
| 190 | 189 | ||
| 191 | static int clocksource_watchdog_kthread(void *data); | 190 | static int clocksource_watchdog_kthread(void *data); |
| @@ -254,11 +253,6 @@ static void clocksource_watchdog(unsigned long data) | |||
| 254 | if (!watchdog_running) | 253 | if (!watchdog_running) |
| 255 | goto out; | 254 | goto out; |
| 256 | 255 | ||
| 257 | wdnow = watchdog->read(watchdog); | ||
| 258 | wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask, | ||
| 259 | watchdog->mult, watchdog->shift); | ||
| 260 | watchdog_last = wdnow; | ||
| 261 | |||
| 262 | list_for_each_entry(cs, &watchdog_list, wd_list) { | 256 | list_for_each_entry(cs, &watchdog_list, wd_list) { |
| 263 | 257 | ||
| 264 | /* Clocksource already marked unstable? */ | 258 | /* Clocksource already marked unstable? */ |
| @@ -268,19 +262,28 @@ static void clocksource_watchdog(unsigned long data) | |||
| 268 | continue; | 262 | continue; |
| 269 | } | 263 | } |
| 270 | 264 | ||
| 265 | local_irq_disable(); | ||
| 271 | csnow = cs->read(cs); | 266 | csnow = cs->read(cs); |
| 267 | wdnow = watchdog->read(watchdog); | ||
| 268 | local_irq_enable(); | ||
| 272 | 269 | ||
| 273 | /* Clocksource initialized ? */ | 270 | /* Clocksource initialized ? */ |
| 274 | if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { | 271 | if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { |
| 275 | cs->flags |= CLOCK_SOURCE_WATCHDOG; | 272 | cs->flags |= CLOCK_SOURCE_WATCHDOG; |
| 276 | cs->wd_last = csnow; | 273 | cs->wd_last = wdnow; |
| 274 | cs->cs_last = csnow; | ||
| 277 | continue; | 275 | continue; |
| 278 | } | 276 | } |
| 279 | 277 | ||
| 280 | /* Check the deviation from the watchdog clocksource. */ | 278 | wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask, |
| 281 | cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) & | 279 | watchdog->mult, watchdog->shift); |
| 280 | |||
| 281 | cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) & | ||
| 282 | cs->mask, cs->mult, cs->shift); | 282 | cs->mask, cs->mult, cs->shift); |
| 283 | cs->wd_last = csnow; | 283 | cs->cs_last = csnow; |
| 284 | cs->wd_last = wdnow; | ||
| 285 | |||
| 286 | /* Check the deviation from the watchdog clocksource. */ | ||
| 284 | if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) { | 287 | if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) { |
| 285 | clocksource_unstable(cs, cs_nsec - wd_nsec); | 288 | clocksource_unstable(cs, cs_nsec - wd_nsec); |
| 286 | continue; | 289 | continue; |
| @@ -318,7 +321,6 @@ static inline void clocksource_start_watchdog(void) | |||
| 318 | return; | 321 | return; |
| 319 | init_timer(&watchdog_timer); | 322 | init_timer(&watchdog_timer); |
| 320 | watchdog_timer.function = clocksource_watchdog; | 323 | watchdog_timer.function = clocksource_watchdog; |
| 321 | watchdog_last = watchdog->read(watchdog); | ||
| 322 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; | 324 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; |
| 323 | add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask)); | 325 | add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask)); |
| 324 | watchdog_running = 1; | 326 | watchdog_running = 1; |
