[ovs-dev] [threaded-learning 16/25] ofproto: Protect index by cookie with ofproto_mutex.

Ben Pfaff blp at nicira.com
Wed Sep 11 05:27:16 UTC 2013


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

Signed-off-by: Ben Pfaff <blp at 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 edc9abc..dd93743 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);
@@ -230,7 +231,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 9e33684..f5bac6a 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2943,6 +2943,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));
@@ -2950,6 +2951,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);
 }
@@ -2959,6 +2961,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);
@@ -2966,6 +2969,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);
     }
 }
 
@@ -3099,6 +3103,7 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id,
     if (cookie_mask == htonll(UINT64_MAX)) {
         struct rule *rule;
 
+        ovs_mutex_lock(&ofproto_mutex);
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie),
                                    &ofproto->cookies) {
             if (cls_rule_is_loose_match(&rule->cr, &cr.match)) {
@@ -3109,6 +3114,7 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id,
                 }
             }
         }
+        ovs_mutex_unlock(&ofproto_mutex);
     } else {
         FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
             struct cls_cursor cursor;
@@ -3164,6 +3170,7 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id,
     if (cookie_mask == htonll(UINT64_MAX)) {
         struct rule *rule;
 
+        ovs_mutex_lock(&ofproto_mutex);
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie),
                                    &ofproto->cookies) {
             if (cls_rule_equal(&rule->cr, &cr)) {
@@ -3174,6 +3181,7 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id,
                 }
             }
         }
+        ovs_mutex_unlock(&ofproto_mutex);
     } else {
         FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
             struct rule *rule;
@@ -6205,7 +6213,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)) {
@@ -6248,7 +6260,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




More information about the dev mailing list