The cookie index is only used for flow_mods, so it makes sense to use this
global mutex.

Signed-off-by: Ben Pfaff <b...@nicira.com>
Acked-by: Ethan Jackson <et...@nicira.com>
---
 ofproto/ofproto-provider.h |    5 +++--
 ofproto/ofproto.c          |   15 +++++++++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index c9fd71e..bd40fbf 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -77,7 +77,8 @@ struct ofproto {
     struct oftable *tables;
     int n_tables;
 
-    struct hindex cookies;      /* Rules indexed on their cookie values. */
+    /* Rules indexed on their cookie values, in all flow tables. */
+    struct hindex cookies OVS_GUARDED_BY(ofproto_mutex);
 
     /* List of expirable flows, in all flow tables. */
     struct list expirable OVS_GUARDED_BY(ofproto_mutex);
@@ -234,7 +235,7 @@ struct rule {
 
     ovs_be64 flow_cookie;        /* Controller-issued identifier. Guarded by
                                     rwlock. */
-    struct hindex_node cookie_node; /* In owning ofproto's 'cookies' index. */
+    struct hindex_node cookie_node OVS_GUARDED_BY(ofproto_mutex);
 
     long long int created;       /* Creation time. */
     long long int modified;      /* Time of last modification. */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 4fa5af1..97a2c07 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2975,6 +2975,7 @@ hash_cookie(ovs_be64 cookie)
 
 static void
 cookies_insert(struct ofproto *ofproto, struct rule *rule)
+    OVS_REQUIRES(ofproto_mutex)
 {
     hindex_insert(&ofproto->cookies, &rule->cookie_node,
                   hash_cookie(rule->flow_cookie));
@@ -2982,6 +2983,7 @@ cookies_insert(struct ofproto *ofproto, struct rule *rule)
 
 static void
 cookies_remove(struct ofproto *ofproto, struct rule *rule)
+    OVS_REQUIRES(ofproto_mutex)
 {
     hindex_remove(&ofproto->cookies, &rule->cookie_node);
 }
@@ -2991,6 +2993,7 @@ ofproto_rule_change_cookie(struct ofproto *ofproto, 
struct rule *rule,
                            ovs_be64 new_cookie)
 {
     if (new_cookie != rule->flow_cookie) {
+        ovs_mutex_lock(&ofproto_mutex);
         cookies_remove(ofproto, rule);
 
         ovs_rwlock_wrlock(&rule->rwlock);
@@ -2998,6 +3001,7 @@ ofproto_rule_change_cookie(struct ofproto *ofproto, 
struct rule *rule,
         ovs_rwlock_unlock(&rule->rwlock);
 
         cookies_insert(ofproto, rule);
+        ovs_mutex_unlock(&ofproto_mutex);
     }
 }
 
@@ -3185,6 +3189,7 @@ collect_rules_loose(struct ofproto *ofproto,
     if (criteria->cookie_mask == htonll(UINT64_MAX)) {
         struct rule *rule;
 
+        ovs_mutex_lock(&ofproto_mutex);
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
                                    hash_cookie(criteria->cookie),
                                    &ofproto->cookies) {
@@ -3195,6 +3200,7 @@ collect_rules_loose(struct ofproto *ofproto,
                 }
             }
         }
+        ovs_mutex_unlock(&ofproto_mutex);
     } else {
         FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) {
             struct cls_cursor cursor;
@@ -3245,6 +3251,7 @@ collect_rules_strict(struct ofproto *ofproto,
     if (criteria->cookie_mask == htonll(UINT64_MAX)) {
         struct rule *rule;
 
+        ovs_mutex_lock(&ofproto_mutex);
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
                                    hash_cookie(criteria->cookie),
                                    &ofproto->cookies) {
@@ -3255,6 +3262,7 @@ collect_rules_strict(struct ofproto *ofproto,
                 }
             }
         }
+        ovs_mutex_unlock(&ofproto_mutex);
     } else {
         FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) {
             struct rule *rule;
@@ -6330,7 +6338,11 @@ oftable_remove_rule__(struct ofproto *ofproto, struct 
classifier *cls,
     OVS_REQ_WRLOCK(cls->rwlock) OVS_RELEASES(rule->rwlock)
 {
     classifier_remove(cls, &rule->cr);
+
+    ovs_mutex_lock(&ofproto_mutex);
     cookies_remove(ofproto, rule);
+    ovs_mutex_unlock(&ofproto_mutex);
+
     eviction_group_remove_rule(rule);
     ovs_mutex_lock(&ofproto_mutex);
     if (!list_is_empty(&rule->expirable)) {
@@ -6373,7 +6385,10 @@ oftable_insert_rule(struct rule *rule)
         list_insert(&ofproto->expirable, &rule->expirable);
         ovs_mutex_unlock(&ofproto_mutex);
     }
+
+    ovs_mutex_lock(&ofproto_mutex);
     cookies_insert(ofproto, rule);
+    ovs_mutex_unlock(&ofproto_mutex);
 
     if (rule->actions->meter_id) {
         struct meter *meter = ofproto->meters[rule->actions->meter_id];
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to