From 28d18d2bc0d56e447a0adeebc3e48b7da6890b2a Mon Sep 17 00:00:00 2001 From: Alaa Hleihel Date: Tue, 19 May 2020 07:48:58 -0400 Subject: [PATCH 236/312] [netdrv] net/mlx5: E-Switch, Get reg_c1 value on miss Message-id: <20200519074934.6303-28-ahleihel@redhat.com> Patchwork-id: 310530 Patchwork-instance: patchwork O-Subject: [RHEL8.3 BZ 1663246 27/63] net/mlx5: E-Switch, Get reg_c1 value on miss Bugzilla: 1790219 1790218 1663246 RH-Acked-by: Marcelo Leitner RH-Acked-by: Jarod Wilson RH-Acked-by: John Linville RH-Acked-by: Ivan Vecera RH-Acked-by: Tony Camuso RH-Acked-by: Kamal Heib Bugzilla: http://bugzilla.redhat.com/1663246 Bugzilla: http://bugzilla.redhat.com/1790219 Bugzilla: http://bugzilla.redhat.com/1790218 Upstream: v5.7-rc1 commit 6724e66b90eebb19d146b7623b3e2af15616782b Author: Paul Blakey Date: Sun Feb 16 12:01:35 2020 +0200 net/mlx5: E-Switch, Get reg_c1 value on miss The HW model implicitly decapsulates tunnels on chain 0 and sets reg_c1 with the mapped tunnel id. On miss, the packet does not have the outer header and the driver restores the tunnel information from the tunnel id. Getting reg_c1 value in software requires enabling reg_c1 loopback and copying reg_c1 to reg_b. reg_b comes up on CQE as cqe->imm_inval_pkey. Use the reg_c0 restoration rules to also copy reg_c1 to reg_B. Signed-off-by: Paul Blakey Reviewed-by: Oz Shlomo Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed Signed-off-by: Alaa Hleihel Signed-off-by: Frantisek Hrbata --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 1 + .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 31 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index a384cab195c1..3240f6de94bd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -233,6 +233,7 @@ struct mlx5_esw_offload { #ifndef __GENKSYMS__ struct mlx5_flow_table *ft_offloads_restore; struct mlx5_flow_group *restore_group; + struct mlx5_modify_hdr *restore_copy_hdr_id; #endif struct mlx5_flow_table *ft_offloads; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index eab876a2208a..a9b2522b9f03 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -782,9 +782,11 @@ static int esw_set_passing_vport_metadata(struct mlx5_eswitch *esw, bool enable) esw_vport_context.fdb_to_vport_reg_c_id); if (enable) - fdb_to_vport_reg_c_id |= MLX5_FDB_TO_VPORT_REG_C_0; + fdb_to_vport_reg_c_id |= MLX5_FDB_TO_VPORT_REG_C_0 | + MLX5_FDB_TO_VPORT_REG_C_1; else - fdb_to_vport_reg_c_id &= ~MLX5_FDB_TO_VPORT_REG_C_0; + fdb_to_vport_reg_c_id &= ~(MLX5_FDB_TO_VPORT_REG_C_0 | + MLX5_FDB_TO_VPORT_REG_C_1); MLX5_SET(modify_esw_vport_context_in, in, esw_vport_context.fdb_to_vport_reg_c_id, fdb_to_vport_reg_c_id); @@ -1045,7 +1047,9 @@ esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag) misc_parameters_2); MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0, tag); spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2; - flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; + flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | + MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; + flow_act.modify_hdr = esw->offloads.restore_copy_hdr_id; flow_context = &spec->flow_context; flow_context->flags |= FLOW_CONTEXT_HAS_TAG; @@ -1404,16 +1408,19 @@ static void esw_destroy_restore_table(struct mlx5_eswitch *esw) { struct mlx5_esw_offload *offloads = &esw->offloads; + mlx5_modify_header_dealloc(esw->dev, offloads->restore_copy_hdr_id); mlx5_destroy_flow_group(offloads->restore_group); mlx5_destroy_flow_table(offloads->ft_offloads_restore); } static int esw_create_restore_table(struct mlx5_eswitch *esw) { + u8 modact[MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto)] = {}; int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); struct mlx5_flow_table_attr ft_attr = {}; struct mlx5_core_dev *dev = esw->dev; struct mlx5_flow_namespace *ns; + struct mlx5_modify_hdr *mod_hdr; void *match_criteria, *misc; struct mlx5_flow_table *ft; struct mlx5_flow_group *g; @@ -1462,11 +1469,29 @@ static int esw_create_restore_table(struct mlx5_eswitch *esw) goto err_group; } + MLX5_SET(copy_action_in, modact, action_type, MLX5_ACTION_TYPE_COPY); + MLX5_SET(copy_action_in, modact, src_field, + MLX5_ACTION_IN_FIELD_METADATA_REG_C_1); + MLX5_SET(copy_action_in, modact, dst_field, + MLX5_ACTION_IN_FIELD_METADATA_REG_B); + mod_hdr = mlx5_modify_header_alloc(esw->dev, + MLX5_FLOW_NAMESPACE_KERNEL, 1, + modact); + if (IS_ERR(mod_hdr)) { + esw_warn(dev, "Failed to create restore mod header, err: %d\n", + err); + err = PTR_ERR(mod_hdr); + goto err_mod_hdr; + } + esw->offloads.ft_offloads_restore = ft; esw->offloads.restore_group = g; + esw->offloads.restore_copy_hdr_id = mod_hdr; return 0; +err_mod_hdr: + mlx5_destroy_flow_group(g); err_group: mlx5_destroy_flow_table(ft); out_free: -- 2.13.6