History

net/mlx5: Fix command stats access after free

Command may fail while driver is reloading and can't accept FW commands till command interface is reinitialized. Such command failure is being logged to command stats. This results in NULL pointer access as command stats structure is being freed and reallocated during mlx5 devlink reload (see kernel log below). Fix it by making command stats statically allocated on driver probe. Kernel log: [ 2394.808802] BUG: unable to handle kernel paging request at 000000000002a9c0 [ 2394.810610] PGD 0 P4D 0 [ 2394.811811] Oops: 0002 [#1] SMP NOPTI ... [ 2394.815482] RIP: 0010:native_queued_spin_lock_slowpath+0x183/0x1d0 ... [ 2394.829505] Call Trace: [ 2394.830667] _raw_spin_lock_irq+0x23/0x26 [ 2394.831858] cmd_status_err+0x55/0x110 [mlx5_core] [ 2394.833020] mlx5_access_reg+0xe7/0x150 [mlx5_core] [ 2394.834175] mlx5_query_port_ptys+0x78/0xa0 [mlx5_core] [ 2394.835337] mlx5e_ethtool_get_link_ksettings+0x74/0x590 [mlx5_core] [ 2394.836454] ? kmem_cache_alloc_trace+0x140/0x1c0 [ 2394.837562] __rh_call_get_link_ksettings+0x33/0x100 [ 2394.838663] ? __rtnl_unlock+0x25/0x50 [ 2394.839755] __ethtool_get_link_ksettings+0x72/0x150 [ 2394.840862] duplex_show+0x6e/0xc0 [ 2394.841963] dev_attr_show+0x1c/0x40 [ 2394.843048] sysfs_kf_seq_show+0x9b/0x100 [ 2394.844123] seq_read+0x153/0x410 [ 2394.845187] vfs_read+0x91/0x140 [ 2394.846226] ksys_read+0x4f/0xb0 [ 2394.847234] do_syscall_64+0x5b/0x1a0 [ 2394.848228] entry_SYSCALL_64_after_hwframe+0x65/0xca

Moshe Shemesh committed 3 years ago

Commit da2e5521 parent 5e72f3f2 files · +3 −12Browse files

Unified · Split

2 files
  1. drivers/net/ethernet/mellanox/mlx5/core/cmd.c +2 −11
  2. include/linux/mlx5/driver.h +1 −1
drivers/net/ethernet/mellanox/mlx5/core/cmd.c+2−11
@@ -2176,15 +2176,9 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) · 2175 unmodified lines
21762176 return -EINVAL;
21772177 }
21782178
2179− cmd->stats = kvcalloc(MLX5_CMD_OP_MAX, sizeof(*cmd->stats), GFP_KERNEL);
2180− if (!cmd->stats)
2181− return -ENOMEM;
2182−
21832179 cmd->pool = dma_pool_create("mlx5_cmd", mlx5_core_dma_dev(dev), size, align, 0);
2184− if (!cmd->pool) {
2185− err = -ENOMEM;
2186− goto dma_pool_err;
2187− }
2180+ if (!cmd->pool)
2181+ return -ENOMEM;
21882182
21892183 err = alloc_cmd_page(dev, cmd);
21902184 if (err)
@@ -2268,8 +2262,6 @@ err_free_page: · 77 unmodified lines
22682262
22692263 err_free_pool:
22702264 dma_pool_destroy(cmd->pool);
2271−dma_pool_err:
2272− kvfree(cmd->stats);
22732265 return err;
22742266 }
22752267
@@ -2282,7 +2274,6 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev) · 6 unmodified lines
22822274 destroy_msg_cache(dev);
22832275 free_cmd_page(dev, cmd);
22842276 dma_pool_destroy(cmd->pool);
2285− kvfree(cmd->stats);
22862277 }
22872278
22882279 void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
include/linux/mlx5/driver.h+1−1
@@ -315,7 +315,7 @@ struct mlx5_cmd { · 314 unmodified lines
315315 struct mlx5_cmd_debug dbg;
316316 struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];
317317 int checksum_disabled;
318− struct mlx5_cmd_stats *stats;
318+ struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX];
319319 };
320320
321321 struct mlx5_cmd_mailbox {