[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