From: RYAN D. MOATS <rmo...@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 <rmo...@us.ibm.com>
---
 ovn/controller/binding.c        |    3 ++
 ovn/controller/lflow.c          |   53 +++++++++++++++++++++++++++++++++------
 ovn/controller/lflow.h          |    4 +-
 ovn/controller/ofctrl.c         |    4 +-
 ovn/controller/ofctrl.h         |    2 +
 ovn/controller/ovn-controller.c |    5 +++-
 6 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index 602a8fe..87cae99 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"
@@ -139,6 +140,7 @@ remove_local_datapath(struct hmap *local_datapaths, 
unsigned int ins_seqno)
     if (ld) {
         hmap_remove(local_datapaths, &ld->hmap_node);
         hmap_remove(&local_datapaths_by_seqno, &ld->seqno_hmap_node);
+        reset_flow_processing();
     }
 }
 
@@ -156,6 +158,7 @@ add_local_datapath(struct hmap *local_datapaths,
     hmap_insert(local_datapaths, &ld->hmap_node,
                 binding_rec->datapath->tunnel_key);
     hmap_insert(&local_datapaths_by_seqno, &ld->seqno_hmap_node, ins_seqno);
+    reset_flow_processing();
 }
 
 static void
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 4856362..6d0d417 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -176,6 +176,20 @@ struct logical_datapath {
     enum ldp_type type;         /* Type of logical datapath */
 };
 
+void reset_flow_processing(void);
+void ldp_port_create(uint32_t ins_seqno, char *name,
+                     struct logical_datapath *ldp);
+void ldp_port_update(uint32_t ins_seqno, char *name,
+                     struct logical_datapath *ldp);
+
+bool restart_flow_processing = false;
+
+void
+reset_flow_processing(void)
+{
+    restart_flow_processing = true;
+}
+
 /* Contains "struct logical_datapath"s. */
 static struct hmap logical_datapaths = HMAP_INITIALIZER(&logical_datapaths);
 
@@ -208,6 +222,7 @@ ldp_create(const struct sbrec_datapath_binding *binding)
     const char *ls = smap_get(&binding->external_ids, "logical-switch");
     ldp->type = ls ? LDP_TYPE_SWITCH : LDP_TYPE_ROUTER;
     simap_init(&ldp->ports);
+    reset_flow_processing();
     return ldp;
 }
 
@@ -224,6 +239,7 @@ ldp_free(struct logical_datapath *ldp)
     simap_destroy(&ldp->ports);
     hmap_remove(&logical_datapaths, &ldp->hmap_node);
     free(ldp);
+    reset_flow_processing();
 }
 
 /* Whether a particular port has been seen or not
@@ -319,6 +335,7 @@ ldp_run(struct controller_ctx *ctx)
                                             binding->logical_port);
         if (!old || old->data != binding->tunnel_key) {
             simap_put(&ldp->ports, binding->logical_port, binding->tunnel_key);
+            reset_flow_processing();
         }
        
         ldp_port_update(ins_seqno, binding->logical_port, ldp);
@@ -380,13 +397,21 @@ lflow_init(void)
 
 /* Translates logical flows in the Logical_Flow table in the OVN_SB database
  * into OpenFlow flows.  See ovn-architecture(7) for more information. */
-void
+unsigned int
 lflow_run(struct controller_ctx *ctx,
           const struct simap *ct_zones,
-          struct hmap *local_datapaths)
+          struct hmap *local_datapaths,
+          unsigned int seqno)
 {
     struct hmap flows = HMAP_INITIALIZER(&flows);
     uint32_t conj_id_ofs = 1;
+    unsigned int processed_seqno = seqno;
+
+    if (restart_flow_processing) {
+        seqno = 0;
+        ovn_flow_table_clear();
+        restart_flow_processing = false;
+    }
 
     ldp_run(ctx);
 
@@ -398,17 +423,29 @@ lflow_run(struct controller_ctx *ctx,
             OVSDB_IDL_CHANGE_MODIFY);
         unsigned int ins_seqno = sbrec_logical_flow_row_get_seqno(lflow,
             OVSDB_IDL_CHANGE_INSERT);
-        // this offset is to protect the hard coded rules in physical.c
-        ins_seqno += 4;
-
+        if (del_seqno <= seqno && mod_seqno <= seqno && ins_seqno <= 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).
-         * Therefore all we can do is to pass the ins_seqno to 
+         * Therefore all we can do is to pass the offset ins_seqno to 
          * ofctrl_remove_flow() to remove the flow */
         if (del_seqno > 0) {
-            ofctrl_remove_flow(ins_seqno);
+            ofctrl_remove_flow(ins_seqno+4);
+            if (del_seqno > processed_seqno) {
+                processed_seqno = del_seqno;
+            }
             continue;
         }
+        if (mod_seqno > processed_seqno) {
+            processed_seqno = mod_seqno;
+        }
+        if (ins_seqno > processed_seqno) {
+            processed_seqno = ins_seqno;
+        }
+
+        // this offset is to protect the hard coded rules in physical.c
+        ins_seqno += 4;
 
         /* Find the "struct logical_datapath" associated with this
          * Logical_Flow row.  If there's no such struct, that must be because
@@ -544,12 +581,12 @@ lflow_run(struct controller_ctx *ctx,
                 ofpbuf_uninit(&conj);
             }
         }
-
         /* Clean up. */
         expr_matches_destroy(&matches);
         ofpbuf_uninit(&ofpacts);
         conj_id_ofs += n_conjs;
     }
+    return processed_seqno;
 }
 
 void
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index e0e902c..31b187a 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -56,8 +56,8 @@ struct uuid;
 #define LOG_PIPELINE_LEN 16
 
 void lflow_init(void);
-void lflow_run(struct controller_ctx *, const struct simap *ct_zones,
-               struct hmap *local_datapaths);
+unsigned int lflow_run(struct controller_ctx *, const struct simap *ct_zones,
+                       struct hmap *local_datapaths, unsigned int seqno);
 void lflow_destroy(void);
 
 #endif /* ovn/lflow.h */
diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c
index 2479ca1..5aa7044 100644
--- a/ovn/controller/ofctrl.c
+++ b/ovn/controller/ofctrl.c
@@ -106,7 +106,7 @@ static struct hmap installed_flows;
  * S_CLEAR_FLOWS or S_UPDATE_FLOWS, this is really the option we have. */
 static enum mf_field_id mff_ovn_geneve;
 
-static void ovn_flow_table_clear(void);
+void ovn_flow_table_clear(void);
 static void ovn_flow_table_destroy(void);
 
 static void ofctrl_recv(const struct ofp_header *, enum ofptype);
@@ -728,7 +728,7 @@ ovn_flow_destroy(struct ovn_flow *f)
 
 /* Flow tables of struct ovn_flow. */
 
-static void
+void
 ovn_flow_table_clear(void)
 {
     struct ovn_flow *f, *next;
diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h
index 4ae0d42..ff870e6 100644
--- a/ovn/controller/ofctrl.h
+++ b/ovn/controller/ofctrl.h
@@ -43,4 +43,6 @@ void ofctrl_add_flow(uint8_t table_id, uint16_t priority,
 
 void ofctrl_remove_flow(unsigned int ins_seqno);
 
+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 cb8536b..258d83e 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -208,6 +208,7 @@ main(int argc, char *argv[])
     struct unixctl_server *unixctl;
     bool exiting;
     int retval;
+    unsigned int ovnsb_last_lflow_seqno = 0;
 
     ovs_cmdl_proctitle_init(argc, argv);
     set_program_name(argv[0]);
@@ -303,7 +304,9 @@ main(int argc, char *argv[])
 
             pinctrl_run(&ctx, br_int);
 
-            lflow_run(&ctx, &ct_zones, &local_datapaths);
+            ovnsb_last_lflow_seqno = lflow_run(&ctx, &ct_zones,
+                                               &local_datapaths,
+                                               ovnsb_last_lflow_seqno);
             if (chassis_id) {
                 physical_run(&ctx, mff_ovn_geneve,
                              br_int, chassis_id, &ct_zones, 
-- 
1.7.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to