aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-09-11 09:33:05 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-11 14:17:18 -0400
commitf79e0258ea1f04d63db499479b5fb855dff6dbc5 (patch)
tree66edb089e5c3aee03e1326d41e47d7e14c21e76b /kernel/time
parente500011ffa191d662ac64d4ada6a5187b3180e16 (diff)
clocksource: Resolve cpu hotplug dead lock with TSC unstable, fix crash
The watchdog timer is started after the watchdog clocksource and at least one watched clocksource have been registered. The clocksource work element watchdog_work is initialized just before the clocksource timer is started. This is too late for the clocksource_mark_unstable call from native_cpu_up. To fix this use a static initializer for watchdog_work. This resolves a boot crash reported by multiple people. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Jens Axboe <jens.axboe@oracle.com> Cc: John Stultz <johnstul@us.ibm.com> LKML-Reference: <20090911153305.3fe9a361@skybase> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/clocksource.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index a0af4ffcb6e5..5697155f1868 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -123,10 +123,12 @@ static DEFINE_MUTEX(clocksource_mutex);
123static char override_name[32]; 123static char override_name[32];
124 124
125#ifdef CONFIG_CLOCKSOURCE_WATCHDOG 125#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
126static void clocksource_watchdog_work(struct work_struct *work);
127
126static LIST_HEAD(watchdog_list); 128static LIST_HEAD(watchdog_list);
127static struct clocksource *watchdog; 129static struct clocksource *watchdog;
128static struct timer_list watchdog_timer; 130static struct timer_list watchdog_timer;
129static struct work_struct watchdog_work; 131static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
130static DEFINE_SPINLOCK(watchdog_lock); 132static DEFINE_SPINLOCK(watchdog_lock);
131static cycle_t watchdog_last; 133static cycle_t watchdog_last;
132static int watchdog_running; 134static int watchdog_running;
@@ -257,7 +259,6 @@ static inline void clocksource_start_watchdog(void)
257{ 259{
258 if (watchdog_running || !watchdog || list_empty(&watchdog_list)) 260 if (watchdog_running || !watchdog || list_empty(&watchdog_list))
259 return; 261 return;
260 INIT_WORK(&watchdog_work, clocksource_watchdog_work);
261 init_timer(&watchdog_timer); 262 init_timer(&watchdog_timer);
262 watchdog_timer.function = clocksource_watchdog; 263 watchdog_timer.function = clocksource_watchdog;
263 watchdog_last = watchdog->read(watchdog); 264 watchdog_last = watchdog->read(watchdog);