| From 140de0542b255923d9276f6621b69b4e32507369 Mon Sep 17 00:00:00 2001 |
| From: Ingo Molnar <mingo@elte.hu> |
| Date: Fri, 3 Jul 2009 08:30:32 -0500 |
| Subject: [PATCH] timers: fix timer hotplug on -rt |
| |
| commit e5e57bd60fce5d9e674f8fb3a1eaeb0dee114337 in tip. |
| |
| 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> |
| |
| diff --git a/kernel/timer.c b/kernel/timer.c |
| index 9f1a662..47ff839 100644 |
| --- a/kernel/timer.c |
| +++ b/kernel/timer.c |
| @@ -1653,6 +1653,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)); |
| @@ -1662,8 +1663,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); |
| |
| @@ -1677,7 +1681,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 */ |
| -- |
| 1.7.1.1 |
| |