ofproto-dpif: Push statistics less frequently.
authorEthan Jackson <ethan@nicira.com>
Fri, 22 Mar 2013 02:04:52 +0000 (19:04 -0700)
committerEthan Jackson <ethan@nicira.com>
Mon, 1 Apr 2013 22:59:29 +0000 (15:59 -0700)
The most natural place to push facet statistics is in
update_stats() where they're pulled from the datapath.  However,
under load, update_stats() can be called as many as 10 times per
second causing us to push statistics so frequently it hurts
performance.  By pushing statistics much less frequently, this
patch generates a roughly 8% improvement in TCP_CRR performance.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
ofproto/ofproto-dpif.c

index 30ef5f9..32ed091 100644 (file)
@@ -909,6 +909,7 @@ lookup_ofproto_dpif_by_port_name(const char *name)
 static int
 type_run(const char *type)
 {
+    static long long int push_timer = LLONG_MIN;
     struct dpif_backer *backer;
     char *devname;
     int error;
@@ -922,6 +923,16 @@ type_run(const char *type)
 
     dpif_run(backer->dpif);
 
+    /* The most natural place to push facet statistics is when they're pulled
+     * from the datapath.  However, when there are many flows in the datapath,
+     * this expensive operation can occur so frequently, that it reduces our
+     * ability to quickly set up flows.  To reduce the cost, we push statistics
+     * here instead. */
+    if (time_msec() > push_timer) {
+        push_timer = time_msec() + 2000;
+        push_all_stats();
+    }
+
     if (backer->need_revalidate
         || !tag_set_is_empty(&backer->revalidate_set)) {
         struct tag_set revalidate_set = backer->revalidate_set;
@@ -4210,7 +4221,6 @@ update_subfacet_stats(struct subfacet *subfacet,
         facet_account(facet);
         facet->accounted_bytes = facet->byte_count;
     }
-    facet_push_stats(facet);
 }
 
 /* 'key' with length 'key_len' bytes is a flow in 'dpif' that we know nothing