Commit f79e0258 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Ingo Molnar

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: default avatarMartin 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: default avatarIngo Molnar <mingo@elte.hu>
parent e500011f
...@@ -123,10 +123,12 @@ static DEFINE_MUTEX(clocksource_mutex); ...@@ -123,10 +123,12 @@ static DEFINE_MUTEX(clocksource_mutex);
static char override_name[32]; static char override_name[32];
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
static void clocksource_watchdog_work(struct work_struct *work);
static LIST_HEAD(watchdog_list); static LIST_HEAD(watchdog_list);
static struct clocksource *watchdog; static struct clocksource *watchdog;
static struct timer_list watchdog_timer; static struct timer_list watchdog_timer;
static struct work_struct watchdog_work; static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
static DEFINE_SPINLOCK(watchdog_lock); static DEFINE_SPINLOCK(watchdog_lock);
static cycle_t watchdog_last; static cycle_t watchdog_last;
static int watchdog_running; static int watchdog_running;
...@@ -257,7 +259,6 @@ static inline void clocksource_start_watchdog(void) ...@@ -257,7 +259,6 @@ static inline void clocksource_start_watchdog(void)
{ {
if (watchdog_running || !watchdog || list_empty(&watchdog_list)) if (watchdog_running || !watchdog || list_empty(&watchdog_list))
return; return;
INIT_WORK(&watchdog_work, clocksource_watchdog_work);
init_timer(&watchdog_timer); init_timer(&watchdog_timer);
watchdog_timer.function = clocksource_watchdog; watchdog_timer.function = clocksource_watchdog;
watchdog_last = watchdog->read(watchdog); watchdog_last = watchdog->read(watchdog);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment