Acked-by: Ethan Jackson <et...@nicira.com>
On Wed, Sep 4, 2013 at 12:39 PM, Ben Pfaff <b...@nicira.com> wrote: > 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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev