Commit bdf27475 authored by Dmytro Linkin's avatar Dmytro Linkin Committed by Saeed Mahameed

net/mlx5e: Don't attach netdev profile while handling internal error

As part of switchdev mode disablement, driver changes port netdevice
profile from uplink to nic. If this process is triggered by health
recovery flow (PCI reset, for ex.) profile attach would fail because all
fw commands aborted when internal error flag is set. As a result, nic
netdevice profile is not attached and driver fails to rollback to uplink
profile, which leave driver in broken state and cause crash later.

To handle broken state do netdevice profile initialization only instead
of full attachment and release mdev resources on driver suspend as
expected. Actual netdevice attachment is done during driver load.

Fixes: c4d7eb57 ("net/mxl5e: Add change profile method")
Signed-off-by: default avatarDmytro Linkin <dlinkin@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 5d862ec6
...@@ -5833,7 +5833,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv) ...@@ -5833,7 +5833,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv)
} }
static int static int
mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mdev, mlx5e_netdev_init_profile(struct net_device *netdev, struct mlx5_core_dev *mdev,
const struct mlx5e_profile *new_profile, void *new_ppriv) const struct mlx5e_profile *new_profile, void *new_ppriv)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
...@@ -5850,6 +5850,25 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde ...@@ -5850,6 +5850,25 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde
err = new_profile->init(priv->mdev, priv->netdev); err = new_profile->init(priv->mdev, priv->netdev);
if (err) if (err)
goto priv_cleanup; goto priv_cleanup;
return 0;
priv_cleanup:
mlx5e_priv_cleanup(priv);
return err;
}
static int
mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mdev,
const struct mlx5e_profile *new_profile, void *new_ppriv)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
err = mlx5e_netdev_init_profile(netdev, mdev, new_profile, new_ppriv);
if (err)
return err;
err = mlx5e_attach_netdev(priv); err = mlx5e_attach_netdev(priv);
if (err) if (err)
goto profile_cleanup; goto profile_cleanup;
...@@ -5857,7 +5876,6 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde ...@@ -5857,7 +5876,6 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde
profile_cleanup: profile_cleanup:
new_profile->cleanup(priv); new_profile->cleanup(priv);
priv_cleanup:
mlx5e_priv_cleanup(priv); mlx5e_priv_cleanup(priv);
return err; return err;
} }
...@@ -5876,6 +5894,12 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, ...@@ -5876,6 +5894,12 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
priv->profile->cleanup(priv); priv->profile->cleanup(priv);
mlx5e_priv_cleanup(priv); mlx5e_priv_cleanup(priv);
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
mlx5e_netdev_init_profile(netdev, mdev, new_profile, new_ppriv);
set_bit(MLX5E_STATE_DESTROYING, &priv->state);
return -EIO;
}
err = mlx5e_netdev_attach_profile(netdev, mdev, new_profile, new_ppriv); err = mlx5e_netdev_attach_profile(netdev, mdev, new_profile, new_ppriv);
if (err) { /* roll back to original profile */ if (err) { /* roll back to original profile */
netdev_warn(netdev, "%s: new profile init failed, %d\n", __func__, err); netdev_warn(netdev, "%s: new profile init failed, %d\n", __func__, err);
...@@ -5937,8 +5961,11 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state) ...@@ -5937,8 +5961,11 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
if (!netif_device_present(netdev)) if (!netif_device_present(netdev)) {
if (test_bit(MLX5E_STATE_DESTROYING, &priv->state))
mlx5e_destroy_mdev_resources(mdev);
return -ENODEV; return -ENODEV;
}
mlx5e_detach_netdev(priv); mlx5e_detach_netdev(priv);
mlx5e_destroy_mdev_resources(mdev); mlx5e_destroy_mdev_resources(mdev);
......
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