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