aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/time/clocksource.c28
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;
121static LIST_HEAD(clocksource_list); 121static LIST_HEAD(clocksource_list);
122static DEFINE_MUTEX(clocksource_mutex); 122static DEFINE_MUTEX(clocksource_mutex);
123static char override_name[32]; 123static char override_name[32];
124static int finished_booting;
124 125
125#ifdef CONFIG_CLOCKSOURCE_WATCHDOG 126#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
126static void clocksource_watchdog_work(struct work_struct *work); 127static 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
161static void clocksource_unstable(struct clocksource *cs, int64_t delta) 163static 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
381static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { } 384static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
382static inline void clocksource_resume_watchdog(void) { } 385static inline void clocksource_resume_watchdog(void) { }
386static 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
418static 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
468static 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)
471static int __init clocksource_done_booting(void) 479static 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}
479fs_initcall(clocksource_done_booting); 493fs_initcall(clocksource_done_booting);
480 494
481#else /* CONFIG_GENERIC_TIME */
482
483static 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 */