diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-07-03 08:30:32 -0500 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2009-07-29 23:30:38 +0200 |
| commit | e5e57bd60fce5d9e674f8fb3a1eaeb0dee114337 (patch) | |
| tree | 2d9c851bb1ad2d4c24b9170221a470c31642609b /kernel/timer.c | |
| parent | c90fc5b4462b0291bfce50ddf31e142471dc4803 (diff) | |
| download | lwn-e5e57bd60fce5d9e674f8fb3a1eaeb0dee114337.tar.gz lwn-e5e57bd60fce5d9e674f8fb3a1eaeb0dee114337.zip | |
timers: fix timer hotplug on -rt
Here we are in the CPU_DEAD notifier, and we must not sleep nor
enable interrupts.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 09026a957eef..e7b2deb54893 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1610,6 +1610,7 @@ static void __cpuinit migrate_timers(int cpu) { struct tvec_base *old_base; struct tvec_base *new_base; + unsigned long flags; int i; BUG_ON(cpu_online(cpu)); @@ -1619,8 +1620,11 @@ static void __cpuinit migrate_timers(int cpu) * The caller is globally serialized and nobody else * takes two locks at once, deadlock is not possible. */ - spin_lock_irq(&new_base->lock); - spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); + local_irq_save(flags); + while (!spin_trylock(&new_base->lock)) + cpu_relax(); + while (!spin_trylock(&old_base->lock)) + cpu_relax(); BUG_ON(old_base->running_timer); @@ -1634,7 +1638,9 @@ static void __cpuinit migrate_timers(int cpu) } spin_unlock(&old_base->lock); - spin_unlock_irq(&new_base->lock); + spin_unlock(&new_base->lock); + local_irq_restore(flags); + put_cpu_var(tvec_bases); } #endif /* CONFIG_HOTPLUG_CPU */ |
