---
 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
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to