Setting tag sliver-openvswitch-2.2.90-1
[sliver-openvswitch.git] / ofproto / ofproto-dpif-mirror.c
index 0819b72..fcc7758 100644 (file)
@@ -36,7 +36,7 @@ struct mbridge {
     bool need_revalidate;
     bool has_mirrors;
 
-    int ref_cnt;
+    struct ovs_refcount ref_cnt;
 };
 
 struct mbundle {
@@ -75,7 +75,6 @@ static void mbundle_lookup_multiple(const struct mbridge *, struct ofbundle **,
                                   size_t n_bundles, struct hmapx *mbundles);
 static int mirror_scan(struct mbridge *);
 static void mirror_update_dups(struct mbridge *);
-static int mirror_mask_ffs(mirror_mask_t);
 
 struct mbridge *
 mbridge_create(void)
@@ -83,7 +82,7 @@ mbridge_create(void)
     struct mbridge *mbridge;
 
     mbridge = xzalloc(sizeof *mbridge);
-    mbridge->ref_cnt = 1;
+    ovs_refcount_init(&mbridge->ref_cnt);
 
     hmap_init(&mbridge->mbundles);
     return mbridge;
@@ -94,8 +93,7 @@ mbridge_ref(const struct mbridge *mbridge_)
 {
     struct mbridge *mbridge = CONST_CAST(struct mbridge *, mbridge_);
     if (mbridge) {
-        ovs_assert(mbridge->ref_cnt > 0);
-        mbridge->ref_cnt++;
+        ovs_refcount_ref(&mbridge->ref_cnt);
     }
     return mbridge;
 }
@@ -110,23 +108,20 @@ mbridge_unref(struct mbridge *mbridge)
         return;
     }
 
-    ovs_assert(mbridge->ref_cnt > 0);
-    if (--mbridge->ref_cnt) {
-        return;
-    }
+    if (ovs_refcount_unref(&mbridge->ref_cnt) == 1) {
+        for (i = 0; i < MAX_MIRRORS; i++) {
+            if (mbridge->mirrors[i]) {
+                mirror_destroy(mbridge, mbridge->mirrors[i]->aux);
+            }
+        }
 
-    for (i = 0; i < MAX_MIRRORS; i++) {
-        if (mbridge->mirrors[i]) {
-            mirror_destroy(mbridge, mbridge->mirrors[i]->aux);
+        HMAP_FOR_EACH_SAFE (mbundle, next, hmap_node, &mbridge->mbundles) {
+            mbridge_unregister_bundle(mbridge, mbundle->ofbundle);
         }
-    }
 
-    HMAP_FOR_EACH_SAFE (mbundle, next, hmap_node, &mbridge->mbundles) {
-        mbridge_unregister_bundle(mbridge, mbundle->ofbundle);
+        hmap_destroy(&mbridge->mbundles);
+        free(mbridge);
     }
-
-    hmap_destroy(&mbridge->mbundles);
-    free(mbridge);
 }
 
 bool
@@ -363,7 +358,7 @@ mirror_update_stats(struct mbridge *mbridge, mirror_mask_t mirrors,
     for (; mirrors; mirrors = zero_rightmost_1bit(mirrors)) {
         struct mirror *m;
 
-        m = mbridge->mirrors[mirror_mask_ffs(mirrors) - 1];
+        m = mbridge->mirrors[raw_ctz(mirrors)];
 
         if (!m) {
             /* In normal circumstances 'm' will not be NULL.  However,