summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2018-08-10 14:46:09 +0100
committerBen Hutchings <ben@decadent.org.uk>2018-09-13 01:52:52 +0100
commit26224f8bb88d96d9cbe261277fc4713f611d70b1 (patch)
tree93e7489ebcf9a2b173c63677121dfb4c874508fa /debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
parent07b57afec5de4a495564a09151407d1d4a44cbbc (diff)
downloadlinux-debian-26224f8bb88d96d9cbe261277fc4713f611d70b1.tar.gz
Move featureset patches and series file to debian/patches-<featureset>.
Fixes lintian warning patch-file-present-but-not-mentioned-in-series. Also preparation for using dgit, which will remove everything except the main patch series under debian/patches.
Diffstat (limited to 'debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch')
-rw-r--r--debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch348
1 files changed, 348 insertions, 0 deletions
diff --git a/debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch b/debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
new file mode 100644
index 000000000..cacef31c4
--- /dev/null
+++ b/debian/patches-rt/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch
@@ -0,0 +1,348 @@
+Subject: rcu: Merge RCU-bh into RCU-preempt
+Date: Wed, 5 Oct 2011 11:59:38 -0700
+From: Thomas Gleixner <tglx@linutronix.de>
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.18/older/patches-4.18.5-rt3.tar.xz
+
+The Linux kernel has long RCU-bh read-side critical sections that
+intolerably increase scheduling latency under mainline's RCU-bh rules,
+which include RCU-bh read-side critical sections being non-preemptible.
+This patch therefore arranges for RCU-bh to be implemented in terms of
+RCU-preempt for CONFIG_PREEMPT_RT_FULL=y.
+
+This has the downside of defeating the purpose of RCU-bh, namely,
+handling the case where the system is subjected to a network-based
+denial-of-service attack that keeps at least one CPU doing full-time
+softirq processing. This issue will be fixed by a later commit.
+
+The current commit will need some work to make it appropriate for
+mainline use, for example, it needs to be extended to cover Tiny RCU.
+
+[ paulmck: Added a useful changelog ]
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/20111005185938.GA20403@linux.vnet.ibm.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+
+---
+ include/linux/rcupdate.h | 19 +++++++++++++++++++
+ include/linux/rcutree.h | 8 ++++++++
+ kernel/rcu/rcu.h | 14 +++++++++++---
+ kernel/rcu/rcutorture.c | 7 +++++++
+ kernel/rcu/tree.c | 24 ++++++++++++++++++++++++
+ kernel/rcu/tree.h | 2 ++
+ kernel/rcu/update.c | 2 ++
+ 7 files changed, 73 insertions(+), 3 deletions(-)
+
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -56,7 +56,11 @@ void call_rcu(struct rcu_head *head, rcu
+ #define call_rcu call_rcu_sched
+ #endif /* #else #ifdef CONFIG_PREEMPT_RCU */
+
++#ifdef CONFIG_PREEMPT_RT_FULL
++#define call_rcu_bh call_rcu
++#else
+ void call_rcu_bh(struct rcu_head *head, rcu_callback_t func);
++#endif
+ void call_rcu_sched(struct rcu_head *head, rcu_callback_t func);
+ void synchronize_sched(void);
+ void rcu_barrier_tasks(void);
+@@ -264,7 +268,14 @@ extern struct lockdep_map rcu_sched_lock
+ extern struct lockdep_map rcu_callback_map;
+ int debug_lockdep_rcu_enabled(void);
+ int rcu_read_lock_held(void);
++#ifdef CONFIG_PREEMPT_RT_FULL
++static inline int rcu_read_lock_bh_held(void)
++{
++ return rcu_read_lock_held();
++}
++#else
+ int rcu_read_lock_bh_held(void);
++#endif
+ int rcu_read_lock_sched_held(void);
+
+ #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+@@ -665,10 +676,14 @@ static inline void rcu_read_unlock(void)
+ static inline void rcu_read_lock_bh(void)
+ {
+ local_bh_disable();
++#ifdef CONFIG_PREEMPT_RT_FULL
++ rcu_read_lock();
++#else
+ __acquire(RCU_BH);
+ rcu_lock_acquire(&rcu_bh_lock_map);
+ RCU_LOCKDEP_WARN(!rcu_is_watching(),
+ "rcu_read_lock_bh() used illegally while idle");
++#endif
+ }
+
+ /*
+@@ -678,10 +693,14 @@ static inline void rcu_read_lock_bh(void
+ */
+ static inline void rcu_read_unlock_bh(void)
+ {
++#ifdef CONFIG_PREEMPT_RT_FULL
++ rcu_read_unlock();
++#else
+ RCU_LOCKDEP_WARN(!rcu_is_watching(),
+ "rcu_read_unlock_bh() used illegally while idle");
+ rcu_lock_release(&rcu_bh_lock_map);
+ __release(RCU_BH);
++#endif
+ local_bh_enable();
+ }
+
+--- a/include/linux/rcutree.h
++++ b/include/linux/rcutree.h
+@@ -44,7 +44,11 @@ static inline void rcu_virt_note_context
+ rcu_note_context_switch(false);
+ }
+
++#ifdef CONFIG_PREEMPT_RT_FULL
++# define synchronize_rcu_bh synchronize_rcu
++#else
+ void synchronize_rcu_bh(void);
++#endif
+ void synchronize_sched_expedited(void);
+ void synchronize_rcu_expedited(void);
+
+@@ -72,7 +76,11 @@ static inline void synchronize_rcu_bh_ex
+ }
+
+ void rcu_barrier(void);
++#ifdef CONFIG_PREEMPT_RT_FULL
++# define rcu_barrier_bh rcu_barrier
++#else
+ void rcu_barrier_bh(void);
++#endif
+ void rcu_barrier_sched(void);
+ bool rcu_eqs_special_set(int cpu);
+ unsigned long get_state_synchronize_rcu(void);
+--- a/kernel/rcu/rcu.h
++++ b/kernel/rcu/rcu.h
+@@ -478,20 +478,28 @@ static inline void show_rcu_gp_kthreads(
+ extern unsigned long rcutorture_testseq;
+ extern unsigned long rcutorture_vernum;
+ unsigned long rcu_batches_started(void);
+-unsigned long rcu_batches_started_bh(void);
+ unsigned long rcu_batches_started_sched(void);
+ unsigned long rcu_batches_completed(void);
+-unsigned long rcu_batches_completed_bh(void);
+ unsigned long rcu_batches_completed_sched(void);
+ unsigned long rcu_exp_batches_completed(void);
+ unsigned long rcu_exp_batches_completed_sched(void);
+ unsigned long srcu_batches_completed(struct srcu_struct *sp);
+ void show_rcu_gp_kthreads(void);
+ void rcu_force_quiescent_state(void);
+-void rcu_bh_force_quiescent_state(void);
+ void rcu_sched_force_quiescent_state(void);
+ extern struct workqueue_struct *rcu_gp_wq;
+ extern struct workqueue_struct *rcu_par_gp_wq;
++
++#ifndef CONFIG_PREEMPT_RT_FULL
++void rcu_bh_force_quiescent_state(void);
++unsigned long rcu_batches_started_bh(void);
++unsigned long rcu_batches_completed_bh(void);
++#else
++# define rcu_bh_force_quiescent_state rcu_force_quiescent_state
++# define rcu_batches_completed_bh rcu_batches_completed
++# define rcu_batches_started_bh rcu_batches_completed
++#endif
++
+ #endif /* #else #ifdef CONFIG_TINY_RCU */
+
+ #ifdef CONFIG_RCU_NOCB_CPU
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -413,6 +413,7 @@ static struct rcu_torture_ops rcu_ops =
+ .name = "rcu"
+ };
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /*
+ * Definitions for rcu_bh torture testing.
+ */
+@@ -452,6 +453,12 @@ static struct rcu_torture_ops rcu_bh_ops
+ .name = "rcu_bh"
+ };
+
++#else
++static struct rcu_torture_ops rcu_bh_ops = {
++ .ttype = INVALID_RCU_FLAVOR,
++};
++#endif
++
+ /*
+ * Don't even think about trying any of these in real life!!!
+ * The names includes "busted", and they really means it!
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -243,6 +243,7 @@ void rcu_sched_qs(void)
+ this_cpu_ptr(&rcu_sched_data), true);
+ }
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ void rcu_bh_qs(void)
+ {
+ RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!");
+@@ -253,6 +254,7 @@ void rcu_bh_qs(void)
+ __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false);
+ }
+ }
++#endif
+
+ /*
+ * Steal a bit from the bottom of ->dynticks for idle entry/exit
+@@ -549,11 +551,13 @@ EXPORT_SYMBOL_GPL(rcu_batches_started_sc
+ /*
+ * Return the number of RCU BH batches started thus far for debug & stats.
+ */
++#ifndef CONFIG_PREEMPT_RT_FULL
+ unsigned long rcu_batches_started_bh(void)
+ {
+ return rcu_bh_state.gpnum;
+ }
+ EXPORT_SYMBOL_GPL(rcu_batches_started_bh);
++#endif
+
+ /*
+ * Return the number of RCU batches completed thus far for debug & stats.
+@@ -573,6 +577,7 @@ unsigned long rcu_batches_completed_sche
+ }
+ EXPORT_SYMBOL_GPL(rcu_batches_completed_sched);
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /*
+ * Return the number of RCU BH batches completed thus far for debug & stats.
+ */
+@@ -581,6 +586,7 @@ unsigned long rcu_batches_completed_bh(v
+ return rcu_bh_state.completed;
+ }
+ EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
++#endif
+
+ /*
+ * Return the number of RCU expedited batches completed thus far for
+@@ -604,6 +610,7 @@ unsigned long rcu_exp_batches_completed_
+ }
+ EXPORT_SYMBOL_GPL(rcu_exp_batches_completed_sched);
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /*
+ * Force a quiescent state.
+ */
+@@ -622,6 +629,13 @@ void rcu_bh_force_quiescent_state(void)
+ }
+ EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state);
+
++#else
++void rcu_force_quiescent_state(void)
++{
++}
++EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
++#endif
++
+ /*
+ * Force a quiescent state for RCU-sched.
+ */
+@@ -672,9 +686,11 @@ void rcutorture_get_gp_data(enum rcutort
+ case RCU_FLAVOR:
+ rsp = rcu_state_p;
+ break;
++#ifndef CONFIG_PREEMPT_RT_FULL
+ case RCU_BH_FLAVOR:
+ rsp = &rcu_bh_state;
+ break;
++#endif
+ case RCU_SCHED_FLAVOR:
+ rsp = &rcu_sched_state;
+ break;
+@@ -2986,6 +3002,7 @@ void call_rcu_sched(struct rcu_head *hea
+ }
+ EXPORT_SYMBOL_GPL(call_rcu_sched);
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /**
+ * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
+ * @head: structure to be used for queueing the RCU updates.
+@@ -3013,6 +3030,7 @@ void call_rcu_bh(struct rcu_head *head,
+ __call_rcu(head, func, &rcu_bh_state, -1, 0);
+ }
+ EXPORT_SYMBOL_GPL(call_rcu_bh);
++#endif
+
+ /*
+ * Queue an RCU callback for lazy invocation after a grace period.
+@@ -3098,6 +3116,7 @@ void synchronize_sched(void)
+ }
+ EXPORT_SYMBOL_GPL(synchronize_sched);
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /**
+ * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
+ *
+@@ -3124,6 +3143,7 @@ void synchronize_rcu_bh(void)
+ wait_rcu_gp(call_rcu_bh);
+ }
+ EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
++#endif
+
+ /**
+ * get_state_synchronize_rcu - Snapshot current RCU state
+@@ -3457,6 +3477,7 @@ static void _rcu_barrier(struct rcu_stat
+ mutex_unlock(&rsp->barrier_mutex);
+ }
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /**
+ * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
+ */
+@@ -3465,6 +3486,7 @@ void rcu_barrier_bh(void)
+ _rcu_barrier(&rcu_bh_state);
+ }
+ EXPORT_SYMBOL_GPL(rcu_barrier_bh);
++#endif
+
+ /**
+ * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
+@@ -4081,7 +4103,9 @@ void __init rcu_init(void)
+
+ rcu_bootup_announce();
+ rcu_init_geometry();
++#ifndef CONFIG_PREEMPT_RT_FULL
+ rcu_init_one(&rcu_bh_state);
++#endif
+ rcu_init_one(&rcu_sched_state);
+ if (dump_tree)
+ rcu_dump_rcu_node_tree(&rcu_sched_state);
+--- a/kernel/rcu/tree.h
++++ b/kernel/rcu/tree.h
+@@ -422,7 +422,9 @@ extern struct list_head rcu_struct_flavo
+ */
+ extern struct rcu_state rcu_sched_state;
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ extern struct rcu_state rcu_bh_state;
++#endif
+
+ #ifdef CONFIG_PREEMPT_RCU
+ extern struct rcu_state rcu_preempt_state;
+--- a/kernel/rcu/update.c
++++ b/kernel/rcu/update.c
+@@ -286,6 +286,7 @@ int rcu_read_lock_held(void)
+ }
+ EXPORT_SYMBOL_GPL(rcu_read_lock_held);
+
++#ifndef CONFIG_PREEMPT_RT_FULL
+ /**
+ * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section?
+ *
+@@ -312,6 +313,7 @@ int rcu_read_lock_bh_held(void)
+ return in_softirq() || irqs_disabled();
+ }
+ EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
++#endif
+
+ #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+