summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0162-srcu-replace-local_irqsave-with-a-locallock.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches-rt/0162-srcu-replace-local_irqsave-with-a-locallock.patch77
1 files changed, 77 insertions, 0 deletions
diff --git a/debian/patches-rt/0162-srcu-replace-local_irqsave-with-a-locallock.patch b/debian/patches-rt/0162-srcu-replace-local_irqsave-with-a-locallock.patch
new file mode 100644
index 000000000..5cdde2079
--- /dev/null
+++ b/debian/patches-rt/0162-srcu-replace-local_irqsave-with-a-locallock.patch
@@ -0,0 +1,77 @@
+From 62524e62d2f224889aee36c1c134f0efb2fba025 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Thu, 12 Oct 2017 18:37:12 +0200
+Subject: [PATCH 162/347] srcu: replace local_irqsave() with a locallock
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz
+
+There are two instances which disable interrupts in order to become a
+stable this_cpu_ptr() pointer. The restore part is coupled with
+spin_unlock_irqrestore() which does not work on RT.
+Replace the local_irq_save() call with the appropriate local_lock()
+version of it.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/rcu/srcutree.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
+index df0375453ba1..0f09a1a9e17c 100644
+--- a/kernel/rcu/srcutree.c
++++ b/kernel/rcu/srcutree.c
+@@ -39,6 +39,7 @@
+ #include <linux/module.h>
+ #include <linux/srcu.h>
+ #include <linux/cpu.h>
++#include <linux/locallock.h>
+
+ #include "rcu.h"
+ #include "rcu_segcblist.h"
+@@ -760,6 +761,8 @@ static void srcu_flip(struct srcu_struct *sp)
+ * negligible when amoritized over that time period, and the extra latency
+ * of a needlessly non-expedited grace period is similarly negligible.
+ */
++static DEFINE_LOCAL_IRQ_LOCK(sp_llock);
++
+ static bool srcu_might_be_idle(struct srcu_struct *sp)
+ {
+ unsigned long curseq;
+@@ -768,13 +771,13 @@ static bool srcu_might_be_idle(struct srcu_struct *sp)
+ unsigned long t;
+
+ /* If the local srcu_data structure has callbacks, not idle. */
+- local_irq_save(flags);
++ local_lock_irqsave(sp_llock, flags);
+ sdp = this_cpu_ptr(sp->sda);
+ if (rcu_segcblist_pend_cbs(&sdp->srcu_cblist)) {
+- local_irq_restore(flags);
++ local_unlock_irqrestore(sp_llock, flags);
+ return false; /* Callbacks already present, so not idle. */
+ }
+- local_irq_restore(flags);
++ local_unlock_irqrestore(sp_llock, flags);
+
+ /*
+ * No local callbacks, so probabalistically probe global state.
+@@ -852,7 +855,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp,
+ return;
+ }
+ rhp->func = func;
+- local_irq_save(flags);
++ local_lock_irqsave(sp_llock, flags);
+ sdp = this_cpu_ptr(sp->sda);
+ spin_lock_rcu_node(sdp);
+ rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false);
+@@ -868,7 +871,8 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp,
+ sdp->srcu_gp_seq_needed_exp = s;
+ needexp = true;
+ }
+- spin_unlock_irqrestore_rcu_node(sdp, flags);
++ spin_unlock_rcu_node(sdp);
++ local_unlock_irqrestore(sp_llock, flags);
+ if (needgp)
+ srcu_funnel_gp_start(sp, sdp, s, do_norm);
+ else if (needexp)
+--
+2.36.1
+