Otherwise ovsrcu_synchronize() busy-waits in its loop because its poll_block() un-quiesces, causing the global_seqno to increase, which is what it waits for.
Reported-by: Alex Wang <al...@nicira.com> Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/ovs-rcu.c | 7 +++++++ lib/ovs-rcu.h | 1 + lib/timeval.c | 14 +++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c index 269f51b..b3c434d 100644 --- a/lib/ovs-rcu.c +++ b/lib/ovs-rcu.c @@ -134,6 +134,13 @@ ovsrcu_quiesce(void) ovsrcu_quiesced(); } +bool +ovsrcu_is_quiescent(void) +{ + ovsrcu_init(); + return pthread_getspecific(perthread_key) == NULL; +} + static void ovsrcu_synchronize(void) { diff --git a/lib/ovs-rcu.h b/lib/ovs-rcu.h index 710870a..4b451b2 100644 --- a/lib/ovs-rcu.h +++ b/lib/ovs-rcu.h @@ -178,5 +178,6 @@ void ovsrcu_postpone__(void (*function)(void *aux), void *aux); void ovsrcu_quiesce_start(void); void ovsrcu_quiesce_end(void); void ovsrcu_quiesce(void); +bool ovsrcu_is_quiescent(void); #endif /* ovs-rcu.h */ diff --git a/lib/timeval.c b/lib/timeval.c index ebbdb98..d2a4380 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -263,6 +263,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, { long long int *last_wakeup = last_wakeup_get(); long long int start; + bool quiescent; int retval = 0; time_init(); @@ -274,6 +275,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, start = time_msec(); timeout_when = MIN(timeout_when, deadline); + quiescent = ovsrcu_is_quiescent(); for (;;) { long long int now = time_msec(); @@ -287,10 +289,12 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, time_left = timeout_when - now; } - if (!time_left) { - ovsrcu_quiesce(); - } else { - ovsrcu_quiesce_start(); + if (!quiescent) { + if (!time_left) { + ovsrcu_quiesce(); + } else { + ovsrcu_quiesce_start(); + } } #ifndef _WIN32 @@ -313,7 +317,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, } #endif - if (time_left) { + if (!quiescent && time_left) { ovsrcu_quiesce_end(); } -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev