The list of identical, but lower priority rules is not currently used
in classifier lookup.  A later patch introducing conjunctive matches
needs to access the list during lookups, so we must make the list RCU.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/classifier-private.h |    6 +++---
 lib/classifier.c         |   49 +++++++++++++++++++++++-----------------------
 tests/test-classifier.c  |    2 +-
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/lib/classifier-private.h b/lib/classifier-private.h
index 145efbb..24d277e 100644
--- a/lib/classifier-private.h
+++ b/lib/classifier-private.h
@@ -17,10 +17,10 @@
 #ifndef CLASSIFIER_PRIVATE_H
 #define CLASSIFIER_PRIVATE_H 1
 
+#include "cmap.h"
 #include "flow.h"
 #include "hash.h"
-#include "cmap.h"
-#include "list.h"
+#include "rculist.h"
 #include "tag.h"
 
 /* Classifier internal definitions, subject to change at any time. */
@@ -65,7 +65,7 @@ struct cls_partition {
 /* Internal representation of a rule in a "struct cls_subtable". */
 struct cls_match {
     /* Accessed only by writers and iterators. */
-    struct list list OVS_GUARDED; /* List of identical, lower-priority rules. 
*/
+    struct rculist list OVS_GUARDED; /* Identical, lower-priority rules. */
 
     /* Accessed only by writers. */
     struct cls_partition *partition OVS_GUARDED;
diff --git a/lib/classifier.c b/lib/classifier.c
index dab43ec..ca79e6c 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -71,6 +71,22 @@ static struct cls_match *find_match_wc(const struct 
cls_subtable *,
 static struct cls_match *find_equal(struct cls_subtable *,
                                     const struct miniflow *, uint32_t hash);
 
+static inline struct cls_match *
+next_rule_in_list__(struct cls_match *rule)
+    OVS_NO_THREAD_SAFETY_ANALYSIS
+{
+    struct cls_match *next = NULL;
+    next = OBJECT_CONTAINING(rculist_next(&rule->list), next, list);
+    return next;
+}
+
+static inline struct cls_match *
+next_rule_in_list(struct cls_match *rule)
+{
+    struct cls_match *next = next_rule_in_list__(rule);
+    return next->priority < rule->priority ? next : NULL;
+}
+
 /* Iterates RULE over HEAD and all of the cls_rules on HEAD->list.
  * Classifier's mutex must be held while iterating, as the list is
  * protoceted by it. */
@@ -576,14 +592,13 @@ classifier_remove(struct classifier *cls, struct cls_rule 
*rule)
 
     head = find_equal(subtable, &rule->match.flow, hash);
     if (head != cls_match) {
-        list_remove(&cls_match->list);
-    } else if (list_is_empty(&cls_match->list)) {
+        rculist_remove(&cls_match->list);
+    } else if (rculist_is_empty(&cls_match->list)) {
         cmap_remove(&subtable->rules, &cls_match->cmap_node, hash);
     } else {
-        struct cls_match *next = CONTAINER_OF(cls_match->list.next,
-                                              struct cls_match, list);
+        struct cls_match *next = next_rule_in_list(cls_match);
 
-        list_remove(&cls_match->list);
+        rculist_remove(&cls_match->list);
         cmap_replace(&subtable->rules, &cls_match->cmap_node,
                      &next->cmap_node, hash);
     }
@@ -1387,7 +1402,7 @@ insert_rule(struct classifier *cls, struct cls_subtable 
*subtable,
     head = find_equal(subtable, &new_rule->match.flow, hash);
     if (!head) {
         cmap_insert(&subtable->rules, &new->cmap_node, hash);
-        list_init(&new->list);
+        rculist_init(&new->list);
         goto out;
     } else {
         /* Scan the list for the insertion point that will keep the list in
@@ -1403,17 +1418,17 @@ insert_rule(struct classifier *cls, struct cls_subtable 
*subtable,
                 }
 
                 if (new->priority == rule->priority) {
-                    list_replace(&new->list, &rule->list);
+                    rculist_replace(&new->list, &rule->list);
                     old = rule;
                 } else {
-                    list_insert(&rule->list, &new->list);
+                    rculist_insert(&rule->list, &new->list);
                 }
                 goto out;
             }
         }
 
         /* Insert 'new' at the end of the list. */
-        list_push_back(&head->list, &new->list);
+        rculist_push_back(&head->list, &new->list);
     }
 
  out:
@@ -1441,22 +1456,6 @@ insert_rule(struct classifier *cls, struct cls_subtable 
*subtable,
     }
     return old;
 }
-
-static struct cls_match *
-next_rule_in_list__(struct cls_match *rule)
-    OVS_NO_THREAD_SAFETY_ANALYSIS
-{
-    struct cls_match *next = NULL;
-    next = OBJECT_CONTAINING(rule->list.next, next, list);
-    return next;
-}
-
-static struct cls_match *
-next_rule_in_list(struct cls_match *rule)
-{
-    struct cls_match *next = next_rule_in_list__(rule);
-    return next->priority < rule->priority ? next : NULL;
-}
 
 /* A longest-prefix match tree. */
 
diff --git a/tests/test-classifier.c b/tests/test-classifier.c
index 67bcbc6..bdfd0ef 100644
--- a/tests/test-classifier.c
+++ b/tests/test-classifier.c
@@ -563,7 +563,7 @@ check_tables(const struct classifier *cls, int n_tables, 
int n_rules,
 
             found_rules++;
             ovs_mutex_lock(&cls->mutex);
-            LIST_FOR_EACH (rule, list, &head->list) {
+            RCULIST_FOR_EACH (rule, list, &head->list) {
                 assert(rule->priority < prev_priority);
                 assert(rule->priority <= table->max_priority);
 
-- 
1.7.10.4

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

Reply via email to