rcu: don't use stop_machine_run() for rcu_barrier()
authorJuergen Gross <jgross@suse.com>
Thu, 26 Mar 2020 11:43:23 +0000 (12:43 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 26 Mar 2020 11:43:23 +0000 (12:43 +0100)
commit53594c7bd1970bd5e30d24140a204e9ffff44e01
tree35b779619f0af75a402441bd3607da6b6564a3ac
parentc301211a511111caca29f3bd797eb13965026c78
rcu: don't use stop_machine_run() for rcu_barrier()

Today rcu_barrier() is calling stop_machine_run() to synchronize all
physical cpus in order to ensure all pending rcu calls have finished
when returning.

As stop_machine_run() is using tasklets this requires scheduling of
idle vcpus on all cpus imposing the need to call rcu_barrier() on idle
cpus only in case of core scheduling being active, as otherwise a
scheduling deadlock would occur.

There is no need at all to do the syncing of the cpus in tasklets, as
rcu activity is started in __do_softirq() called whenever softirq
activity is allowed. So rcu_barrier() can easily be modified to use
softirq for synchronization of the cpus no longer requiring any
scheduling activity.

As there already is a rcu softirq reuse that for the synchronization.

Remove the barrier element from struct rcu_data as it isn't used.

Finally switch rcu_barrier() to return void as it now can never fail.

Partially-based-on-patch-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/common/rcupdate.c
xen/include/xen/rcupdate.h