Optimize lflow generation code in build_gw_lrouter_nat_flows_for_lb when the system is running with datapath group enabled. The following tests have been carried out on running ovn-northd on a real openshift db composed of 120 nodes, 10K pods, and 10K load balancers applied to all node logical switches and routers:
ovn-main: --------- Statistics for 'lflows_lbs' Total samples: 51 Maximum: 1319 msec Minimum: 1282 msec 95th percentile: 1309.836278 msec Short term average: 1296.054252 msec Long term average: 1295.728676 msec ovn-main+optimization: ---------------------- Statistics for 'lflows_lbs' Total samples: 51 Maximum: 526 msec Minimum: 503 msec 95th percentile: 524.794986 msec Short term average: 518.826313 msec Long term average: 509.005444 msec Signed-off-by: Lorenzo Bianconi <[email protected]> --- northd/northd.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index afe723adb..d6cd671b8 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -9834,6 +9834,20 @@ build_gw_lrouter_nat_flows_for_lb(struct ovn_northd_lb *lb, char *est_action, struct hmap *lflows, int prio, const struct shash *meter_groups) { + if (!n_dplist) { + return; + } + + struct ovn_lflow *lflow_ref_new = NULL, *lflow_ref_est = NULL; + uint32_t hash_new = ovn_logical_flow_hash( + ovn_stage_get_table(S_ROUTER_IN_DNAT), + ovn_stage_get_pipeline(S_ROUTER_IN_DNAT), + prio, new_match, new_action); + uint32_t hash_est = ovn_logical_flow_hash( + ovn_stage_get_table(S_ROUTER_IN_DNAT), + ovn_stage_get_pipeline(S_ROUTER_IN_DNAT), + prio, est_match, est_action); + for (size_t i = 0; i < n_dplist; i++) { struct ovn_datapath *od = dplist[i]; const char *meter = NULL; @@ -9841,11 +9855,20 @@ build_gw_lrouter_nat_flows_for_lb(struct ovn_northd_lb *lb, if (reject) { meter = copp_meter_get(COPP_REJECT, od->nbr->copp, meter_groups); } - ovn_lflow_add_with_hint__(lflows, od, S_ROUTER_IN_DNAT, prio, - new_match, new_action, NULL, meter, - &lb->nlb->header_); - ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DNAT, prio, - est_match, est_action, &lb->nlb->header_); + if (meter || !ovn_dp_group_add_with_reference(lflow_ref_new, od)) { + struct ovn_lflow *lflow = ovn_lflow_add_at_with_hash(lflows, od, + S_ROUTER_IN_DNAT, prio, new_match, new_action, + NULL, meter, &lb->nlb->header_, OVS_SOURCE_LOCATOR, + hash_new); + lflow_ref_new = meter ? NULL : lflow; + } + + if (!ovn_dp_group_add_with_reference(lflow_ref_est, od)) { + lflow_ref_est = ovn_lflow_add_at_with_hash(lflows, od, + S_ROUTER_IN_DNAT, prio, est_match, est_action, + NULL, NULL, &lb->nlb->header_, + OVS_SOURCE_LOCATOR, hash_est); + } } } -- 2.35.3 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
