ofproto-dpif: Lock the expirable list.
authorEthan Jackson <ethan@nicira.com>
Thu, 8 Aug 2013 00:41:17 +0000 (17:41 -0700)
committerEthan Jackson <ethan@nicira.com>
Thu, 8 Aug 2013 21:08:20 +0000 (14:08 -0700)
Signed-off-by: Ethan Jackson <ethan@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
ofproto/ofproto-dpif-xlate.c
ofproto/ofproto-dpif.c
ofproto/ofproto-provider.h
ofproto/ofproto.c

index 8aa2bb1..86d8222 100644 (file)
@@ -2036,14 +2036,16 @@ xlate_fin_timeout(struct xlate_ctx *ctx,
     if (ctx->xin->tcp_flags & (TCP_FIN | TCP_RST) && ctx->rule) {
         struct rule_dpif *rule = ctx->rule;
 
-         if (list_is_empty(&rule->up.expirable)) {
-             list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
-         }
-
-         ovs_mutex_lock(&rule->up.timeout_mutex);
-         reduce_timeout(oft->fin_idle_timeout, &rule->up.idle_timeout);
-         reduce_timeout(oft->fin_hard_timeout, &rule->up.hard_timeout);
-         ovs_mutex_unlock(&rule->up.timeout_mutex);
+        ovs_mutex_lock(&rule->up.ofproto->expirable_mutex);
+        if (list_is_empty(&rule->up.expirable)) {
+            list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
+        }
+        ovs_mutex_unlock(&rule->up.ofproto->expirable_mutex);
+
+        ovs_mutex_lock(&rule->up.timeout_mutex);
+        reduce_timeout(oft->fin_idle_timeout, &rule->up.idle_timeout);
+        reduce_timeout(oft->fin_hard_timeout, &rule->up.hard_timeout);
+        ovs_mutex_unlock(&rule->up.timeout_mutex);
     }
 }
 
index d357b8d..1a3567d 100644 (file)
@@ -4028,10 +4028,12 @@ expire(struct dpif_backer *backer)
 
         /* Expire OpenFlow flows whose idle_timeout or hard_timeout
          * has passed. */
+        ovs_mutex_lock(&ofproto->up.expirable_mutex);
         LIST_FOR_EACH_SAFE (rule, next_rule, expirable,
                             &ofproto->up.expirable) {
             rule_expire(rule_dpif_cast(rule));
         }
+        ovs_mutex_unlock(&ofproto->up.expirable_mutex);
 
         /* All outstanding data in existing flows has been accounted, so it's a
          * good time to do bond rebalancing. */
index 75bcefc..68f4a80 100644 (file)
@@ -76,7 +76,9 @@ struct ofproto {
 
     /* Optimisation for flow expiry.
      * These flows should all be present in tables. */
-    struct list expirable;      /* Expirable 'struct rule"s in all tables. */
+    struct ovs_mutex expirable_mutex;
+    struct list expirable OVS_GUARDED; /* Expirable 'struct rule"s in all
+                                          tables. */
 
     /* Meter table.
      * OpenFlow meters start at 1.  To avoid confusion we leave the first
index 34298d4..fad8746 100644 (file)
@@ -430,6 +430,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
     ofproto->n_tables = 0;
     hindex_init(&ofproto->cookies);
     list_init(&ofproto->expirable);
+    ovs_mutex_init(&ofproto->expirable_mutex, PTHREAD_MUTEX_RECURSIVE);
     ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
     ofproto->state = S_OPENFLOW;
     list_init(&ofproto->pending);
@@ -1115,6 +1116,7 @@ ofproto_destroy__(struct ofproto *ofproto)
 
     free(ofproto->vlan_bitmap);
 
+    ovs_mutex_destroy(&ofproto->expirable_mutex);
     ofproto->ofproto_class->dealloc(ofproto);
 }
 
@@ -5401,9 +5403,11 @@ oftable_remove_rule(struct rule *rule)
     }
     cookies_remove(ofproto, rule);
     eviction_group_remove_rule(rule);
+    ovs_mutex_lock(&ofproto->expirable_mutex);
     if (!list_is_empty(&rule->expirable)) {
         list_remove(&rule->expirable);
     }
+    ovs_mutex_unlock(&ofproto->expirable_mutex);
     if (!list_is_empty(&rule->meter_list_node)) {
         list_remove(&rule->meter_list_node);
     }
@@ -5425,7 +5429,9 @@ oftable_replace_rule(struct rule *rule)
     ovs_mutex_unlock(&rule->timeout_mutex);
 
     if (may_expire) {
+        ovs_mutex_lock(&ofproto->expirable_mutex);
         list_insert(&ofproto->expirable, &rule->expirable);
+        ovs_mutex_unlock(&ofproto->expirable_mutex);
     }
     cookies_insert(ofproto, rule);
     if (rule->meter_id) {
@@ -5439,9 +5445,11 @@ oftable_replace_rule(struct rule *rule)
         }
         cookies_remove(ofproto, victim);
 
+        ovs_mutex_lock(&ofproto->expirable_mutex);
         if (!list_is_empty(&victim->expirable)) {
             list_remove(&victim->expirable);
         }
+        ovs_mutex_unlock(&ofproto->expirable_mutex);
         eviction_group_remove_rule(victim);
     }
     eviction_group_add_rule(rule);