This patch implements change handler for port-binding in flow_output for physical flows computing, so that physical flow computing will be incremental.
This patch together with previous incremental processing engine related changes supports incremental processing for lflow changes and port-binding changes of lports on other HVs, which are the most common scenarios in a cloud where workloads come up and down. The CPU time of ovn-controller in ovn-scale-test for 500 lports creating and binding decreased 90% comparing with master without incremental processing engine related changes. (TODO: test case 2337 failed) Signed-off-by: Han Zhou <[email protected]> --- ovn/controller/ovn-controller.c | 36 ++++++++++++++++++++++++++++++++++- ovn/controller/physical.c | 42 ++++++++++++++++++++++++++++++++++------- ovn/controller/physical.h | 6 ++++++ 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 31f78f1..b92dcf5 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -780,6 +780,40 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) return true; } +static bool +flow_output_sb_port_binding_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = data->local_datapaths; + struct sset *active_tunnels = data->active_tunnels; + struct chassis_index *chassis_index = data->chassis_index; + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + // TODO: handle port-binding for lflow processing + + enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); + physical_handle_port_binding_changes(ctx, mff_ovn_geneve, + chassis, ctx->ct_zones, + local_datapaths, + chassis_index, active_tunnels); + + node->changed = true; + return true; +} + int main(int argc, char *argv[]) { @@ -911,7 +945,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_address_set, NULL); engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); - engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_port_binding, flow_output_sb_port_binding_handler); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler); engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 41ea9fe..b14051b 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -358,7 +358,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_finish_CLONE(ofpacts_p, &clone); ofctrl_add_flow(OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); return; } @@ -426,7 +426,7 @@ consider_port_binding(struct controller_ctx *ctx, } ofctrl_add_flow(OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); goto out; } @@ -558,7 +558,7 @@ consider_port_binding(struct controller_ctx *ctx, /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); ofctrl_add_flow(OFTABLE_PHY_TO_LOG, - tag ? 150 : 100, 0, &match, ofpacts_p, hc_uuid); + tag ? 150 : 100, 0, &match, ofpacts_p, &binding->header_.uuid); if (!tag && (!strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway"))) { @@ -568,7 +568,7 @@ consider_port_binding(struct controller_ctx *ctx, * action. */ ofpbuf_pull(ofpacts_p, ofpacts_orig_size); match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI)); - ofctrl_add_flow(0, 100, 0, &match, ofpacts_p, hc_uuid); + ofctrl_add_flow(0, 100, 0, &match, ofpacts_p, &binding->header_.uuid); } /* Table 65, Priority 100. @@ -596,7 +596,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_put_STRIP_VLAN(ofpacts_p); } ofctrl_add_flow(OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else if (!tun && !is_ha_remote) { /* Remote port connected by localnet port */ /* Table 33, priority 100. @@ -619,7 +619,7 @@ consider_port_binding(struct controller_ctx *ctx, /* Resubmit to table 33. */ put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); ofctrl_add_flow(OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else { /* Remote port connected by tunnel */ @@ -710,7 +710,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_finish_BUNDLE(ofpacts_p, &bundle); } ofctrl_add_flow(OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } out: if (gateway_chassis) { @@ -857,6 +857,33 @@ update_ofports(struct simap *old, struct simap *new) } void +physical_handle_port_binding_changes(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct chassis_index *chassis_index, + struct sset *active_tunnels) +{ + const struct sbrec_port_binding *binding; + struct ofpbuf ofpacts; + ofpbuf_init(&ofpacts, 0); + SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding, ctx->ovnsb_idl) { + if (sbrec_port_binding_is_deleted(binding)) { + ofctrl_remove_flows(&binding->header_.uuid); + } else { + if (!sbrec_port_binding_is_new(binding)) { + ofctrl_remove_flows(&binding->header_.uuid); + } + consider_port_binding(ctx, mff_ovn_geneve, ct_zones, + chassis_index, active_tunnels, + local_datapaths, binding, chassis, + &ofpacts); + } + } + +} + +void physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, @@ -978,6 +1005,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, /* Capture changed or removed openflow ports. */ physical_map_changed |= update_ofports(&localvif_to_ofport, &new_localvif_to_ofport); + // TODO: maybe this is not needed any more? if (physical_map_changed) { /* Reprocess logical flow table immediately. */ poll_immediate_wake(); diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 4aeec04..e0b31a4 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -51,5 +51,11 @@ void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve, const struct sset *local_lports, struct chassis_index *chassis_index, struct sset *active_tunnels); +void physical_handle_port_binding_changes(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct chassis_index *chassis_index, + struct sset *active_tunnels); #endif /* ovn/physical.h */ -- 2.1.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
