Skip to content

Commit c8d75a9

Browse files
majdmellanoxjgunthorpe
authored andcommitted
IB/mlx5: Respect new UMR capabilities
In some firmware configuration, UMR usage from Virtual Functions is restricted. This information is published to the driver using new capability bits. Avoid using UMRs in these cases and use the Firmware slow-path flow to create mkeys and populate them with Virtual to Physical address translation. Older drivers that do not have this patch, will end up using memory keys that aren't populated with Virtual to Physical address translation that is done part of the UMR work. Reviewed-by: Mark Bloch <[email protected]> Signed-off-by: Majd Dibbiny <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Tested-by: Laurence Oberman <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent ea8af0d commit c8d75a9

File tree

3 files changed

+53
-9
lines changed

3 files changed

+53
-9
lines changed

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ static void clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
5151
static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
5252
static int mr_cache_max_order(struct mlx5_ib_dev *dev);
5353
static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
54+
static bool umr_can_modify_entity_size(struct mlx5_ib_dev *dev)
55+
{
56+
return !MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled);
57+
}
58+
59+
static bool umr_can_use_indirect_mkey(struct mlx5_ib_dev *dev)
60+
{
61+
return !MLX5_CAP_GEN(dev->mdev, umr_indirect_mkey_disabled);
62+
}
63+
64+
static bool use_umr(struct mlx5_ib_dev *dev, int order)
65+
{
66+
return order <= mr_cache_max_order(dev) &&
67+
umr_can_modify_entity_size(dev);
68+
}
5469

5570
static int destroy_mkey(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
5671
{
@@ -956,7 +971,10 @@ static inline int populate_xlt(struct mlx5_ib_mr *mr, int idx, int npages,
956971
{
957972
struct mlx5_ib_dev *dev = mr->dev;
958973
struct ib_umem *umem = mr->umem;
974+
959975
if (flags & MLX5_IB_UPD_XLT_INDIRECT) {
976+
if (!umr_can_use_indirect_mkey(dev))
977+
return -EPERM;
960978
mlx5_odp_populate_klm(xlt, idx, npages, mr, flags);
961979
return npages;
962980
}
@@ -1003,6 +1021,10 @@ int mlx5_ib_update_xlt(struct mlx5_ib_mr *mr, u64 idx, int npages,
10031021
gfp_t gfp;
10041022
bool use_emergency_page = false;
10051023

1024+
if ((flags & MLX5_IB_UPD_XLT_INDIRECT) &&
1025+
!umr_can_use_indirect_mkey(dev))
1026+
return -EPERM;
1027+
10061028
/* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes,
10071029
* so we need to align the offset and length accordingly
10081030
*/
@@ -1211,13 +1233,13 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
12111233
{
12121234
struct mlx5_ib_dev *dev = to_mdev(pd->device);
12131235
struct mlx5_ib_mr *mr = NULL;
1236+
bool populate_mtts = false;
12141237
struct ib_umem *umem;
12151238
int page_shift;
12161239
int npages;
12171240
int ncont;
12181241
int order;
12191242
int err;
1220-
bool use_umr = true;
12211243

12221244
if (!IS_ENABLED(CONFIG_INFINIBAND_USER_MEM))
12231245
return ERR_PTR(-EOPNOTSUPP);
@@ -1244,26 +1266,29 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
12441266
if (err < 0)
12451267
return ERR_PTR(err);
12461268

1247-
if (order <= mr_cache_max_order(dev)) {
1269+
if (use_umr(dev, order)) {
12481270
mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont,
12491271
page_shift, order, access_flags);
12501272
if (PTR_ERR(mr) == -EAGAIN) {
12511273
mlx5_ib_dbg(dev, "cache empty for order %d\n", order);
12521274
mr = NULL;
12531275
}
1276+
populate_mtts = false;
12541277
} else if (!MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) {
12551278
if (access_flags & IB_ACCESS_ON_DEMAND) {
12561279
err = -EINVAL;
12571280
pr_err("Got MR registration for ODP MR > 512MB, not supported for Connect-IB\n");
12581281
goto error;
12591282
}
1260-
use_umr = false;
1283+
populate_mtts = true;
12611284
}
12621285

12631286
if (!mr) {
1287+
if (!umr_can_modify_entity_size(dev))
1288+
populate_mtts = true;
12641289
mutex_lock(&dev->slow_path_mutex);
12651290
mr = reg_create(NULL, pd, virt_addr, length, umem, ncont,
1266-
page_shift, access_flags, !use_umr);
1291+
page_shift, access_flags, populate_mtts);
12671292
mutex_unlock(&dev->slow_path_mutex);
12681293
}
12691294

@@ -1281,7 +1306,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
12811306
update_odp_mr(mr);
12821307
#endif
12831308

1284-
if (use_umr) {
1309+
if (!populate_mtts) {
12851310
int update_xlt_flags = MLX5_IB_UPD_XLT_ENABLE;
12861311

12871312
if (access_flags & IB_ACCESS_ON_DEMAND)

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3697,8 +3697,19 @@ static __be64 get_umr_update_pd_mask(void)
36973697
return cpu_to_be64(result);
36983698
}
36993699

3700-
static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
3701-
struct ib_send_wr *wr, int atomic)
3700+
static int umr_check_mkey_mask(struct mlx5_ib_dev *dev, u64 mask)
3701+
{
3702+
if ((mask & MLX5_MKEY_MASK_PAGE_SIZE &&
3703+
MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled)) ||
3704+
(mask & MLX5_MKEY_MASK_A &&
3705+
MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled)))
3706+
return -EPERM;
3707+
return 0;
3708+
}
3709+
3710+
static int set_reg_umr_segment(struct mlx5_ib_dev *dev,
3711+
struct mlx5_wqe_umr_ctrl_seg *umr,
3712+
struct ib_send_wr *wr, int atomic)
37023713
{
37033714
struct mlx5_umr_wr *umrwr = umr_wr(wr);
37043715

@@ -3730,6 +3741,8 @@ static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
37303741

37313742
if (!wr->num_sge)
37323743
umr->flags |= MLX5_UMR_INLINE;
3744+
3745+
return umr_check_mkey_mask(dev, be64_to_cpu(umr->mkey_mask));
37333746
}
37343747

37353748
static u8 get_umr_flags(int acc)
@@ -4552,7 +4565,9 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
45524565
}
45534566
qp->sq.wr_data[idx] = MLX5_IB_WR_UMR;
45544567
ctrl->imm = cpu_to_be32(umr_wr(wr)->mkey);
4555-
set_reg_umr_segment(seg, wr, !!(MLX5_CAP_GEN(mdev, atomic)));
4568+
err = set_reg_umr_segment(dev, seg, wr, !!(MLX5_CAP_GEN(mdev, atomic)));
4569+
if (unlikely(err))
4570+
goto out;
45564571
seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
45574572
size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
45584573
if (unlikely((seg == qend)))

include/linux/mlx5/mlx5_ifc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,11 @@ struct mlx5_ifc_cmd_hca_cap_bits {
916916
u8 reserved_at_202[0x1];
917917
u8 ipoib_enhanced_offloads[0x1];
918918
u8 ipoib_basic_offloads[0x1];
919-
u8 reserved_at_205[0x5];
919+
u8 reserved_at_205[0x1];
920+
u8 repeated_block_disabled[0x1];
921+
u8 umr_modify_entity_size_disabled[0x1];
922+
u8 umr_modify_atomic_disabled[0x1];
923+
u8 umr_indirect_mkey_disabled[0x1];
920924
u8 umr_fence[0x2];
921925
u8 reserved_at_20c[0x3];
922926
u8 drain_sigerr[0x1];

0 commit comments

Comments
 (0)