From d997f23fe5eb75003a0aaa37b3a6e6fae8ecfa03 Mon Sep 17 00:00:00 2001 From: Zoltan Kiss Date: Fri, 25 Sep 2015 11:42:40 -0700 Subject: [PATCH] ofproto-dpif: Do not block on uninitialized pause barriers. e4e74c3a "dpif-netdev: Purge all ukeys when reconfigure pmd." introduced a new dp_purge_cb function, which calls udpif_pause_revalidators() and that tries to block on pause_barrier. But if OVS was started with flow-restore-wait="true" (e.g. through ovs-ctl), type_run() will have backer->recv_set_enable == false, and udpif_set_threads won't initialize the barrier, which leads to a segfault like this: This patch introduces ofproto_dpif_backer_enabled(), which checks recv_set_enable before touching the latch and blocking on pause_barrier. Signed-off-by: Zoltan Kiss Acked-by: Joe Stringer --- ofproto/ofproto-dpif-upcall.c | 12 ++++++++---- ofproto/ofproto-dpif.c | 6 ++++++ ofproto/ofproto-dpif.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 8a43bbf45..3b897e06e 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -522,8 +522,10 @@ udpif_start_threads(struct udpif *udpif, size_t n_handlers, static void udpif_pause_revalidators(struct udpif *udpif) { - latch_set(&udpif->pause_latch); - ovs_barrier_block(&udpif->pause_barrier); + if (ofproto_dpif_backer_enabled(udpif->backer)) { + latch_set(&udpif->pause_latch); + ovs_barrier_block(&udpif->pause_barrier); + } } /* Resumes the pausing of revalidators. Should only be called by the @@ -531,8 +533,10 @@ udpif_pause_revalidators(struct udpif *udpif) static void udpif_resume_revalidators(struct udpif *udpif) { - latch_poll(&udpif->pause_latch); - ovs_barrier_block(&udpif->pause_barrier); + if (ofproto_dpif_backer_enabled(udpif->backer)) { + latch_poll(&udpif->pause_latch); + ovs_barrier_block(&udpif->pause_barrier); + } } /* Tells 'udpif' how many threads it should use to handle upcalls. diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index cffedb9c7..ef1ad1829 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -515,6 +515,12 @@ lookup_ofproto_dpif_by_port_name(const char *name) return NULL; } +bool +ofproto_dpif_backer_enabled(struct dpif_backer* backer) +{ + return backer->recv_set_enable; +} + static int type_run(const char *type) { diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 2397fb459..dab422aac 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -169,6 +169,8 @@ struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); struct ofport_dpif *ofp_port_to_ofport(const struct ofproto_dpif *, ofp_port_t); +bool ofproto_dpif_backer_enabled(struct dpif_backer* backer); + int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, const struct match *, int priority, uint16_t idle_timeout,