summaryrefslogtreecommitdiff
path: root/lib/classifier.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2014-11-13 11:54:31 -0800
committerJarno Rajahalme <jrajahalme@nicira.com>2014-11-14 16:00:46 -0800
commit802f84ffd71a6c94234cec43f4a5abaf02b56fa8 (patch)
treebeb41962362454c8f6b362dcc8c2f47ead7c2042 /lib/classifier.c
parentd0999f1b34ecaefc5b3ab7bef3e7804383cdc3f7 (diff)
downloadopenvswitch-802f84ffd71a6c94234cec43f4a5abaf02b56fa8.tar.gz
classifier: Defer pvector publication.
This patch adds a new functions classifier_defer() and classifier_publish(), which control when the classifier modifications are made available to lookups. By default, all modifications are made available to lookups immediately. Modifications made after a classifier_defer() call MAY be 'deferred' for later 'publication'. A call to classifier_publish() will both publish any deferred modifications, and cause subsequent changes to to be published immediately. Currently any deferring is limited to the visibility of the subtable vector changes. pvector now processes modifications mostly in a working copy, which needs to be explicitly published with pvector_publish(). pvector_publish() sorts the working copy and removes gaps before publishing it. This change helps avoiding O(n**2) memory behavior in corner cases, where large number of rules with different masks are inserted or deleted. VMware-BZ: #1322017 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.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index bf9a44ccd..b05d140ea 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -248,6 +248,7 @@ classifier_init(struct classifier *cls, const uint8_t *flow_segments)
for (int i = 0; i < CLS_MAX_TRIES; i++) {
trie_init(cls, i, NULL);
}
+ cls->publish = true;
}
/* Destroys 'cls'. Rules within 'cls', if any, are not freed; this is the
@@ -634,6 +635,11 @@ classifier_replace(struct classifier *cls, const struct cls_rule *rule)
/* Nothing was replaced. */
cls->n_rules++;
+
+ if (cls->publish) {
+ pvector_publish(&cls->subtables);
+ }
+
return NULL;
}
@@ -767,6 +773,11 @@ check_priority:
pvector_change_priority(&cls->subtables, subtable, max_priority);
}
}
+
+ if (cls->publish) {
+ pvector_publish(&cls->subtables);
+ }
+
free:
ovsrcu_postpone(free, cls_match);
cls->n_rules--;