From b7a5c5ef96a345812ca14dfae9411cee5a0f83a5 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:30:20 -0500
Subject: [PATCH 078/365] timers: Preempt-rt support

The base->lock is a sleeping lock. Try not to workaround with a
spin_trylock(). The rt-mutex lock is not irq save even the try-lock
due to way how the inner lock accessed. Even with this fixed have the
problem that the owner is not the current process on the CPU but his
pid is used while taking the lock.  Therefore we go with ext jiffy for
the wakeup. Also drop preempt_disable() usage since we need just to
ensure not to switch CPUs (the data structures have own locks).

[bigeasy: dropped that spin try lock]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/timer.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 5fa215eefa52..2230419c5155 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1422,6 +1422,14 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
 	if (cpu_is_offline(smp_processor_id()))
 		return expires;
 
+#ifdef CONFIG_PREEMPT_RT_FULL
+	/*
+	 * On PREEMPT_RT we cannot sleep here. As a result we can't take
+	 * the base lock to check when the next timer is pending and so
+	 * we assume the next jiffy.
+	 */
+	return basej;
+#endif
 	spin_lock(&base->lock);
 	if (base->active_timers) {
 		if (time_before_eq(base->next_timer, base->timer_jiffies))
@@ -1621,7 +1629,7 @@ static void migrate_timers(int cpu)
 
 	BUG_ON(cpu_online(cpu));
 	old_base = per_cpu_ptr(&tvec_bases, cpu);
-	new_base = get_cpu_ptr(&tvec_bases);
+	new_base = get_local_ptr(&tvec_bases);
 	/*
 	 * The caller is globally serialized and nobody else
 	 * takes two locks at once, deadlock is not possible.
@@ -1645,7 +1653,7 @@ static void migrate_timers(int cpu)
 
 	spin_unlock(&old_base->lock);
 	spin_unlock_irq(&new_base->lock);
-	put_cpu_ptr(&tvec_bases);
+	put_local_ptr(&tvec_bases);
 }
 
 static int timer_cpu_notify(struct notifier_block *self,
-- 
2.10.2

