summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2015-11-18 16:46:40 +0100
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2015-11-18 16:46:40 +0100
commit371db5665725de79cf8552f2d5b7a3061d1af876 (patch)
tree8b6f2db99edcf173550e0329ec8868f6713faa9f
parent3f1c9e7b4ba7cefa263a3af0156881f53f60ef09 (diff)
download4.9-rt-patches-371db5665725de79cf8552f2d5b7a3061d1af876.tar.gz
[ANNOUNCE] 4.1.13-rt15
Dear RT folks! I'm pleased to announce the v4.1.13-rt15 patch set. Changes since v4.1.13-rt14: Sebastian Andrzej Siewior (1): v4.1.13-rt15 Thomas Gleixner (1): irqwork: Move irq safe work to irq context Known issues: - bcache stays disabled - CPU hotplug is not better than before - The netlink_release() OOPS, reported by Clark, is still on the list, but unsolved due to lack of information The delta patch against 4.1.13-rt15 is appended below and can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.1/incr/patch-4.1.13-rt14-rt15.patch.xz You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.1.13-rt15 The RT patch against 4.1.13 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.1/patch-4.1.13-rt15.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.1/patches-4.1.13-rt15.tar.xz Sebastian diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h --- a/include/linux/irq_work.h +++ b/include/linux/irq_work.h @@ -52,4 +52,10 @@ static inline bool irq_work_needs_cpu(void) { return false; } static inline void irq_work_run(void) { } #endif +#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) +void irq_work_tick_soft(void); +#else +static inline void irq_work_tick_soft(void) { } +#endif + #endif /* _LINUX_IRQ_WORK_H */ diff --git a/kernel/irq_work.c b/kernel/irq_work.c --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -200,8 +200,17 @@ void irq_work_tick(void) if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) irq_work_run_list(raised); + + if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) + irq_work_run_list(this_cpu_ptr(&lazy_list)); +} + +#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) +void irq_work_tick_soft(void) +{ irq_work_run_list(this_cpu_ptr(&lazy_list)); } +#endif /* * Synchronize against the irq_work @entry, ensures the entry is not diff --git a/kernel/time/timer.c b/kernel/time/timer.c --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1455,7 +1455,7 @@ void update_process_times(int user_tick) scheduler_tick(); run_local_timers(); rcu_check_callbacks(user_tick); -#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) +#if defined(CONFIG_IRQ_WORK) if (in_irq()) irq_work_tick(); #endif @@ -1471,9 +1471,7 @@ static void run_timer_softirq(struct softirq_action *h) hrtimer_run_pending(); -#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) - irq_work_tick(); -#endif + irq_work_tick_soft(); if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); diff --git a/localversion-rt b/localversion-rt --- a/localversion-rt +++ b/localversion-rt @@ -1 +1 @@ --rt14 +-rt15 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/irqwork-Move-irq-safe-work-to-irq-context.patch83
-rw-r--r--patches/localversion.patch4
-rw-r--r--patches/series1
3 files changed, 86 insertions, 2 deletions
diff --git a/patches/irqwork-Move-irq-safe-work-to-irq-context.patch b/patches/irqwork-Move-irq-safe-work-to-irq-context.patch
new file mode 100644
index 00000000000000..99c5a41041c6a9
--- /dev/null
+++ b/patches/irqwork-Move-irq-safe-work-to-irq-context.patch
@@ -0,0 +1,83 @@
+Subject: irqwork: Move irq safe work to irq context
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 15 Nov 2015 18:40:17 +0100
+
+On architectures where arch_irq_work_has_interrupt() returns false, we
+end up running the irq safe work from the softirq context. That
+results in a potential deadlock in the scheduler irq work which
+expects that function to be called with interrupts disabled.
+
+Split the irq_work_tick() function into a hard and soft variant. Call
+the hard variant from the tick interrupt and add the soft variant to
+the timer softirq.
+
+Reported-and-tested-by: Yanjiang Jin <yanjiang.jin@windriver.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable-rt@vger.kernel.org
+---
+ include/linux/irq_work.h | 6 ++++++
+ kernel/irq_work.c | 9 +++++++++
+ kernel/time/timer.c | 6 ++----
+ 3 files changed, 17 insertions(+), 4 deletions(-)
+
+Index: linux-rt-devel/include/linux/irq_work.h
+===================================================================
+--- linux-rt-devel.orig/include/linux/irq_work.h
++++ linux-rt-devel/include/linux/irq_work.h
+@@ -52,4 +52,10 @@ static inline bool irq_work_needs_cpu(vo
+ static inline void irq_work_run(void) { }
+ #endif
+
++#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL)
++void irq_work_tick_soft(void);
++#else
++static inline void irq_work_tick_soft(void) { }
++#endif
++
+ #endif /* _LINUX_IRQ_WORK_H */
+Index: linux-rt-devel/kernel/irq_work.c
+===================================================================
+--- linux-rt-devel.orig/kernel/irq_work.c
++++ linux-rt-devel/kernel/irq_work.c
+@@ -200,8 +200,17 @@ void irq_work_tick(void)
+
+ if (!llist_empty(raised) && !arch_irq_work_has_interrupt())
+ irq_work_run_list(raised);
++
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL))
++ irq_work_run_list(this_cpu_ptr(&lazy_list));
++}
++
++#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL)
++void irq_work_tick_soft(void)
++{
+ irq_work_run_list(this_cpu_ptr(&lazy_list));
+ }
++#endif
+
+ /*
+ * Synchronize against the irq_work @entry, ensures the entry is not
+Index: linux-rt-devel/kernel/time/timer.c
+===================================================================
+--- linux-rt-devel.orig/kernel/time/timer.c
++++ linux-rt-devel/kernel/time/timer.c
+@@ -1455,7 +1455,7 @@ void update_process_times(int user_tick)
+ scheduler_tick();
+ run_local_timers();
+ rcu_check_callbacks(user_tick);
+-#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL)
++#if defined(CONFIG_IRQ_WORK)
+ if (in_irq())
+ irq_work_tick();
+ #endif
+@@ -1471,9 +1471,7 @@ static void run_timer_softirq(struct sof
+
+ hrtimer_run_pending();
+
+-#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL)
+- irq_work_tick();
+-#endif
++ irq_work_tick_soft();
+
+ if (time_after_eq(jiffies, base->timer_jiffies))
+ __run_timers(base);
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 9979b294ecb5d4..73791b7238aabc 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -1,4 +1,4 @@
-Subject: v4.1.13-rt14
+Subject: v4.1.13-rt15
From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 08 Jul 2011 20:25:16 +0200
@@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- /dev/null
+++ b/localversion-rt
@@ -0,0 +1 @@
-+-rt14
++-rt15
diff --git a/patches/series b/patches/series
index 3fb0a5aa1f54d7..c9cf63a135c1a4 100644
--- a/patches/series
+++ b/patches/series
@@ -434,6 +434,7 @@ net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch
# irqwork
irqwork-push_most_work_into_softirq_context.patch
+irqwork-Move-irq-safe-work-to-irq-context.patch
# Sound
snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch