timer: Fix hotplug regression
authorThomas Gleixner <tglx@linutronix.de>
Fri, 26 Jun 2015 20:08:38 +0000 (22:08 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 26 Jun 2015 20:58:06 +0000 (22:58 +0200)
The recent timer wheel rework removed the get/put_cpu_var() pair in
the hotplug migration code, which results in:

BUG: using smp_processor_id() in preemptible [00000000] code: hib.sh/2845
...
[<ffffffff810d4fa3>] timer_cpu_notify+0x53/0x12

That hunk is a leftover from an earlier iteration and went unnoticed
so far.

Restore the previous code which was obviously correct.

Fixes: 0eeda71bc30d 'timer: Replace timer base by a cpu index'
Reported-and_tested-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/time/timer.c

index 520499dd85af42e96b2bbd8c729df36d238ad27a..5e097fa9faf7016470b8283931023a15d20ed97d 100644 (file)
@@ -1566,7 +1566,7 @@ static void migrate_timers(int cpu)
 
        BUG_ON(cpu_online(cpu));
        old_base = per_cpu_ptr(&tvec_bases, cpu);
-       new_base = this_cpu_ptr(&tvec_bases);
+       new_base = get_cpu_ptr(&tvec_bases);
        /*
         * The caller is globally serialized and nobody else
         * takes two locks at once, deadlock is not possible.
@@ -1590,6 +1590,7 @@ static void migrate_timers(int cpu)
 
        spin_unlock(&old_base->lock);
        spin_unlock_irq(&new_base->lock);
+       put_cpu_ptr(&tvec_bases);
 }
 
 static int timer_cpu_notify(struct notifier_block *self,