When a bridge that has active traffic is deleted, the bridge's ofproto can be referenced by in-flight "flow_miss"es. This commit fixes the problem by destroying "flow_miss"es that reference the ofproto that is being deleted.
I found the problem by adding and removing a bridge that had active traffic (via hping3) while running under valgrind. Signed-off-by: Ben Pfaff <b...@nicira.com> --- ofproto/ofproto-dpif-upcall.c | 31 +++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-upcall.h | 3 +++ ofproto/ofproto-dpif.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 22cdf1b..3294d3b 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -347,6 +347,37 @@ flow_miss_batch_destroy(struct flow_miss_batch *fmb) free(fmb); } +/* Discards any flow miss batches queued up in 'udpif' for 'ofproto' (because + * 'ofproto' is being destroyed). + * + * 'ofproto''s xports must already have been removed, otherwise new flow miss + * batches could still end up getting queued. */ +void +flow_miss_batch_ofproto_destroyed(struct udpif *udpif, + const struct ofproto_dpif *ofproto) +{ + struct flow_miss_batch *fmb, *next_fmb; + + ovs_mutex_lock(&udpif->fmb_mutex); + LIST_FOR_EACH_SAFE (fmb, next_fmb, list_node, &udpif->fmbs) { + struct flow_miss *miss, *next_miss; + + HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &fmb->misses) { + if (miss->ofproto == ofproto) { + hmap_remove(&fmb->misses, &miss->hmap_node); + miss_destroy(miss); + } + } + + if (hmap_is_empty(&fmb->misses)) { + list_remove(&fmb->list_node); + flow_miss_batch_destroy(fmb); + udpif->n_fmbs--; + } + } + ovs_mutex_unlock(&udpif->fmb_mutex); +} + /* Retreives the next drop key which ofproto-dpif needs to process. The caller * is responsible for destroying it with drop_key_destroy(). */ struct drop_key * diff --git a/ofproto/ofproto-dpif-upcall.h b/ofproto/ofproto-dpif-upcall.h index f597672..8e8264e 100644 --- a/ofproto/ofproto-dpif-upcall.h +++ b/ofproto/ofproto-dpif-upcall.h @@ -109,6 +109,9 @@ struct flow_miss_batch { struct flow_miss_batch *flow_miss_batch_next(struct udpif *); void flow_miss_batch_destroy(struct flow_miss_batch *); + +void flow_miss_batch_ofproto_destroyed(struct udpif *, + const struct ofproto_dpif *); /* Drop keys are odp flow keys which have drop flows installed in the kernel. * These are datapath flows which have no associated ofproto, if they did we diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 336453c..c8c56bb 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1437,6 +1437,8 @@ destruct(struct ofproto *ofproto_) xlate_remove_ofproto(ofproto); ovs_rwlock_unlock(&xlate_rwlock); + flow_miss_batch_ofproto_destroyed(ofproto->backer->udpif, ofproto); + hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node); complete_operations(ofproto); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev