Commit eff849b2 authored by Rabie Loulou's avatar Rabie Loulou Committed by Saeed Mahameed
Browse files

net/mlx5: Allow/disallow LAG according to pre-req only



Remove the lag forbid/allow functions, change the lag prereq check to
run in the do-bond logic, so every change in the prereq state will
cause LAG to be disabled/enabled accordingly after the next do-bond run.

Add lag update function, so every component which changes the prereq
state and want the LAG to re-calc the conditions can call the update
function.

Signed-off-by: default avatarRabie Loulou <rabiel@mellanox.com>
Signed-off-by: default avatarAviv Heller <avivh@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 3b5ff59f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1632,6 +1632,8 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
	esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode);
	esw->mode = mode;

	mlx5_lag_update(esw->dev);

	if (mode == SRIOV_LEGACY) {
		err = esw_create_legacy_fdb_table(esw);
	} else {
@@ -1708,6 +1710,8 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
	old_mode = esw->mode;
	esw->mode = SRIOV_NONE;

	mlx5_lag_update(esw->dev);

	if (old_mode == SRIOV_OFFLOADS)
		mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
}
@@ -2225,3 +2229,12 @@ u8 mlx5_eswitch_mode(struct mlx5_eswitch *esw)
	return ESW_ALLOWED(esw) ? esw->mode : SRIOV_NONE;
}
EXPORT_SYMBOL_GPL(mlx5_eswitch_mode);

bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1)
{
	if (dev0->priv.eswitch->mode == SRIOV_NONE &&
	    dev1->priv.eswitch->mode == SRIOV_NONE)
		return true;

	return false;
}
+4 −0
Original line number Diff line number Diff line
@@ -351,6 +351,9 @@ static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev
		MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan_2);
}

bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0,
			 struct mlx5_core_dev *dev1);

#define MLX5_DEBUG_ESWITCH_MASK BIT(3)

#define esw_info(dev, format, ...)				\
@@ -367,6 +370,7 @@ static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
static inline int  mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; }
static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {}
static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; }

#define FDB_MAX_CHAIN 1
#define FDB_SLOW_PATH_CHAIN (FDB_MAX_CHAIN + 1)
+16 −46
Original line number Diff line number Diff line
@@ -62,11 +62,6 @@ struct mlx5_lag {
	struct lag_tracker        tracker;
	struct delayed_work       bond_work;
	struct notifier_block     nb;

	/* Admin state. Allow lag only if allowed is true
	 * even if network conditions for lag were met
	 */
	bool                      allowed;
};

/* General purpose, use for short periods of time.
@@ -254,6 +249,16 @@ static void mlx5_deactivate_lag(struct mlx5_lag *ldev)
			      err);
}

static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
{
	if (ldev->pf[0].dev &&
	    ldev->pf[1].dev &&
	    mlx5_esw_lag_prereq(ldev->pf[0].dev, ldev->pf[1].dev))
		return true;
	else
		return false;
}

static void mlx5_do_bond(struct mlx5_lag *ldev)
{
	struct mlx5_core_dev *dev0 = ldev->pf[0].dev;
@@ -271,7 +276,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
	tracker = ldev->tracker;
	mutex_unlock(&lag_mutex);

	do_bond = tracker.is_bonded && ldev->allowed;
	do_bond = tracker.is_bonded && mlx5_lag_check_prereq(ldev);

	if (do_bond && !mlx5_lag_is_bonded(ldev)) {
		if (!sriov_enabled)
@@ -449,15 +454,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
	return NOTIFY_DONE;
}

static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
{
	if ((ldev->pf[0].dev && mlx5_sriov_is_enabled(ldev->pf[0].dev)) ||
	    (ldev->pf[1].dev && mlx5_sriov_is_enabled(ldev->pf[1].dev)))
		return false;
	else
		return true;
}

static struct mlx5_lag *mlx5_lag_dev_alloc(void)
{
	struct mlx5_lag *ldev;
@@ -467,7 +463,6 @@ static struct mlx5_lag *mlx5_lag_dev_alloc(void)
		return NULL;

	INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work);
	ldev->allowed = mlx5_lag_check_prereq(ldev);

	return ldev;
}
@@ -492,7 +487,6 @@ static void mlx5_lag_dev_add_pf(struct mlx5_lag *ldev,
	ldev->tracker.netdev_state[fn].link_up = 0;
	ldev->tracker.netdev_state[fn].tx_enabled = 0;

	ldev->allowed = mlx5_lag_check_prereq(ldev);
	dev->priv.lag = ldev;

	mutex_unlock(&lag_mutex);
@@ -514,7 +508,6 @@ static void mlx5_lag_dev_remove_pf(struct mlx5_lag *ldev,
	memset(&ldev->pf[i], 0, sizeof(*ldev->pf));

	dev->priv.lag = NULL;
	ldev->allowed = mlx5_lag_check_prereq(ldev);
	mutex_unlock(&lag_mutex);
}

@@ -593,42 +586,19 @@ bool mlx5_lag_is_active(struct mlx5_core_dev *dev)
}
EXPORT_SYMBOL(mlx5_lag_is_active);

static int mlx5_lag_set_state(struct mlx5_core_dev *dev, bool allow)
void mlx5_lag_update(struct mlx5_core_dev *dev)
{
	struct mlx5_lag *ldev;
	int ret = 0;
	bool lag_active;

	mlx5_dev_list_lock();

	ldev = mlx5_lag_dev_get(dev);
	if (!ldev) {
		ret = -ENODEV;
		goto unlock;
	}
	lag_active = mlx5_lag_is_bonded(ldev);
	if (!mlx5_lag_check_prereq(ldev) && allow) {
		ret = -EINVAL;
		goto unlock;
	}
	if (ldev->allowed == allow)
	if (!ldev)
		goto unlock;
	ldev->allowed = allow;
	if ((lag_active && !allow) || allow)

	mlx5_do_bond(ldev);

unlock:
	mlx5_dev_list_unlock();
	return ret;
}

int mlx5_lag_forbid(struct mlx5_core_dev *dev)
{
	return mlx5_lag_set_state(dev, false);
}

int mlx5_lag_allow(struct mlx5_core_dev *dev)
{
	return mlx5_lag_set_state(dev, true);
}

struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev)
+1 −3
Original line number Diff line number Diff line
@@ -185,10 +185,8 @@ static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
		    MLX5_CAP_GEN(dev, lag_master);
}

int mlx5_lag_allow(struct mlx5_core_dev *dev);
int mlx5_lag_forbid(struct mlx5_core_dev *dev);

void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol);
void mlx5_lag_update(struct mlx5_core_dev *dev);

enum {
	MLX5_NIC_IFC_FULL		= 0,
+2 −12
Original line number Diff line number Diff line
@@ -216,20 +216,10 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
	if (!mlx5_core_is_pf(dev))
		return -EPERM;

	if (num_vfs) {
		int ret;

		ret = mlx5_lag_forbid(dev);
		if (ret && (ret != -ENODEV))
			return ret;
	}

	if (num_vfs) {
	if (num_vfs)
		err = mlx5_sriov_enable(pdev, num_vfs);
	} else {
	else
		mlx5_sriov_disable(pdev);
		mlx5_lag_allow(dev);
	}

	return err ? err : num_vfs;
}