2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

classifier: Make classifier_find_rule_exactly() lockless.

struct cls_match 'list' member was recently changed to an rculist.
This allows classifier_find_rule_exactly() to be made lockless.

Since subtable's 'max_priority' member would still require a lock, we
no longer check it before calling find_equal().  This adds a hash
table lookup in cases where the subtable may already be known to not
contain any rule of the target priority.
classifier_find_rule_exactly() is never called on the fastpath, so
this should not be significant.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Jarno Rajahalme
2014-11-03 09:56:54 -08:00
parent dfea28b3b4
commit 98abae4aa6

View File

@@ -755,33 +755,26 @@ classifier_lookup(const struct classifier *cls, const struct flow *flow,
const struct cls_rule *
classifier_find_rule_exactly(const struct classifier *cls,
const struct cls_rule *target)
OVS_EXCLUDED(cls->mutex)
{
const struct cls_match *head, *rule;
const struct cls_subtable *subtable;
ovs_mutex_lock(&cls->mutex);
subtable = find_subtable(cls, &target->match.mask);
if (!subtable) {
goto out;
}
/* Skip if there is no hope. */
if (target->priority > subtable->max_priority) {
goto out;
return NULL;
}
head = find_equal(subtable, &target->match.flow,
miniflow_hash_in_minimask(&target->match.flow,
&target->match.mask, 0));
if (!head) {
return NULL;
}
FOR_EACH_RULE_IN_LIST (rule, head) {
if (target->priority >= rule->priority) {
ovs_mutex_unlock(&cls->mutex);
return target->priority == rule->priority ? rule->cls_rule : NULL;
}
}
out:
ovs_mutex_unlock(&cls->mutex);
return NULL;
}