ofproto-dpif: Do not block on uninitialized pause barriers.
authorZoltan Kiss <zoltan.kiss@linaro.org>
Fri, 25 Sep 2015 18:42:40 +0000 (11:42 -0700)
committerJoe Stringer <joestringer@nicira.com>
Fri, 25 Sep 2015 22:26:27 +0000 (15:26 -0700)
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 <zoltan.kiss@linaro.org>
Acked-by: Joe Stringer <joestringer@nicira.com>
ofproto/ofproto-dpif-upcall.c
ofproto/ofproto-dpif.c
ofproto/ofproto-dpif.h

index 8a43bbf..3b897e0 100644 (file)
@@ -522,8 +522,10 @@ udpif_start_threads(struct udpif *udpif, size_t n_handlers,
 static void
 udpif_pause_revalidators(struct udpif *udpif)
 {
 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
 }
 
 /* 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)
 {
 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.
 }
 
 /* Tells 'udpif' how many threads it should use to handle upcalls.
index cffedb9..ef1ad18 100644 (file)
@@ -515,6 +515,12 @@ lookup_ofproto_dpif_by_port_name(const char *name)
     return NULL;
 }
 
     return NULL;
 }
 
+bool
+ofproto_dpif_backer_enabled(struct dpif_backer* backer)
+{
+    return backer->recv_set_enable;
+}
+
 static int
 type_run(const char *type)
 {
 static int
 type_run(const char *type)
 {
index 2397fb4..dab422a 100644 (file)
@@ -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);
 
 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,
 int ofproto_dpif_add_internal_flow(struct ofproto_dpif *,
                                    const struct match *, int priority,
                                    uint16_t idle_timeout,