diff options
| -rw-r--r-- | kernel/time/clocksource.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 2c2e5ba1453d..09113347d328 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -121,6 +121,7 @@ static struct clocksource *curr_clocksource; | |||
| 121 | static LIST_HEAD(clocksource_list); | 121 | static LIST_HEAD(clocksource_list); |
| 122 | static DEFINE_MUTEX(clocksource_mutex); | 122 | static DEFINE_MUTEX(clocksource_mutex); |
| 123 | static char override_name[32]; | 123 | static char override_name[32]; |
| 124 | static int finished_booting; | ||
| 124 | 125 | ||
| 125 | #ifdef CONFIG_CLOCKSOURCE_WATCHDOG | 126 | #ifdef CONFIG_CLOCKSOURCE_WATCHDOG |
| 126 | static void clocksource_watchdog_work(struct work_struct *work); | 127 | static void clocksource_watchdog_work(struct work_struct *work); |
| @@ -155,7 +156,8 @@ static void __clocksource_unstable(struct clocksource *cs) | |||
| 155 | { | 156 | { |
| 156 | cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); | 157 | cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); |
| 157 | cs->flags |= CLOCK_SOURCE_UNSTABLE; | 158 | cs->flags |= CLOCK_SOURCE_UNSTABLE; |
| 158 | schedule_work(&watchdog_work); | 159 | if (finished_booting) |
| 160 | schedule_work(&watchdog_work); | ||
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | static void clocksource_unstable(struct clocksource *cs, int64_t delta) | 163 | static void clocksource_unstable(struct clocksource *cs, int64_t delta) |
| @@ -207,7 +209,8 @@ static void clocksource_watchdog(unsigned long data) | |||
| 207 | 209 | ||
| 208 | /* Clocksource already marked unstable? */ | 210 | /* Clocksource already marked unstable? */ |
| 209 | if (cs->flags & CLOCK_SOURCE_UNSTABLE) { | 211 | if (cs->flags & CLOCK_SOURCE_UNSTABLE) { |
| 210 | schedule_work(&watchdog_work); | 212 | if (finished_booting) |
| 213 | schedule_work(&watchdog_work); | ||
| 211 | continue; | 214 | continue; |
| 212 | } | 215 | } |
| 213 | 216 | ||
| @@ -380,6 +383,7 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs) | |||
| 380 | 383 | ||
| 381 | static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { } | 384 | static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { } |
| 382 | static inline void clocksource_resume_watchdog(void) { } | 385 | static inline void clocksource_resume_watchdog(void) { } |
| 386 | static inline int clocksource_watchdog_kthread(void *data) { return 0; } | ||
| 383 | 387 | ||
| 384 | #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ | 388 | #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ |
| 385 | 389 | ||
| @@ -415,8 +419,6 @@ void clocksource_touch_watchdog(void) | |||
| 415 | 419 | ||
| 416 | #ifdef CONFIG_GENERIC_TIME | 420 | #ifdef CONFIG_GENERIC_TIME |
| 417 | 421 | ||
| 418 | static int finished_booting; | ||
| 419 | |||
| 420 | /** | 422 | /** |
| 421 | * clocksource_select - Select the best clocksource available | 423 | * clocksource_select - Select the best clocksource available |
| 422 | * | 424 | * |
| @@ -461,6 +463,12 @@ static void clocksource_select(void) | |||
| 461 | } | 463 | } |
| 462 | } | 464 | } |
| 463 | 465 | ||
| 466 | #else /* CONFIG_GENERIC_TIME */ | ||
| 467 | |||
| 468 | static inline void clocksource_select(void) { } | ||
| 469 | |||
| 470 | #endif | ||
| 471 | |||
| 464 | /* | 472 | /* |
| 465 | * clocksource_done_booting - Called near the end of core bootup | 473 | * clocksource_done_booting - Called near the end of core bootup |
| 466 | * | 474 | * |
| @@ -471,6 +479,12 @@ static void clocksource_select(void) | |||
| 471 | static int __init clocksource_done_booting(void) | 479 | static int __init clocksource_done_booting(void) |
| 472 | { | 480 | { |
| 473 | finished_booting = 1; | 481 | finished_booting = 1; |
| 482 | |||
| 483 | /* | ||
| 484 | * Run the watchdog first to eliminate unstable clock sources | ||
| 485 | */ | ||
| 486 | clocksource_watchdog_kthread(NULL); | ||
| 487 | |||
| 474 | mutex_lock(&clocksource_mutex); | 488 | mutex_lock(&clocksource_mutex); |
| 475 | clocksource_select(); | 489 | clocksource_select(); |
| 476 | mutex_unlock(&clocksource_mutex); | 490 | mutex_unlock(&clocksource_mutex); |
| @@ -478,12 +492,6 @@ static int __init clocksource_done_booting(void) | |||
| 478 | } | 492 | } |
| 479 | fs_initcall(clocksource_done_booting); | 493 | fs_initcall(clocksource_done_booting); |
| 480 | 494 | ||
| 481 | #else /* CONFIG_GENERIC_TIME */ | ||
| 482 | |||
| 483 | static inline void clocksource_select(void) { } | ||
| 484 | |||
| 485 | #endif | ||
| 486 | |||
| 487 | /* | 495 | /* |
| 488 | * Enqueue the clocksource sorted by rating | 496 | * Enqueue the clocksource sorted by rating |
| 489 | */ | 497 | */ |
