[kernel] r19929 - dists/sid/linux/debian/patches/features/all/rt

Ben Hutchings benh at alioth.debian.org
Thu Mar 21 05:25:15 UTC 2013


Author: benh
Date: Thu Mar 21 05:25:15 2013
New Revision: 19929

Log:
[rt] Resolve a tricky conflict with an hrtimer fix in 3.2.40

Modified:
   dists/sid/linux/debian/patches/features/all/rt/0134-hrtimer-fixup-hrtimer-callback-changes-for-preempt-r.patch
   dists/sid/linux/debian/patches/features/all/rt/0135-hrtimer-Don-t-call-the-timer-handler-from-hrtimer_st.patch

Modified: dists/sid/linux/debian/patches/features/all/rt/0134-hrtimer-fixup-hrtimer-callback-changes-for-preempt-r.patch
==============================================================================
--- dists/sid/linux/debian/patches/features/all/rt/0134-hrtimer-fixup-hrtimer-callback-changes-for-preempt-r.patch	Thu Mar 21 03:39:15 2013	(r19928)
+++ dists/sid/linux/debian/patches/features/all/rt/0134-hrtimer-fixup-hrtimer-callback-changes-for-preempt-r.patch	Thu Mar 21 05:25:15 2013	(r19929)
@@ -1,4 +1,3 @@
-From c495d005449523772e27a22fb74814dc3cebff8e Mon Sep 17 00:00:00 2001
 From: Thomas Gleixner <tglx at linutronix.de>
 Date: Fri, 3 Jul 2009 08:44:31 -0500
 Subject: [PATCH 134/304] hrtimer: fixup hrtimer callback changes for
@@ -12,6 +11,10 @@
 
 Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
 Signed-off-by: Ingo Molnar <mingo at elte.hu>
+[bwh: Pull the changes to hrtimer_enqueue_reprogram() up into
+ __hrtimer_start_range_ns(), following changes in
+ commit b22affe0aef4 'hrtimer: Prevent hrtimer_enqueue_reprogram race'
+ backported into 3.2.40]
 ---
  include/linux/hrtimer.h  |    3 +
  kernel/hrtimer.c         |  194 +++++++++++++++++++++++++++++++++++++++++-----
@@ -20,8 +23,6 @@
  kernel/watchdog.c        |    1 +
  5 files changed, 181 insertions(+), 20 deletions(-)
 
-diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
-index 75b2545..26b008b 100644
 --- a/include/linux/hrtimer.h
 +++ b/include/linux/hrtimer.h
 @@ -111,6 +111,8 @@ struct hrtimer {
@@ -41,11 +42,9 @@
  	ktime_t			resolution;
  	ktime_t			(*get_time)(void);
  	ktime_t			softirq_time;
-diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
-index 45b923b..392fa07 100644
 --- a/kernel/hrtimer.c
 +++ b/kernel/hrtimer.c
-@@ -589,8 +589,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
+@@ -589,8 +589,7 @@ static int hrtimer_reprogram(struct hrti
  	 * When the callback is running, we do not reprogram the clock event
  	 * device. The timer callback is either running on a different CPU or
  	 * the callback is executed in the hrtimer_interrupt context. The
@@ -55,7 +54,7 @@
  	 */
  	if (hrtimer_callback_running(timer))
  		return 0;
-@@ -625,6 +624,9 @@ static int hrtimer_reprogram(struct hrtimer *timer,
+@@ -625,6 +624,9 @@ static int hrtimer_reprogram(struct hrti
  	return res;
  }
  
@@ -65,37 +64,7 @@
  /*
   * Initialize the high resolution related parts of cpu_base
   */
-@@ -644,7 +646,29 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
- 					    struct hrtimer_clock_base *base,
- 					    int wakeup)
- {
-+#ifdef CONFIG_PREEMPT_RT_BASE
-+again:
- 	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
-+		/*
-+		 * Move softirq based timers away from the rbtree in
-+		 * case it expired already. Otherwise we would have a
-+		 * stale base->first entry until the softirq runs.
-+		 */
-+		if (!hrtimer_rt_defer(timer)) {
-+			ktime_t now = ktime_get();
-+
-+			__run_hrtimer(timer, &now);
-+			/*
-+			 * __run_hrtimer might have requeued timer and
-+			 * it could be base->first again.
-+			 */
-+			if (&timer->node == base->active.next)
-+				goto again;
-+			return 1;
-+		}
-+#else
-+	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
-+#endif
- 		if (wakeup) {
- 			raw_spin_unlock(&base->cpu_base->lock);
- 			raise_softirq_irqoff(HRTIMER_SOFTIRQ);
-@@ -743,6 +767,11 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
+@@ -730,6 +732,11 @@ static inline int hrtimer_enqueue_reprog
  }
  static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { }
  static inline void retrigger_next_event(void *arg) { }
@@ -107,7 +76,7 @@
  
  #endif /* CONFIG_HIGH_RES_TIMERS */
  
-@@ -874,9 +903,9 @@ void hrtimer_wait_for_timer(const struct hrtimer *timer)
+@@ -861,9 +868,9 @@ void hrtimer_wait_for_timer(const struct
  {
  	struct hrtimer_clock_base *base = timer->base;
  
@@ -119,7 +88,7 @@
  }
  
  #else
-@@ -926,6 +955,11 @@ static void __remove_hrtimer(struct hrtimer *timer,
+@@ -913,6 +920,11 @@ static void __remove_hrtimer(struct hrti
  	if (!(timer->state & HRTIMER_STATE_ENQUEUED))
  		goto out;
  
@@ -131,7 +100,34 @@
  	next_timer = timerqueue_getnext(&base->active);
  	timerqueue_del(&base->active, &timer->node);
  	if (&timer->node == next_timer) {
-@@ -1188,6 +1222,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
+@@ -1011,6 +1023,26 @@ int __hrtimer_start_range_ns(struct hrti
+ 	 */
+ 	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases)
+ 		&& hrtimer_enqueue_reprogram(timer, new_base)) {
++#ifdef CONFIG_PREEMPT_RT_BASE
++	again:
++		/*
++		 * Move softirq based timers away from the rbtree in
++		 * case it expired already. Otherwise we would have a
++		 * stale base->first entry until the softirq runs.
++		 */
++		if (!hrtimer_rt_defer(timer)) {
++			ktime_t now = ktime_get();
++
++			__run_hrtimer(timer, &now);
++			/*
++			 * __run_hrtimer might have requeued timer and
++			 * it could be base->first again.
++			 */
++			if (&timer->node == new_base->active.next &&
++			    hrtimer_enqueue_reprogram(timer, new_base))
++				goto again;
++		} else
++#endif
+ 		if (wakeup) {
+ 			/*
+ 			 * We need to drop cpu_base->lock to avoid a
+@@ -1188,6 +1220,7 @@ static void __hrtimer_init(struct hrtime
  
  	base = hrtimer_clockid_to_base(clock_id);
  	timer->base = &cpu_base->clock_base[base];
@@ -139,7 +135,7 @@
  	timerqueue_init(&timer->node);
  
  #ifdef CONFIG_TIMER_STATS
-@@ -1271,10 +1306,118 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
+@@ -1271,10 +1304,118 @@ static void __run_hrtimer(struct hrtimer
  	timer->state &= ~HRTIMER_STATE_CALLBACK;
  }
  
@@ -260,7 +256,7 @@
  /*
   * High resolution timer interrupt
   * Called with interrupts disabled
-@@ -1283,7 +1426,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
+@@ -1283,7 +1424,7 @@ void hrtimer_interrupt(struct clock_even
  {
  	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
  	ktime_t expires_next, now, entry_time, delta;
@@ -269,7 +265,7 @@
  
  	BUG_ON(!cpu_base->hres_active);
  	cpu_base->nr_events++;
-@@ -1349,7 +1492,10 @@ retry:
+@@ -1349,7 +1490,10 @@ retry:
  				break;
  			}
  
@@ -281,7 +277,7 @@
  		}
  	}
  
-@@ -1364,6 +1510,10 @@ retry:
+@@ -1364,6 +1508,10 @@ retry:
  	if (expires_next.tv64 == KTIME_MAX ||
  	    !tick_program_event(expires_next, 0)) {
  		cpu_base->hang_detected = 0;
@@ -292,7 +288,7 @@
  		return;
  	}
  
-@@ -1444,6 +1594,12 @@ void hrtimer_peek_ahead_timers(void)
+@@ -1444,6 +1592,12 @@ void hrtimer_peek_ahead_timers(void)
  	local_irq_restore(flags);
  }
  
@@ -305,7 +301,7 @@
  static void run_hrtimer_softirq(struct softirq_action *h)
  {
  	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
-@@ -1453,15 +1609,9 @@ static void run_hrtimer_softirq(struct softirq_action *h)
+@@ -1453,15 +1607,9 @@ static void run_hrtimer_softirq(struct s
  		clock_was_set();
  	}
  
@@ -322,7 +318,7 @@
  /*
   * Called from timer softirq every jiffy, expire hrtimers:
   *
-@@ -1494,7 +1644,7 @@ void hrtimer_run_queues(void)
+@@ -1494,7 +1642,7 @@ void hrtimer_run_queues(void)
  	struct timerqueue_node *node;
  	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
  	struct hrtimer_clock_base *base;
@@ -331,7 +327,7 @@
  
  	if (hrtimer_hres_active())
  		return;
-@@ -1519,12 +1669,16 @@ void hrtimer_run_queues(void)
+@@ -1519,12 +1667,16 @@ void hrtimer_run_queues(void)
  					hrtimer_get_expires_tv64(timer))
  				break;
  
@@ -350,7 +346,7 @@
  }
  
  /*
-@@ -1546,6 +1700,7 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
+@@ -1546,6 +1698,7 @@ static enum hrtimer_restart hrtimer_wake
  void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
  {
  	sl->timer.function = hrtimer_wakeup;
@@ -358,7 +354,7 @@
  	sl->task = task;
  }
  EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
-@@ -1684,6 +1839,7 @@ static void __cpuinit init_hrtimers_cpu(int cpu)
+@@ -1684,6 +1837,7 @@ static void __cpuinit init_hrtimers_cpu(
  	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
  		cpu_base->clock_base[i].cpu_base = cpu_base;
  		timerqueue_init_head(&cpu_base->clock_base[i].active);
@@ -366,7 +362,7 @@
  	}
  
  	hrtimer_init_hres(cpu_base);
-@@ -1802,9 +1958,7 @@ void __init hrtimers_init(void)
+@@ -1802,9 +1956,7 @@ void __init hrtimers_init(void)
  	hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
  			  (void *)(long)smp_processor_id());
  	register_cpu_notifier(&hrtimers_nb);
@@ -376,11 +372,9 @@
  }
  
  /**
-diff --git a/kernel/sched.c b/kernel/sched.c
-index 6c05b86..a877974 100644
 --- a/kernel/sched.c
 +++ b/kernel/sched.c
-@@ -189,6 +189,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime)
+@@ -189,6 +189,7 @@ void init_rt_bandwidth(struct rt_bandwid
  
  	hrtimer_init(&rt_b->rt_period_timer,
  			CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -388,7 +382,7 @@
  	rt_b->rt_period_timer.function = sched_rt_period_timer;
  }
  
-@@ -1274,6 +1275,7 @@ static void init_rq_hrtick(struct rq *rq)
+@@ -1274,6 +1275,7 @@ static void init_rq_hrtick(struct rq *rq
  
  	hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  	rq->hrtick_timer.function = hrtick;
@@ -396,8 +390,6 @@
  }
  #else	/* CONFIG_SCHED_HRTICK */
  static inline void hrtick_clear(struct rq *rq)
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 9964bda..548d311 100644
 --- a/kernel/time/tick-sched.c
 +++ b/kernel/time/tick-sched.c
 @@ -805,6 +805,7 @@ void tick_setup_sched_timer(void)
@@ -408,11 +400,9 @@
  	ts->sched_timer.function = tick_sched_timer;
  
  	/* Get the next period (per cpu) */
-diff --git a/kernel/watchdog.c b/kernel/watchdog.c
-index 7016b38..3a4d0bc 100644
 --- a/kernel/watchdog.c
 +++ b/kernel/watchdog.c
-@@ -436,6 +436,7 @@ static void watchdog_prepare_cpu(int cpu)
+@@ -436,6 +436,7 @@ static void watchdog_prepare_cpu(int cpu
  	WARN_ON(per_cpu(softlockup_watchdog, cpu));
  	hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  	hrtimer->function = watchdog_timer_fn;

Modified: dists/sid/linux/debian/patches/features/all/rt/0135-hrtimer-Don-t-call-the-timer-handler-from-hrtimer_st.patch
==============================================================================
--- dists/sid/linux/debian/patches/features/all/rt/0135-hrtimer-Don-t-call-the-timer-handler-from-hrtimer_st.patch	Thu Mar 21 03:39:15 2013	(r19928)
+++ dists/sid/linux/debian/patches/features/all/rt/0135-hrtimer-Don-t-call-the-timer-handler-from-hrtimer_st.patch	Thu Mar 21 05:25:15 2013	(r19929)
@@ -1,4 +1,3 @@
-From 80cc960e628509c72f63a7327a4dc22707a02b81 Mon Sep 17 00:00:00 2001
 From: Peter Zijlstra <a.p.zijlstra at chello.nl>
 Date: Fri, 12 Aug 2011 17:39:54 +0200
 Subject: [PATCH 135/304] hrtimer: Don't call the timer handler from
@@ -28,25 +27,22 @@
 timers.
 
 Signed-off-by: Peter Zijlstra <a.p.zijlstra at chello.nl>
+[bwh: Pull the changes to hrtimer_enqueue_reprogram() up into
+ __hrtimer_start_range_ns(), following changes in
+ commit b22affe0aef4 'hrtimer: Prevent hrtimer_enqueue_reprogram race'
+ backported into 3.2.40]
 ---
  kernel/hrtimer.c |   48 +++++++++++++++++++++++-------------------------
  1 file changed, 23 insertions(+), 25 deletions(-)
 
-diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
-index 392fa07..27a3192 100644
 --- a/kernel/hrtimer.c
 +++ b/kernel/hrtimer.c
-@@ -646,37 +646,24 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
- 					    struct hrtimer_clock_base *base,
- 					    int wakeup)
- {
+@@ -1023,37 +1023,31 @@ int __hrtimer_start_range_ns(struct hrti
+ 	 */
+ 	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases)
+ 		&& hrtimer_enqueue_reprogram(timer, new_base)) {
 -#ifdef CONFIG_PREEMPT_RT_BASE
--again:
- 	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
-+		if (!wakeup)
-+			return -ETIME;
-+
-+#ifdef CONFIG_PREEMPT_RT_BASE
+-	again:
  		/*
  		 * Move softirq based timers away from the rbtree in
  		 * case it expired already. Otherwise we would have a
@@ -60,39 +56,29 @@
 -			 * __run_hrtimer might have requeued timer and
 -			 * it could be base->first again.
 -			 */
--			if (&timer->node == base->active.next)
+-			if (&timer->node == new_base->active.next &&
+-			    hrtimer_enqueue_reprogram(timer, new_base))
 -				goto again;
--			return 1;
--		}
--#else
--	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
-+		if (!hrtimer_rt_defer(timer))
-+			return -ETIME;
+-		} else
++		if (wakeup
++#ifdef CONFIG_PREEMPT_RT_BASE
++		    && hrtimer_rt_defer(timer)
  #endif
 -		if (wakeup) {
--			raw_spin_unlock(&base->cpu_base->lock);
--			raise_softirq_irqoff(HRTIMER_SOFTIRQ);
--			raw_spin_lock(&base->cpu_base->lock);
--		} else
+-			/*
+-			 * We need to drop cpu_base->lock to avoid a
+-			 * lock ordering issue vs. rq->lock.
+-			 */
++		    ) {
+ 			raw_spin_unlock(&new_base->cpu_base->lock);
+ 			raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+ 			local_irq_restore(flags);
+-			return ret;
++			return 0;
+ 		} else {
 -			__raise_softirq_irqoff(HRTIMER_SOFTIRQ);
-+		raw_spin_unlock(&base->cpu_base->lock);
-+		raise_softirq_irqoff(HRTIMER_SOFTIRQ);
-+		raw_spin_lock(&base->cpu_base->lock);
- 
--		return 1;
-+		return 0;
- 	}
- 
- 	return 0;
-@@ -1056,8 +1043,19 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
- 	 *
- 	 * XXX send_remote_softirq() ?
- 	 */
--	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases))
--		hrtimer_enqueue_reprogram(timer, new_base, wakeup);
-+	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases)) {
-+		ret = hrtimer_enqueue_reprogram(timer, new_base, wakeup);
-+		if (ret) {
++			ret = -ETIME;
++
 +			/*
 +			 * In case we failed to reprogram the timer (mostly
 +			 * because out current timer is already elapsed),
@@ -101,8 +87,6 @@
 +			 */
 +			__remove_hrtimer(timer, new_base,
 +					timer->state & HRTIMER_STATE_CALLBACK, 0);
-+		}
-+	}
- 
- 	unlock_hrtimer_base(timer, &flags);
+ 		}
+ 	}
  



More information about the Kernel-svn-changes mailing list