|
|
d8f823 |
From d1efc329df288e6249c8652723b9e120b71cccec Mon Sep 17 00:00:00 2001
|
|
|
d8f823 |
From: Alaa Hleihel <ahleihel@redhat.com>
|
|
|
d8f823 |
Date: Tue, 19 May 2020 07:48:51 -0400
|
|
|
d8f823 |
Subject: [PATCH 229/312] [netdrv] net/mlx5: E-Switch, Mark miss packets with
|
|
|
d8f823 |
new chain id mapping
|
|
|
d8f823 |
|
|
|
d8f823 |
Message-id: <20200519074934.6303-21-ahleihel@redhat.com>
|
|
|
d8f823 |
Patchwork-id: 310523
|
|
|
d8f823 |
Patchwork-instance: patchwork
|
|
|
d8f823 |
O-Subject: [RHEL8.3 BZ 1663246 20/63] net/mlx5: E-Switch, Mark miss packets with new chain id mapping
|
|
|
d8f823 |
Bugzilla: 1790219 1790218 1663246
|
|
|
d8f823 |
RH-Acked-by: Marcelo Leitner <mleitner@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: John Linville <linville@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Kamal Heib <kheib@redhat.com>
|
|
|
d8f823 |
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1663246
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1790219
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1790218
|
|
|
d8f823 |
Upstream: v5.7-rc1
|
|
|
d8f823 |
|
|
|
d8f823 |
commit 8f1e0b97cc708aa6a4d84b0431afc410feba00b6
|
|
|
d8f823 |
Author: Paul Blakey <paulb@mellanox.com>
|
|
|
d8f823 |
Date: Sun Feb 16 12:01:28 2020 +0200
|
|
|
d8f823 |
|
|
|
d8f823 |
net/mlx5: E-Switch, Mark miss packets with new chain id mapping
|
|
|
d8f823 |
|
|
|
d8f823 |
Currently, if we miss in hardware after jumping to some chain,
|
|
|
d8f823 |
we continue in chain 0 in software. This is wrong, and with the new
|
|
|
d8f823 |
tc skb extension we can now restore the chain id on the skb, so
|
|
|
d8f823 |
tc can continue with in the correct chain.
|
|
|
d8f823 |
|
|
|
d8f823 |
To restore the chain id in software after a miss in hardware, we create
|
|
|
d8f823 |
a register mapping from 32bit chain ids to 16bit of reg_c0 (that
|
|
|
d8f823 |
survives loopback), to 32bit chain ids. We then mark packets that
|
|
|
d8f823 |
miss on some chain with the current chain id mapping on their reg_c0
|
|
|
d8f823 |
field. Using this mapping, we will support up to 64K concurrent
|
|
|
d8f823 |
chains.
|
|
|
d8f823 |
|
|
|
d8f823 |
This register survives loopback and gets to the CQE on flow_tag
|
|
|
d8f823 |
via the eswitch restore rules.
|
|
|
d8f823 |
|
|
|
d8f823 |
In next commit, we will reverse the mapping we got on the CQE
|
|
|
d8f823 |
to a chain id and tell tc to continue in the sw chain where we
|
|
|
d8f823 |
left off via the tc skb extension.
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Paul Blakey <paulb@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Roi Dayan <roid@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Oz Shlomo <ozsh@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Mark Bloch <markb@mellanox.com>
|
|
|
d8f823 |
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
|
|
|
d8f823 |
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
|
|
|
d8f823 |
---
|
|
|
d8f823 |
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 8 ++
|
|
|
d8f823 |
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 12 ++
|
|
|
d8f823 |
.../mellanox/mlx5/core/eswitch_offloads_chains.c | 130 ++++++++++++++++++++-
|
|
|
d8f823 |
.../mellanox/mlx5/core/eswitch_offloads_chains.h | 4 +-
|
|
|
d8f823 |
4 files changed, 150 insertions(+), 4 deletions(-)
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
index 9d6ac9a1461b..a9142bde2dc6 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
@@ -153,6 +153,14 @@ struct mlx5e_tc_flow_parse_attr {
|
|
|
d8f823 |
#define MLX5E_TC_TABLE_NUM_GROUPS 4
|
|
|
d8f823 |
#define MLX5E_TC_TABLE_MAX_GROUP_SIZE BIT(16)
|
|
|
d8f823 |
|
|
|
d8f823 |
+struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = {
|
|
|
d8f823 |
+ [CHAIN_TO_REG] = {
|
|
|
d8f823 |
+ .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_0,
|
|
|
d8f823 |
+ .moffset = 0,
|
|
|
d8f823 |
+ .mlen = 2,
|
|
|
d8f823 |
+ },
|
|
|
d8f823 |
+};
|
|
|
d8f823 |
+
|
|
|
d8f823 |
struct mlx5e_hairpin {
|
|
|
d8f823 |
struct mlx5_hairpin *pair;
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
index 262cdb7b69b1..e2dbbae6d4d7 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
@@ -91,6 +91,18 @@ int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags);
|
|
|
d8f823 |
|
|
|
d8f823 |
void mlx5e_tc_reoffload_flows_work(struct work_struct *work);
|
|
|
d8f823 |
|
|
|
d8f823 |
+enum mlx5e_tc_attr_to_reg {
|
|
|
d8f823 |
+ CHAIN_TO_REG,
|
|
|
d8f823 |
+};
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+struct mlx5e_tc_attr_to_reg_mapping {
|
|
|
d8f823 |
+ int mfield; /* rewrite field */
|
|
|
d8f823 |
+ int moffset; /* offset of mfield */
|
|
|
d8f823 |
+ int mlen; /* bytes to rewrite/match */
|
|
|
d8f823 |
+};
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+extern struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[];
|
|
|
d8f823 |
+
|
|
|
d8f823 |
bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
|
|
|
d8f823 |
struct net_device *out_dev);
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.c
|
|
|
d8f823 |
index 6ffc4f041b6c..12ca184cd795 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.c
|
|
|
d8f823 |
@@ -6,14 +6,17 @@
|
|
|
d8f823 |
#include <linux/mlx5/fs.h>
|
|
|
d8f823 |
|
|
|
d8f823 |
#include "eswitch_offloads_chains.h"
|
|
|
d8f823 |
+#include "en/mapping.h"
|
|
|
d8f823 |
#include "mlx5_core.h"
|
|
|
d8f823 |
#include "fs_core.h"
|
|
|
d8f823 |
#include "eswitch.h"
|
|
|
d8f823 |
#include "en.h"
|
|
|
d8f823 |
+#include "en_tc.h"
|
|
|
d8f823 |
|
|
|
d8f823 |
#define esw_chains_priv(esw) ((esw)->fdb_table.offloads.esw_chains_priv)
|
|
|
d8f823 |
#define esw_chains_lock(esw) (esw_chains_priv(esw)->lock)
|
|
|
d8f823 |
#define esw_chains_ht(esw) (esw_chains_priv(esw)->chains_ht)
|
|
|
d8f823 |
+#define esw_chains_mapping(esw) (esw_chains_priv(esw)->chains_mapping)
|
|
|
d8f823 |
#define esw_prios_ht(esw) (esw_chains_priv(esw)->prios_ht)
|
|
|
d8f823 |
#define fdb_pool_left(esw) (esw_chains_priv(esw)->fdb_left)
|
|
|
d8f823 |
#define tc_slow_fdb(esw) ((esw)->fdb_table.offloads.slow_fdb)
|
|
|
d8f823 |
@@ -42,6 +45,7 @@ struct mlx5_esw_chains_priv {
|
|
|
d8f823 |
struct mutex lock;
|
|
|
d8f823 |
|
|
|
d8f823 |
struct mlx5_flow_table *tc_end_fdb;
|
|
|
d8f823 |
+ struct mapping_ctx *chains_mapping;
|
|
|
d8f823 |
|
|
|
d8f823 |
int fdb_left[ARRAY_SIZE(ESW_POOLS)];
|
|
|
d8f823 |
};
|
|
|
d8f823 |
@@ -52,9 +56,12 @@ struct fdb_chain {
|
|
|
d8f823 |
u32 chain;
|
|
|
d8f823 |
|
|
|
d8f823 |
int ref;
|
|
|
d8f823 |
+ int id;
|
|
|
d8f823 |
|
|
|
d8f823 |
struct mlx5_eswitch *esw;
|
|
|
d8f823 |
struct list_head prios_list;
|
|
|
d8f823 |
+ struct mlx5_flow_handle *restore_rule;
|
|
|
d8f823 |
+ struct mlx5_modify_hdr *miss_modify_hdr;
|
|
|
d8f823 |
};
|
|
|
d8f823 |
|
|
|
d8f823 |
struct fdb_prio_key {
|
|
|
d8f823 |
@@ -258,6 +265,70 @@ mlx5_esw_chains_destroy_fdb_table(struct mlx5_eswitch *esw,
|
|
|
d8f823 |
mlx5_destroy_flow_table(fdb);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
+static int
|
|
|
d8f823 |
+create_fdb_chain_restore(struct fdb_chain *fdb_chain)
|
|
|
d8f823 |
+{
|
|
|
d8f823 |
+ char modact[MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto)];
|
|
|
d8f823 |
+ struct mlx5_eswitch *esw = fdb_chain->esw;
|
|
|
d8f823 |
+ struct mlx5_modify_hdr *mod_hdr;
|
|
|
d8f823 |
+ u32 index;
|
|
|
d8f823 |
+ int err;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ if (fdb_chain->chain == mlx5_esw_chains_get_ft_chain(esw))
|
|
|
d8f823 |
+ return 0;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ err = mapping_add(esw_chains_mapping(esw), &fdb_chain->chain, &index);
|
|
|
d8f823 |
+ if (err)
|
|
|
d8f823 |
+ return err;
|
|
|
d8f823 |
+ if (index == MLX5_FS_DEFAULT_FLOW_TAG) {
|
|
|
d8f823 |
+ /* we got the special default flow tag id, so we won't know
|
|
|
d8f823 |
+ * if we actually marked the packet with the restore rule
|
|
|
d8f823 |
+ * we create.
|
|
|
d8f823 |
+ *
|
|
|
d8f823 |
+ * This case isn't possible with MLX5_FS_DEFAULT_FLOW_TAG = 0.
|
|
|
d8f823 |
+ */
|
|
|
d8f823 |
+ err = mapping_add(esw_chains_mapping(esw),
|
|
|
d8f823 |
+ &fdb_chain->chain, &index);
|
|
|
d8f823 |
+ mapping_remove(esw_chains_mapping(esw),
|
|
|
d8f823 |
+ MLX5_FS_DEFAULT_FLOW_TAG);
|
|
|
d8f823 |
+ if (err)
|
|
|
d8f823 |
+ return err;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ fdb_chain->id = index;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ MLX5_SET(set_action_in, modact, action_type, MLX5_ACTION_TYPE_SET);
|
|
|
d8f823 |
+ MLX5_SET(set_action_in, modact, field,
|
|
|
d8f823 |
+ mlx5e_tc_attr_to_reg_mappings[CHAIN_TO_REG].mfield);
|
|
|
d8f823 |
+ MLX5_SET(set_action_in, modact, offset,
|
|
|
d8f823 |
+ mlx5e_tc_attr_to_reg_mappings[CHAIN_TO_REG].moffset * 8);
|
|
|
d8f823 |
+ MLX5_SET(set_action_in, modact, length,
|
|
|
d8f823 |
+ mlx5e_tc_attr_to_reg_mappings[CHAIN_TO_REG].mlen * 8);
|
|
|
d8f823 |
+ MLX5_SET(set_action_in, modact, data, fdb_chain->id);
|
|
|
d8f823 |
+ mod_hdr = mlx5_modify_header_alloc(esw->dev, MLX5_FLOW_NAMESPACE_FDB,
|
|
|
d8f823 |
+ 1, modact);
|
|
|
d8f823 |
+ if (IS_ERR(mod_hdr)) {
|
|
|
d8f823 |
+ err = PTR_ERR(mod_hdr);
|
|
|
d8f823 |
+ goto err_mod_hdr;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+ fdb_chain->miss_modify_hdr = mod_hdr;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ fdb_chain->restore_rule = esw_add_restore_rule(esw, fdb_chain->id);
|
|
|
d8f823 |
+ if (IS_ERR(fdb_chain->restore_rule)) {
|
|
|
d8f823 |
+ err = PTR_ERR(fdb_chain->restore_rule);
|
|
|
d8f823 |
+ goto err_rule;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ return 0;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+err_rule:
|
|
|
d8f823 |
+ mlx5_modify_header_dealloc(esw->dev, fdb_chain->miss_modify_hdr);
|
|
|
d8f823 |
+err_mod_hdr:
|
|
|
d8f823 |
+ /* Datapath can't find this mapping, so we can safely remove it */
|
|
|
d8f823 |
+ mapping_remove(esw_chains_mapping(esw), fdb_chain->id);
|
|
|
d8f823 |
+ return err;
|
|
|
d8f823 |
+}
|
|
|
d8f823 |
+
|
|
|
d8f823 |
static struct fdb_chain *
|
|
|
d8f823 |
mlx5_esw_chains_create_fdb_chain(struct mlx5_eswitch *esw, u32 chain)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
@@ -272,6 +343,10 @@ mlx5_esw_chains_create_fdb_chain(struct mlx5_eswitch *esw, u32 chain)
|
|
|
d8f823 |
fdb_chain->chain = chain;
|
|
|
d8f823 |
INIT_LIST_HEAD(&fdb_chain->prios_list);
|
|
|
d8f823 |
|
|
|
d8f823 |
+ err = create_fdb_chain_restore(fdb_chain);
|
|
|
d8f823 |
+ if (err)
|
|
|
d8f823 |
+ goto err_restore;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
err = rhashtable_insert_fast(&esw_chains_ht(esw), &fdb_chain->node,
|
|
|
d8f823 |
chain_params);
|
|
|
d8f823 |
if (err)
|
|
|
d8f823 |
@@ -280,6 +355,12 @@ mlx5_esw_chains_create_fdb_chain(struct mlx5_eswitch *esw, u32 chain)
|
|
|
d8f823 |
return fdb_chain;
|
|
|
d8f823 |
|
|
|
d8f823 |
err_insert:
|
|
|
d8f823 |
+ if (fdb_chain->chain != mlx5_esw_chains_get_ft_chain(esw)) {
|
|
|
d8f823 |
+ mlx5_del_flow_rules(fdb_chain->restore_rule);
|
|
|
d8f823 |
+ mlx5_modify_header_dealloc(esw->dev,
|
|
|
d8f823 |
+ fdb_chain->miss_modify_hdr);
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+err_restore:
|
|
|
d8f823 |
kvfree(fdb_chain);
|
|
|
d8f823 |
return ERR_PTR(err);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
@@ -291,6 +372,15 @@ mlx5_esw_chains_destroy_fdb_chain(struct fdb_chain *fdb_chain)
|
|
|
d8f823 |
|
|
|
d8f823 |
rhashtable_remove_fast(&esw_chains_ht(esw), &fdb_chain->node,
|
|
|
d8f823 |
chain_params);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ if (fdb_chain->chain != mlx5_esw_chains_get_ft_chain(esw)) {
|
|
|
d8f823 |
+ mlx5_del_flow_rules(fdb_chain->restore_rule);
|
|
|
d8f823 |
+ mlx5_modify_header_dealloc(esw->dev,
|
|
|
d8f823 |
+ fdb_chain->miss_modify_hdr);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ mapping_remove(esw_chains_mapping(esw), fdb_chain->id);
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
kvfree(fdb_chain);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
@@ -313,10 +403,12 @@ mlx5_esw_chains_get_fdb_chain(struct mlx5_eswitch *esw, u32 chain)
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
static struct mlx5_flow_handle *
|
|
|
d8f823 |
-mlx5_esw_chains_add_miss_rule(struct mlx5_flow_table *fdb,
|
|
|
d8f823 |
+mlx5_esw_chains_add_miss_rule(struct fdb_chain *fdb_chain,
|
|
|
d8f823 |
+ struct mlx5_flow_table *fdb,
|
|
|
d8f823 |
struct mlx5_flow_table *next_fdb)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
static const struct mlx5_flow_spec spec = {};
|
|
|
d8f823 |
+ struct mlx5_eswitch *esw = fdb_chain->esw;
|
|
|
d8f823 |
struct mlx5_flow_destination dest = {};
|
|
|
d8f823 |
struct mlx5_flow_act act = {};
|
|
|
d8f823 |
|
|
|
d8f823 |
@@ -325,6 +417,11 @@ mlx5_esw_chains_add_miss_rule(struct mlx5_flow_table *fdb,
|
|
|
d8f823 |
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
|
|
|
d8f823 |
dest.ft = next_fdb;
|
|
|
d8f823 |
|
|
|
d8f823 |
+ if (fdb_chain->chain != mlx5_esw_chains_get_ft_chain(esw)) {
|
|
|
d8f823 |
+ act.modify_hdr = fdb_chain->miss_modify_hdr;
|
|
|
d8f823 |
+ act.action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
return mlx5_add_flow_rules(fdb, &spec, &act, &dest, 1);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
@@ -348,7 +445,8 @@ mlx5_esw_chains_update_prio_prevs(struct fdb_prio *fdb_prio,
|
|
|
d8f823 |
list_for_each_entry_continue_reverse(pos,
|
|
|
d8f823 |
&fdb_chain->prios_list,
|
|
|
d8f823 |
list) {
|
|
|
d8f823 |
- miss_rules[n] = mlx5_esw_chains_add_miss_rule(pos->fdb,
|
|
|
d8f823 |
+ miss_rules[n] = mlx5_esw_chains_add_miss_rule(fdb_chain,
|
|
|
d8f823 |
+ pos->fdb,
|
|
|
d8f823 |
next_fdb);
|
|
|
d8f823 |
if (IS_ERR(miss_rules[n])) {
|
|
|
d8f823 |
err = PTR_ERR(miss_rules[n]);
|
|
|
d8f823 |
@@ -462,7 +560,7 @@ mlx5_esw_chains_create_fdb_prio(struct mlx5_eswitch *esw,
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
/* Add miss rule to next_fdb */
|
|
|
d8f823 |
- miss_rule = mlx5_esw_chains_add_miss_rule(fdb, next_fdb);
|
|
|
d8f823 |
+ miss_rule = mlx5_esw_chains_add_miss_rule(fdb_chain, fdb, next_fdb);
|
|
|
d8f823 |
if (IS_ERR(miss_rule)) {
|
|
|
d8f823 |
err = PTR_ERR(miss_rule);
|
|
|
d8f823 |
goto err_miss_rule;
|
|
|
d8f823 |
@@ -627,6 +725,7 @@ mlx5_esw_chains_init(struct mlx5_eswitch *esw)
|
|
|
d8f823 |
struct mlx5_esw_chains_priv *chains_priv;
|
|
|
d8f823 |
struct mlx5_core_dev *dev = esw->dev;
|
|
|
d8f823 |
u32 max_flow_counter, fdb_max;
|
|
|
d8f823 |
+ struct mapping_ctx *mapping;
|
|
|
d8f823 |
int err;
|
|
|
d8f823 |
|
|
|
d8f823 |
chains_priv = kzalloc(sizeof(*chains_priv), GFP_KERNEL);
|
|
|
d8f823 |
@@ -663,10 +762,20 @@ mlx5_esw_chains_init(struct mlx5_eswitch *esw)
|
|
|
d8f823 |
if (err)
|
|
|
d8f823 |
goto init_prios_ht_err;
|
|
|
d8f823 |
|
|
|
d8f823 |
+ mapping = mapping_create(sizeof(u32), esw_get_max_restore_tag(esw),
|
|
|
d8f823 |
+ true);
|
|
|
d8f823 |
+ if (IS_ERR(mapping)) {
|
|
|
d8f823 |
+ err = PTR_ERR(mapping);
|
|
|
d8f823 |
+ goto mapping_err;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+ esw_chains_mapping(esw) = mapping;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
mutex_init(&esw_chains_lock(esw));
|
|
|
d8f823 |
|
|
|
d8f823 |
return 0;
|
|
|
d8f823 |
|
|
|
d8f823 |
+mapping_err:
|
|
|
d8f823 |
+ rhashtable_destroy(&esw_prios_ht(esw));
|
|
|
d8f823 |
init_prios_ht_err:
|
|
|
d8f823 |
rhashtable_destroy(&esw_chains_ht(esw));
|
|
|
d8f823 |
init_chains_ht_err:
|
|
|
d8f823 |
@@ -678,6 +787,7 @@ static void
|
|
|
d8f823 |
mlx5_esw_chains_cleanup(struct mlx5_eswitch *esw)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
mutex_destroy(&esw_chains_lock(esw));
|
|
|
d8f823 |
+ mapping_destroy(esw_chains_mapping(esw));
|
|
|
d8f823 |
rhashtable_destroy(&esw_prios_ht(esw));
|
|
|
d8f823 |
rhashtable_destroy(&esw_chains_ht(esw));
|
|
|
d8f823 |
|
|
|
d8f823 |
@@ -756,3 +866,17 @@ mlx5_esw_chains_destroy(struct mlx5_eswitch *esw)
|
|
|
d8f823 |
mlx5_esw_chains_close(esw);
|
|
|
d8f823 |
mlx5_esw_chains_cleanup(esw);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+int mlx5_eswitch_get_chain_for_tag(struct mlx5_eswitch *esw, u32 tag,
|
|
|
d8f823 |
+ u32 *chain)
|
|
|
d8f823 |
+{
|
|
|
d8f823 |
+ int err;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ err = mapping_find(esw_chains_mapping(esw), tag, chain);
|
|
|
d8f823 |
+ if (err) {
|
|
|
d8f823 |
+ esw_warn(esw->dev, "Can't find chain for tag: %d\n", tag);
|
|
|
d8f823 |
+ return -ENOENT;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ return 0;
|
|
|
d8f823 |
+}
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.h
|
|
|
d8f823 |
index 4ae2baf2a7a1..e806d8de868e 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.h
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_chains.h
|
|
|
d8f823 |
@@ -28,5 +28,7 @@ mlx5_esw_chains_get_tc_end_ft(struct mlx5_eswitch *esw);
|
|
|
d8f823 |
int mlx5_esw_chains_create(struct mlx5_eswitch *esw);
|
|
|
d8f823 |
void mlx5_esw_chains_destroy(struct mlx5_eswitch *esw);
|
|
|
d8f823 |
|
|
|
d8f823 |
-#endif /* __ML5_ESW_CHAINS_H__ */
|
|
|
d8f823 |
+int
|
|
|
d8f823 |
+mlx5_eswitch_get_chain_for_tag(struct mlx5_eswitch *esw, u32 tag, u32 *chain);
|
|
|
d8f823 |
|
|
|
d8f823 |
+#endif /* __ML5_ESW_CHAINS_H__ */
|
|
|
d8f823 |
--
|
|
|
d8f823 |
2.13.6
|
|
|
d8f823 |
|