summaryrefslogtreecommitdiff
path: root/lib/classifier.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2014-10-14 13:31:48 -0700
committerJarno Rajahalme <jrajahalme@nicira.com>2014-10-14 13:31:48 -0700
commitd2064437e2bf91859a0a50fba30dcabba668a811 (patch)
treeaa22f6469a10e8b0667073dda4fb6042894f7adf /lib/classifier.c
parent3be1eaee7501dda17a75ab8a56e487f12cd066aa (diff)
downloadopenvswitch-d2064437e2bf91859a0a50fba30dcabba668a811.tar.gz
lib/classifier: Minimize critical section.
classifier_find_rule_exactly() only needs the mutex to protect the list traversal. Subtables are already RCU protected. Locking here can be eliminated completely when RCU list is available. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/classifier.c')
-rw-r--r--lib/classifier.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index f30ba9579..4a2fd170d 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -114,8 +114,7 @@ cls_match_alloc(struct cls_rule *rule)
}
static struct cls_subtable *find_subtable(const struct classifier *cls,
- const struct minimask *)
- OVS_REQUIRES(cls->mutex);
+ const struct minimask *);
static struct cls_subtable *insert_subtable(struct classifier *cls,
const struct minimask *)
OVS_REQUIRES(cls->mutex);
@@ -1090,28 +1089,26 @@ classifier_find_rule_exactly(const struct classifier *cls,
struct cls_match *head, *rule;
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;
+ if (!subtable || target->priority > subtable->max_priority) {
+ return NULL;
}
head = find_equal(subtable, &target->match.flow,
miniflow_hash_in_minimask(&target->match.flow,
&target->match.mask, 0));
+
+
+ /* Use RCU list instead of locking when one is available. */
+ ovs_mutex_lock(&cls->mutex);
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;
}
@@ -1339,7 +1336,6 @@ cls_cursor_advance(struct cls_cursor *cursor)
static struct cls_subtable *
find_subtable(const struct classifier *cls, const struct minimask *mask)
- OVS_REQUIRES(cls->mutex)
{
struct cls_subtable *subtable;