revalidator: Improve optimization to skip revalidation.
authorJoe Stringer <joestringer@nicira.com>
Wed, 2 Jul 2014 07:41:33 +0000 (07:41 +0000)
committerJoe Stringer <joestringer@nicira.com>
Wed, 2 Jul 2014 06:17:41 +0000 (18:17 +1200)
The should_revalidate() optimisation introduced with commit 698ffe3623
(revalidator: Only revalidate high-throughput flows.) was a little
aggressive, occasionally deleting flows even when OVS is quite capable
of performing full revalidation.

This commit modifies the logic to:
* Firstly, check if we are likely to handle full revalidation, and
  attempt that instead.
* Secondly, fall back to the existing flow throughput estimations to
  determine whether to revalidate the flow or just delete it.

VMware-BZ: #1271926

Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Alex Wang <alexw@nicira.com>
ofproto/ofproto-dpif-upcall.c

index a126210..74d9686 100644 (file)
@@ -1175,10 +1175,16 @@ ukey_delete(struct revalidator *revalidator, struct udpif_key *ukey)
 }
 
 static bool
-should_revalidate(uint64_t packets, long long int used)
+should_revalidate(const struct udpif *udpif, uint64_t packets,
+                  long long int used)
 {
     long long int metric, now, duration;
 
+    if (udpif->dump_duration < 200) {
+        /* We are likely to handle full revalidation for the flows. */
+        return true;
+    }
+
     /* Calculate the mean time between seeing these packets. If this
      * exceeds the threshold, then delete the flow rather than performing
      * costly revalidation for flows that aren't being hit frequently.
@@ -1194,10 +1200,11 @@ should_revalidate(uint64_t packets, long long int used)
     duration = now - used;
     metric = duration / packets;
 
-    if (metric > 200) {
-        return false;
+    if (metric < 200) {
+        /* The flow is receiving more than ~5pps, so keep it. */
+        return true;
     }
-    return true;
+    return false;
 }
 
 static bool
@@ -1237,7 +1244,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
         : 0;
 
     if (udpif->need_revalidate && last_used
-        && !should_revalidate(push.n_packets, last_used)) {
+        && !should_revalidate(udpif, push.n_packets, last_used)) {
         ok = false;
         goto exit;
     }