diff options
author | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-10-14 13:31:48 -0700 |
---|---|---|
committer | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-10-14 13:31:48 -0700 |
commit | d2064437e2bf91859a0a50fba30dcabba668a811 (patch) | |
tree | aa22f6469a10e8b0667073dda4fb6042894f7adf /lib/classifier.c | |
parent | 3be1eaee7501dda17a75ab8a56e487f12cd066aa (diff) | |
download | openvswitch-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.c | 20 |
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; |