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 | 65 +++++++++++++++++++++++++++++++++++++-- ovn/controller/lflow.h | 1 + ovn/controller/lport.c | 7 ++++ ovn/controller/ofctrl.c | 4 +- ovn/controller/ofctrl.h | 2 + ovn/controller/ovn-controller.c | 3 +- 7 files changed, 78 insertions(+), 7 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 62b0d73..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" @@ -139,6 +140,7 @@ remove_local_datapath(struct hmap *local_datapaths, const struct uuid *uuid) if (ld) { hmap_remove(local_datapaths, &ld->hmap_node); hmap_remove(&local_datapaths_by_uuid, &ld->uuid_hmap_node); + reset_flow_processing(); } } @@ -157,6 +159,7 @@ add_local_datapath(struct hmap *local_datapaths, binding_rec->datapath->tunnel_key); hmap_insert(&local_datapaths_by_uuid, &ld->uuid_hmap_node, uuid_hash(uuid)); + reset_flow_processing(); } static void diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 066dea6..cd4ec9b 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -35,6 +35,16 @@ VLOG_DEFINE_THIS_MODULE(lflow); /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */ static struct shash symtab; +void reset_flow_processing(void); + +bool restart_flow_processing = false; + +void +reset_flow_processing(void) +{ + restart_flow_processing = true; +} + static void add_logical_register(struct shash *symtab, enum mf_field_id id) { @@ -193,6 +203,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, @@ -206,18 +218,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"); @@ -356,7 +386,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); @@ -377,6 +406,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. */ @@ -393,18 +424,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) { @@ -446,8 +499,14 @@ lflow_run(struct controller_ctx *ctx, const struct lport_index *lports, const struct hmap *local_datapaths, const struct simap *ct_zones) { - add_logical_flows(ctx, lports, mcgroups, local_datapaths, - 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_neighbor_flows(ctx, lports); } diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 9bf36c3..746169c 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -64,5 +64,6 @@ 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); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c index b0fa433..5bcc05a 100644 --- a/ovn/controller/lport.c +++ b/ovn/controller/lport.c @@ -17,6 +17,7 @@ #include "lport.h" #include "hash.h" +#include "lflow.h" #include "openvswitch/vlog.h" #include "ovn/lib/ovn-sb-idl.h" @@ -65,6 +66,7 @@ lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) * to remove the port. */ if (del_seqno > 0) { lport_index_remove(lports, &pb->header_.uuid); + reset_flow_processing(); continue; } @@ -81,6 +83,7 @@ lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) uuid_hash(&pb->header_.uuid)); p->uuid = &pb->header_.uuid; p->pb = pb; + reset_flow_processing(); } } @@ -97,6 +100,7 @@ lport_index_clear(struct lport_index *lports) hmap_remove(&lports->by_uuid, &port->uuid_node); free(port); } + reset_flow_processing(); } void @@ -192,6 +196,7 @@ mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl) * to remove the port. */ if (del_seqno > 0) { mcgroup_index_remove(mcgroups, &mg->header_.uuid); + reset_flow_processing(); continue; } @@ -207,6 +212,7 @@ mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl) uuid_hash(&mg->header_.uuid)); m->uuid = &mg->header_.uuid; m->mg = mg; + reset_flow_processing(); } } @@ -219,6 +225,7 @@ mcgroup_index_clear(struct mcgroup_index *mcgroups) hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node); free(mcgroup); } + reset_flow_processing(); } void diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index a20b4e8..0ee2b92 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -103,7 +103,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); @@ -719,7 +719,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 c7118ab..a8ae4f8 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_remove_flows_from_table(uint8_t table_id, const struct uuid *uuid); +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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev