Commit 6e0504c6 authored by Maxim Mikityanskiy's avatar Maxim Mikityanskiy Committed by Saeed Mahameed

net/mlx5e: Change inline mode correctly when changing trust state

The current steps that are performed when the trust state changes, if
the channels are active:

1. The trust state is changed in hardware.

2. The new inline mode is calculated.

3. If the new inline mode is different, the channels are recreated using
the new inline mode.

This approach has some issues:

1. There is a time gap between changing trust state in hardware and
starting sending enough inline headers (the latter happens after
recreation of channels). It leads to failed transmissions and error
CQEs.

2. If the new channels fail to open, we'll be left with the old ones,
but the hardware will be configured for the new trust state, so the
interval when we can see TX errors never ends.

This patch fixes the issues above by moving the trust state change into
the preactivate hook that runs during the recreation of the channels
when no channels are active, so it eliminates the gap of partially
applied configuration. If the inline mode doesn't change with the change
of the trust state, the channels won't be recreated, just like before
this patch.
Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
Reviewed-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent b9ab5d0e
...@@ -1098,49 +1098,59 @@ void mlx5e_dcbnl_delete_app(struct mlx5e_priv *priv) ...@@ -1098,49 +1098,59 @@ void mlx5e_dcbnl_delete_app(struct mlx5e_priv *priv)
mlx5e_dcbnl_dscp_app(priv, DELETE); mlx5e_dcbnl_dscp_app(priv, DELETE);
} }
static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv, static void mlx5e_params_calc_trust_tx_min_inline_mode(struct mlx5_core_dev *mdev,
struct mlx5e_params *params) struct mlx5e_params *params,
u8 trust_state)
{ {
mlx5_query_min_inline(priv->mdev, &params->tx_min_inline_mode); mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP && if (trust_state == MLX5_QPTS_TRUST_DSCP &&
params->tx_min_inline_mode == MLX5_INLINE_MODE_L2) params->tx_min_inline_mode == MLX5_INLINE_MODE_L2)
params->tx_min_inline_mode = MLX5_INLINE_MODE_IP; params->tx_min_inline_mode = MLX5_INLINE_MODE_IP;
} }
static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv) static int mlx5e_update_trust_state_hw(struct mlx5e_priv *priv, void *context)
{
u8 *trust_state = context;
int err;
err = mlx5_set_trust_state(priv->mdev, *trust_state);
if (err)
return err;
priv->dcbx_dp.trust_state = *trust_state;
return 0;
}
static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
{ {
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
bool reset_channels = true;
int err = 0;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
new_channels.params = priv->channels.params; new_channels.params = priv->channels.params;
mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params); mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &new_channels.params,
trust_state);
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
priv->channels.params = new_channels.params; priv->channels.params = new_channels.params;
goto out; reset_channels = false;
} }
/* Skip if tx_min_inline is the same */ /* Skip if tx_min_inline is the same */
if (new_channels.params.tx_min_inline_mode == if (new_channels.params.tx_min_inline_mode ==
priv->channels.params.tx_min_inline_mode) priv->channels.params.tx_min_inline_mode)
goto out; reset_channels = false;
mlx5e_safe_switch_channels(priv, &new_channels, NULL, NULL); if (reset_channels)
err = mlx5e_safe_switch_channels(priv, &new_channels,
mlx5e_update_trust_state_hw,
&trust_state);
else
err = mlx5e_update_trust_state_hw(priv, &trust_state);
out:
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
}
static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
{
int err;
err = mlx5_set_trust_state(priv->mdev, trust_state);
if (err)
return err;
priv->dcbx_dp.trust_state = trust_state;
mlx5e_trust_update_sq_inline_mode(priv);
return err; return err;
} }
...@@ -1171,7 +1181,8 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv) ...@@ -1171,7 +1181,8 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv)
if (err) if (err)
return err; return err;
mlx5e_trust_update_tx_min_inline_mode(priv, &priv->channels.params); mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &priv->channels.params,
priv->dcbx_dp.trust_state);
err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio); err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment