Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55c2503d authored by Saeed Mahameed's avatar Saeed Mahameed
Browse files

net/mlx5e: Introduce switch channels



A fail safe helper functions that allows switching to new channels on the
fly,  In simple words:

make_new_config(new_params)
{
    new_channels = open_channels(new_params);
    if (!new_channels)
         return "Failed, but current channels are still active :)"

    switch_channels(new_channels);

    return "SUCCESS";
}

Demonstrate mlx5e_switch_priv_channels usage in set channels ethtool
callback and make it fail-safe using the new switch channels mechanism.

Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Reviewed-by: default avatarTariq Toukan <tariqt@mellanox.com>
parent 9008ae07
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -863,6 +863,13 @@ void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,

int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev);

int mlx5e_open_channels(struct mlx5e_priv *priv,
			struct mlx5e_channels *chs);
void mlx5e_close_channels(struct mlx5e_channels *chs);
void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
				struct mlx5e_channels *new_chs);

void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
				   u32 *indirection_rqt, int len,
				   int num_channels);
+17 −12
Original line number Diff line number Diff line
@@ -556,8 +556,8 @@ static int mlx5e_set_channels(struct net_device *dev,
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	unsigned int count = ch->combined_count;
	struct mlx5e_channels new_channels = {};
	bool arfs_enabled;
	bool was_opened;
	int err = 0;

	if (!count) {
@@ -571,22 +571,27 @@ static int mlx5e_set_channels(struct net_device *dev,

	mutex_lock(&priv->state_lock);

	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
	if (was_opened)
		mlx5e_close_locked(dev);
	new_channels.params = priv->channels.params;
	new_channels.params.num_channels = count;
	mlx5e_build_default_indir_rqt(priv->mdev, new_channels.params.indirection_rqt,
				      MLX5E_INDIR_RQT_SIZE, count);

	if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
		priv->channels.params = new_channels.params;
		goto out;
	}

	/* Create fresh channels with new parameters */
	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		goto out;

	arfs_enabled = dev->features & NETIF_F_NTUPLE;
	if (arfs_enabled)
		mlx5e_arfs_disable(priv);

	priv->channels.params.num_channels = count;
	mlx5e_build_default_indir_rqt(priv->mdev, priv->channels.params.indirection_rqt,
				      MLX5E_INDIR_RQT_SIZE, count);

	if (was_opened)
		err = mlx5e_open_locked(dev);
	if (err)
		goto out;
	/* Switch to new channels, set new parameters and close old ones */
	mlx5e_switch_priv_channels(priv, &new_channels);

	if (arfs_enabled) {
		err = mlx5e_arfs_enable(priv);
+27 −3
Original line number Diff line number Diff line
@@ -1972,7 +1972,7 @@ static void mlx5e_build_channel_param(struct mlx5e_priv *priv,
	mlx5e_build_ico_cq_param(priv, icosq_log_wq_sz, &cparam->icosq_cq);
}

static int mlx5e_open_channels(struct mlx5e_priv *priv,
int mlx5e_open_channels(struct mlx5e_priv *priv,
			struct mlx5e_channels *chs)
{
	struct mlx5e_channel_param *cparam;
@@ -2037,7 +2037,7 @@ static void mlx5e_deactivate_channels(struct mlx5e_channels *chs)
		mlx5e_deactivate_channel(chs->c[i]);
}

static void mlx5e_close_channels(struct mlx5e_channels *chs)
void mlx5e_close_channels(struct mlx5e_channels *chs)
{
	int i;

@@ -2533,6 +2533,30 @@ static void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
	mlx5e_deactivate_channels(&priv->channels);
}

void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
				struct mlx5e_channels *new_chs)
{
	struct net_device *netdev = priv->netdev;
	int new_num_txqs;

	new_num_txqs = new_chs->num * new_chs->params.num_tc;

	netif_carrier_off(netdev);

	if (new_num_txqs < netdev->real_num_tx_queues)
		netif_set_real_num_tx_queues(netdev, new_num_txqs);

	mlx5e_deactivate_priv_channels(priv);
	mlx5e_close_channels(&priv->channels);

	priv->channels = *new_chs;

	mlx5e_refresh_tirs(priv, false);
	mlx5e_activate_priv_channels(priv);

	mlx5e_update_carrier(priv);
}

int mlx5e_open_locked(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);