On Fri, Dec 27, 2013 at 8:03 PM, Ben Pfaff <b...@nicira.com> wrote: > By making "destroyed" own a reference, we can treat dp_netdev's ref_cnt > like any other in Open vSwitch. > > Signed-off-by: Ben Pfaff <b...@nicira.com>
Looks good to me. > --- > lib/dpif-netdev.c | 23 ++++++++++++++--------- > 1 file changed, 14 insertions(+), 9 deletions(-) > > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index b890e4f..62837b0 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -91,8 +91,8 @@ struct dp_netdev_queue { > struct dp_netdev { > const struct dpif_class *class; > char *name; > - int open_cnt; > - bool destroyed; > + struct ovs_refcount ref_cnt; > + atomic_flag destroyed; > > struct dp_netdev_queue queues[N_QUEUES]; > struct classifier cls; /* Classifier. */ > @@ -224,7 +224,7 @@ create_dpif_netdev(struct dp_netdev *dp) > uint16_t netflow_id = hash_string(dp->name, 0); > struct dpif_netdev *dpif; > > - dp->open_cnt++; > + ovs_refcount_ref(&dp->ref_cnt); > > dpif = xmalloc(sizeof *dpif); > dpif_init(&dpif->dpif, dp->class, dp->name, netflow_id >> 8, netflow_id); > @@ -286,7 +286,8 @@ create_dp_netdev(const char *name, const struct > dpif_class *class, > dp = xzalloc(sizeof *dp); > dp->class = class; > dp->name = xstrdup(name); > - dp->open_cnt = 0; > + ovs_refcount_init(&dp->ref_cnt); > + atomic_flag_init(&dp->destroyed); > for (i = 0; i < N_QUEUES; i++) { > dp->queues[i].head = dp->queues[i].tail = 0; > } > @@ -371,6 +372,8 @@ dp_netdev_free(struct dp_netdev *dp) > hmap_destroy(&dp->flow_table); > seq_destroy(dp->port_seq); > hmap_destroy(&dp->ports); > + atomic_flag_destroy(&dp->destroyed); > + ovs_refcount_destroy(&dp->ref_cnt); > free(dp->name); > free(dp); > } > @@ -382,8 +385,7 @@ dpif_netdev_close(struct dpif *dpif) > > ovs_mutex_lock(&dp_netdev_mutex); > > - ovs_assert(dp->open_cnt > 0); > - if (--dp->open_cnt == 0 && dp->destroyed) { > + if (ovs_refcount_unref(&dp->ref_cnt) == 1) { > shash_find_and_delete(&dp_netdevs, dp->name); > dp_netdev_free(dp); > } > @@ -397,9 +399,12 @@ dpif_netdev_destroy(struct dpif *dpif) > { > struct dp_netdev *dp = get_dp_netdev(dpif); > > - ovs_mutex_lock(&dp_netdev_mutex); > - dp->destroyed = true; > - ovs_mutex_unlock(&dp_netdev_mutex); > + if (!atomic_flag_test_and_set(&dp->destroyed)) { > + if (ovs_refcount_unref(&dp->ref_cnt) == 1) { > + /* Can't happen: 'dpif' still owns a reference to 'dp'. */ > + OVS_NOT_REACHED(); > + } > + } > > return 0; > } > -- > 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