diff options
author | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-11-14 15:58:09 -0800 |
---|---|---|
committer | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-11-14 15:58:09 -0800 |
commit | fccd7c092e09ce9767d34436bf9c70302c87c5f5 (patch) | |
tree | c8f4b214dcc276199be878ce9c4b1c603cec0a8f /lib/classifier.c | |
parent | de4ad4a21569fa63912be87c1b2e858d888dc1b0 (diff) | |
download | openvswitch-fccd7c092e09ce9767d34436bf9c70302c87c5f5.tar.gz |
classifier: Remove internal mutex.
Almost all classifier users already exclude concurrent modifications,
or are single-threaded, hence the classifier internal mutex can be
removed. Due to this change, ovs-router.c and tnl-ports.c need new
mutexes, which are added.
As noted by Ben in review, ovs_router_flush() should also free the
entries it removes from the classifier. It now calls
ovsrcu_postpone() to that effect.
Suggested-by: Ben Pfaff <blp@nicira.com>
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 | 46 |
1 files changed, 5 insertions, 41 deletions
diff --git a/lib/classifier.c b/lib/classifier.c index 4560f4028..aa4c351dd 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -56,10 +56,8 @@ cls_match_alloc(struct cls_rule *rule) static struct cls_subtable *find_subtable(const struct classifier *cls, const struct minimask *); static struct cls_subtable *insert_subtable(struct classifier *cls, - const struct minimask *) - OVS_REQUIRES(cls->mutex); -static void destroy_subtable(struct classifier *cls, struct cls_subtable *) - OVS_REQUIRES(cls->mutex); + const struct minimask *); +static void destroy_subtable(struct classifier *cls, struct cls_subtable *); static const struct cls_match *find_match_wc(const struct cls_subtable *, const struct flow *, @@ -99,9 +97,7 @@ next_rule_in_list_protected(struct cls_match *rule) return next->priority < rule->priority ? next : NULL; } -/* 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 - * protoceted by it. */ +/* Iterates RULE over HEAD and all of the cls_rules on HEAD->list. */ #define FOR_EACH_RULE_IN_LIST(RULE, HEAD) \ for ((RULE) = (HEAD); (RULE) != NULL; (RULE) = next_rule_in_list(RULE)) #define FOR_EACH_RULE_IN_LIST_PROTECTED(RULE, HEAD) \ @@ -111,8 +107,7 @@ next_rule_in_list_protected(struct cls_match *rule) static unsigned int minimask_get_prefix_len(const struct minimask *, const struct mf_field *); static void trie_init(struct classifier *cls, int trie_idx, - const struct mf_field *) - OVS_REQUIRES(cls->mutex); + const struct mf_field *); static unsigned int trie_lookup(const struct cls_trie *, const struct flow *, union mf_value *plens); static unsigned int trie_lookup_value(const rcu_trie_ptr *, @@ -134,7 +129,6 @@ static bool mask_prefix_bits_set(const struct flow_wildcards *, static inline void cls_rule_init__(struct cls_rule *rule, unsigned int priority) - OVS_NO_THREAD_SAFETY_ANALYSIS { rculist_init(&rule->node); rule->priority = priority; @@ -181,7 +175,6 @@ cls_rule_clone(struct cls_rule *dst, const struct cls_rule *src) * The caller must eventually destroy 'dst' with cls_rule_destroy(). */ void cls_rule_move(struct cls_rule *dst, struct cls_rule *src) - OVS_NO_THREAD_SAFETY_ANALYSIS { ovs_assert(!src->cls_match); /* Must not be in a classifier. */ cls_rule_init__(dst, src->priority); @@ -194,7 +187,6 @@ cls_rule_move(struct cls_rule *dst, struct cls_rule *src) * ('rule' must not currently be in a classifier.) */ void cls_rule_destroy(struct cls_rule *rule) - OVS_NO_THREAD_SAFETY_ANALYSIS { ovs_assert(!rule->cls_match); /* Must not be in a classifier. */ @@ -240,10 +232,7 @@ cls_rule_is_catchall(const struct cls_rule *rule) * rules. */ void classifier_init(struct classifier *cls, const uint8_t *flow_segments) - OVS_EXCLUDED(cls->mutex) { - ovs_mutex_init(&cls->mutex); - ovs_mutex_lock(&cls->mutex); cls->n_rules = 0; cmap_init(&cls->subtables_map); pvector_init(&cls->subtables); @@ -259,7 +248,6 @@ classifier_init(struct classifier *cls, const uint8_t *flow_segments) for (int i = 0; i < CLS_MAX_TRIES; i++) { trie_init(cls, i, NULL); } - ovs_mutex_unlock(&cls->mutex); } /* Destroys 'cls'. Rules within 'cls', if any, are not freed; this is the @@ -267,14 +255,12 @@ classifier_init(struct classifier *cls, const uint8_t *flow_segments) * May only be called after all the readers have been terminated. */ void classifier_destroy(struct classifier *cls) - OVS_EXCLUDED(cls->mutex) { if (cls) { struct cls_partition *partition; struct cls_subtable *subtable; int i; - ovs_mutex_lock(&cls->mutex); for (i = 0; i < cls->n_tries; i++) { trie_destroy(&cls->tries[i].root); } @@ -290,8 +276,6 @@ classifier_destroy(struct classifier *cls) cmap_destroy(&cls->partitions); pvector_destroy(&cls->subtables); - ovs_mutex_unlock(&cls->mutex); - ovs_mutex_destroy(&cls->mutex); } } @@ -300,14 +284,12 @@ bool classifier_set_prefix_fields(struct classifier *cls, const enum mf_field_id *trie_fields, unsigned int n_fields) - OVS_EXCLUDED(cls->mutex) { const struct mf_field * new_fields[CLS_MAX_TRIES]; struct mf_bitmap fields = MF_BITMAP_INITIALIZER; int i, n_tries = 0; bool changed = false; - ovs_mutex_lock(&cls->mutex); for (i = 0; i < n_fields && n_tries < CLS_MAX_TRIES; i++) { const struct mf_field *field = mf_from_id(trie_fields[i]); if (field->flow_be32ofs < 0 || field->n_bits % 32) { @@ -370,17 +352,14 @@ classifier_set_prefix_fields(struct classifier *cls, } cls->n_tries = n_tries; - ovs_mutex_unlock(&cls->mutex); return true; } - ovs_mutex_unlock(&cls->mutex); return false; /* No change. */ } static void trie_init(struct classifier *cls, int trie_idx, const struct mf_field *field) - OVS_REQUIRES(cls->mutex) { struct cls_trie *trie = &cls->tries[trie_idx]; struct cls_subtable *subtable; @@ -422,7 +401,6 @@ classifier_is_empty(const struct classifier *cls) /* Returns the number of rules in 'cls'. */ int classifier_count(const struct classifier *cls) - OVS_NO_THREAD_SAFETY_ANALYSIS { /* n_rules is an int, so in the presence of concurrent writers this will * return either the old or a new value. */ @@ -453,7 +431,6 @@ find_partition(const struct classifier *cls, ovs_be64 metadata, uint32_t hash) static struct cls_partition * create_partition(struct classifier *cls, struct cls_subtable *subtable, ovs_be64 metadata) - OVS_REQUIRES(cls->mutex) { uint32_t hash = hash_metadata(metadata); struct cls_partition *partition = find_partition(cls, metadata, hash); @@ -480,7 +457,6 @@ subtable_replace_head_rule(struct classifier *cls OVS_UNUSED, struct cls_subtable *subtable, struct cls_match *head, struct cls_match *new, uint32_t hash, uint32_t ihash[CLS_MAX_INDICES]) - OVS_REQUIRES(cls->mutex) { /* Rule's data is already in the tries. */ @@ -510,7 +486,6 @@ subtable_replace_head_rule(struct classifier *cls OVS_UNUSED, */ const struct cls_rule * classifier_replace(struct classifier *cls, struct cls_rule *rule) - OVS_EXCLUDED(cls->mutex) { struct cls_match *new = cls_match_alloc(rule); struct cls_subtable *subtable; @@ -522,7 +497,6 @@ classifier_replace(struct classifier *cls, struct cls_rule *rule) uint32_t hash; int i; - ovs_mutex_lock(&cls->mutex); rule->cls_match = new; subtable = find_subtable(cls, &rule->match.mask); @@ -628,7 +602,6 @@ classifier_replace(struct classifier *cls, struct cls_rule *rule) /* Return displaced rule. Caller is responsible for keeping it * around until all threads quiesce. */ - ovs_mutex_unlock(&cls->mutex); return old; } } else { @@ -659,7 +632,6 @@ classifier_replace(struct classifier *cls, struct cls_rule *rule) /* Nothing was replaced. */ cls->n_rules++; - ovs_mutex_unlock(&cls->mutex); return NULL; } @@ -686,7 +658,6 @@ classifier_insert(struct classifier *cls, struct cls_rule *rule) */ const struct cls_rule * classifier_remove(struct classifier *cls, const struct cls_rule *rule) - OVS_EXCLUDED(cls->mutex) { struct cls_partition *partition; struct cls_match *cls_match; @@ -698,11 +669,9 @@ classifier_remove(struct classifier *cls, const struct cls_rule *rule) uint8_t prev_be32ofs = 0; size_t n_rules; - ovs_mutex_lock(&cls->mutex); cls_match = rule->cls_match; if (!cls_match) { - rule = NULL; - goto unlock; /* Already removed. */ + return NULL; } /* Mark as removed. */ CONST_CAST(struct cls_rule *, rule)->cls_match = NULL; @@ -799,8 +768,6 @@ check_priority: free: ovsrcu_postpone(free, cls_match); cls->n_rules--; -unlock: - ovs_mutex_unlock(&cls->mutex); return rule; } @@ -1134,7 +1101,6 @@ find_subtable(const struct classifier *cls, const struct minimask *mask) /* The new subtable will be visible to the readers only after this. */ static struct cls_subtable * insert_subtable(struct classifier *cls, const struct minimask *mask) - OVS_REQUIRES(cls->mutex) { uint32_t hash = minimask_hash(mask, 0); struct cls_subtable *subtable; @@ -1204,7 +1170,6 @@ insert_subtable(struct classifier *cls, const struct minimask *mask) /* RCU readers may still access the subtable before it is actually freed. */ static void destroy_subtable(struct classifier *cls, struct cls_subtable *subtable) - OVS_REQUIRES(cls->mutex) { int i; @@ -1605,7 +1570,6 @@ trie_node_rcu_realloc(const struct trie_node *node) return new_node; } -/* May only be called while holding the classifier mutex. */ static void trie_destroy(rcu_trie_ptr *trie) { |