summaryrefslogtreecommitdiff
path: root/patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch')
-rw-r--r--patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch43
1 files changed, 14 insertions, 29 deletions
diff --git a/patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch b/patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch
index 55c7406a11d7..852b23cfed8d 100644
--- a/patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch
+++ b/patches/rcutorture__Avoid_problematic_critical_section_nesting_on_RT.patch
@@ -7,19 +7,7 @@ From: Scott Wood <swood@redhat.com>
rcutorture was generating some nesting scenarios that are not
reasonable. Constrain the state selection to avoid them.
-Example #1:
-
-1. preempt_disable()
-2. local_bh_disable()
-3. preempt_enable()
-4. local_bh_enable()
-
-On PREEMPT_RT, BH disabling takes a local lock only when called in
-non-atomic context. Thus, atomic context must be retained until after BH
-is re-enabled. Likewise, if BH is initially disabled in non-atomic
-context, it cannot be re-enabled in atomic context.
-
-Example #2:
+Example:
1. rcu_read_lock()
2. local_irq_disable()
@@ -36,13 +24,13 @@ kernels, until debug checks are added to ensure that they are not
happening elsewhere.
Signed-off-by: Scott Wood <swood@redhat.com>
+[valentin.schneider@arm.com: Don't disable BH in atomic context]
+[bigeasy: remove 'preempt_disable(); local_bh_disable(); preempt_enable();
+ local_bh_enable();' from the examples because this works on RT now. ]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-
-
---
- kernel/rcu/rcutorture.c | 97 +++++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 83 insertions(+), 14 deletions(-)
+ kernel/rcu/rcutorture.c | 94 ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 80 insertions(+), 14 deletions(-)
---
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -136,7 +124,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
/* Mostly only one bit (need preemption!), sometimes lots of bits. */
-@@ -1503,11 +1534,49 @@ rcutorture_extend_mask(int oldmask, stru
+@@ -1503,11 +1534,46 @@ rcutorture_extend_mask(int oldmask, stru
mask = mask & randmask2;
else
mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
@@ -160,6 +148,13 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ */
+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ /*
++ * Can't disable bh in atomic context if bh was already
++ * disabled by another task on the same CPU. Instead of
++ * attempting to track this, just avoid disabling bh in atomic
++ * context.
++ */
++ mask &= ~atomic_bhs;
++ /*
+ * Can't release the outermost rcu lock in an irq disabled
+ * section without preemption also being disabled, if irqs
+ * had ever been enabled during this RCU critical section
@@ -170,16 +165,6 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ !(mask & preempts))
+ mask |= RCUTORTURE_RDR_RCU;
+
-+ /* Can't modify atomic bh in non-atomic context */
-+ if ((oldmask & atomic_bhs) && (mask & atomic_bhs) &&
-+ !(mask & preempts_irq)) {
-+ mask |= oldmask & preempts_irq;
-+ if (mask & RCUTORTURE_RDR_IRQ)
-+ mask |= oldmask & tmp;
-+ }
-+ if ((mask & atomic_bhs) && !(mask & preempts_irq))
-+ mask |= RCUTORTURE_RDR_PREEMPT;
-+
+ /* Can't modify non-atomic bh in atomic context */
+ tmp = nonatomic_bhs;
+ if (oldmask & preempts_irq)