Commit a91d98a0 authored by Chris Mi's avatar Chris Mi Committed by Saeed Mahameed
Browse files

net/mlx5: Map register values to restore objects



Currently reg_c0 lower 16 bits and reg_b are used to store the chain
id that missed in FDB and NIC tables accordingly. However, the
registers' values may index a restore object, rather than a single u32
value. Different object types can be used to restore mutually exclusive
contexts such as chain id and sample group id.

Use the mapping object to associate an index with a restore object
as a prestep for supporting additional restore types.

Signed-off-by: default avatarChris Mi <cmi@nvidia.com>
Reviewed-by: default avatarOz Shlomo <ozsh@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c1904360
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -618,9 +618,10 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
			     struct mlx5e_tc_update_priv *tc_priv)
{
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
	u32 chain = 0, reg_c0, reg_c1, tunnel_id, zone_restore_id;
	u32 reg_c0, reg_c1, tunnel_id, zone_restore_id;
	struct mlx5_rep_uplink_priv *uplink_priv;
	struct mlx5e_rep_priv *uplink_rpriv;
	struct mlx5_mapped_obj mapped_obj;
	struct tc_skb_ext *tc_skb_ext;
	struct mlx5_eswitch *esw;
	struct mlx5e_priv *priv;
@@ -640,22 +641,23 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
	priv = netdev_priv(skb->dev);
	esw = priv->mdev->priv.eswitch;

	err = mlx5_get_chain_for_tag(esw_chains(esw), reg_c0, &chain);
	err = mlx5_get_mapped_object(esw_chains(esw), reg_c0, &mapped_obj);
	if (err) {
		netdev_dbg(priv->netdev,
			   "Couldn't find chain for chain tag: %d, err: %d\n",
			   "Couldn't find mapped object for reg_c0: %d, err: %d\n",
			   reg_c0, err);
		return false;
	}

	if (chain) {
	if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) {
		if (mapped_obj.chain) {
			tc_skb_ext = skb_ext_add(skb, TC_SKB_EXT);
			if (!tc_skb_ext) {
				WARN_ON(1);
				return false;
			}

		tc_skb_ext->chain = chain;
			tc_skb_ext->chain = mapped_obj.chain;

			zone_restore_id = reg_c1 & ESW_ZONE_ID_MASK;

@@ -665,6 +667,10 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
						      zone_restore_id))
				return false;
		}
	} else {
		netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type);
		return false;
	}

	tunnel_id = reg_c1 >> ESW_TUN_OFFSET;
	return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id);
+7 −2
Original line number Diff line number Diff line
@@ -4973,6 +4973,7 @@ bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe,
	u32 chain = 0, chain_tag, reg_b, zone_restore_id;
	struct mlx5e_priv *priv = netdev_priv(skb->dev);
	struct mlx5e_tc_table *tc = &priv->fs.tc;
	struct mlx5_mapped_obj mapped_obj;
	struct tc_skb_ext *tc_skb_ext;
	int err;

@@ -4980,7 +4981,7 @@ bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe,

	chain_tag = reg_b & MLX5E_TC_TABLE_CHAIN_TAG_MASK;

	err = mlx5_get_chain_for_tag(nic_chains(priv), chain_tag, &chain);
	err = mlx5_get_mapped_object(nic_chains(priv), chain_tag, &mapped_obj);
	if (err) {
		netdev_dbg(priv->netdev,
			   "Couldn't find chain for chain tag: %d, err: %d\n",
@@ -4988,7 +4989,8 @@ bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe,
		return false;
	}

	if (chain) {
	if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) {
		chain = mapped_obj.chain;
		tc_skb_ext = skb_ext_add(skb, TC_SKB_EXT);
		if (WARN_ON(!tc_skb_ext))
			return false;
@@ -5001,6 +5003,9 @@ bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe,
		if (!mlx5e_tc_ct_restore_flow(tc->ct, skb,
					      zone_restore_id))
			return false;
	} else {
		netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type);
		return false;
	}
#endif /* CONFIG_NET_TC_SKB_EXT */

+11 −2
Original line number Diff line number Diff line
@@ -47,6 +47,17 @@
#include "sf/sf.h"
#include "en/tc_ct.h"

enum mlx5_mapped_obj_type {
	MLX5_MAPPED_OBJ_CHAIN,
};

struct mlx5_mapped_obj {
	enum mlx5_mapped_obj_type type;
	union {
		u32 chain;
	};
};

#ifdef CONFIG_MLX5_ESWITCH

#define ESW_OFFLOADS_DEFAULT_NUM_GROUPS 15
@@ -733,8 +744,6 @@ mlx5_esw_vporttbl_put(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr

struct mlx5_flow_handle *
esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag);
u32
esw_get_max_restore_tag(struct mlx5_eswitch *esw);

int esw_offloads_load_rep(struct mlx5_eswitch *esw, u16 vport_num);
void esw_offloads_unload_rep(struct mlx5_eswitch *esw, u16 vport_num);
+4 −10
Original line number Diff line number Diff line
@@ -1286,7 +1286,7 @@ esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag)
	misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
			    misc_parameters_2);
	MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
		 ESW_CHAIN_TAG_METADATA_MASK);
		 ESW_REG_C0_USER_DATA_METADATA_MASK);
	misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
			    misc_parameters_2);
	MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0, tag);
@@ -1312,12 +1312,6 @@ esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag)
	return flow_rule;
}

u32
esw_get_max_restore_tag(struct mlx5_eswitch *esw)
{
	return ESW_CHAIN_TAG_METADATA_MASK;
}

#define MAX_PF_SQ 256
#define MAX_SQ_NVPORTS 32

@@ -1434,7 +1428,7 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb)
	attr.max_ft_sz = fdb_max;
	attr.max_grp_num = esw->params.large_group_num;
	attr.default_ft = miss_fdb;
	attr.max_restore_tag = esw_get_max_restore_tag(esw);
	attr.max_restore_tag = ESW_REG_C0_USER_DATA_METADATA_MASK;

	chains = mlx5_chains_create(dev, &attr);
	if (IS_ERR(chains)) {
@@ -1928,7 +1922,7 @@ static int esw_create_restore_table(struct mlx5_eswitch *esw)
		goto out_free;
	}

	ft_attr.max_fte = 1 << ESW_CHAIN_TAG_METADATA_BITS;
	ft_attr.max_fte = 1 << ESW_REG_C0_USER_DATA_METADATA_BITS;
	ft = mlx5_create_flow_table(ns, &ft_attr);
	if (IS_ERR(ft)) {
		err = PTR_ERR(ft);
@@ -1943,7 +1937,7 @@ static int esw_create_restore_table(struct mlx5_eswitch *esw)
			    misc_parameters_2);

	MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
		 ESW_CHAIN_TAG_METADATA_MASK);
		 ESW_REG_C0_USER_DATA_METADATA_MASK);
	MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
	MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index,
		 ft_attr.max_fte - 1);
+13 −7
Original line number Diff line number Diff line
@@ -832,8 +832,7 @@ mlx5_chains_init(struct mlx5_core_dev *dev, struct mlx5_chains_attr *attr)
	if (err)
		goto init_prios_ht_err;

	mapping = mapping_create(sizeof(u32), attr->max_restore_tag,
				 true);
	mapping = mapping_create(sizeof(struct mlx5_mapped_obj), attr->max_restore_tag, true);
	if (IS_ERR(mapping)) {
		err = PTR_ERR(mapping);
		goto mapping_err;
@@ -884,21 +883,28 @@ int
mlx5_chains_get_chain_mapping(struct mlx5_fs_chains *chains, u32 chain,
			      u32 *chain_mapping)
{
	return mapping_add(chains_mapping(chains), &chain, chain_mapping);
	struct mapping_ctx *ctx = chains->chains_mapping;
	struct mlx5_mapped_obj mapped_obj = {};

	mapped_obj.type = MLX5_MAPPED_OBJ_CHAIN;
	mapped_obj.chain = chain;
	return mapping_add(ctx, &mapped_obj, chain_mapping);
}

int
mlx5_chains_put_chain_mapping(struct mlx5_fs_chains *chains, u32 chain_mapping)
{
	return mapping_remove(chains_mapping(chains), chain_mapping);
	struct mapping_ctx *ctx = chains->chains_mapping;

	return mapping_remove(ctx, chain_mapping);
}

int mlx5_get_chain_for_tag(struct mlx5_fs_chains *chains, u32 tag,
			   u32 *chain)
int
mlx5_get_mapped_object(struct mlx5_fs_chains *chains, u32 tag, struct mlx5_mapped_obj *obj)
{
	int err;

	err = mapping_find(chains_mapping(chains), tag, chain);
	err = mapping_find(chains->chains_mapping, tag, obj);
	if (err) {
		mlx5_core_warn(chains->dev, "Can't find chain for tag: %d\n", tag);
		return -ENOENT;
Loading