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

Reply via email to