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
2176 return -EINVAL;2176 return -EINVAL;
2177 }2177 }
2178 2178
2179 cmd->stats = kvcalloc(MLX5_CMD_OP_MAX, sizeof(*cmd->stats), GFP_KERNEL);
2180 if (!cmd->stats)
2181 return -ENOMEM;
2182
2183 cmd->pool = dma_pool_create("mlx5_cmd", mlx5_core_dma_dev(dev), size, align, 0);2179 cmd->pool = dma_pool_create("mlx5_cmd", mlx5_core_dma_dev(dev), size, align, 0);
2184 if (!cmd->pool) {2180 if (!cmd->pool)
2185 err = -ENOMEM;2181 return -ENOMEM;
2186 goto dma_pool_err;
2187 }
2188 2182
2189 err = alloc_cmd_page(dev, cmd);2183 err = alloc_cmd_page(dev, cmd);
2190 if (err)2184 if (err)
@@ -2268,8 +2262,6 @@ err_free_page: · 77 unmodified lines
2268 2262
2269err_free_pool:2263err_free_pool:
2270 dma_pool_destroy(cmd->pool);2264 dma_pool_destroy(cmd->pool);
2271dma_pool_err:
2272 kvfree(cmd->stats);
2273 return err;2265 return err;
2274}2266}
2275 2267
@@ -2282,7 +2274,6 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev) · 6 unmodified lines
2282 destroy_msg_cache(dev);2274 destroy_msg_cache(dev);
2283 free_cmd_page(dev, cmd);2275 free_cmd_page(dev, cmd);
2284 dma_pool_destroy(cmd->pool);2276 dma_pool_destroy(cmd->pool);
2285 kvfree(cmd->stats);
2286}2277}
2287 2278
2288void mlx5_cmd_set_state(struct mlx5_core_dev *dev,2279void 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
315 struct mlx5_cmd_debug dbg;315 struct mlx5_cmd_debug dbg;
316 struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];316 struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];
317 int checksum_disabled;317 int checksum_disabled;
318 struct mlx5_cmd_stats *stats;318 struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX];
319};319};
320 320
321struct mlx5_cmd_mailbox {321struct mlx5_cmd_mailbox {