Skip to content

Commit

Permalink
net/mlx5e: Fail safe mtu and lro setting
Browse files Browse the repository at this point in the history
Use the new fail-safe channels switch mechanism to set new
netdev mtu and lro settings.

MTU and lro settings demand some HW configuration changes after new
channels are created and ready for action. In order to unify switch
channels routine for LRO and MTU changes, and maybe future configuration
features, we now pass to it a modify HW function pointer to be
invoked directly after old channels are de-activated and before new
channels are activated.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
  • Loading branch information
Saeed Mahameed committed Mar 27, 2017
1 parent 6f9485a commit 2e20a15
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 32 deletions.
8 changes: 7 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -867,8 +867,14 @@ 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);

/* Function pointer to be used to modify WH settings while
* switching channels
*/
typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv);
void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *new_chs);
struct mlx5e_channels *new_chs,
mlx5e_fp_hw_modify hw_modify);

void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
u32 *indirection_rqt, int len,
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
if (err)
goto unlock;

mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);

unlock:
mutex_unlock(&priv->state_lock);
Expand Down Expand Up @@ -597,7 +597,7 @@ static int mlx5e_set_channels(struct net_device *dev,
mlx5e_arfs_disable(priv);

/* Switch to new channels, set new parameters and close old ones */
mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);

if (arfs_enabled) {
err = mlx5e_arfs_enable(priv);
Expand Down Expand Up @@ -691,7 +691,7 @@ static int mlx5e_set_coalesce(struct net_device *netdev,
if (err)
goto out;

mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);

out:
mutex_unlock(&priv->state_lock);
Expand Down Expand Up @@ -1166,7 +1166,7 @@ static int mlx5e_set_tunable(struct net_device *dev,
err = mlx5e_open_channels(priv, &new_channels);
if (err)
break;
mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);

break;
default:
Expand Down Expand Up @@ -1503,7 +1503,7 @@ static int set_pflag_rx_cqe_based_moder(struct net_device *netdev, bool enable)
if (err)
return err;

mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);
return 0;
}

Expand Down Expand Up @@ -1534,7 +1534,7 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
if (err)
return err;

mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);
return 0;
}

Expand Down
70 changes: 45 additions & 25 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2437,9 +2437,9 @@ static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu)
*mtu = MLX5E_HW2SW_MTU(hw_mtu);
}

static int mlx5e_set_dev_port_mtu(struct net_device *netdev)
static int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
struct net_device *netdev = priv->netdev;
u16 mtu;
int err;

Expand Down Expand Up @@ -2534,7 +2534,8 @@ static void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
}

void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *new_chs)
struct mlx5e_channels *new_chs,
mlx5e_fp_hw_modify hw_modify)
{
struct net_device *netdev = priv->netdev;
int new_num_txqs;
Expand All @@ -2551,6 +2552,10 @@ void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,

priv->channels = *new_chs;

/* New channels are ready to roll, modify HW settings if needed */
if (hw_modify)
hw_modify(priv);

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

Expand Down Expand Up @@ -2930,7 +2935,7 @@ static int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
if (err)
goto out;

mlx5e_switch_priv_channels(priv, &new_channels);
mlx5e_switch_priv_channels(priv, &new_channels, NULL);
out:
mutex_unlock(&priv->state_lock);
return err;
Expand Down Expand Up @@ -3049,26 +3054,31 @@ typedef int (*mlx5e_feature_handler)(struct net_device *netdev, bool enable);
static int set_feature_lro(struct net_device *netdev, bool enable)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
bool was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
int err;
struct mlx5e_channels new_channels = {};
int err = 0;
bool reset;

mutex_lock(&priv->state_lock);

if (was_opened && (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST))
mlx5e_close_locked(priv->netdev);
reset = (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST);
reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state);

priv->channels.params.lro_en = enable;
err = mlx5e_modify_tirs_lro(priv);
if (err) {
netdev_err(netdev, "lro modify failed, %d\n", err);
priv->channels.params.lro_en = !enable;
new_channels.params = priv->channels.params;
new_channels.params.lro_en = enable;

if (!reset) {
priv->channels.params = new_channels.params;
err = mlx5e_modify_tirs_lro(priv);
goto out;
}

if (was_opened && (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST))
mlx5e_open_locked(priv->netdev);
err = mlx5e_open_channels(priv, &new_channels);
if (err)
goto out;

mlx5e_switch_priv_channels(priv, &new_channels, mlx5e_modify_tirs_lro);
out:
mutex_unlock(&priv->state_lock);

return err;
}

Expand Down Expand Up @@ -3191,7 +3201,8 @@ static int mlx5e_set_features(struct net_device *netdev,
static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
bool was_opened;
struct mlx5e_channels new_channels = {};
int curr_mtu;
int err = 0;
bool reset;

Expand All @@ -3201,18 +3212,27 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
(priv->channels.params.rq_wq_type !=
MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ);

was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
if (was_opened && reset)
mlx5e_close_locked(netdev);
reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state);

curr_mtu = netdev->mtu;
netdev->mtu = new_mtu;
mlx5e_set_dev_port_mtu(netdev);

if (was_opened && reset)
err = mlx5e_open_locked(netdev);
if (!reset) {
mlx5e_set_dev_port_mtu(priv);
goto out;
}

mutex_unlock(&priv->state_lock);
new_channels.params = priv->channels.params;
err = mlx5e_open_channels(priv, &new_channels);
if (err) {
netdev->mtu = curr_mtu;
goto out;
}

mlx5e_switch_priv_channels(priv, &new_channels, mlx5e_set_dev_port_mtu);

out:
mutex_unlock(&priv->state_lock);
return err;
}

Expand Down Expand Up @@ -4169,7 +4189,7 @@ int mlx5e_attach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev)
mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
netdev->max_mtu = MLX5E_HW2SW_MTU(max_mtu);

mlx5e_set_dev_port_mtu(netdev);
mlx5e_set_dev_port_mtu(priv);

if (profile->enable)
profile->enable(priv);
Expand Down

0 comments on commit 2e20a15

Please sign in to comment.