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

Reply via email to