From patchwork Sat Nov 14 07:56:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400238 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CY73j6rSWz9sRK for ; Sat, 14 Nov 2020 18:57:37 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 6AD3587A2C; Sat, 14 Nov 2020 07:57:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9RHYUyl5xtf5; Sat, 14 Nov 2020 07:57:30 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 9B90F87A33; Sat, 14 Nov 2020 07:57:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7BFD7C1DD3; Sat, 14 Nov 2020 07:57:28 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id DEBC8C1DCD for ; Sat, 14 Nov 2020 07:57:27 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id ACC652E2A4 for ; Sat, 14 Nov 2020 07:57:27 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EqZ1CWtiMzRN for ; Sat, 14 Nov 2020 07:57:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by silver.osuosl.org (Postfix) with ESMTPS id 3D48320466 for ; Sat, 14 Nov 2020 07:57:12 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 40D5CFF805; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:53 +0100 Message-Id: <20201114075653.9142-7-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 6/6] northd: Use same Logical Datapath Group for different flows. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This significantly reduces space wasted on storing duplicated datapath groups. Signed-off-by: Ilya Maximets --- northd/ovn-northd.c | 102 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 782a539dc..a08b709fd 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -11315,12 +11315,29 @@ build_lswitch_and_lrouter_flows(struct hmap *datapaths, struct hmap *ports, build_lrouter_flows(datapaths, ports, lflows, meter_groups, lbs); } +struct ovn_dp_group { + struct hmapx map; + struct sbrec_logical_datapath_group *dp_group; + struct hmap_node node; +}; -static void -ovn_sb_set_lflow_logical_datapath_group( - struct northd_context *ctx, - const struct sbrec_logical_flow *sbflow, - const struct hmapx *od) +static struct ovn_dp_group * +ovn_dp_group_find(const struct hmap *dp_groups, + const struct hmapx *od, uint32_t hash) +{ + struct ovn_dp_group *dpg; + + HMAP_FOR_EACH_WITH_HASH (dpg, node, hash, dp_groups) { + if (hmapx_equals(&dpg->map, od)) { + return dpg; + } + } + return NULL; +} + +static struct sbrec_logical_datapath_group * +ovn_sb_insert_logical_datapath_group(struct northd_context *ctx, + const struct hmapx *od) { struct sbrec_logical_datapath_group *dp_group; const struct sbrec_datapath_binding **sb; @@ -11335,7 +11352,26 @@ ovn_sb_set_lflow_logical_datapath_group( sbrec_logical_datapath_group_set_datapaths( dp_group, (struct sbrec_datapath_binding **) sb, n); free(sb); - sbrec_logical_flow_set_logical_datapath_group(sbflow, dp_group); + + return dp_group; +} + +static void +ovn_sb_set_lflow_logical_datapath_group( + struct northd_context *ctx, + struct hmap *dp_groups, + const struct sbrec_logical_flow *sbflow, + const struct hmapx *od) +{ + struct ovn_dp_group *dpg; + + dpg = ovn_dp_group_find(dp_groups, od, hash_int(hmapx_count(od), 0)); + ovs_assert(dpg != NULL); + + if (!dpg->dp_group) { + dpg->dp_group = ovn_sb_insert_logical_datapath_group(ctx, &dpg->map); + } + sbrec_logical_flow_set_logical_datapath_group(sbflow, dpg->dp_group); } /* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database, @@ -11353,7 +11389,24 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, port_groups, &lflows, mcgroups, igmp_groups, meter_groups, lbs); + /* Collecting all unique datapath groups. */ + struct hmap dp_groups = HMAP_INITIALIZER(&dp_groups); + struct ovn_lflow *lflow; + HMAP_FOR_EACH (lflow, hmap_node, &lflows) { + uint32_t hash = hash_int(hmapx_count(&lflow->od), 0); + struct ovn_dp_group *dpg; + + dpg = ovn_dp_group_find(&dp_groups, &lflow->od, hash); + if (!dpg) { + dpg = xzalloc(sizeof *dpg); + hmapx_clone(&dpg->map, &lflow->od); + hmap_insert(&dp_groups, &dpg->node, hash); + } + } + /* Push changes to the Logical_Flow table to database. */ + struct hmapx orphaned_dp_groups = HMAPX_INITIALIZER(&orphaned_dp_groups); + struct hmapx kept_dp_groups = HMAPX_INITIALIZER(&kept_dp_groups); const struct sbrec_logical_flow *sbflow, *next_sbflow; SBREC_LOGICAL_FLOW_FOR_EACH_SAFE (sbflow, next_sbflow, ctx->ovnsb_idl) { struct sbrec_logical_datapath_group *dp_group @@ -11376,7 +11429,7 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, if (!n_valid_datapaths) { /* This lflow has no valid logical datapaths. */ - sbrec_logical_datapath_group_delete(dp_group); + hmapx_add(&orphaned_dp_groups, dp_group); sbrec_logical_flow_delete(sbflow); free(od); continue; @@ -11384,10 +11437,10 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, enum ovn_pipeline pipeline = !strcmp(sbflow->pipeline, "ingress") ? P_IN : P_OUT; - struct ovn_lflow *lflow = ovn_lflow_find( + + lflow = ovn_lflow_find( &lflows, ovn_stage_build(dp_type, pipeline, sbflow->table_id), sbflow->priority, sbflow->match, sbflow->actions, sbflow->hash); - if (lflow) { /* This is a valid lflow. Checking if the datapath group needs * updates. */ @@ -11406,25 +11459,39 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, if (update_datapath_group) { /* Re-creating datapath group since there are changes. */ - sbrec_logical_datapath_group_delete(dp_group); - ovn_sb_set_lflow_logical_datapath_group(ctx, + hmapx_add(&orphaned_dp_groups, dp_group); + ovn_sb_set_lflow_logical_datapath_group(ctx, &dp_groups, sbflow, &lflow->od); + } else { + hmapx_add(&kept_dp_groups, dp_group); } /* This lflow updated. Not needed anymore. */ ovn_lflow_destroy(&lflows, lflow); } else { - sbrec_logical_datapath_group_delete(dp_group); + hmapx_add(&orphaned_dp_groups, dp_group); sbrec_logical_flow_delete(sbflow); } free(od); } - struct ovn_lflow *lflow, *next_lflow; + + /* Remove all orphaned datapath groups, i.e. all groups without lflows. */ + const struct hmapx_node *node; + HMAPX_FOR_EACH (node, &orphaned_dp_groups) { + if (!hmapx_contains(&kept_dp_groups, node->data)) { + sbrec_logical_datapath_group_delete(node->data); + } + } + hmapx_destroy(&orphaned_dp_groups); + hmapx_destroy(&kept_dp_groups); + + struct ovn_lflow *next_lflow; HMAP_FOR_EACH_SAFE (lflow, next_lflow, hmap_node, &lflows) { const char *pipeline = ovn_stage_get_pipeline_name(lflow->stage); uint8_t table = ovn_stage_get_table(lflow->stage); sbflow = sbrec_logical_flow_insert(ctx->ovnsb_txn); - ovn_sb_set_lflow_logical_datapath_group(ctx, sbflow, &lflow->od); + ovn_sb_set_lflow_logical_datapath_group(ctx, &dp_groups, + sbflow, &lflow->od); sbrec_logical_flow_set_pipeline(sbflow, pipeline); sbrec_logical_flow_set_table_id(sbflow, table); sbrec_logical_flow_set_priority(sbflow, lflow->priority); @@ -11456,6 +11523,13 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, } hmap_destroy(&lflows); + struct ovn_dp_group *dpg; + HMAP_FOR_EACH_POP (dpg, node, &dp_groups) { + hmapx_destroy(&dpg->map); + free(dpg); + } + hmap_destroy(&dp_groups); + /* Push changes to the Multicast_Group table to database. */ const struct sbrec_multicast_group *sbmc, *next_sbmc; SBREC_MULTICAST_GROUP_FOR_EACH_SAFE (sbmc, next_sbmc, ctx->ovnsb_idl) {