From: Eli Cohen Date: Thu, 9 Feb 2012 16:10:06 +0000 (+0200) Subject: mlx4: Enforce device max FMR maps in FMR alloc X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=a5bbe892da9441835cb6fece26d9bbd95fc820be;p=mv-sheeva.git mlx4: Enforce device max FMR maps in FMR alloc ConnectX devices have a limit on the number of mappings that can be done on an FMR before having to call sync_tpt. The current mlx4_ib driver reports the limit correctly in max_map_per_fmr in .query_device(), but mlx4_core doesn't check it when actually allocating FMRs. Add a max_fmr_maps field to struct mlx4_caps and enforce this maximum value on FMR allocations. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier --- diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 7b445df6a66..e152837b75a 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -163,7 +163,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->max_mcast_qp_attach = dev->dev->caps.num_qp_per_mgm; props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * props->max_mcast_grp; - props->max_map_per_fmr = (1 << (32 - ilog2(dev->dev->caps.num_mpts))) - 1; + props->max_map_per_fmr = dev->dev->caps.max_fmr_maps; out: kfree(in_mad); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 678558b502f..3e593ae56e0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1131,6 +1131,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) goto err_stop_fw; } + dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; + init_hca.log_uar_sz = ilog2(dev->caps.num_uars); init_hca.uar_page_sz = PAGE_SHIFT - 12; diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 25a80d71fb2..5b7c06e0cd0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -816,6 +816,9 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, u64 mtt_offset; int err = -ENOMEM; + if (max_maps > dev->caps.max_fmr_maps) + return -EINVAL; + if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) return -EINVAL; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index aea61905499..263d2ae21ac 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -273,6 +273,7 @@ struct mlx4_caps { int num_comp_vectors; int comp_pool; int num_mpts; + int max_fmr_maps; int num_mtts; int fmr_reserved_mtts; int reserved_mtts;