srcu: Expedite first synchronize_srcu() when idle
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 25 Apr 2017 18:34:40 +0000 (11:34 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Wed, 26 Apr 2017 23:32:16 +0000 (16:32 -0700)
commit2da4b2a7fd8de52c44fa83c59f00d38a0d90caae
tree12ae8f7939181af0c8722f81232dbd23b1fffe76
parent1e9a038b7fe9a8c10ef1238f4e695d5fbe0dd594
srcu: Expedite first synchronize_srcu() when idle

Classic SRCU in effect expedites the first synchronize_srcu() when SRCU
is idle, and Mike Galbraith demonstrated that some use cases do in fact
rely on this behavior.  In particular, Mike showed that Steven Rostedt's
hotplug stress script takes 55 seconds with Classic SRCU and more than
16 -minutes- when running Tree SRCU.  Assuming that each Tree SRCU's call
to synchronize_srcu() takes four milliseconds, this implies that Steven's
test invokes synchronize_srcu() in isolation, but more than once per
200 microseconds.  Mike used ftrace to demonstrate that the time between
successive calls to synchronize_srcu() ranged from 118 to 342 microseconds,
with one outlier at 80 milliseconds.  This data clearly indicates that
Tree SRCU needs to expedite the first invocation of synchronize_srcu()
during an SRCU idle period.

This commit therefor introduces a srcu_might_be_idle() function that
probabilistically checks whether or not SRCU is idle.  This function is
used by synchronize_rcu() as an additional criterion in deciding whether
or not to expedite.

(Hat trick to Peter Zijlstra for his earlier suggestion that this might
in fact be a problem.  Which for all I know might have motivated Mike to
look into it.)

Reported-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Mike Galbraith <efault@gmx.de>
kernel/rcu/srcutree.c