From: RYAN D. MOATS <rmo...@us.ibm.com> This code changes lflow_run to do incremental processing rather than recreating the flow table on each run.
Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com> --- ovn/controller/lflow.c | 60 +++++++++++++++++++++++++++++++++++--- ovn/controller/lflow.h | 5 ++- ovn/controller/ovn-controller.c | 14 ++++++++- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index d53213c..d6aab60 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -273,25 +273,62 @@ 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; + unsigned int last_seqno = 0; + bool reset_seqno = false; ldp_run(ctx); 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 skip it. + * Further, we have to remember the smallest sequence number of + * a skipped flow to ensure that we return the correct value + * and don't skip things in a later pass */ const struct logical_datapath *ldp; ldp = ldp_lookup(lflow->logical_datapath); if (!ldp) { + if (last_seqno == 0 || (mod_seqno > 0 && last_seqno > mod_seqno)) { + last_seqno = mod_seqno; + } + if (last_seqno == 0 || (ins_seqno > 0 && last_seqno > ins_seqno)) { + last_seqno = ins_seqno; + } + reset_seqno = true; continue; } @@ -322,6 +359,15 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table, struct hmap_node *ld; ld = hmap_first_with_hash(local_datapaths, ldp->tunnel_key); if (!ld) { + if (last_seqno == 0 || (mod_seqno > 0 && + last_seqno > mod_seqno)) { + last_seqno = mod_seqno; + } + if (last_seqno == 0 || (ins_seqno > 0 && + last_seqno > ins_seqno)) { + last_seqno = ins_seqno; + } + reset_seqno = true; continue; } } @@ -425,6 +471,10 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table, ofpbuf_uninit(&ofpacts); conj_id_ofs += n_conjs; } + if (reset_seqno) { + processed_seqno = last_seqno-1; + } + return processed_seqno; } void diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index ccbad30..91320a7 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -56,9 +56,10 @@ 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); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 5a4174e..a161123 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); @@ -261,6 +263,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