From: Bodong Wang bodong@mellanox.com
[ Upstream commit 14c844cbf3503076de6e2e48d575216f1600b19f ]
Consider scenario below, CPU 1 is at risk to query already destroyed drop counters. Need to apply the same state mutex when disabling vport.
+-------------------------------+-------------------------------------+ | CPU 0 | CPU 1 | +-------------------------------+-------------------------------------+ | mlx5_device_disable_sriov | mlx5e_get_vf_stats | | mlx5_eswitch_disable | mlx5_eswitch_get_vport_stats | | esw_disable_vport | mlx5_eswitch_query_vport_drop_stats | | mlx5_fc_destroy(drop_counter) | mlx5_fc_query(drop_counter) | +-------------------------------+-------------------------------------+
Fixes: b8a0dbe3a90b ("net/mlx5e: E-switch, Add steering drop counters") Signed-off-by: Bodong Wang bodong@mellanox.com Reviewed-by: Parav Pandit parav@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 07282c679dcdf..d92e11e9343f5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -2597,9 +2597,13 @@ static int mlx5_eswitch_query_vport_drop_stats(struct mlx5_core_dev *dev, u64 bytes = 0; int err = 0;
- if (!vport->enabled || esw->mode != MLX5_ESWITCH_LEGACY) + if (esw->mode != MLX5_ESWITCH_LEGACY) return 0;
+ mutex_lock(&esw->state_lock); + if (!vport->enabled) + goto unlock; + if (vport->egress.legacy.drop_counter) mlx5_fc_query(dev, vport->egress.legacy.drop_counter, &stats->rx_dropped, &bytes); @@ -2610,20 +2614,22 @@ static int mlx5_eswitch_query_vport_drop_stats(struct mlx5_core_dev *dev,
if (!MLX5_CAP_GEN(dev, receive_discard_vport_down) && !MLX5_CAP_GEN(dev, transmit_discard_vport_down)) - return 0; + goto unlock;
err = mlx5_query_vport_down_stats(dev, vport->vport, 1, &rx_discard_vport_down, &tx_discard_vport_down); if (err) - return err; + goto unlock;
if (MLX5_CAP_GEN(dev, receive_discard_vport_down)) stats->rx_dropped += rx_discard_vport_down; if (MLX5_CAP_GEN(dev, transmit_discard_vport_down)) stats->tx_dropped += tx_discard_vport_down;
- return 0; +unlock: + mutex_unlock(&esw->state_lock); + return err; }
int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,