* Paul E. McKenney <paul...@linux.vnet.ibm.com> wrote:
> > > But if we look at the bigger API picture:
> > >
> > > !PREEMPT_RCU PREEMPT_RCU=y
> > > rcu_read_lock(): atomic preemptible
> > > rcu_read_lock_sched(): atomic atomic
> > > srcu_read_lock(): preemptible preemptible
> > >
> > > Then we could maintain full read side API flexibility by making
> > > PREEMPT_RCU=y the
> > > only model, merging it with SRCU and using these main read side APIs:
> > >
> > > rcu_read_lock_preempt_disable(): atomic
> > > rcu_read_lock(): preemptible
> One issue with merging SRCU into rcu_read_lock() is the general blocking
> SRCU readers. Once merged in, these guys block everyone. We should focus
> initially on the non-SRCU variants.
> On the other hand, Linus's suggestion of merging rcu_read_lock_sched()
> into rcu_read_lock() just might be feasible. If that really does pan
> out, we end up with the following:
> !PREEMPT PREEMPT=y
> rcu_read_lock(): atomic preemptible
> srcu_read_lock(): preemptible preemptible
> In this model, rcu_read_lock_sched() maps to preempt_disable() and (as
> you say above) rcu_read_lock_bh() maps to local_bh_disable(). The way
> this works is that in PREEMPT=y kernels, synchronize_rcu() waits not
> only for RCU read-side critical sections, but also for regions of code
> with preemption disabled. The main caveat seems to be that there be an
> assumed point of preemptibility between each interrupt and each softirq
> handler, which should be OK.
> There will be some adjustments required for lockdep-RCU, but that should
> be reasonably straightforward.
> Seem reasonable?
Yes, that approach sounds very reasonable to me: it is similar to what we do on
the locking side as well, where we have 'atomic' variants (spinlocks/rwlocks)
'sleeping' variants (mutexes, rwsems, etc.).
( This means there will be more automatic coupling between BH and preempt
sections and RCU models not captured via explicit RCU-namespace APIs, but that
should be OK I think. )
A couple of small side notes:
- Could we please also clean up the namespace of the synchronization APIs and
change them all to an rcu_ prefix, like all the other RCU APIs are? Right
have a mixture like rcu_read_lock() but synchronize_rcu(), while I'd reall
to be able to do:
git grep '\<rcu_' ...
... to see RCU API usage within a particular kernel area. This would also
up some of the internal inconsistencies like having 'struct rcu_synchronize'.
- If we are cleaning up the write side APIs, could we move over to a _wait
nomenclature, i.e. rcu_wait*()?
I.e. the new RCU namespace would be something like:
rcu_read_lock => rcu_read_lock # unchanged
rcu_read_unlock => rcu_read_unlock # unchanged
call_rcu => rcu_call_rcu
call_rcu_bh => rcu_call_bh
call_rcu_sched => rcu_call_sched
synchronize_rcu => rcu_wait_
synchronize_rcu_bh => rcu_wait_bh
synchronize_rcu_bh_expedited => rcu_wait_expedited_bh
synchronize_rcu_expedited => rcu_wait_expedited
synchronize_rcu_mult => rcu_wait_mult
synchronize_rcu_sched => rcu_wait_sched
synchronize_rcu_tasks => rcu_wait_tasks
srcu_read_lock => srcu_read_lock # unchanged
srcu_read_unlock => srcu_read_unlock # unchanged
synchronize_srcu => srcu_wait
synchronize_srcu_expedited => srcu_wait_expedited
Note that due to the prefix approach we gain various new patterns:
git grep rcu_wait # matches both rcu and srcu
git grep rcu_wait # matches all RCU waiting variants
git grep wait_expedited # matches all expedited variants
... which all increase the organization of the namespace.
- While we are at it, the two RCU-state API variants, while rarely used, are
named in a pretty obscure, disconnected fashion as well. A much better
get_state_synchronize_rcu => rcu_get_state
cond_synchronize_rcu => rcu_wait_state
... or so. This would also move them into the new, unified rcu_ prefix
Note how consistent and hierarchical the new RCU API namespace is:
If you agree with the overall concept of this I'd be glad to help out with
scripting & testing the RCU namespace transition safely in an unintrusive
once you've done the model unification work, with compatibility defines to not
create conflicts, churn and pain, etc.