Commit b8922a73 authored by Saeed Mahameed's avatar Saeed Mahameed
Browse files

net/mlx5e: API to manipulate TTC rules destinations



Store the default destinations of the on-load generated TTC
(Traffic Type Classifier) rules in the ttc rules table.

Introduce TTC API functions to manipulate/restore and get the TTC rule
destination and use these API functions in arfs implementation.

This will allow a better decoupling between TTC implementation and its
users.

Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Reviewed-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
parent c293ac92
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -105,10 +105,15 @@ enum mlx5e_tunnel_types {

bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev);

struct mlx5e_ttc_rule {
	struct mlx5_flow_handle *rule;
	struct mlx5_flow_destination default_dest;
};

/* L3/L4 traffic type classifier */
struct mlx5e_ttc_table {
	struct mlx5e_flow_table ft;
	struct mlx5_flow_handle	 *rules[MLX5E_NUM_TT];
	struct mlx5e_ttc_rule rules[MLX5E_NUM_TT];
	struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
};

@@ -248,6 +253,11 @@ void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
				   struct mlx5e_ttc_table *ttc);

void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
		       struct mlx5_flow_destination *new_dest);
struct mlx5_flow_destination
mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);
int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);

void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
+12 −22
Original line number Diff line number Diff line
@@ -90,23 +90,15 @@ static enum mlx5e_traffic_types arfs_get_tt(enum arfs_type type)

static int arfs_disable(struct mlx5e_priv *priv)
{
	struct mlx5_flow_destination dest = {};
	struct mlx5e_tir *tir = priv->indir_tir;
	int err = 0;
	int tt;
	int i;
	int err, i;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
	for (i = 0; i < ARFS_NUM_TYPES; i++) {
		dest.tir_num = tir[i].tirn;
		tt = arfs_get_tt(i);
		/* Modify ttc rules destination to bypass the aRFS tables*/
		err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
						   &dest, NULL);
		/* Modify ttc rules destination back to their default */
		err = mlx5e_ttc_fwd_default_dest(priv, arfs_get_tt(i));
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc destination failed\n",
				   __func__);
				   "%s: modify ttc[%d] default destination failed, err(%d)\n",
				   __func__, arfs_get_tt(i), err);
			return err;
		}
	}
@@ -125,21 +117,17 @@ int mlx5e_arfs_disable(struct mlx5e_priv *priv)
int mlx5e_arfs_enable(struct mlx5e_priv *priv)
{
	struct mlx5_flow_destination dest = {};
	int err = 0;
	int tt;
	int i;
	int err, i;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	for (i = 0; i < ARFS_NUM_TYPES; i++) {
		dest.ft = priv->fs.arfs.arfs_tables[i].ft.t;
		tt = arfs_get_tt(i);
		/* Modify ttc rules destination to point on the aRFS FTs */
		err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
						   &dest, NULL);
		err = mlx5e_ttc_fwd_dest(priv, arfs_get_tt(i), &dest);
		if (err) {
			netdev_err(priv->netdev,
				   "%s: modify ttc destination failed err=%d\n",
				   __func__, err);
				   "%s: modify ttc[%d] dest to arfs, failed err(%d)\n",
				   __func__, arfs_get_tt(i), err);
			arfs_disable(priv);
			return err;
		}
@@ -186,8 +174,10 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
		return -EINVAL;
	}

	/* FIXME: Must use mlx5e_ttc_get_default_dest(),
	 * but can't since TTC default is not setup yet !
	 */
	dest.tir_num = tir[tt].tirn;

	arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, NULL,
						   &flow_act,
						   &dest, 1);
+61 −23
Original line number Diff line number Diff line
@@ -672,9 +672,9 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
	int i;

	for (i = 0; i < MLX5E_NUM_TT; i++) {
		if (!IS_ERR_OR_NULL(ttc->rules[i])) {
			mlx5_del_flow_rules(ttc->rules[i]);
			ttc->rules[i] = NULL;
		if (!IS_ERR_OR_NULL(ttc->rules[i].rule)) {
			mlx5_del_flow_rules(ttc->rules[i].rule);
			ttc->rules[i].rule = NULL;
		}
	}

@@ -857,7 +857,8 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
					  struct mlx5e_ttc_table *ttc)
{
	struct mlx5_flow_destination dest = {};
	struct mlx5_flow_handle **rules;
	struct mlx5_flow_handle **trules;
	struct mlx5e_ttc_rule *rules;
	struct mlx5_flow_table *ft;
	int tt;
	int err;
@@ -867,39 +868,47 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,

	dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
	for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
		struct mlx5e_ttc_rule *rule = &rules[tt];

		if (tt == MLX5E_TT_ANY)
			dest.tir_num = params->any_tt_tirn;
		else
			dest.tir_num = params->indir_tirn[tt];
		rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,

		rule->rule = mlx5e_generate_ttc_rule(priv, ft, &dest,
						     ttc_rules[tt].etype,
						     ttc_rules[tt].proto);
		if (IS_ERR(rules[tt]))
		if (IS_ERR(rule->rule)) {
			err = PTR_ERR(rule->rule);
			rule->rule = NULL;
			goto del_rules;
		}
		rule->default_dest = dest;
	}

	if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
		return 0;

	rules     = ttc->tunnel_rules;
	trules    = ttc->tunnel_rules;
	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	dest.ft   = params->inner_ttc->ft.t;
	for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
		if (!mlx5e_tunnel_proto_supported(priv->mdev,
						  ttc_tunnel_rules[tt].proto))
			continue;
		rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
		trules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
						     ttc_tunnel_rules[tt].etype,
						     ttc_tunnel_rules[tt].proto);
		if (IS_ERR(rules[tt]))
		if (IS_ERR(trules[tt])) {
			err = PTR_ERR(trules[tt]);
			trules[tt] = NULL;
			goto del_rules;
		}
	}

	return 0;

del_rules:
	err = PTR_ERR(rules[tt]);
	rules[tt] = NULL;
	mlx5e_cleanup_ttc_rules(ttc);
	return err;
}
@@ -1015,33 +1024,38 @@ static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv,
						struct mlx5e_ttc_table *ttc)
{
	struct mlx5_flow_destination dest = {};
	struct mlx5_flow_handle **rules;
	struct mlx5e_ttc_rule *rules;
	struct mlx5_flow_table *ft;
	int err;
	int tt;

	ft = ttc->ft.t;
	rules = ttc->rules;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;

	for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
		struct mlx5e_ttc_rule *rule = &rules[tt];

		if (tt == MLX5E_TT_ANY)
			dest.tir_num = params->any_tt_tirn;
		else
			dest.tir_num = params->indir_tirn[tt];

		rules[tt] = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
		rule->rule = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
							   ttc_rules[tt].etype,
							   ttc_rules[tt].proto);
		if (IS_ERR(rules[tt]))
		if (IS_ERR(rule->rule)) {
			err = PTR_ERR(rule->rule);
			rule->rule = NULL;
			goto del_rules;
		}
		rule->default_dest = dest;
	}

	return 0;

del_rules:
	err = PTR_ERR(rules[tt]);
	rules[tt] = NULL;

	mlx5e_cleanup_ttc_rules(ttc);
	return err;
}
@@ -1210,6 +1224,30 @@ err:
	return err;
}

int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
		       struct mlx5_flow_destination *new_dest)
{
	return mlx5_modify_rule_destination(priv->fs.ttc.rules[type].rule, new_dest, NULL);
}

struct mlx5_flow_destination
mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
{
	struct mlx5_flow_destination *dest = &priv->fs.ttc.rules[type].default_dest;

	WARN_ONCE(dest->type != MLX5_FLOW_DESTINATION_TYPE_TIR,
		  "TTC[%d] default dest is not setup yet", type);

	return *dest;
}

int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
{
	struct mlx5_flow_destination dest = mlx5e_ttc_get_default_dest(priv, type);

	return mlx5e_ttc_fwd_dest(priv, type, &dest);
}

static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
				   struct mlx5e_l2_rule *ai)
{