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 | */ |