From f335bcc4033fef31042428ecf989027d9d9b65d8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar 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 Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- kernel/timer.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index e342eef..a081803 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1655,6 +1655,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)); @@ -1664,8 +1665,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); @@ -1679,7 +1683,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.0.4