Messages in this thread | | | Date | Tue, 4 Sep 2012 15:36:26 -0700 | From | "Paul E. McKenney" <> | Subject | Re: [PATCH tip/core/rcu 01/15] rcu: Add PROVE_RCU_DELAY to provoke difficult races |
| |
On Fri, Aug 31, 2012 at 09:49:36AM -0700, Josh Triplett wrote: > On Thu, Aug 30, 2012 at 11:56:14AM -0700, Paul E. McKenney wrote: > > From: "Paul E. McKenney" <paul.mckenney@linaro.org> > > > > There have been some recent bugs that were triggered only when > > preemptible RCU's __rcu_read_unlock() was preempted just after setting > > ->rcu_read_lock_nesting to INT_MIN, which is a low-probability event. > > Therefore, reproducing those bugs (to say nothing of gaining confidence > > in alleged fixes) was quite difficult. This commit therefore creates > > a new debug-only RCU kernel config option that forces a short delay > > in __rcu_read_unlock() to increase the probability of those sorts of > > bugs occurring. > > > > Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> > > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> > > Reviewed-by: Josh Triplett <josh@joshtriplett.org> > > If you end up adding more such conditional race-provoking delays > elsewhere in the code, consider creating a prove_rcu_udelay() wrapper > to avoid multiple #ifdefs in the code.
Good point! In fact, I have added this to my list.
Thanx, Paul
> > --- > > kernel/rcupdate.c | 4 ++++ > > lib/Kconfig.debug | 14 ++++++++++++++ > > 2 files changed, 18 insertions(+), 0 deletions(-) > > > > diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c > > index 4e6a61b..29ca1c6 100644 > > --- a/kernel/rcupdate.c > > +++ b/kernel/rcupdate.c > > @@ -45,6 +45,7 @@ > > #include <linux/mutex.h> > > #include <linux/export.h> > > #include <linux/hardirq.h> > > +#include <linux/delay.h> > > > > #define CREATE_TRACE_POINTS > > #include <trace/events/rcu.h> > > @@ -81,6 +82,9 @@ void __rcu_read_unlock(void) > > } else { > > barrier(); /* critical section before exit code. */ > > t->rcu_read_lock_nesting = INT_MIN; > > +#ifdef CONFIG_PROVE_RCU_DELAY > > + udelay(10); /* Make preemption more probable. */ > > +#endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ > > barrier(); /* assign before ->rcu_read_unlock_special load */ > > if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) > > rcu_read_unlock_special(t); > > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug > > index 2403a63..dacbbe4 100644 > > --- a/lib/Kconfig.debug > > +++ b/lib/Kconfig.debug > > @@ -629,6 +629,20 @@ config PROVE_RCU_REPEATEDLY > > > > Say N if you are unsure. > > > > +config PROVE_RCU_DELAY > > + bool "RCU debugging: preemptible RCU race provocation" > > + depends on DEBUG_KERNEL && PREEMPT_RCU > > + default n > > + help > > + There is a class of races that involve an unlikely preemption > > + of __rcu_read_unlock() just after ->rcu_read_lock_nesting has > > + been set to INT_MIN. This feature inserts a delay at that > > + point to increase the probability of these races. > > + > > + Say Y to increase probability of preemption of __rcu_read_unlock(). > > + > > + Say N if you are unsure. > > + > > config SPARSE_RCU_POINTER > > bool "RCU debugging: sparse-based checks for pointer usage" > > default n > > -- > > 1.7.8 > > >
| |