On Tue, 02/03 13:52, Paolo Bonzini wrote: > call_rcu operates on the principle that either there is a steady stream of > incoming RCU callbacks, or it is not worthwhile to wake up and process the > few that are there. > > This however makes it hard to assert in testcases that all RCU callbacks > are processed. To avoid this, make call_rcu also process callbacks if there > is a steady stream of synchronize_rcu calls. > > This avoids deadlocks in the upcoming test-rcu-list unit test, which waits > for call_rcu to reclaim all nodes that it allocates. Especially with very > high load on the host, call_rcu decided to wait for a few more callbacks > to pile up, but the test was done and was not going to produce more. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > util/rcu.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/util/rcu.c b/util/rcu.c > index c9c3e6e..aa9f639 100644 > --- a/util/rcu.c > +++ b/util/rcu.c > @@ -48,6 +48,9 @@ unsigned long rcu_gp_ctr = RCU_GP_LOCKED; > QemuEvent rcu_gp_event; > static QemuMutex rcu_gp_lock; > > +static int rcu_call_count; > +static QemuEvent rcu_call_ready_event; > + > /* > * Check whether a quiescent state was crossed between the beginning of > * update_counter_and_wait and now. > @@ -149,6 +152,9 @@ void synchronize_rcu(void) > } > > qemu_mutex_unlock(&rcu_gp_lock); > + if (atomic_read(&rcu_call_count)) { > + qemu_event_set(&rcu_call_ready_event); > + } > } > > > @@ -159,8 +165,6 @@ void synchronize_rcu(void) > */ > static struct rcu_head dummy; > static struct rcu_head *head = &dummy, **tail = &dummy.next; > -static int rcu_call_count; > -static QemuEvent rcu_call_ready_event; > > static void enqueue(struct rcu_head *node) > { > -- > 1.8.3.1 > >
Reviewed-by: Fam Zheng <f...@redhat.com>