[ovs-dev] [PATCH v12 5/9] Add incremental proessing to lflow_run

Ryan Moats rmoats at us.ibm.com
Wed Mar 30 21:36:02 UTC 2016


From: RYAN D. MOATS <rmoats at us.ibm.com>

This code changes lflow_run to do incremental process of the
logical flow table rather than processing the full table each run.

Signed-off-by: RYAN D. MOATS <rmoats at us.ibm.com>
---
 ovn/controller/binding.c        |    1 +
 ovn/controller/lflow.c          |   52 ++++++++++++++++++++++++++++++++++++--
 ovn/controller/lflow.h          |    1 +
 ovn/controller/ofctrl.h         |    2 +
 ovn/controller/ovn-controller.c |    3 +-
 5 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index 0d5940f..58402fd 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -15,6 +15,7 @@
 
 #include <config.h>
 #include "binding.h"
+#include "lflow.h"
 
 #include "lib/bitmap.h"
 #include "lib/hmap.h"
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index dfd95e0..c77a888 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -201,6 +201,8 @@ is_switch(const struct sbrec_datapath_binding *ldp)
 
 }
 
+unsigned int lflow_logical_flow_seqno = 0;
+
 /* Adds the logical flows from the Logical_Flow table to 'flow_table'. */
 static void
 add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
@@ -214,18 +216,36 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
     SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) {
         unsigned int del_seqno = sbrec_logical_flow_row_get_seqno(lflow,
             OVSDB_IDL_CHANGE_DELETE);
+        unsigned int ins_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+            OVSDB_IDL_CHANGE_INSERT);
         unsigned int mod_seqno = sbrec_logical_flow_row_get_seqno(lflow,
             OVSDB_IDL_CHANGE_MODIFY);
 
+        if (del_seqno <= lflow_logical_flow_seqno
+            && mod_seqno <= lflow_logical_flow_seqno
+            && ins_seqno <= lflow_logical_flow_seqno) {
+            continue;
+        }
+
         /* if the row has a del_seqno > 0, then trying to process the
          * row isn't going to work (as it has already been freed).
          * What we can do is to pass a pointer to the ovs_idl_row to
          * ofctrl_remove_flows() to remove flows from this record */
         if (del_seqno > 0) {
             ofctrl_remove_flows(&lflow->header_.uuid);
+            if (del_seqno > lflow_logical_flow_seqno) {
+                lflow_logical_flow_seqno = del_seqno;
+            }
             continue;
         }
 
+        if (mod_seqno > lflow_logical_flow_seqno) {
+            lflow_logical_flow_seqno = mod_seqno;
+        }
+        if (ins_seqno > lflow_logical_flow_seqno) {
+            lflow_logical_flow_seqno = ins_seqno;
+        }
+
         /* Determine translation of logical table IDs to physical table IDs. */
         bool ingress = !strcmp(lflow->pipeline, "ingress");
 
@@ -364,7 +384,6 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
                 ofpbuf_uninit(&conj);
             }
         }
-
         /* Clean up. */
         expr_matches_destroy(&matches);
         ofpbuf_uninit(&ofpacts);
@@ -385,6 +404,8 @@ put_load(const uint8_t *data, size_t len,
     bitwise_one(&sf->mask, sf->field->n_bytes, ofs, n_bits);
 }
 
+unsigned int lflow_mac_binding_seqno = 0;
+
 /* Adds an OpenFlow flow to 'flow_table' for each MAC binding in the OVN
  * southbound database, using 'lports' to resolve logical port names to
  * numbers. */
@@ -401,18 +422,40 @@ add_neighbor_flows(struct controller_ctx *ctx,
     SBREC_MAC_BINDING_FOR_EACH_TRACKED (b, ctx->ovnsb_idl) {
         unsigned int del_seqno = sbrec_mac_binding_row_get_seqno(b,
             OVSDB_IDL_CHANGE_DELETE);
+        unsigned int ins_seqno = sbrec_mac_binding_row_get_seqno(b,
+            OVSDB_IDL_CHANGE_MODIFY);
         unsigned int mod_seqno = sbrec_mac_binding_row_get_seqno(b,
             OVSDB_IDL_CHANGE_MODIFY);
 
+        /* TODO (regXboi) the following hunk of code is commented out
+         * because the above seqnos all return 0 at this point.
+         * Once that issue is fixed, this code can be uncommented
+         * and this comment removed.
+        if (del_seqno <= lflow_mac_binding_seqno
+            && mod_seqno <= lflow_mac_binding_seqno
+            && ins_seqno <= lflow_mac_binding_seqno) {
+            continue;
+        }
+        */
+
         /* if the row has a del_seqno > 0, then trying to process the
          * row isn't going to work (as it has already been freed).
          * What we can do pass a pointer to the ovs_idl_row to 
          * ofctrl_remove_flows() to remove the flow */
         if (del_seqno > 0) {
             ofctrl_remove_flows(&b->header_.uuid);
+            if (del_seqno > lflow_mac_binding_seqno) {
+                lflow_mac_binding_seqno = del_seqno;
+            }
             continue;
         }
 
+        if (mod_seqno > lflow_mac_binding_seqno) {
+            lflow_mac_binding_seqno = mod_seqno;
+        }
+        if (ins_seqno > lflow_mac_binding_seqno) {
+            lflow_mac_binding_seqno = ins_seqno;
+        }
         const struct sbrec_port_binding *pb
             = lport_lookup_by_name(lports, b->logical_port);
         if (!pb) {
@@ -455,10 +498,13 @@ lflow_run(struct controller_ctx *ctx, const struct lport_index *lports,
           const struct simap *ct_zones)
 {
     if (restart_flow_processing) {
+        lflow_logical_flow_seqno = 0;
+        lflow_mac_binding_seqno = 0;
         ovn_flow_table_clear();
+        restart_flow_processing = false;
     }
-    add_logical_flows(ctx, lports, mcgroups, local_datapaths,
-                      ct_zones);
+
+    add_logical_flows(ctx, lports, mcgroups, local_datapaths, ct_zones);
     add_neighbor_flows(ctx, lports);
 }
 
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index 8d0a354..c53a031 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -64,6 +64,7 @@ void lflow_run(struct controller_ctx *, const struct lport_index *,
                const struct hmap *local_datapaths, 
                const struct simap *ct_zones);
 void lflow_destroy(void);
+void reset_flow_processing(void);
 
 void reset_flow_processing(void);
 
diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h
index 1e70ad6..978cb95 100644
--- a/ovn/controller/ofctrl.h
+++ b/ovn/controller/ofctrl.h
@@ -46,4 +46,6 @@ void ofctrl_remove_flows(const struct uuid *uuid);
 
 void ofctrl_flow_table_clear(void);
 
+void ovn_flow_table_clear(void);
+
 #endif /* ovn/ofctrl.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 037178b..1165e76 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -312,8 +312,7 @@ main(int argc, char *argv[])
 
             pinctrl_run(&ctx, &lports, br_int);
 
-            lflow_run(&ctx, &lports, &mcgroups, &local_datapaths,
-                      &ct_zones);
+            lflow_run(&ctx, &lports, &mcgroups, &local_datapaths, &ct_zones);
             if (chassis_id) {
                 physical_run(&ctx, mff_ovn_geneve,
                              br_int, chassis_id, &ct_zones,
-- 
1.7.1




More information about the dev mailing list