Commit b1e5dfa6 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-mlx5e-support-rss-for-ipsec-offload'

Tariq Toukan says:

====================
net/mlx5e: Support RSS for IPSec offload

The series by Jianbo uses a new firmware feature to identify the inner
protocol of decrypted packets, adding new flow groups and steering rules
to redirect them for proper L4-based RSS. This ensures traffic is spread
across multiple CPU cores.
====================

Link: https://patch.msgid.link/1758179963-649455-1-git-send-email-tariqt@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3fb4f35a 72ed3ebf
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ struct mlx5e_l2_table {
	bool                       promisc_enabled;
};

#define MLX5E_NUM_INDIR_TIRS (MLX5_NUM_TT - 1)
#define MLX5E_NUM_INDIR_TIRS (MLX5_NUM_INDIR_TIRS)

#define MLX5_HASH_IP		(MLX5_HASH_FIELD_SEL_SRC_IP   |\
				 MLX5_HASH_FIELD_SEL_DST_IP)
@@ -132,7 +132,8 @@ struct mlx5e_ptp_fs;

void mlx5e_set_ttc_params(struct mlx5e_flow_steering *fs,
			  struct mlx5e_rx_res *rx_res,
			  struct ttc_params *ttc_params, bool tunnel);
			  struct ttc_params *ttc_params, bool tunnel,
			  bool ipsec_rss);

void mlx5e_destroy_ttc_table(struct mlx5e_flow_steering *fs);
int mlx5e_create_ttc_table(struct mlx5e_flow_steering  *fs,
+32 −8
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ struct mlx5e_ipsec_rx {
	struct mlx5_flow_table *pol_miss_ft;
	struct mlx5_flow_handle *pol_miss_rule;
	u8 allow_tunnel_mode : 1;
	u8 ttc_rules_added : 1;
};

/* IPsec RX flow steering */
@@ -585,6 +586,20 @@ static int ipsec_miss_create(struct mlx5_core_dev *mdev,
	return err;
}

static struct mlx5_flow_destination
ipsec_rx_decrypted_pkt_def_dest(struct mlx5_ttc_table *ttc, u32 family)
{
	struct mlx5_flow_destination dest;

	if (!mlx5_ttc_has_esp_flow_group(ttc))
		return mlx5_ttc_get_default_dest(ttc, family2tt(family));

	dest.ft = mlx5_get_ttc_flow_table(ttc);
	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;

	return dest;
}

static void ipsec_rx_update_default_dest(struct mlx5e_ipsec_rx *rx,
					 struct mlx5_flow_destination *old_dest,
					 struct mlx5_flow_destination *new_dest)
@@ -598,10 +613,10 @@ static void handle_ipsec_rx_bringup(struct mlx5e_ipsec *ipsec, u32 family)
{
	struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, XFRM_DEV_OFFLOAD_PACKET);
	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(ipsec->fs, false);
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
	struct mlx5_flow_destination old_dest, new_dest;

	old_dest = mlx5_ttc_get_default_dest(mlx5e_fs_get_ttc(ipsec->fs, false),
					     family2tt(family));
	old_dest = ipsec_rx_decrypted_pkt_def_dest(ttc, family);

	mlx5_ipsec_fs_roce_rx_create(ipsec->mdev, ipsec->roce, ns, &old_dest, family,
				     MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL, MLX5E_NIC_PRIO);
@@ -614,12 +629,12 @@ static void handle_ipsec_rx_bringup(struct mlx5e_ipsec *ipsec, u32 family)
static void handle_ipsec_rx_cleanup(struct mlx5e_ipsec *ipsec, u32 family)
{
	struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, XFRM_DEV_OFFLOAD_PACKET);
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
	struct mlx5_flow_destination old_dest, new_dest;

	old_dest.ft = mlx5_ipsec_fs_roce_ft_get(ipsec->roce, family);
	old_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	new_dest = mlx5_ttc_get_default_dest(mlx5e_fs_get_ttc(ipsec->fs, false),
					     family2tt(family));
	new_dest = ipsec_rx_decrypted_pkt_def_dest(ttc, family);
	ipsec_rx_update_default_dest(rx, &old_dest, &new_dest);

	mlx5_ipsec_fs_roce_rx_destroy(ipsec->roce, family, ipsec->mdev);
@@ -669,10 +684,13 @@ static void ipsec_mpv_work_handler(struct work_struct *_work)
	complete(&work->master_priv->ipsec->comp);
}

static void ipsec_rx_ft_disconnect(struct mlx5e_ipsec *ipsec, u32 family)
static void ipsec_rx_ft_disconnect(struct mlx5e_ipsec *ipsec,
				   struct mlx5e_ipsec_rx *rx, u32 family)
{
	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);

	if (rx->ttc_rules_added)
		mlx5_ttc_destroy_ipsec_rules(ttc);
	mlx5_ttc_fwd_default_dest(ttc, family2tt(family));
}

@@ -707,7 +725,7 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
{
	/* disconnect */
	if (rx != ipsec->rx_esw)
		ipsec_rx_ft_disconnect(ipsec, family);
		ipsec_rx_ft_disconnect(ipsec, rx, family);

	mlx5_del_flow_rules(rx->sa.rule);
	mlx5_destroy_flow_group(rx->sa.group);
@@ -764,7 +782,7 @@ static int ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec,
	if (rx == ipsec->rx_esw)
		return mlx5_esw_ipsec_rx_status_pass_dest_get(ipsec, dest);

	*dest = mlx5_ttc_get_default_dest(attr->ttc, family2tt(attr->family));
	*dest = ipsec_rx_decrypted_pkt_def_dest(attr->ttc, attr->family);
	err = mlx5_ipsec_fs_roce_rx_create(ipsec->mdev, ipsec->roce, attr->ns, dest,
					   attr->family, MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
					   attr->prio);
@@ -807,10 +825,16 @@ static void ipsec_rx_ft_connect(struct mlx5e_ipsec *ipsec,
				struct mlx5e_ipsec_rx_create_attr *attr)
{
	struct mlx5_flow_destination dest = {};
	struct mlx5_ttc_table *ttc, *inner_ttc;

	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
	dest.ft = rx->ft.sa;
	mlx5_ttc_fwd_dest(attr->ttc, family2tt(attr->family), &dest);
	if (mlx5_ttc_fwd_dest(attr->ttc, family2tt(attr->family), &dest))
		return;

	ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
	inner_ttc = mlx5e_fs_get_ttc(ipsec->fs, true);
	rx->ttc_rules_added = !mlx5_ttc_create_ipsec_rules(ttc, inner_ttc);
}

static int ipsec_rx_chains_create_miss(struct mlx5e_ipsec *ipsec,
+19 −2
Original line number Diff line number Diff line
@@ -905,6 +905,9 @@ static void mlx5e_set_inner_ttc_params(struct mlx5e_flow_steering *fs,
	ft_attr->prio = MLX5E_NIC_PRIO;

	for (tt = 0; tt < MLX5_NUM_TT; tt++) {
		if (mlx5_ttc_is_decrypted_esp_tt(tt))
			continue;

		ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
		ttc_params->dests[tt].tir_num =
			tt == MLX5_TT_ANY ?
@@ -914,9 +917,17 @@ static void mlx5e_set_inner_ttc_params(struct mlx5e_flow_steering *fs,
	}
}

static bool mlx5e_ipsec_rss_supported(struct mlx5_core_dev *mdev)
{
	return MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, ipsec_next_header) &&
	       MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, outer_l4_type_ext) &&
	       MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, inner_l4_type_ext);
}

void mlx5e_set_ttc_params(struct mlx5e_flow_steering *fs,
			  struct mlx5e_rx_res *rx_res,
			  struct ttc_params *ttc_params, bool tunnel)
			  struct ttc_params *ttc_params, bool tunnel,
			  bool ipsec_rss)

{
	struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr;
@@ -927,7 +938,13 @@ void mlx5e_set_ttc_params(struct mlx5e_flow_steering *fs,
	ft_attr->level = MLX5E_TTC_FT_LEVEL;
	ft_attr->prio = MLX5E_NIC_PRIO;

	ttc_params->ipsec_rss = ipsec_rss &&
				mlx5e_ipsec_rss_supported(fs->mdev);

	for (tt = 0; tt < MLX5_NUM_TT; tt++) {
		if (mlx5_ttc_is_decrypted_esp_tt(tt))
			continue;

		ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
		ttc_params->dests[tt].tir_num =
			tt == MLX5_TT_ANY ?
@@ -1293,7 +1310,7 @@ int mlx5e_create_ttc_table(struct mlx5e_flow_steering *fs,
{
	struct ttc_params ttc_params = {};

	mlx5e_set_ttc_params(fs, rx_res, &ttc_params, true);
	mlx5e_set_ttc_params(fs, rx_res, &ttc_params, true, true);
	fs->ttc = mlx5_create_ttc_table(fs->mdev, &ttc_params);
	return PTR_ERR_OR_ZERO(fs->ttc);
}
+1 −1
Original line number Diff line number Diff line
@@ -974,7 +974,7 @@ static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
						MLX5_FLOW_NAMESPACE_KERNEL), false);

	/* The inner_ttc in the ttc params is intentionally not set */
	mlx5e_set_ttc_params(priv->fs, priv->rx_res, &ttc_params, false);
	mlx5e_set_ttc_params(priv->fs, priv->rx_res, &ttc_params, false, false);

	if (rep->vport != MLX5_VPORT_UPLINK)
		/* To give uplik rep TTC a lower level for chaining from root ft */
+3 −0
Original line number Diff line number Diff line
@@ -838,6 +838,9 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,

	ttc_params->ns_type = MLX5_FLOW_NAMESPACE_KERNEL;
	for (tt = 0; tt < MLX5_NUM_TT; tt++) {
		if (mlx5_ttc_is_decrypted_esp_tt(tt))
			continue;

		ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
		ttc_params->dests[tt].tir_num =
			tt == MLX5_TT_ANY ?
Loading