Classifier's rule count now contains temporary duplicates and rules whose deletion has been deferred. Maintain a new 'n_flows' count in struct oftable to as the count of rules in the latest version.
Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- ofproto/connmgr.c | 2 +- ofproto/ofproto-provider.h | 5 ++++- ofproto/ofproto.c | 32 ++++++++++++++++++++++---------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 1fee860..975ee33 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -2027,7 +2027,7 @@ connmgr_flushed(struct connmgr *mgr) /* Returns the number of hidden rules created by the in-band and fail-open * implementations in table 0. (Subtracting this count from the number of - * rules in the table 0 classifier, as returned by classifier_count(), yields + * rules in the table 0 classifier, as maintained in struct oftable, yields * the number of flows that OVS should report via OpenFlow for table 0.) */ int connmgr_count_hidden_rules(const struct connmgr *mgr) diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 07229c5..fd66e49 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -220,6 +220,9 @@ struct oftable { /* Maximum number of flows or UINT_MAX if there is no limit besides any * limit imposed by resource limitations. */ unsigned int max_flows; + /* Current number of flows, not counting temporary duplicates nor deferred + * deletions. */ + unsigned int n_flows; /* These members determine the handling of an attempt to add a flow that * would cause the table to have more than 'max_flows' flows. @@ -818,7 +821,7 @@ struct ofproto_class { * * - 'table_id' to the array index. * - * - 'active_count' to the classifier_count() for the table. + * - 'active_count' to the 'n_flows' of struct ofproto for the table. * * - 'lookup_count' and 'matched_count' to 0. * diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 35e1ed2..67ade45 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1698,12 +1698,11 @@ ofproto_run(struct ofproto *p) continue; } - if (classifier_count(&table->cls) > 100000) { + if (table->n_flows > 100000) { static struct vlog_rate_limit count_rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_WARN_RL(&count_rl, "Table %"PRIuSIZE" has an excessive" - " number of rules: %d", i, - classifier_count(&table->cls)); + " number of rules: %d", i, table->n_flows); } ovs_mutex_lock(&ofproto_mutex); @@ -1797,7 +1796,7 @@ ofproto_get_memory_usage(const struct ofproto *ofproto, struct simap *usage) n_rules = 0; OFPROTO_FOR_EACH_TABLE (table, ofproto) { - n_rules += classifier_count(&table->cls); + n_rules += table->n_flows; } simap_increase(usage, "rules", n_rules); @@ -3160,10 +3159,9 @@ query_tables(struct ofproto *ofproto, stats = *statsp = xcalloc(ofproto->n_tables, sizeof *stats); for (i = 0; i < ofproto->n_tables; i++) { struct ofputil_table_stats *s = &stats[i]; - struct classifier *cls = &ofproto->tables[i].cls; s->table_id = i; - s->active_count = classifier_count(cls); + s->active_count = ofproto->tables[i].n_flows; if (i == 0) { s->active_count -= connmgr_count_hidden_rules( ofproto->connmgr); @@ -4368,7 +4366,7 @@ evict_rules_from_table(struct oftable *table, unsigned int extra_space) { enum ofperr error = 0; struct rule_collection rules; - unsigned int count = classifier_count(&table->cls) + extra_space; + unsigned int count = table->n_flows + extra_space; unsigned int max_flows = table->max_flows; rule_collection_init(&rules); @@ -4664,6 +4662,8 @@ replace_rule_start(struct ofproto *ofproto, cls_rule_make_invisible_in_version(&old_rule->cr, ofproto->tables_version + 1, ofproto->tables_version); + } else { + table->n_flows++; } /* Insert flow to the classifier, so that later flow_mods may relate * to it. This is reversible, in case later errors require this to @@ -4679,9 +4679,12 @@ static void replace_rule_revert(struct ofproto *ofproto, { struct oftable *table = &ofproto->tables[new_rule->table_id]; - /* Restore the original visibility of the old rule. */ if (old_rule) { + /* Restore the original visibility of the old rule. */ cls_rule_restore_visibility(&old_rule->cr); + } else { + /* Restore table's rule count. */ + table->n_flows--; } /* Remove the new rule immediately. It was never visible to lookups. */ @@ -4914,7 +4917,11 @@ delete_flows_start__(struct ofproto *ofproto, OVS_REQUIRES(ofproto_mutex) { for (size_t i = 0; i < rules->n; i++) { - cls_rule_make_invisible_in_version(&rules->rules[i]->cr, + struct rule *rule = rules->rules[i]; + struct oftable *table = &ofproto->tables[rule->table_id]; + + table->n_flows--; + cls_rule_make_invisible_in_version(&rule->cr, ofproto->tables_version + 1, ofproto->tables_version); } @@ -4992,12 +4999,16 @@ delete_flows_start_loose(struct ofproto *ofproto, } static void -delete_flows_revert(struct ofproto *ofproto OVS_UNUSED, +delete_flows_revert(struct ofproto *ofproto, struct rule_collection *rules) OVS_REQUIRES(ofproto_mutex) { for (size_t i = 0; i < rules->n; i++) { struct rule *rule = rules->rules[i]; + struct oftable *table = &ofproto->tables[rule->table_id]; + + /* Restore table's rule count. */ + table->n_flows++; /* Restore the original visibility of the rule. */ cls_rule_restore_visibility(&rule->cr); @@ -7324,6 +7335,7 @@ oftable_init(struct oftable *table) memset(table, 0, sizeof *table); classifier_init(&table->cls, flow_segment_u64s); table->max_flows = UINT_MAX; + table->n_flows = 0; atomic_init(&table->miss_config, OFPUTIL_TABLE_MISS_DEFAULT); classifier_set_prefix_fields(&table->cls, default_prefix_fields, -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev