mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
mlx4_core: Use MOD_STAT_CFG command to get minimal page size
There was a bug in some versions of the mlx4 driver in mlx4_alloc_fmr(), which hardcoded the minimum acceptable page_shift to be 12. However, new ConnectX firmware can support a minimum page_shift of 9 (log_pg_sz of 9 returned by QUERY_DEV_LIM) -- so with old drivers, ib_fmr_alloc() would fail for ULPs using the device minimum when creating FMRs. To preserve firmware compatibility with released mlx4 drivers, the firmware will continue to return 12 as before for log_page_sz in QUERY_DEV_CAP for these drivers. However, to enable new drivers to take advantage of the available smaller page size, the mlx4 driver now first sets the log_pg_sz to the device minimum by setting a log_page_sz value to 0 via the MOD_STAT_CFG command and then reading the real minimum via QUERY_DEV_CAP. Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il> Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
de910bd921
commit
2d92865158
3 changed files with 41 additions and 0 deletions
|
@ -101,6 +101,34 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags)
|
|||
mlx4_dbg(dev, " %s\n", fname[i]);
|
||||
}
|
||||
|
||||
int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
|
||||
{
|
||||
struct mlx4_cmd_mailbox *mailbox;
|
||||
u32 *inbox;
|
||||
int err = 0;
|
||||
|
||||
#define MOD_STAT_CFG_IN_SIZE 0x100
|
||||
|
||||
#define MOD_STAT_CFG_PG_SZ_M_OFFSET 0x002
|
||||
#define MOD_STAT_CFG_PG_SZ_OFFSET 0x003
|
||||
|
||||
mailbox = mlx4_alloc_cmd_mailbox(dev);
|
||||
if (IS_ERR(mailbox))
|
||||
return PTR_ERR(mailbox);
|
||||
inbox = mailbox->buf;
|
||||
|
||||
memset(inbox, 0, MOD_STAT_CFG_IN_SIZE);
|
||||
|
||||
MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET);
|
||||
MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET);
|
||||
|
||||
err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_MOD_STAT_CFG,
|
||||
MLX4_CMD_TIME_CLASS_A);
|
||||
|
||||
mlx4_free_cmd_mailbox(dev, mailbox);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
{
|
||||
struct mlx4_cmd_mailbox *mailbox;
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "mlx4.h"
|
||||
#include "icm.h"
|
||||
|
||||
struct mlx4_mod_stat_cfg {
|
||||
u8 log_pg_sz;
|
||||
u8 log_pg_sz_m;
|
||||
};
|
||||
|
||||
struct mlx4_dev_cap {
|
||||
int max_srq_sz;
|
||||
int max_qp_sz;
|
||||
|
@ -162,5 +167,6 @@ int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages);
|
|||
int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm);
|
||||
int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev);
|
||||
int mlx4_NOP(struct mlx4_dev *dev);
|
||||
int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg);
|
||||
|
||||
#endif /* MLX4_FW_H */
|
||||
|
|
|
@ -485,6 +485,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
struct mlx4_adapter adapter;
|
||||
struct mlx4_dev_cap dev_cap;
|
||||
struct mlx4_mod_stat_cfg mlx4_cfg;
|
||||
struct mlx4_profile profile;
|
||||
struct mlx4_init_hca_param init_hca;
|
||||
u64 icm_size;
|
||||
|
@ -502,6 +503,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
mlx4_cfg.log_pg_sz_m = 1;
|
||||
mlx4_cfg.log_pg_sz = 0;
|
||||
err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg);
|
||||
if (err)
|
||||
mlx4_warn(dev, "Failed to override log_pg_sz parameter\n");
|
||||
|
||||
err = mlx4_dev_cap(dev, &dev_cap);
|
||||
if (err) {
|
||||
mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n");
|
||||
|
|
Loading…
Reference in a new issue