diff options
| author | Huy Nguyen <huyn@mellanox.com> | 2017-08-08 14:17:00 -0400 |
|---|---|---|
| committer | Saeed Mahameed <saeedm@mellanox.com> | 2017-08-30 14:20:43 -0400 |
| commit | b3cb5388499c5e219324bfe7da2e46cbad82bfcf (patch) | |
| tree | a955b5290d59ec1e87ba1e7cebae113d69da139b | |
| parent | 672d0880b7798a917bcc622308f25a0fbb991dab (diff) | |
net/mlx5: Skip mlx5_unload_one if mlx5_load_one fails
There is an issue where the firmware fails during mlx5_load_one,
the health_care timer detects the issue and schedules a health_care call.
Then the mlx5_load_one detects the issue, cleans up and quits. Then
the health_care starts and calls mlx5_unload_one to clean up the resources
that no longer exist and causes kernel panic.
The root cause is that the bit MLX5_INTERFACE_STATE_DOWN is not set
after mlx5_load_one fails. The solution is removing the bit
MLX5_INTERFACE_STATE_DOWN and quit mlx5_unload_one if the
bit MLX5_INTERFACE_STATE_UP is not set. The bit MLX5_INTERFACE_STATE_DOWN
is redundant and we can use MLX5_INTERFACE_STATE_UP instead.
Fixes: 5fc7197d3a25 ("net/mlx5: Add pci shutdown callback")
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 | ||||
| -rw-r--r-- | include/linux/mlx5/driver.h | 5 |
2 files changed, 3 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index c065132b956d..4cdb414aa2d5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
| @@ -1186,7 +1186,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, | |||
| 1186 | } | 1186 | } |
| 1187 | } | 1187 | } |
| 1188 | 1188 | ||
| 1189 | clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | ||
| 1190 | set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | 1189 | set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
| 1191 | out: | 1190 | out: |
| 1192 | mutex_unlock(&dev->intf_state_mutex); | 1191 | mutex_unlock(&dev->intf_state_mutex); |
| @@ -1261,7 +1260,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, | |||
| 1261 | mlx5_drain_health_recovery(dev); | 1260 | mlx5_drain_health_recovery(dev); |
| 1262 | 1261 | ||
| 1263 | mutex_lock(&dev->intf_state_mutex); | 1262 | mutex_lock(&dev->intf_state_mutex); |
| 1264 | if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { | 1263 | if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
| 1265 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", | 1264 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", |
| 1266 | __func__); | 1265 | __func__); |
| 1267 | if (cleanup) | 1266 | if (cleanup) |
| @@ -1270,7 +1269,6 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, | |||
| 1270 | } | 1269 | } |
| 1271 | 1270 | ||
| 1272 | clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | 1271 | clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
| 1273 | set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | ||
| 1274 | 1272 | ||
| 1275 | if (mlx5_device_registered(dev)) | 1273 | if (mlx5_device_registered(dev)) |
| 1276 | mlx5_detach_device(dev); | 1274 | mlx5_detach_device(dev); |
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index df6ce59a1f95..918f5e644506 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
| @@ -673,9 +673,8 @@ enum mlx5_device_state { | |||
| 673 | }; | 673 | }; |
| 674 | 674 | ||
| 675 | enum mlx5_interface_state { | 675 | enum mlx5_interface_state { |
| 676 | MLX5_INTERFACE_STATE_DOWN = BIT(0), | 676 | MLX5_INTERFACE_STATE_UP = BIT(0), |
| 677 | MLX5_INTERFACE_STATE_UP = BIT(1), | 677 | MLX5_INTERFACE_STATE_SHUTDOWN = BIT(1), |
| 678 | MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2), | ||
| 679 | }; | 678 | }; |
| 680 | 679 | ||
| 681 | enum mlx5_pci_status { | 680 | enum mlx5_pci_status { |
