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>

authored by Martin Schwidefsky and committed by Ingo Molnar f79e0258 e500011f

+3 -2
+3 -2
kernel/time/clocksource.c
··· 123 static char override_name[32]; 124 125 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG 126 static LIST_HEAD(watchdog_list); 127 static struct clocksource *watchdog; 128 static struct timer_list watchdog_timer; 129 - static struct work_struct watchdog_work; 130 static DEFINE_SPINLOCK(watchdog_lock); 131 static cycle_t watchdog_last; 132 static int watchdog_running; ··· 259 { 260 if (watchdog_running || !watchdog || list_empty(&watchdog_list)) 261 return; 262 - INIT_WORK(&watchdog_work, clocksource_watchdog_work); 263 init_timer(&watchdog_timer); 264 watchdog_timer.function = clocksource_watchdog; 265 watchdog_last = watchdog->read(watchdog);
··· 123 static char override_name[32]; 124 125 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG 126 + static void clocksource_watchdog_work(struct work_struct *work); 127 + 128 static LIST_HEAD(watchdog_list); 129 static struct clocksource *watchdog; 130 static struct timer_list watchdog_timer; 131 + static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); 132 static DEFINE_SPINLOCK(watchdog_lock); 133 static cycle_t watchdog_last; 134 static int watchdog_running; ··· 257 { 258 if (watchdog_running || !watchdog || list_empty(&watchdog_list)) 259 return; 260 init_timer(&watchdog_timer); 261 watchdog_timer.function = clocksource_watchdog; 262 watchdog_last = watchdog->read(watchdog);