[ovs-dev] [urcu-fixes 1/4] timeval: Preserve quiescence across time_poll().
Ben Pfaff
blp at nicira.com
Mon Apr 28 16:06:25 UTC 2014
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 <alexw at nicira.com>
Signed-off-by: Ben Pfaff <blp at 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
More information about the dev
mailing list