diff options
Diffstat (limited to 'kernel/time/clocksource.c')
| -rw-r--r-- | kernel/time/clocksource.c | 24 |
1 files changed, 13 insertions, 11 deletions
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; |
