[ovs-dev] [PATCH 3/6] revalidator: Refactor revalidation early exit.

Joe Stringer joe at ovn.org
Wed Sep 21 01:47:32 UTC 2016


Shift the early-exit conditions for revalidation into a separate
function.

Signed-off-by: Joe Stringer <joe at ovn.org>
---
 ofproto/ofproto-dpif-upcall.c | 136 ++++++++++++++++++++++++------------------
 1 file changed, 78 insertions(+), 58 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 064f043b9eac..052e502de696 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -1793,6 +1793,11 @@ should_revalidate(const struct udpif *udpif, uint64_t packets,
 {
     long long int metric, now, duration;
 
+    if (!used) {
+        /* Always revalidate the first time a flow is dumped. */
+        return true;
+    }
+
     if (udpif->dump_duration < 200) {
         /* We are likely to handle full revalidation for the flows. */
         return true;
@@ -1871,39 +1876,18 @@ xlate_ukey(struct udpif *udpif, const struct udpif_key *ukey,
     return 0;
 }
 
-
-/* Verifies that the datapath actions of 'ukey' are still correct, and pushes
- * 'stats' for it.
- *
- * Returns a recommended action for 'ukey', options include:
- *      UKEY_DELETE The ukey should be deleted.
- *      UKEY_KEEP   The ukey is fine as is.
- *      UKEY_MODIFY The ukey's actions should be changed but is otherwise
- *                  fine.  Callers should change the actions to those found
- *                  in the caller supplied 'odp_actions' buffer.  The
- *                  recirculation references can be found in 'recircs' and
- *                  must be handled by the caller.
- *
- * If the result is UKEY_MODIFY, then references to all recirc_ids used by the
- * new flow will be held within 'recircs' (which may be none).
- *
- * The caller is responsible for both initializing 'recircs' prior this call,
- * and ensuring any references are eventually freed.
- */
 static enum reval_result
-revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
-                const struct dpif_flow_stats *stats,
-                struct ofpbuf *odp_actions, uint64_t reval_seq,
-                struct recirc_refs *recircs)
+revalidate_ukey__(struct udpif *udpif, struct udpif_key *ukey,
+                  const struct dpif_flow_stats *push,
+                  struct ofpbuf *odp_actions, uint64_t reval_seq,
+                  struct recirc_refs *recircs)
     OVS_REQUIRES(ukey->mutex)
 {
     bool need_revalidate = (ukey->reval_seq != reval_seq);
     struct xlate_out *xoutp;
     struct netflow *netflow;
-    struct dpif_flow_stats push;
     struct flow_wildcards dp_mask, wc;
     enum reval_result result;
-    long long int last_used;
     struct reval_context ctx = {
         .odp_actions = odp_actions,
         .netflow = &netflow,
@@ -1914,35 +1898,6 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
     xoutp = NULL;
     netflow = NULL;
 
-    ofpbuf_clear(odp_actions);
-    last_used = ukey->stats.used;
-    push.used = stats->used;
-    push.tcp_flags = stats->tcp_flags;
-    push.n_packets = (stats->n_packets > ukey->stats.n_packets
-                      ? stats->n_packets - ukey->stats.n_packets
-                      : 0);
-    push.n_bytes = (stats->n_bytes > ukey->stats.n_bytes
-                    ? stats->n_bytes - ukey->stats.n_bytes
-                    : 0);
-
-    if (need_revalidate && last_used
-        && !should_revalidate(udpif, push.n_packets, last_used)) {
-        goto exit;
-    }
-
-    /* We will push the stats, so update the ukey stats cache. */
-    ukey->stats = *stats;
-    if (!push.n_packets && !need_revalidate) {
-        result = UKEY_KEEP;
-        goto exit;
-    }
-
-    if (ukey->xcache && !need_revalidate) {
-        xlate_push_stats(ukey->xcache, &push);
-        result = UKEY_KEEP;
-        goto exit;
-    }
-
     if (need_revalidate) {
         xlate_cache_clear(ukey->xcache);
     }
@@ -1950,7 +1905,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
         ukey->xcache = xlate_cache_new();
     }
     ctx.xcache = ukey->xcache;
-    if (xlate_ukey(udpif, ukey, &push, &ctx)) {
+    if (xlate_ukey(udpif, ukey, push, &ctx)) {
         goto exit;
     }
     xoutp = &ctx.xout;
@@ -1994,9 +1949,6 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
     result = UKEY_KEEP;
 
 exit:
-    if (result != UKEY_DELETE) {
-        ukey->reval_seq = reval_seq;
-    }
     if (netflow && result == UKEY_DELETE) {
         netflow_flow_clear(netflow, &ctx.flow);
     }
@@ -2004,6 +1956,74 @@ exit:
     return result;
 }
 
+/* Verifies that the datapath actions of 'ukey' are still correct, and pushes
+ * 'stats' for it.
+ *
+ * Returns a recommended action for 'ukey', options include:
+ *      UKEY_DELETE The ukey should be deleted.
+ *      UKEY_KEEP   The ukey is fine as is.
+ *      UKEY_MODIFY The ukey's actions should be changed but is otherwise
+ *                  fine.  Callers should change the actions to those found
+ *                  in the caller supplied 'odp_actions' buffer.  The
+ *                  recirculation references can be found in 'recircs' and
+ *                  must be handled by the caller.
+ *
+ * If the result is UKEY_MODIFY, then references to all recirc_ids used by the
+ * new flow will be held within 'recircs' (which may be none).
+ *
+ * The caller is responsible for both initializing 'recircs' prior this call,
+ * and ensuring any references are eventually freed.
+ */
+static enum reval_result
+revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
+                const struct dpif_flow_stats *stats,
+                struct ofpbuf *odp_actions, uint64_t reval_seq,
+                struct recirc_refs *recircs)
+    OVS_REQUIRES(ukey->mutex)
+{
+    bool need_revalidate = ukey->reval_seq != reval_seq;
+    enum reval_result result = UKEY_DELETE;
+    struct dpif_flow_stats push;
+
+    ofpbuf_clear(odp_actions);
+
+    push.used = stats->used;
+    push.tcp_flags = stats->tcp_flags;
+    push.n_packets = (stats->n_packets > ukey->stats.n_packets
+                      ? stats->n_packets - ukey->stats.n_packets
+                      : 0);
+    push.n_bytes = (stats->n_bytes > ukey->stats.n_bytes
+                    ? stats->n_bytes - ukey->stats.n_bytes
+                    : 0);
+
+    if (need_revalidate
+        && !should_revalidate(udpif, push.n_packets, ukey->stats.used)) {
+        goto exit;
+    }
+
+    /* We will push the stats, so update the ukey stats cache. */
+    ukey->stats = *stats;
+    if (!push.n_packets && !need_revalidate) {
+        result = UKEY_KEEP;
+        goto exit;
+    }
+
+    if (ukey->xcache && !need_revalidate) {
+        xlate_push_stats(ukey->xcache, &push);
+        result = UKEY_KEEP;
+        goto exit;
+    }
+
+    result = revalidate_ukey__(udpif, ukey, &push, odp_actions, reval_seq,
+                               recircs);
+
+exit:
+    if (result != UKEY_DELETE) {
+        ukey->reval_seq = reval_seq;
+    }
+    return result;
+}
+
 static void
 delete_op_init__(struct udpif *udpif, struct ukey_op *op,
                  const struct dpif_flow *flow)
-- 
2.9.3




More information about the dev mailing list