Commit 4892bd98 authored by Mark Bloch's avatar Mark Bloch Committed by Saeed Mahameed
Browse files

net/mlx5: Lag, decouple FDB selection and shared FDB



Multiport eswitch is required to use native FDB selection instead of
affinity, This was achieved by passing the shared_fdb flag down
the HW lag creation path. While it did accomplish the goal of setting
FDB selection mode to native, it had the side effect of also
creating a shared FDB configuration.

This created a few issues:
- TC rules are inserted into a non active FDB, which means traffic isn't
  offloaded as all traffic will reach only a single FDB.
- All wire traffic is treated as if a single physical port received it; while
  this is true for a bond configuration, this shouldn't be the case for
  multiport eswitch.

Create a new flag MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE
to indicate what FDB selection mode should be used.

Fixes: 94db3317 ("net/mlx5: Support multiport eswitch mode")
Signed-off-by: default avatarMark Bloch <mbloch@nvidia.com>
Reviewed-by: default avatarEli Cohen <elic@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent d6c13d74
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ static int state_show(struct seq_file *file, void *priv)
static int flags_show(struct seq_file *file, void *priv)
{
	struct mlx5_core_dev *dev = file->private;
	bool fdb_sel_mode_native;
	struct mlx5_lag *ldev;
	bool shared_fdb;
	bool lag_active;
@@ -79,14 +80,21 @@ static int flags_show(struct seq_file *file, void *priv)
	ldev = dev->priv.lag;
	mutex_lock(&ldev->lock);
	lag_active = __mlx5_lag_is_active(ldev);
	if (lag_active)
	if (!lag_active)
		goto unlock;

	shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
	fdb_sel_mode_native = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
				       &ldev->mode_flags);

unlock:
	mutex_unlock(&ldev->lock);
	if (!lag_active)
		return -EINVAL;

	seq_printf(file, "%s:%s\n", "shared_fdb", shared_fdb ? "on" : "off");
	seq_printf(file, "%s:%s\n", "fdb_selection_mode",
		   fdb_sel_mode_native ? "native" : "affinity");
	return 0;
}

+9 −3
Original line number Diff line number Diff line
@@ -68,14 +68,15 @@ static int get_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, u8 *ports, int mode,
			       unsigned long flags)
{
	bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
	bool fdb_sel_mode = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
				     &flags);
	int port_sel_mode = get_port_sel_mode(mode, flags);
	u32 in[MLX5_ST_SZ_DW(create_lag_in)] = {};
	void *lag_ctx;

	lag_ctx = MLX5_ADDR_OF(create_lag_in, in, ctx);
	MLX5_SET(create_lag_in, in, opcode, MLX5_CMD_OP_CREATE_LAG);
	MLX5_SET(lagc, lag_ctx, fdb_selection_mode, shared_fdb);
	MLX5_SET(lagc, lag_ctx, fdb_selection_mode, fdb_sel_mode);
	if (port_sel_mode == MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY) {
		MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[0]);
		MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[1]);
@@ -471,8 +472,13 @@ static int mlx5_lag_set_flags(struct mlx5_lag *ldev, enum mlx5_lag_mode mode,
	bool roce_lag = mode == MLX5_LAG_MODE_ROCE;

	*flags = 0;
	if (shared_fdb)
	if (shared_fdb) {
		set_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, flags);
		set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
	}

	if (mode == MLX5_LAG_MODE_MPESW)
		set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);

	if (roce_lag)
		return mlx5_lag_set_port_sel_mode_roce(ldev, flags);
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ enum {
enum {
	MLX5_LAG_MODE_FLAG_HASH_BASED,
	MLX5_LAG_MODE_FLAG_SHARED_FDB,
	MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
};

enum mlx5_lag_mode {
+2 −3
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
{
	struct mlx5_lag *ldev = dev->priv.lag;
	bool shared_fdb;
	int err = 0;

	if (!ldev)
@@ -55,8 +54,8 @@ int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
		err = -EINVAL;
		goto out;
	}
	shared_fdb = mlx5_shared_fdb_supported(ldev);
	err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, shared_fdb);

	err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
	if (err)
		mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);