Skip to content

Commit

Permalink
net/mlx5e: Change inline mode correctly when changing trust state
Browse files Browse the repository at this point in the history
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: Maxim Mikityanskiy <maximmi@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
  • Loading branch information
Maxim Mikityanskiy authored and Saeed Mahameed committed Feb 26, 2020
1 parent b9ab5d0 commit 6e0504c
Showing 1 changed file with 33 additions and 22 deletions.
55 changes: 33 additions & 22 deletions drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,49 +1098,59 @@ void mlx5e_dcbnl_delete_app(struct mlx5e_priv *priv)
mlx5e_dcbnl_dscp_app(priv, DELETE);
}

static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv,
struct mlx5e_params *params)
static void mlx5e_params_calc_trust_tx_min_inline_mode(struct mlx5_core_dev *mdev,
struct mlx5e_params *params,
u8 trust_state)
{
mlx5_query_min_inline(priv->mdev, &params->tx_min_inline_mode);
if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP &&
mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
if (trust_state == MLX5_QPTS_TRUST_DSCP &&
params->tx_min_inline_mode == MLX5_INLINE_MODE_L2)
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 = {};
bool reset_channels = true;
int err = 0;

mutex_lock(&priv->state_lock);

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)) {
priv->channels.params = new_channels.params;
goto out;
reset_channels = false;
}

/* Skip if tx_min_inline is the same */
if (new_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);
}

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;
}
Expand Down Expand Up @@ -1171,7 +1181,8 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv)
if (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);
if (err)
Expand Down

0 comments on commit 6e0504c

Please sign in to comment.