Signed-off-by: Ethan Jackson <et...@nicira.com>
---
 ofproto/ofproto-dpif-xlate.c |   18 ++++++++++--------
 ofproto/ofproto-dpif.c       |    2 ++
 ofproto/ofproto-provider.h   |    4 +++-
 ofproto/ofproto.c            |    8 ++++++++
 4 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 8aa2bb1..86d8222 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -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);
     }
 }
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 36850d0..16d0fe8 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -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. */
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 9db4346..3ac9aaa 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -75,7 +75,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
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index c3f34c6..7e7ea3b 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -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);
-- 
1.7.9.5

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

Reply via email to