---
configure.ac | 1 +
lib/ovs-thread.c | 16 +++++++++++++++-
lib/timeval.c | 13 +++++++++++++
m4/openvswitch.m4 | 16 ++++++++++++++++
ofproto/ofproto-dpif-upcall.c | 7 +++++++
5 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index d6596f9..14b432b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ AC_CHECK_FUNCS([mlockall strnlen getloadavg statvfs
getmntent_r])
AC_CHECK_HEADERS([mntent.h sys/statvfs.h linux/types.h linux/if_ether.h
stdatomic.h])
AC_CHECK_HEADERS([net/if_mib.h], [], [], [[#include <sys/types.h>
#include <net/if.h>]])
+OVS_CHECK_LIBURCU
OVS_CHECK_PKIDIR
OVS_CHECK_RUNDIR
diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index b3a87bb..f034bd5 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -20,6 +20,7 @@
#include <poll.h>
#include <stdlib.h>
#include <unistd.h>
+#include <urcu-qsbr.h>
#include "compiler.h"
#include "poll-loop.h"
#include "socket-util.h"
@@ -196,6 +197,12 @@ struct ovsthread_aux {
void *arg;
};
+static void
+unregister_rcu(void *unused OVS_UNUSED)
+{
+ rcu_unregister_thread();
+}
+
static void *
ovsthread_wrapper(void *aux_)
{
@@ -204,14 +211,21 @@ ovsthread_wrapper(void *aux_)
struct ovsthread_aux *auxp = aux_;
struct ovsthread_aux aux;
unsigned int id;
+ void *retval;
atomic_add(&next_id, 1, &id);
*ovsthread_id_get() = id;
+ rcu_register_thread();
+
aux = *auxp;
free(auxp);
- return aux.start(aux.arg);
+ pthread_cleanup_push(unregister_rcu, NULL);
+ retval = aux.start(aux.arg);
+ pthread_cleanup_pop(true);
+
+ return retval;
}
void
diff --git a/lib/timeval.c b/lib/timeval.c
index 2ce45fc..49a6e9c 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -25,6 +25,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
+#include <urcu-qsbr.h>
#include "coverage.h"
#include "dummy.h"
#include "dynamic-string.h"
@@ -97,6 +98,8 @@ do_init_time(void)
struct timespec ts;
coverage_init();
+ rcu_register_thread();
+ rcu_read_lock();
init_clock(&monotonic_clock, (!clock_gettime(CLOCK_MONOTONIC, &ts)
? CLOCK_MONOTONIC
@@ -261,11 +264,21 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long
long int timeout_when,
time_left = timeout_when - now;
}
+ if (!time_left) {
+ rcu_quiescent_state();
+ } else {
+ rcu_thread_offline();
+ }
+
retval = poll(pollfds, n_pollfds, time_left);
if (retval < 0) {
retval = -errno;
}
+ if (time_left) {
+ rcu_thread_online();
+ }
+
if (deadline <= time_msec()) {
fatal_signal_handler(SIGALRM);
if (retval < 0) {
diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4
index dca6cca..62f4e0f 100644
--- a/m4/openvswitch.m4
+++ b/m4/openvswitch.m4
@@ -507,3 +507,19 @@ dnl OVS_CHECK_POSIX_AIO
AC_DEFUN([OVS_CHECK_POSIX_AIO],
[AC_SEARCH_LIBS([aio_write], [rt])
AM_CONDITIONAL([HAVE_POSIX_AIO], [test "$ac_cv_search_aio_write" != no])])
+
+dnl OVS_CHECK_LIBURCU.
+dnl
+dnl If liburcu-qsbr and <urcu-qsbr.h> are available, links against the
+dnl library and defines HAVE_LIBURCU.
+AC_DEFUN([OVS_CHECK_LIBURCU],
+ [save_LIBS=$LIBS
+ LIBS="-lurcu-qsbr $LIBS"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([#include <urcu-qsbr.h>
+#include <urcu-call-rcu.h>
+], [rcu_quiescent_state();])],
+ [AC_DEFINE([HAVE_LIBURCU], 1,
+ [Define to 1 if liburcu-qsbr and <urcu-qsbr.h> are
+ available.])],
+ [LIBS=$save_LIBS])])
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 954e92f..5192448 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <stdbool.h>
#include <inttypes.h>
+#include <urcu-qsbr.h>
#include "coverage.h"
#include "dynamic-string.h"
@@ -169,6 +170,8 @@ udpif_destroy(struct udpif *udpif)
void
udpif_recv_set(struct udpif *udpif, size_t n_handlers, bool enable)
{
+ rcu_thread_offline();
+
n_handlers = enable ? n_handlers : 0;
n_handlers = MIN(n_handlers, 64);
@@ -230,6 +233,8 @@ udpif_recv_set(struct udpif *udpif, size_t n_handlers, bool
enable)
}
xpthread_create(&udpif->dispatcher, NULL, udpif_dispatcher, udpif);
}
+
+ rcu_thread_online();
}
void
@@ -406,7 +411,9 @@ udpif_upcall_handler(void *arg)
}
if (!handler->n_upcalls) {
+ rcu_thread_offline();
ovs_mutex_cond_wait(&handler->wake_cond, &handler->mutex);
+ rcu_thread_online();
}
for (i = 0; i < FLOW_MISS_MAX_BATCH; i++) {
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev