mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 14:55:18 +00:00
classifier: Use rculist.
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 <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -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;
|
||||
|
@@ -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. */
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user