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