mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 15:55:19 +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
|
#ifndef CLASSIFIER_PRIVATE_H
|
||||||
#define CLASSIFIER_PRIVATE_H 1
|
#define CLASSIFIER_PRIVATE_H 1
|
||||||
|
|
||||||
|
#include "cmap.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "cmap.h"
|
#include "rculist.h"
|
||||||
#include "list.h"
|
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
|
||||||
/* Classifier internal definitions, subject to change at any time. */
|
/* 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". */
|
/* Internal representation of a rule in a "struct cls_subtable". */
|
||||||
struct cls_match {
|
struct cls_match {
|
||||||
/* Accessed only by writers and iterators. */
|
/* 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. */
|
/* Accessed only by writers. */
|
||||||
struct cls_partition *partition OVS_GUARDED;
|
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 *,
|
static struct cls_match *find_equal(struct cls_subtable *,
|
||||||
const struct miniflow *, uint32_t hash);
|
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.
|
/* 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
|
* Classifier's mutex must be held while iterating, as the list is
|
||||||
* protoceted by it. */
|
* protoceted by it. */
|
||||||
@@ -576,14 +592,13 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule)
|
|||||||
|
|
||||||
head = find_equal(subtable, &rule->match.flow, hash);
|
head = find_equal(subtable, &rule->match.flow, hash);
|
||||||
if (head != cls_match) {
|
if (head != cls_match) {
|
||||||
list_remove(&cls_match->list);
|
rculist_remove(&cls_match->list);
|
||||||
} else if (list_is_empty(&cls_match->list)) {
|
} else if (rculist_is_empty(&cls_match->list)) {
|
||||||
cmap_remove(&subtable->rules, &cls_match->cmap_node, hash);
|
cmap_remove(&subtable->rules, &cls_match->cmap_node, hash);
|
||||||
} else {
|
} else {
|
||||||
struct cls_match *next = CONTAINER_OF(cls_match->list.next,
|
struct cls_match *next = next_rule_in_list(cls_match);
|
||||||
struct cls_match, list);
|
|
||||||
|
|
||||||
list_remove(&cls_match->list);
|
rculist_remove(&cls_match->list);
|
||||||
cmap_replace(&subtable->rules, &cls_match->cmap_node,
|
cmap_replace(&subtable->rules, &cls_match->cmap_node,
|
||||||
&next->cmap_node, hash);
|
&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);
|
head = find_equal(subtable, &new_rule->match.flow, hash);
|
||||||
if (!head) {
|
if (!head) {
|
||||||
cmap_insert(&subtable->rules, &new->cmap_node, hash);
|
cmap_insert(&subtable->rules, &new->cmap_node, hash);
|
||||||
list_init(&new->list);
|
rculist_init(&new->list);
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
/* Scan the list for the insertion point that will keep the list in
|
/* 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) {
|
if (new->priority == rule->priority) {
|
||||||
list_replace(&new->list, &rule->list);
|
rculist_replace(&new->list, &rule->list);
|
||||||
old = rule;
|
old = rule;
|
||||||
} else {
|
} else {
|
||||||
list_insert(&rule->list, &new->list);
|
rculist_insert(&rule->list, &new->list);
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert 'new' at the end of the list. */
|
/* Insert 'new' at the end of the list. */
|
||||||
list_push_back(&head->list, &new->list);
|
rculist_push_back(&head->list, &new->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1441,22 +1456,6 @@ insert_rule(struct classifier *cls, struct cls_subtable *subtable,
|
|||||||
}
|
}
|
||||||
return old;
|
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. */
|
/* A longest-prefix match tree. */
|
||||||
|
|
||||||
|
@@ -563,7 +563,7 @@ check_tables(const struct classifier *cls, int n_tables, int n_rules,
|
|||||||
|
|
||||||
found_rules++;
|
found_rules++;
|
||||||
ovs_mutex_lock(&cls->mutex);
|
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 < prev_priority);
|
||||||
assert(rule->priority <= table->max_priority);
|
assert(rule->priority <= table->max_priority);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user