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          |   38 ++++++++++++++++++++++++++------------
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 495364f..519f2b0 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 6123adc..7fbad00 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 c805357..2bcdf73 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1693,12 +1693,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);
@@ -1792,7 +1791,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);
 
@@ -3152,10 +3151,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);
@@ -4357,7 +4355,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);
@@ -4651,6 +4649,8 @@ replace_rule_start(struct ofproto *ofproto,
         /* Mark the old rule for removal in the next version. */
         cls_rule_make_removable_after_version(&old_rule->cr,
                                               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
@@ -4667,10 +4667,15 @@ 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 it
-     * was inserted before this transaction. */
-    if (old_rule && old_rule->version <= ofproto->tables_version) {
-        cls_rule_restore_version(&old_rule->cr, old_rule->version);
+    if (old_rule) {
+        /* Restore the original visibility of the old rule if it
+         * was inserted before this transaction. */
+        if (old_rule->version <= ofproto->tables_version) {
+            cls_rule_restore_version(&old_rule->cr, old_rule->version);
+        }
+    } else {
+        /* Restore table's rule count. */
+        table->n_flows--;
     }
 
     /* Remove the new rule immediately.  It was never visible to lookups. */
@@ -4900,7 +4905,11 @@ delete_flows_start__(struct ofproto *ofproto,
     OVS_REQUIRES(ofproto_mutex)
 {
     for (size_t i = 0; i < rules->n; i++) {
-        cls_rule_make_removable_after_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_removable_after_version(&rule->cr,
                                               ofproto->tables_version);
     }
 }
@@ -4983,6 +4992,10 @@ delete_flows_revert(struct ofproto *ofproto,
 {
     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 old rule if it
          * was inserted before this transaction. */
@@ -7312,6 +7325,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

Reply via email to