As the number of flows grows so does the length of time taken to update the
statistics of all facets. It has been obvserved that this becomes a performance
problem. This patch mitiages this effect by only dumping a limited number of
facets at a time.

Signed-off-by: Simon Horman <ho...@verge.net.au>

---

Since the last time that I tested this code (changest
279320b8276011df3667478de6750d5a40d0c6eb, "rhel: Add ability to enable bridge
compatibility mode in /etc/sysconfig/openvswitch") it seems that the cost of
dumping statistics has increased. I suspect that this relates to the
introducation of subfacet_find().  In any case I believe that a higher cost of
dumping stats makes a stronger case for the change introduced in this patch.

The previously posted version of this patch used a limit of 100,000 facets per
statistics dump. This revision uses a limit of 20,000 subfacets per dump.
Empirically these two revisions appear to exhibit the same performance.

---
 ofproto/ofproto-dpif.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index ea5ed1e..e2a3939 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -345,6 +345,7 @@ struct subfacet {
     /* Owners. */
     struct hmap_node hmap_node; /* In struct ofproto_dpif 'subfacets' list. */
     struct list list_node;      /* In struct facet's 'facets' list. */
+    struct list may_expire;     /* Potential expiry list. */
     struct facet *facet;        /* Owning facet. */
 
     /* Key.
@@ -507,6 +508,7 @@ struct ofproto_dpif {
     /* Facets. */
     struct hmap facets;
     struct hmap subfacets;
+    struct list expirable_subfacets;
 
     /* Revalidation. */
     struct table_dpif tables[N_TABLES];
@@ -659,6 +661,7 @@ construct(struct ofproto *ofproto_, int *n_tablesp)
 
     hmap_init(&ofproto->facets);
     hmap_init(&ofproto->subfacets);
+    list_init(&ofproto->expirable_subfacets);
 
     for (i = 0; i < N_TABLES; i++) {
         struct table_dpif *table = &ofproto->tables[i];
@@ -2916,12 +2919,18 @@ static void
 update_stats(struct ofproto_dpif *p)
 {
     const struct dpif_flow_stats *stats;
-    struct dpif_flow_dump dump;
+    static struct dpif_flow_dump dump;
     const struct nlattr *key;
     size_t key_len;
+    static bool complete = true;
+    int count = 20000;
 
-    dpif_flow_dump_start(&dump, p->dpif);
-    while (dpif_flow_dump_next(&dump, &key, &key_len, NULL, NULL, &stats)) {
+    if (complete) {
+        dpif_flow_dump_start(&dump, p->dpif);
+        complete = false;
+    }
+    while (--count &&
+           dpif_flow_dump_next(&dump, &key, &key_len, NULL, NULL, &stats)) {
         struct subfacet *subfacet;
 
         subfacet = subfacet_find(p, key, key_len);
@@ -2944,6 +2953,7 @@ update_stats(struct ofproto_dpif *p)
             subfacet->dp_packet_count = stats->n_packets;
             subfacet->dp_byte_count = stats->n_bytes;
 
+            list_insert(&p->expirable_subfacets, &subfacet->may_expire);
             subfacet_update_time(subfacet, stats->used);
             facet_account(facet);
             facet_push_stats(facet);
@@ -2963,7 +2973,10 @@ update_stats(struct ofproto_dpif *p)
             dpif_flow_del(p->dpif, key, key_len, NULL);
         }
     }
-    dpif_flow_dump_done(&dump);
+    if (count) {
+        dpif_flow_dump_done(&dump);
+        complete = true;
+    }
 }
 
 /* Calculates and returns the number of milliseconds of idle time after which
@@ -3060,11 +3073,12 @@ expire_subfacets(struct ofproto_dpif *ofproto, int 
dp_max_idle)
     long long int cutoff = time_msec() - dp_max_idle;
     struct subfacet *subfacet, *next_subfacet;
 
-    HMAP_FOR_EACH_SAFE (subfacet, next_subfacet, hmap_node,
-                        &ofproto->subfacets) {
+    LIST_FOR_EACH_SAFE (subfacet, next_subfacet, may_expire,
+                        &ofproto->expirable_subfacets) {
         if (subfacet->used < cutoff) {
             subfacet_destroy(subfacet);
         }
+        list_remove(&subfacet->may_expire);
     }
 }
 
@@ -3739,6 +3753,7 @@ subfacet_create(struct facet *facet, enum odp_key_fitness 
key_fitness,
     subfacet = xzalloc(sizeof *subfacet);
     hmap_insert(&ofproto->subfacets, &subfacet->hmap_node, key_hash);
     list_push_back(&facet->subfacets, &subfacet->list_node);
+    list_init(&subfacet->may_expire);
     subfacet->facet = facet;
     subfacet->used = time_msec();
     subfacet->key_fitness = key_fitness;
@@ -3780,6 +3795,7 @@ subfacet_destroy__(struct subfacet *subfacet)
 
     subfacet_uninstall(subfacet);
     hmap_remove(&ofproto->subfacets, &subfacet->hmap_node);
+    list_remove(&subfacet->may_expire);
     list_remove(&subfacet->list_node);
     free(subfacet->key);
     free(subfacet->actions);
-- 
1.7.4.1
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to