From 16c012682565f640403e2a3f6bf0d8d09dc365a0 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Thu, 25 Feb 2021 11:20:00 -0800 Subject: [PATCH] net/mlx5e: reset XPS on error flow if netdev isn't registered yet commit 77ecd10d0a8aaa6e4871d8c63626e4c9fc5e47db upstream. mlx5e_attach_netdev can be called prior to registering the netdevice: Example stack: ipoib_new_child_link -> ipoib_intf_init-> rdma_init_netdev-> mlx5_rdma_setup_rn-> mlx5e_attach_netdev-> mlx5e_num_channels_changed -> mlx5e_set_default_xps_cpumasks -> netif_set_xps_queue -> __netif_set_xps_queue -> kmalloc If any later stage fails at any point after mlx5e_num_channels_changed() returns, XPS allocated maps will never be freed as they are only freed during netdev unregistration, which will never happen for yet to be registered netdevs. Fixes: 3909a12e7913 ("net/mlx5e: Fix configuration of XPS cpumasks and netdev queues in corner cases") Signed-off-by: Saeed Mahameed Signed-off-by: Aya Levin Reviewed-by: Tariq Toukan Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 5db63b9f3b70d..94908a9bf835c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -5604,6 +5604,11 @@ static void mlx5e_update_features(struct net_device *netdev) rtnl_unlock(); } +static void mlx5e_reset_channels(struct net_device *netdev) +{ + netdev_reset_tc(netdev); +} + int mlx5e_attach_netdev(struct mlx5e_priv *priv) { const bool take_rtnl = priv->netdev->reg_state == NETREG_REGISTERED; @@ -5658,6 +5663,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) profile->cleanup_tx(priv); out: + mlx5e_reset_channels(priv->netdev); set_bit(MLX5E_STATE_DESTROYING, &priv->state); cancel_work_sync(&priv->update_stats_work); return err; @@ -5675,6 +5681,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv) profile->cleanup_rx(priv); profile->cleanup_tx(priv); + mlx5e_reset_channels(priv->netdev); cancel_work_sync(&priv->update_stats_work); }