--- 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