Re: [rcu] kernel BUG at include/linux/pagemap.h:149!

From: Paul E. McKenney
Date: Mon Sep 21 2015 - 16:43:47 EST


On Mon, Sep 21, 2015 at 09:30:49PM +0200, Frederic Weisbecker wrote:
> On Fri, Sep 11, 2015 at 10:19:47AM +0800, Boqun Feng wrote:
> > Subject: [PATCH 01/27] rcu: Don't disable preemption for Tiny and Tree RCU
> > readers
> >
> > Because preempt_disable() maps to barrier() for non-debug builds,
> > it forces the compiler to spill and reload registers. Because Tree
> > RCU and Tiny RCU now only appear in CONFIG_PREEMPT=n builds, these
> > barrier() instances generate needless extra code for each instance of
> > rcu_read_lock() and rcu_read_unlock(). This extra code slows down Tree
> > RCU and bloats Tiny RCU.
> >
> > This commit therefore removes the preempt_disable() and preempt_enable()
> > from the non-preemptible implementations of __rcu_read_lock() and
> > __rcu_read_unlock(), respectively.
> >
> > For debug purposes, preempt_disable() and preempt_enable() are still
> > kept if CONFIG_PREEMPT_COUNT=y, which makes the detection of sleeping
> > inside atomic sections still work in non-preemptible kernels.
> >
> > Signed-off-by: Boqun Feng <boqun.feng@xxxxxxxxx>
> > Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
> > ---
> > include/linux/rcupdate.h | 6 ++++--
> > include/linux/rcutiny.h | 1 +
> > kernel/rcu/tree.c | 9 +++++++++
> > 3 files changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> > index d63bb77..6c3cece 100644
> > --- a/include/linux/rcupdate.h
> > +++ b/include/linux/rcupdate.h
> > @@ -297,12 +297,14 @@ void synchronize_rcu(void);
> >
> > static inline void __rcu_read_lock(void)
> > {
> > - preempt_disable();
> > + if (IS_ENABLED(CONFIG_PREEMPT_COUNT))
> > + preempt_disable();
>
> preempt_disable() is a no-op when !CONFIG_PREEMPT_COUNT, right?
> Or rather it's a barrier(), which is anyway implied by rcu_read_lock().
>
> So perhaps we can get rid of the IS_ENABLED() check?

Actually, barrier() is not intended to be implied by rcu_read_lock().
In a non-preemptible RCU implementation, it doesn't help anything
to have the compiler flush its temporaries upon rcu_read_lock()
and rcu_read_unlock().

Thanx, Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/