[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