[ovs-dev] [dpif-netdev 11/15] dpif-netdev: Take advantage of ovs_refcount for dp_netdev.
Ben Pfaff
blp at nicira.com
Sat Dec 28 04:03:12 UTC 2013
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 <blp at nicira.com>
---
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
More information about the dev
mailing list