summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch')
-rw-r--r--debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch b/debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch
new file mode 100644
index 000000000..ad68c8b6d
--- /dev/null
+++ b/debian/patches-rt/0199-net-provide-a-way-to-delegate-processing-a-softirq-t.patch
@@ -0,0 +1,89 @@
+From e035c89c203c5d80fa945338da5efe3ec563c7f7 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 20 Jan 2016 15:39:05 +0100
+Subject: [PATCH 199/347] net: provide a way to delegate processing a softirq
+ to ksoftirqd
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz
+
+If the NET_RX uses up all of his budget it moves the following NAPI
+invocations into the `ksoftirqd`. On -RT it does not do so. Instead it
+rises the NET_RX softirq in its current context again.
+
+In order to get closer to mainline's behaviour this patch provides
+__raise_softirq_irqoff_ksoft() which raises the softirq in the ksoftird.
+
+Cc: stable-rt@vger.kernel.org
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ include/linux/interrupt.h | 8 ++++++++
+ kernel/softirq.c | 21 +++++++++++++++++++++
+ net/core/dev.c | 2 +-
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index e1438fe66467..97d9ba26915e 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -518,6 +518,14 @@ extern void thread_do_softirq(void);
+ extern void open_softirq(int nr, void (*action)(struct softirq_action *));
+ extern void softirq_init(void);
+ extern void __raise_softirq_irqoff(unsigned int nr);
++#ifdef CONFIG_PREEMPT_RT_FULL
++extern void __raise_softirq_irqoff_ksoft(unsigned int nr);
++#else
++static inline void __raise_softirq_irqoff_ksoft(unsigned int nr)
++{
++ __raise_softirq_irqoff(nr);
++}
++#endif
+
+ extern void raise_softirq_irqoff(unsigned int nr);
+ extern void raise_softirq(unsigned int nr);
+diff --git a/kernel/softirq.c b/kernel/softirq.c
+index 27a4bb2303d0..25bcf2f2714b 100644
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -721,6 +721,27 @@ void __raise_softirq_irqoff(unsigned int nr)
+ wakeup_proper_softirq(nr);
+ }
+
++/*
++ * Same as __raise_softirq_irqoff() but will process them in ksoftirqd
++ */
++void __raise_softirq_irqoff_ksoft(unsigned int nr)
++{
++ unsigned int mask;
++
++ if (WARN_ON_ONCE(!__this_cpu_read(ksoftirqd) ||
++ !__this_cpu_read(ktimer_softirqd)))
++ return;
++ mask = 1UL << nr;
++
++ trace_softirq_raise(nr);
++ or_softirq_pending(mask);
++ if (mask & TIMER_SOFTIRQS)
++ __this_cpu_read(ktimer_softirqd)->softirqs_raised |= mask;
++ else
++ __this_cpu_read(ksoftirqd)->softirqs_raised |= mask;
++ wakeup_proper_softirq(nr);
++}
++
+ /*
+ * This function must run with irqs disabled!
+ */
+diff --git a/net/core/dev.c b/net/core/dev.c
+index a59b1db02f8b..2bf357d5602b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6391,7 +6391,7 @@ static __latent_entropy void net_rx_action(struct softirq_action *h)
+ list_splice_tail(&repoll, &list);
+ list_splice(&list, &sd->poll_list);
+ if (!list_empty(&sd->poll_list))
+- __raise_softirq_irqoff(NET_RX_SOFTIRQ);
++ __raise_softirq_irqoff_ksoft(NET_RX_SOFTIRQ);
+
+ net_rps_action_and_irq_enable(sd);
+ out:
+--
+2.36.1
+