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 | 2 + ovn/controller/lflow.c | 53 +++++++++++++++++++++++++++++++++++--- ovn/controller/lflow.h | 7 +++- ovn/controller/ofctrl.c | 4 +- ovn/controller/ofctrl.h | 2 + ovn/controller/ovn-controller.c | 14 +++++++++- 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index cb12cea..24c89f4 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" @@ -132,6 +133,7 @@ add_local_datapath(struct hmap *local_datapaths, ld = xmalloc(sizeof *ld); hmap_insert(local_datapaths, ld, binding_rec->datapath->tunnel_key); + reset_flow_processing(); } } diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 18f0970..f6eb24a 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -174,6 +174,13 @@ struct logical_datapath { enum ldp_type type; /* Type of logical datapath */ }; +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); @@ -206,6 +213,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; } @@ -222,6 +230,7 @@ ldp_free(struct logical_datapath *ldp) simap_destroy(&ldp->ports); hmap_remove(&logical_datapaths, &ldp->hmap_node); free(ldp); + reset_flow_processing(); } /* Iterates through all of the records in the Port_Binding table, updating the @@ -242,6 +251,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(); } } @@ -251,6 +261,7 @@ ldp_run(struct controller_ctx *ctx) struct simap_node *old = simap_find(&ldp->ports, mc->name); if (!old || old->data != mc->tunnel_key) { simap_put(&ldp->ports, mc->name, mc->tunnel_key); + reset_flow_processing(); } } @@ -279,22 +290,53 @@ 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, struct hmap *flow_table, 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; ldp_run(ctx); + if (restart_flow_processing) { + seqno = 0; + ovn_flow_table_clear(flow_table); + restart_flow_processing = false; + } + const struct sbrec_logical_flow *lflow; - SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { - /* Find the "struct logical_datapath" associated with this + 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 mod_seqno = sbrec_logical_flow_row_get_seqno(lflow, + OVSDB_IDL_CHANGE_MODIFY); + unsigned int ins_seqno = sbrec_logical_flow_row_get_seqno(lflow, + OVSDB_IDL_CHANGE_INSERT); + if (del_seqno <= seqno && mod_seqno <= seqno && ins_seqno <= seqno) { + continue; + } + if (del_seqno > 0) { + if (del_seqno > processed_seqno) { + processed_seqno = del_seqno; + } + /* we really don't want to re-process a deleted record so */ + continue; + } + if (mod_seqno > processed_seqno) { + processed_seqno = mod_seqno; + } + if (ins_seqno > processed_seqno) { + processed_seqno = ins_seqno; + } + + /* Find the "struct logical_datapath" asssociated with this * Logical_Flow row. If there's no such struct, that must be because * no logical ports are bound to that logical datapath, so there's no - * point in maintaining any flows for it anyway, so skip it. */ + * point in maintaining any flows for it anyway, so stop here */ const struct logical_datapath *ldp; ldp = ldp_lookup(lflow->logical_datapath); if (!ldp) { @@ -431,6 +473,7 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table, 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 ccbad30..3d9a995 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -56,9 +56,12 @@ struct uuid; #define LOG_PIPELINE_LEN 16 void lflow_init(void); -void lflow_run(struct controller_ctx *, struct hmap *flow_table, +unsigned int lflow_run(struct controller_ctx *, struct hmap *flow_table, const struct simap *ct_zones, - struct hmap *local_datapaths); + struct hmap *local_datapaths, + unsigned int seqno); void lflow_destroy(void); +void reset_lflow_processing(void); + #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 7280c8b..f58728c 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -97,7 +97,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(struct hmap *flow_table); +void ovn_flow_table_clear(struct hmap *flow_table); static void ovn_flow_table_destroy(struct hmap *flow_table); static void ofctrl_recv(const struct ofp_header *, enum ofptype); @@ -612,7 +612,7 @@ ovn_flow_destroy(struct ovn_flow *f) /* Flow tables of struct ovn_flow. */ -static void +void ovn_flow_table_clear(struct hmap *flow_table) { struct ovn_flow *f, *next; diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h index d3fabc0..57f8c43 100644 --- a/ovn/controller/ofctrl.h +++ b/ovn/controller/ofctrl.h @@ -40,4 +40,6 @@ struct ovn_flow *ofctrl_dup_flow(struct ovn_flow *source); void ofctrl_add_flow(struct hmap *flows, uint8_t table_id, uint16_t priority, const struct match *, const struct ofpbuf *ofpacts); +void ovn_flow_table_clear(struct hmap *flow_table); + #endif /* ovn/ofctrl.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index c34dce9..e47da81 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -28,6 +28,7 @@ #include "daemon.h" #include "dirs.h" #include "dynamic-string.h" +#include "match.h" #include "openvswitch/vconn.h" #include "openvswitch/vlog.h" #include "ovn/lib/ovn-sb-idl.h" @@ -204,6 +205,7 @@ main(int argc, char *argv[]) struct unixctl_server *unixctl; bool exiting; int retval; + unsigned int ovnsb_last_lflow_seqno = 0; struct hmap flow_table = HMAP_INITIALIZER(&flow_table); struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths); @@ -262,6 +264,14 @@ main(int argc, char *argv[]) char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl); struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true)); +// struct ovsdb_idl *sb_idl = ovsdb_idl_create(ovnsb_remote, +// &sbrec_idl_class, true, true); + /* set to track the southbound idl */ + ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); + +// struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(sb_idl); + + ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); /* Initialize connection tracking zones. */ @@ -301,7 +311,9 @@ main(int argc, char *argv[]) pinctrl_run(&ctx, br_int); - lflow_run(&ctx, &flow_table, &ct_zones, &local_datapaths); + ovnsb_last_lflow_seqno = lflow_run(&ctx, &flow_table, &ct_zones, + &local_datapaths, + ovnsb_last_lflow_seqno); if (chassis_id) { physical_run(&ctx, mff_ovn_geneve, br_int, chassis_id, &ct_zones, &flow_table); -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev