Skip to content

Commit b005d31

Browse files
Sagi Grimbergdledford
authored andcommitted
mlx5: Add arbitrary sg list support
Allocate proper context for arbitrary scatterlist registration If ib_alloc_mr is called with IB_MR_MAP_ARB_SG, the driver allocate a private klm list instead of a private page list. Set the UMR wqe correctly when posting the fast registration. Also, expose device cap IB_DEVICE_MAP_ARB_SG according to the device id (until we have a FW bit that correctly exposes it). Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent f5aa915 commit b005d31

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
491491
props->device_cap_flags |= IB_DEVICE_MEM_WINDOW |
492492
IB_DEVICE_MEM_WINDOW_TYPE_2B;
493493
props->max_mw = 1 << MLX5_CAP_GEN(mdev, log_max_mkey);
494+
/* We support 'Gappy' memory registration too */
495+
props->device_cap_flags |= IB_DEVICE_SG_GAPS_REG;
494496
}
495497
props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
496498
if (MLX5_CAP_GEN(mdev, sho)) {

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ struct mlx5_ib_mr {
447447
int ndescs;
448448
int max_descs;
449449
int desc_size;
450+
int access_mode;
450451
struct mlx5_core_mkey mmkey;
451452
struct ib_umem *umem;
452453
struct mlx5_shared_mr_info *smr_info;

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,8 +1521,8 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
15211521
struct mlx5_ib_dev *dev = to_mdev(pd->device);
15221522
struct mlx5_create_mkey_mbox_in *in;
15231523
struct mlx5_ib_mr *mr;
1524-
int access_mode, err;
1525-
int ndescs = roundup(max_num_sg, 4);
1524+
int ndescs = ALIGN(max_num_sg, 4);
1525+
int err;
15261526

15271527
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
15281528
if (!mr)
@@ -1540,7 +1540,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
15401540
in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
15411541

15421542
if (mr_type == IB_MR_TYPE_MEM_REG) {
1543-
access_mode = MLX5_ACCESS_MODE_MTT;
1543+
mr->access_mode = MLX5_ACCESS_MODE_MTT;
15441544
in->seg.log2_page_size = PAGE_SHIFT;
15451545

15461546
err = mlx5_alloc_priv_descs(pd->device, mr,
@@ -1550,6 +1550,15 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
15501550

15511551
mr->desc_size = sizeof(u64);
15521552
mr->max_descs = ndescs;
1553+
} else if (mr_type == IB_MR_TYPE_SG_GAPS) {
1554+
mr->access_mode = MLX5_ACCESS_MODE_KLM;
1555+
1556+
err = mlx5_alloc_priv_descs(pd->device, mr,
1557+
ndescs, sizeof(struct mlx5_klm));
1558+
if (err)
1559+
goto err_free_in;
1560+
mr->desc_size = sizeof(struct mlx5_klm);
1561+
mr->max_descs = ndescs;
15531562
} else if (mr_type == IB_MR_TYPE_SIGNATURE) {
15541563
u32 psv_index[2];
15551564

@@ -1568,7 +1577,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
15681577
if (err)
15691578
goto err_free_sig;
15701579

1571-
access_mode = MLX5_ACCESS_MODE_KLM;
1580+
mr->access_mode = MLX5_ACCESS_MODE_KLM;
15721581
mr->sig->psv_memory.psv_idx = psv_index[0];
15731582
mr->sig->psv_wire.psv_idx = psv_index[1];
15741583

@@ -1582,7 +1591,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
15821591
goto err_free_in;
15831592
}
15841593

1585-
in->seg.flags = MLX5_PERM_UMR_EN | access_mode;
1594+
in->seg.flags = MLX5_PERM_UMR_EN | mr->access_mode;
15861595
err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, sizeof(*in),
15871596
NULL, NULL, NULL);
15881597
if (err)
@@ -1739,6 +1748,32 @@ int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
17391748
return ret;
17401749
}
17411750

1751+
static int
1752+
mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr,
1753+
struct scatterlist *sgl,
1754+
unsigned short sg_nents)
1755+
{
1756+
struct scatterlist *sg = sgl;
1757+
struct mlx5_klm *klms = mr->descs;
1758+
u32 lkey = mr->ibmr.pd->local_dma_lkey;
1759+
int i;
1760+
1761+
mr->ibmr.iova = sg_dma_address(sg);
1762+
mr->ibmr.length = 0;
1763+
mr->ndescs = sg_nents;
1764+
1765+
for_each_sg(sgl, sg, sg_nents, i) {
1766+
if (unlikely(i > mr->max_descs))
1767+
break;
1768+
klms[i].va = cpu_to_be64(sg_dma_address(sg));
1769+
klms[i].bcount = cpu_to_be32(sg_dma_len(sg));
1770+
klms[i].key = cpu_to_be32(lkey);
1771+
mr->ibmr.length += sg_dma_len(sg);
1772+
}
1773+
1774+
return i;
1775+
}
1776+
17421777
static int mlx5_set_page(struct ib_mr *ibmr, u64 addr)
17431778
{
17441779
struct mlx5_ib_mr *mr = to_mmr(ibmr);
@@ -1766,7 +1801,10 @@ int mlx5_ib_map_mr_sg(struct ib_mr *ibmr,
17661801
mr->desc_size * mr->max_descs,
17671802
DMA_TO_DEVICE);
17681803

1769-
n = ib_sg_to_pages(ibmr, sg, sg_nents, mlx5_set_page);
1804+
if (mr->access_mode == MLX5_ACCESS_MODE_KLM)
1805+
n = mlx5_ib_sg_to_klms(mr, sg, sg_nents);
1806+
else
1807+
n = ib_sg_to_pages(ibmr, sg, sg_nents, mlx5_set_page);
17701808

17711809
ib_dma_sync_single_for_device(ibmr->device, mr->desc_map,
17721810
mr->desc_size * mr->max_descs,

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,11 @@ static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr,
26292629
int ndescs = mr->ndescs;
26302630

26312631
memset(umr, 0, sizeof(*umr));
2632+
2633+
if (mr->access_mode == MLX5_ACCESS_MODE_KLM)
2634+
/* KLMs take twice the size of MTTs */
2635+
ndescs *= 2;
2636+
26322637
umr->flags = MLX5_UMR_CHECK_NOT_FREE;
26332638
umr->klm_octowords = get_klm_octo(ndescs);
26342639
umr->mkey_mask = frwr_mkey_mask();
@@ -2767,13 +2772,19 @@ static void set_reg_mkey_seg(struct mlx5_mkey_seg *seg,
27672772
int ndescs = ALIGN(mr->ndescs, 8) >> 1;
27682773

27692774
memset(seg, 0, sizeof(*seg));
2770-
seg->flags = get_umr_flags(access) | MLX5_ACCESS_MODE_MTT;
2775+
2776+
if (mr->access_mode == MLX5_ACCESS_MODE_MTT)
2777+
seg->log2_page_size = ilog2(mr->ibmr.page_size);
2778+
else if (mr->access_mode == MLX5_ACCESS_MODE_KLM)
2779+
/* KLMs take twice the size of MTTs */
2780+
ndescs *= 2;
2781+
2782+
seg->flags = get_umr_flags(access) | mr->access_mode;
27712783
seg->qpn_mkey7_0 = cpu_to_be32((key & 0xff) | 0xffffff00);
27722784
seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
27732785
seg->start_addr = cpu_to_be64(mr->ibmr.iova);
27742786
seg->len = cpu_to_be64(mr->ibmr.length);
27752787
seg->xlt_oct_size = cpu_to_be32(ndescs);
2776-
seg->log2_page_size = ilog2(mr->ibmr.page_size);
27772788
}
27782789

27792790
static void set_linv_mkey_seg(struct mlx5_mkey_seg *seg)

0 commit comments

Comments
 (0)