[ovs-dev] [PATCH v2 ovn 2/2] northd: improve unreachable_ips flows processing for dp_groups

Lorenzo Bianconi lorenzo.bianconi at redhat.com
Wed Aug 25 11:58:50 UTC 2021


Improve code efficiency of load-balancer unreachable_ips flows
processing when datapath_groups are enabled. We can avoid to
perform a flow lookup for each ovn_port in
build_lflows_for_unreachable_vips() since lflows only
depends on vips (match and action filters).
Using this approach (with datapath_groups enabled) we reduced
ovn-northd loop time from 12s to 8s (running a production ovn-nb db):

ovn-master:
----------
Statistics for 'ovnnb_db_run'
  Total samples: 97
  Maximum: 12596 msec
  Minimum: 12324 msec
  95th percentile: 12549.921348 msec
  Short term average: 12438.001085 msec
  Long term average: 12407.350781 msec

ovn-master + flow rework:
-------------------------
Statistics for 'ovnnb_db_run'
  Total samples: 97
  Maximum: 8853 msec
  Minimum: 8533 msec
  95th percentile: 8697.718376 msec
  Short term average: 8608.222669 msec
  Long term average: 8623.947235 msec

ovn-nbctl lr-list | wc -l
121
ovn-nbctl ls-list | wc -l
241
ovn-nbctl lb-list | wc -l
47077
ovn-sbctl dump-flows |wc -l
9852935

Acked-by: Mark Michelson <mmichels at redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
 northd/ovn-northd.c | 60 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index f4b5a4a61..6c453c450 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -4362,7 +4362,7 @@ static struct hashrow_locks lflow_locks;
 /* Adds a row with the specified contents to the Logical_Flow table.
  * Version to use when locking is required.
  */
-static void
+static struct ovn_lflow *
 do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od,
                  uint32_t hash, enum ovn_stage stage, uint16_t priority,
                  const char *match, const char *actions, const char *io_port,
@@ -4378,7 +4378,7 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od,
                                    actions, ctrl_meter, hash);
         if (old_lflow) {
             hmapx_add(&old_lflow->od_group, od);
-            return;
+            return old_lflow;
         }
     }
 
@@ -4397,10 +4397,11 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od,
     } else {
         hmap_insert_fast(lflow_map, &lflow->hmap_node, hash);
     }
+    return lflow;
 }
 
 /* Adds a row with the specified contents to the Logical_Flow table. */
-static void
+static struct ovn_lflow *
 ovn_lflow_add_at_with_hash(struct hmap *lflow_map, struct ovn_datapath *od,
                            enum ovn_stage stage, uint16_t priority,
                            const char *match, const char *actions,
@@ -4408,16 +4409,21 @@ ovn_lflow_add_at_with_hash(struct hmap *lflow_map, struct ovn_datapath *od,
                            const struct ovsdb_idl_row *stage_hint,
                            const char *where, uint32_t hash)
 {
+    struct ovn_lflow *lflow;
+
     ovs_assert(ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od));
     if (use_logical_dp_groups && use_parallel_build) {
         lock_hash_row(&lflow_locks, hash);
-        do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match,
-                         actions, io_port, stage_hint, where, ctrl_meter);
+        lflow = do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match,
+                                 actions, io_port, stage_hint, where,
+                                 ctrl_meter);
         unlock_hash_row(&lflow_locks, hash);
     } else {
-        do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match,
-                         actions, io_port, stage_hint, where, ctrl_meter);
+        lflow = do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match,
+                                 actions, io_port, stage_hint, where,
+                                 ctrl_meter);
     }
+    return lflow;
 }
 
 static void
@@ -9441,6 +9447,26 @@ build_lrouter_defrag_flows_for_lb(struct ovn_northd_lb *lb,
     ds_destroy(&defrag_actions);
 }
 
+static bool
+ovn_dp_group_update_with_reference(struct ovn_lflow *lflow_ref,
+                                   struct ovn_datapath *od,
+                                   uint32_t hash)
+{
+    if (!use_logical_dp_groups || !lflow_ref) {
+        return false;
+    }
+
+    if (use_parallel_build) {
+        lock_hash_row(&lflow_locks, hash);
+        hmapx_add(&lflow_ref->od_group, od);
+        unlock_hash_row(&lflow_locks, hash);
+    } else {
+        hmapx_add(&lflow_ref->od_group, od);
+    }
+
+    return true;
+}
+
 static void
 build_lflows_for_unreachable_vips(struct ovn_northd_lb *lb,
                                   struct ovn_lb_vip *lb_vip,
@@ -9450,6 +9476,7 @@ build_lflows_for_unreachable_vips(struct ovn_northd_lb *lb,
 {
     static const char *action = "outport = _MC_flood; output;";
     bool ipv4 = IN6_IS_ADDR_V4MAPPED(&lb_vip->vip);
+    struct ovn_lflow *lflow_ref = NULL;
     ovs_be32 ipv4_addr;
 
     ds_clear(match);
@@ -9495,11 +9522,20 @@ build_lflows_for_unreachable_vips(struct ovn_northd_lb *lb,
                 (!ipv4 && lrouter_port_ipv6_reachable(op, &lb_vip->vip))) {
                 continue;
             }
-            ovn_lflow_add_at_with_hash(lflows, peer->od,
-                                       S_SWITCH_IN_L2_LKUP, 90,
-                                       ds_cstr(match), action,
-                                       NULL, NULL, &peer->nbsp->header_,
-                                       OVS_SOURCE_LOCATOR, hash);
+
+            if (ovn_dp_group_update_with_reference(lflow_ref, od, hash)) {
+                /* if we are running dp_groups, we do not need to run full
+                 * lookup since lflow just depends on the vip and not on
+                 * the ovn_port.
+                 */
+                continue;
+            }
+            lflow_ref = ovn_lflow_add_at_with_hash(lflows, peer->od,
+                                                   S_SWITCH_IN_L2_LKUP, 90,
+                                                   ds_cstr(match), action,
+                                                   NULL, NULL,
+                                                   &peer->nbsp->header_,
+                                                   OVS_SOURCE_LOCATOR, hash);
         }
     }
 }
-- 
2.31.1



More information about the dev mailing list