rcu: Eliminate deadlock between CPU hotplug and expedited grace periods

Currently, the expedited grace-period primitives do get_online_cpus().
This greatly simplifies their implementation, but means that calls to
them holding locks that are acquired by CPU-hotplug notifiers (to say
nothing of calls to these primitives from CPU-hotplug notifiers) can
deadlock.

This commit avoids the deadlock and retains the simplicity by creating
a try_get_online_cpus(), which returns false if the get_online_cpus()
reference count could not immediately be incremented.  If a call to
try_get_online_cpus() returns true, the expedited primitives operate
as before.  If a call returns false, the expedited primitives fall back
to normal grace-period operations.  This falling back of course results
in increased grace-period latency, but only during times when CPU
hotplug operations are actually in flight.  The effect should therefore
be negligible during normal operation.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Josh Triplett <josh@joshtriplett.org>
5 files changed