Skip to content

Commit d2370e0

Browse files
matanb10dledford
authored andcommitted
IB/mlx5: Add memory windows allocation support
This patch adds user-space support for memory windows allocation and deallocation. It also exposes the supported types via query_device_caps verb. Signed-off-by: Matan Barak <[email protected]> Reviewed-by: Yishai Hadas <[email protected]> Tested-by: Max Gurtovoy <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent b2a239d commit d2370e0

File tree

5 files changed

+120
-1
lines changed

5 files changed

+120
-1
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,11 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
487487
props->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG;
488488
if (MLX5_CAP_GEN(mdev, xrc))
489489
props->device_cap_flags |= IB_DEVICE_XRC;
490+
if (MLX5_CAP_GEN(mdev, imaicl)) {
491+
props->device_cap_flags |= IB_DEVICE_MEM_WINDOW |
492+
IB_DEVICE_MEM_WINDOW_TYPE_2B;
493+
props->max_mw = 1 << MLX5_CAP_GEN(mdev, log_max_mkey);
494+
}
490495
props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
491496
if (MLX5_CAP_GEN(mdev, sho)) {
492497
props->device_cap_flags |= IB_DEVICE_SIGNATURE_HANDOVER;
@@ -2306,6 +2311,14 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
23062311

23072312
mlx5_ib_internal_fill_odp_caps(dev);
23082313

2314+
if (MLX5_CAP_GEN(mdev, imaicl)) {
2315+
dev->ib_dev.alloc_mw = mlx5_ib_alloc_mw;
2316+
dev->ib_dev.dealloc_mw = mlx5_ib_dealloc_mw;
2317+
dev->ib_dev.uverbs_cmd_mask |=
2318+
(1ull << IB_USER_VERBS_CMD_ALLOC_MW) |
2319+
(1ull << IB_USER_VERBS_CMD_DEALLOC_MW);
2320+
}
2321+
23092322
if (MLX5_CAP_GEN(mdev, xrc)) {
23102323
dev->ib_dev.alloc_xrcd = mlx5_ib_alloc_xrcd;
23112324
dev->ib_dev.dealloc_xrcd = mlx5_ib_dealloc_xrcd;

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <linux/mlx5/srq.h>
4444
#include <linux/types.h>
4545
#include <linux/mlx5/transobj.h>
46+
#include <rdma/ib_user_verbs.h>
4647

4748
#define mlx5_ib_dbg(dev, format, arg...) \
4849
pr_debug("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__, \
@@ -461,6 +462,11 @@ struct mlx5_ib_mr {
461462
int access_flags; /* Needed for rereg MR */
462463
};
463464

465+
struct mlx5_ib_mw {
466+
struct ib_mw ibmw;
467+
struct mlx5_core_mkey mmkey;
468+
};
469+
464470
struct mlx5_ib_umr_context {
465471
enum ib_wc_status status;
466472
struct completion done;
@@ -633,6 +639,11 @@ static inline struct mlx5_ib_mr *to_mmr(struct ib_mr *ibmr)
633639
return container_of(ibmr, struct mlx5_ib_mr, ibmr);
634640
}
635641

642+
static inline struct mlx5_ib_mw *to_mmw(struct ib_mw *ibmw)
643+
{
644+
return container_of(ibmw, struct mlx5_ib_mw, ibmw);
645+
}
646+
636647
struct mlx5_ib_ah {
637648
struct ib_ah ibah;
638649
struct mlx5_av av;
@@ -693,6 +704,9 @@ struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc);
693704
struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
694705
u64 virt_addr, int access_flags,
695706
struct ib_udata *udata);
707+
struct ib_mw *mlx5_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
708+
struct ib_udata *udata);
709+
int mlx5_ib_dealloc_mw(struct ib_mw *mw);
696710
int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index,
697711
int npages, int zap);
698712
int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <rdma/ib_umem_odp.h>
4141
#include <rdma/ib_verbs.h>
4242
#include "mlx5_ib.h"
43+
#include "user.h"
4344

4445
enum {
4546
MAX_PENDING_REG_MR = 8,
@@ -1620,6 +1621,88 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
16201621
return ERR_PTR(err);
16211622
}
16221623

1624+
struct ib_mw *mlx5_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
1625+
struct ib_udata *udata)
1626+
{
1627+
struct mlx5_ib_dev *dev = to_mdev(pd->device);
1628+
struct mlx5_create_mkey_mbox_in *in = NULL;
1629+
struct mlx5_ib_mw *mw = NULL;
1630+
int ndescs;
1631+
int err;
1632+
struct mlx5_ib_alloc_mw req = {};
1633+
struct {
1634+
__u32 comp_mask;
1635+
__u32 response_length;
1636+
} resp = {};
1637+
1638+
err = ib_copy_from_udata(&req, udata, min(udata->inlen, sizeof(req)));
1639+
if (err)
1640+
return ERR_PTR(err);
1641+
1642+
if (req.comp_mask || req.reserved1 || req.reserved2)
1643+
return ERR_PTR(-EOPNOTSUPP);
1644+
1645+
if (udata->inlen > sizeof(req) &&
1646+
!ib_is_udata_cleared(udata, sizeof(req),
1647+
udata->inlen - sizeof(req)))
1648+
return ERR_PTR(-EOPNOTSUPP);
1649+
1650+
ndescs = req.num_klms ? roundup(req.num_klms, 4) : roundup(1, 4);
1651+
1652+
mw = kzalloc(sizeof(*mw), GFP_KERNEL);
1653+
in = kzalloc(sizeof(*in), GFP_KERNEL);
1654+
if (!mw || !in) {
1655+
err = -ENOMEM;
1656+
goto free;
1657+
}
1658+
1659+
in->seg.status = MLX5_MKEY_STATUS_FREE;
1660+
in->seg.xlt_oct_size = cpu_to_be32(ndescs);
1661+
in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
1662+
in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_KLM |
1663+
MLX5_PERM_LOCAL_READ;
1664+
if (type == IB_MW_TYPE_2)
1665+
in->seg.flags_pd |= cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
1666+
in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
1667+
1668+
err = mlx5_core_create_mkey(dev->mdev, &mw->mmkey, in, sizeof(*in),
1669+
NULL, NULL, NULL);
1670+
if (err)
1671+
goto free;
1672+
1673+
mw->ibmw.rkey = mw->mmkey.key;
1674+
1675+
resp.response_length = min(offsetof(typeof(resp), response_length) +
1676+
sizeof(resp.response_length), udata->outlen);
1677+
if (resp.response_length) {
1678+
err = ib_copy_to_udata(udata, &resp, resp.response_length);
1679+
if (err) {
1680+
mlx5_core_destroy_mkey(dev->mdev, &mw->mmkey);
1681+
goto free;
1682+
}
1683+
}
1684+
1685+
kfree(in);
1686+
return &mw->ibmw;
1687+
1688+
free:
1689+
kfree(mw);
1690+
kfree(in);
1691+
return ERR_PTR(err);
1692+
}
1693+
1694+
int mlx5_ib_dealloc_mw(struct ib_mw *mw)
1695+
{
1696+
struct mlx5_ib_mw *mmw = to_mmw(mw);
1697+
int err;
1698+
1699+
err = mlx5_core_destroy_mkey((to_mdev(mw->device))->mdev,
1700+
&mmw->mmkey);
1701+
if (!err)
1702+
kfree(mmw);
1703+
return err;
1704+
}
1705+
16231706
int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
16241707
struct ib_mr_status *mr_status)
16251708
{

drivers/infiniband/hw/mlx5/user.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ struct mlx5_ib_create_qp_resp {
152152
__u32 uuar_index;
153153
};
154154

155+
struct mlx5_ib_alloc_mw {
156+
__u32 comp_mask;
157+
__u8 num_klms;
158+
__u8 reserved1;
159+
__u16 reserved2;
160+
};
161+
155162
static inline int get_qp_user_index(struct mlx5_ib_ucontext *ucontext,
156163
struct mlx5_ib_create_qp *ucmd,
157164
int inlen,

include/linux/mlx5/mlx5_ifc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
769769
u8 cd[0x1];
770770
u8 reserved_at_22c[0x1];
771771
u8 apm[0x1];
772-
u8 reserved_at_22e[0x7];
772+
u8 reserved_at_22e[0x2];
773+
u8 imaicl[0x1];
774+
u8 reserved_at_231[0x4];
773775
u8 qkv[0x1];
774776
u8 pkv[0x1];
775777
u8 set_deth_sqpn[0x1];

0 commit comments

Comments
 (0)