[RFC PATCH v2 2/3] RDMA/core: Expand the driver method 'reg_user_mr' to support dma-buf
Xiong, Jianxin
jianxin.xiong at intel.com
Tue Jun 30 19:04:41 UTC 2020
Cc'd drm people.
> -----Original Message-----
> From: Xiong, Jianxin <jianxin.xiong at intel.com>
> Sent: Monday, June 29, 2020 10:32 AM
> To: linux-rdma at vger.kernel.org
> Cc: Xiong, Jianxin <jianxin.xiong at intel.com>; Doug Ledford <dledford at redhat.com>; Jason Gunthorpe <jgg at ziepe.ca>; Sumit Semwal
> <sumit.semwal at linaro.org>; Leon Romanovsky <leon at kernel.org>; Vetter, Daniel <daniel.vetter at intel.com>
> Subject: [RFC PATCH v2 2/3] RDMA/core: Expand the driver method 'reg_user_mr' to support dma-buf
>
> Add a parameter 'fd' for the file descriptor associated with the dma-buf
> object to be imported. A negative value indicates that dma-buf is not
> used.
>
> Signed-off-by: Jianxin Xiong <jianxin.xiong at intel.com>
> Reviewed-by: Sean Hefty <sean.hefty at intel.com>
> Acked-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
> ---
> drivers/infiniband/core/uverbs_cmd.c | 2 +-
> drivers/infiniband/core/verbs.c | 2 +-
> drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +++-
> drivers/infiniband/hw/bnxt_re/ib_verbs.h | 2 +-
> drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 3 +-
> drivers/infiniband/hw/cxgb4/mem.c | 8 ++++-
> drivers/infiniband/hw/efa/efa.h | 2 +-
> drivers/infiniband/hw/efa/efa_verbs.c | 7 +++-
> drivers/infiniband/hw/hns/hns_roce_device.h | 2 +-
> drivers/infiniband/hw/hns/hns_roce_mr.c | 7 +++-
> drivers/infiniband/hw/i40iw/i40iw_verbs.c | 6 ++++
> drivers/infiniband/hw/mlx4/mlx4_ib.h | 2 +-
> drivers/infiniband/hw/mlx4/mr.c | 7 +++-
> drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +-
> drivers/infiniband/hw/mlx5/mr.c | 45 ++++++++++++++++++++++---
> drivers/infiniband/hw/mthca/mthca_provider.c | 8 ++++-
> drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 9 ++++-
> drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | 3 +-
> drivers/infiniband/hw/qedr/verbs.c | 8 ++++-
> drivers/infiniband/hw/qedr/verbs.h | 3 +-
> drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 ++++-
> drivers/infiniband/hw/usnic/usnic_ib_verbs.h | 2 +-
> drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c | 6 +++-
> drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h | 2 +-
> drivers/infiniband/sw/rdmavt/mr.c | 6 +++-
> drivers/infiniband/sw/rdmavt/mr.h | 2 +-
> drivers/infiniband/sw/rxe/rxe_verbs.c | 6 ++++
> drivers/infiniband/sw/siw/siw_verbs.c | 8 ++++-
> drivers/infiniband/sw/siw/siw_verbs.h | 3 +-
> include/rdma/ib_verbs.h | 4 +--
> 30 files changed, 150 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index 060b4eb..0199da2 100644
> --- a/drivers/infiniband/core/uverbs_cmd.c
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -757,7 +757,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
> }
>
> mr = pd->device->ops.reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
> - cmd.access_flags,
> + -1, cmd.access_flags,
> &attrs->driver_udata);
> if (IS_ERR(mr)) {
> ret = PTR_ERR(mr);
> diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
> index 56a7133..aa067b2 100644
> --- a/drivers/infiniband/core/verbs.c
> +++ b/drivers/infiniband/core/verbs.c
> @@ -2003,7 +2003,7 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> }
>
> mr = pd->device->ops.reg_user_mr(pd, start, length, virt_addr,
> - access_flags, NULL);
> + -1, access_flags, NULL);
>
> if (IS_ERR(mr))
> return mr;
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index 95f6d49..af40457 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -3695,7 +3695,7 @@ static int fill_umem_pbl_tbl(struct ib_umem *umem, u64 *pbl_tbl_orig,
>
> /* uverbs */
> struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
> - u64 virt_addr, int mr_access_flags,
> + u64 virt_addr, int fd, int mr_access_flags,
> struct ib_udata *udata)
> {
> struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
> @@ -3728,6 +3728,11 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
> /* The fixed portion of the rkey is the same as the lkey */
> mr->ib_mr.rkey = mr->qplib_mr.rkey;
>
> + if (fd >= 0) {
> + rc = -EOPNOTSUPP;
> + goto free_mrw;
> + }
> +
> umem = ib_umem_get(&rdev->ibdev, start, length, mr_access_flags);
> if (IS_ERR(umem)) {
> ibdev_err(&rdev->ibdev, "Failed to get umem");
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> index 23d972d..040e85e 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> @@ -203,7 +203,7 @@ struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,
> struct ib_udata *udata);
> int bnxt_re_dealloc_mw(struct ib_mw *mw);
> struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int mr_access_flags,
> + u64 virt_addr, int fd, int mr_access_flags,
> struct ib_udata *udata);
> int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata);
> void bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
> diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> index e8e11bd..e374f89 100644
> --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> @@ -988,7 +988,8 @@ int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
> struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
> struct ib_udata *udata);
> struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
> - u64 length, u64 virt, int acc,
> + u64 length, u64 virt,
> + int fd, int acc,
> struct ib_udata *udata);
> struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
> int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
> diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
> index 962dc97..b0b912a 100644
> --- a/drivers/infiniband/hw/cxgb4/mem.c
> +++ b/drivers/infiniband/hw/cxgb4/mem.c
> @@ -506,7 +506,8 @@ struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc)
> }
>
> struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt, int acc, struct ib_udata *udata)
> + u64 virt, int fd, int acc,
> + struct ib_udata *udata)
> {
> __be64 *pages;
> int shift, n, i;
> @@ -543,6 +544,11 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
>
> mhp->rhp = rhp;
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err_free_skb;
> + }
> +
> mhp->umem = ib_umem_get(pd->device, start, length, acc);
> if (IS_ERR(mhp->umem))
> goto err_free_skb;
> diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h
> index aa7396a..21872a3 100644
> --- a/drivers/infiniband/hw/efa/efa.h
> +++ b/drivers/infiniband/hw/efa/efa.h
> @@ -142,7 +142,7 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
> int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
> struct ib_udata *udata);
> struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
> int efa_get_port_immutable(struct ib_device *ibdev, u8 port_num,
> diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
> index bf3120f..1362694 100644
> --- a/drivers/infiniband/hw/efa/efa_verbs.c
> +++ b/drivers/infiniband/hw/efa/efa_verbs.c
> @@ -1346,7 +1346,7 @@ static int efa_create_pbl(struct efa_dev *dev,
> }
>
> struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata)
> {
> struct efa_dev *dev = to_edev(ibpd->device);
> @@ -1386,6 +1386,11 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
> goto err_out;
> }
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err_free;
> + }
> +
> mr->umem = ib_umem_get(ibpd->device, start, length, access_flags);
> if (IS_ERR(mr->umem)) {
> err = PTR_ERR(mr->umem);
> diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
> index d7dcf6e..c2b94c6 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_device.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_device.h
> @@ -1185,7 +1185,7 @@ int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
>
> struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc);
> struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int hns_roce_rereg_user_mr(struct ib_mr *mr, int flags, u64 start, u64 length,
> u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
> diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
> index b9898e7..24dd79a 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_mr.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> @@ -1130,7 +1130,7 @@ static int hns_roce_ib_umem_write_mr(struct hns_roce_dev *hr_dev,
> }
>
> struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata)
> {
> struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
> @@ -1145,6 +1145,11 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> if (!mr)
> return ERR_PTR(-ENOMEM);
>
> + if (fd >= 0) {
> + ret = ERR_PTR(-EOPNOTSUPP);
> + goto err_free;
> + }
> +
> mr->umem = ib_umem_get(pd->device, start, length, access_flags);
> if (IS_ERR(mr->umem)) {
> ret = PTR_ERR(mr->umem);
> diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
> index fa12929..d86bf12 100644
> --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
> +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
> @@ -1727,6 +1727,7 @@ static int i40iw_hwreg_mr(struct i40iw_device *iwdev,
> * @start: virtual start address
> * @length: length of mr
> * @virt: virtual address
> + * @fd: file descriptor (for dma-buf)
> * @acc: access of mr
> * @udata: user data
> */
> @@ -1734,6 +1735,7 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
> u64 start,
> u64 length,
> u64 virt,
> + int fd,
> int acc,
> struct ib_udata *udata)
> {
> @@ -1764,6 +1766,10 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
>
> if (length > I40IW_MAX_MR_SIZE)
> return ERR_PTR(-EINVAL);
> +
> + if (fd >= 0)
> + return ERR_PTR(-EOPNOTSUPP);
> +
> region = ib_umem_get(pd->device, start, length, acc);
> if (IS_ERR(region))
> return (struct ib_mr *)region;
> diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
> index d188573..d9db34b 100644
> --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
> +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
> @@ -732,7 +732,7 @@ int mlx4_ib_db_map_user(struct ib_udata *udata, unsigned long virt,
> int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt,
> struct ib_umem *umem);
> struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int mlx4_ib_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
> struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
> diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
> index b0121c9..db45abb 100644
> --- a/drivers/infiniband/hw/mlx4/mr.c
> +++ b/drivers/infiniband/hw/mlx4/mr.c
> @@ -402,7 +402,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
> }
>
> struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata)
> {
> struct mlx4_ib_dev *dev = to_mdev(pd->device);
> @@ -415,6 +415,11 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> if (!mr)
> return ERR_PTR(-ENOMEM);
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err_free;
> + }
> +
> mr->umem = mlx4_get_umem_mr(pd->device, start, length, access_flags);
> if (IS_ERR(mr->umem)) {
> err = PTR_ERR(mr->umem);
> diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
> index 2e42258..5df9f0e 100644
> --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
> +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
> @@ -1189,7 +1189,7 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
> int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
> struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc);
> struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int mlx5_ib_advise_mr(struct ib_pd *pd,
> enum ib_uverbs_advise_mr_advice advice,
> diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
> index 6fa0a83..bd06e35 100644
> --- a/drivers/infiniband/hw/mlx5/mr.c
> +++ b/drivers/infiniband/hw/mlx5/mr.c
> @@ -797,6 +797,39 @@ static int mr_umem_get(struct mlx5_ib_dev *dev, u64 start, u64 length,
> return 0;
> }
>
> +static int mr_umem_dmabuf_get(struct mlx5_ib_dev *dev, u64 start, u64 length,
> + int dmabuf_fd, int access_flags,
> + struct ib_umem **umem, int *npages,
> + int *page_shift, int *ncont, int *order)
> +{
> + struct ib_umem *u;
> +
> + *umem = NULL;
> +
> + u = ib_umem_dmabuf_get(&dev->ib_dev, start, length, dmabuf_fd,
> + access_flags);
> + if (IS_ERR(u)) {
> + mlx5_ib_dbg(dev, "umem get failed (%ld)\n", PTR_ERR(u));
> + return PTR_ERR(u);
> + }
> +
> + mlx5_ib_cont_pages(u, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages,
> + page_shift, ncont, order);
> +
> + if (!*npages) {
> + mlx5_ib_warn(dev, "avoid zero region\n");
> + ib_umem_release(u);
> + return -EINVAL;
> + }
> +
> + *umem = u;
> +
> + mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n",
> + *npages, *ncont, *order, *page_shift);
> +
> + return 0;
> +}
> +
> static void mlx5_ib_umr_done(struct ib_cq *cq, struct ib_wc *wc)
> {
> struct mlx5_ib_umr_context *context =
> @@ -1228,7 +1261,7 @@ struct ib_mr *mlx5_ib_reg_dm_mr(struct ib_pd *pd, struct ib_dm *dm,
> }
>
> struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata)
> {
> struct mlx5_ib_dev *dev = to_mdev(pd->device);
> @@ -1261,9 +1294,13 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> return &mr->ibmr;
> }
>
> - err = mr_umem_get(dev, start, length, access_flags, &umem,
> - &npages, &page_shift, &ncont, &order);
> -
> + if (fd < 0)
> + err = mr_umem_get(dev, start, length, access_flags, &umem,
> + &npages, &page_shift, &ncont, &order);
> + else
> + err = mr_umem_dmabuf_get(dev, start, length, fd, access_flags,
> + &umem, &npages, &page_shift, &ncont,
> + &order);
> if (err < 0)
> return ERR_PTR(err);
>
> diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
> index 69a3e4f..f1f93af 100644
> --- a/drivers/infiniband/hw/mthca/mthca_provider.c
> +++ b/drivers/infiniband/hw/mthca/mthca_provider.c
> @@ -852,7 +852,8 @@ static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
> }
>
> static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt, int acc, struct ib_udata *udata)
> + u64 virt, int fd, int acc,
> + struct ib_udata *udata)
> {
> struct mthca_dev *dev = to_mdev(pd->device);
> struct sg_dma_page_iter sg_iter;
> @@ -880,6 +881,11 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> if (!mr)
> return ERR_PTR(-ENOMEM);
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err;
> + }
> +
> mr->umem = ib_umem_get(pd->device, start, length, acc);
> if (IS_ERR(mr->umem)) {
> err = PTR_ERR(mr->umem);
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> index 10e3438..2c25244 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> @@ -853,7 +853,8 @@ static void build_user_pbes(struct ocrdma_dev *dev, struct ocrdma_mr *mr,
> }
>
> struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
> - u64 usr_addr, int acc, struct ib_udata *udata)
> + u64 usr_addr, int fd, int acc,
> + struct ib_udata *udata)
> {
> int status = -ENOMEM;
> struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
> @@ -869,6 +870,12 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
> mr = kzalloc(sizeof(*mr), GFP_KERNEL);
> if (!mr)
> return ERR_PTR(status);
> +
> + if (fd >= 0) {
> + status = -EOPNOTSUPP;
> + goto umem_err;
> + }
> +
> mr->umem = ib_umem_get(ibpd->device, start, len, acc);
> if (IS_ERR(mr->umem)) {
> status = -EFAULT;
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> index 3a50108..bc3660e 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> @@ -99,7 +99,8 @@ int ocrdma_post_srq_recv(struct ib_srq *, const struct ib_recv_wr *,
> int ocrdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
> struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *, int acc);
> struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length,
> - u64 virt, int acc, struct ib_udata *);
> + u64 virt, int fd, int acc,
> + struct ib_udata *);
> struct ib_mr *ocrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
> u32 max_num_sg, struct ib_udata *udata);
> int ocrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
> diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
> index a5bd3ad..95e865c 100644
> --- a/drivers/infiniband/hw/qedr/verbs.c
> +++ b/drivers/infiniband/hw/qedr/verbs.c
> @@ -2828,7 +2828,8 @@ static int init_mr_info(struct qedr_dev *dev, struct mr_info *info,
> }
>
> struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
> - u64 usr_addr, int acc, struct ib_udata *udata)
> + u64 usr_addr, int fd, int acc,
> + struct ib_udata *udata)
> {
> struct qedr_dev *dev = get_qedr_dev(ibpd->device);
> struct qedr_mr *mr;
> @@ -2849,6 +2850,11 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
>
> mr->type = QEDR_MR_USER;
>
> + if (fd >= 0) {
> + rc = -EOPNOTSUPP;
> + goto err0;
> + }
> +
> mr->umem = ib_umem_get(ibpd->device, start, len, acc);
> if (IS_ERR(mr->umem)) {
> rc = -EFAULT;
> diff --git a/drivers/infiniband/hw/qedr/verbs.h b/drivers/infiniband/hw/qedr/verbs.h
> index 1802784..78effd1 100644
> --- a/drivers/infiniband/hw/qedr/verbs.h
> +++ b/drivers/infiniband/hw/qedr/verbs.h
> @@ -78,7 +78,8 @@ int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
> struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
>
> struct ib_mr *qedr_reg_user_mr(struct ib_pd *, u64 start, u64 length,
> - u64 virt, int acc, struct ib_udata *);
> + u64 virt, int fd, int acc,
> + struct ib_udata *);
>
> int qedr_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
> int sg_nents, unsigned int *sg_offset);
> diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
> index 71f8233..58ed9d1 100644
> --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
> +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
> @@ -603,7 +603,8 @@ void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
> }
>
> struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd,
> + int access_flags,
> struct ib_udata *udata)
> {
> struct usnic_ib_mr *mr;
> @@ -616,6 +617,11 @@ struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
> if (!mr)
> return ERR_PTR(-ENOMEM);
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err_free;
> + }
> +
> mr->umem = usnic_uiom_reg_get(to_upd(pd)->umem_pd, start, length,
> access_flags, 0);
> if (IS_ERR_OR_NULL(mr->umem)) {
> diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
> index 2aedf78..42ba8b7 100644
> --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
> +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
> @@ -62,7 +62,7 @@ int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
> struct ib_udata *udata);
> void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
> struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int usnic_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
> int usnic_ib_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata);
> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
> index b039f1f..8b8b10c 100644
> --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
> @@ -103,13 +103,14 @@ struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc)
> * @start: starting address
> * @length: length of region
> * @virt_addr: I/O virtual address
> + * @fd: file descriptor (for dma-buf)
> * @access_flags: access flags for memory region
> * @udata: user data
> *
> * @return: ib_mr pointer on success, otherwise returns an errno.
> */
> struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata)
> {
> struct pvrdma_dev *dev = to_vdev(pd->device);
> @@ -126,6 +127,9 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> return ERR_PTR(-EINVAL);
> }
>
> + if (fd >= 0)
> + return ERR_PTR(-EOPNOTSUPP);
> +
> umem = ib_umem_get(pd->device, start, length, access_flags);
> if (IS_ERR(umem)) {
> dev_warn(&dev->pdev->dev,
> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> index e4a48f5..7bee943 100644
> --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> @@ -402,7 +402,7 @@ int pvrdma_modify_port(struct ib_device *ibdev, u8 port,
> void pvrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
> struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc);
> struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int access_flags,
> + u64 virt_addr, int fd, int access_flags,
> struct ib_udata *udata);
> int pvrdma_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
> struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
> diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c
> index 72f6534..cbd54de 100644
> --- a/drivers/infiniband/sw/rdmavt/mr.c
> +++ b/drivers/infiniband/sw/rdmavt/mr.c
> @@ -372,13 +372,14 @@ struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc)
> * @pd: protection domain for this memory region
> * @start: starting userspace address
> * @length: length of region to register
> + * @fd: file descriptor (for dma-buf)
> * @mr_access_flags: access flags for this memory region
> * @udata: unused by the driver
> *
> * Return: the memory region on success, otherwise returns an errno.
> */
> struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int mr_access_flags,
> + u64 virt_addr, int fd, int mr_access_flags,
> struct ib_udata *udata)
> {
> struct rvt_mr *mr;
> @@ -390,6 +391,9 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> if (length == 0)
> return ERR_PTR(-EINVAL);
>
> + if (fd >= 0)
> + return ERR_PTR(-EOPNOTSUPP);
> +
> umem = ib_umem_get(pd->device, start, length, mr_access_flags);
> if (IS_ERR(umem))
> return (void *)umem;
> diff --git a/drivers/infiniband/sw/rdmavt/mr.h b/drivers/infiniband/sw/rdmavt/mr.h
> index 2c8d075..9d38d7d 100644
> --- a/drivers/infiniband/sw/rdmavt/mr.h
> +++ b/drivers/infiniband/sw/rdmavt/mr.h
> @@ -76,7 +76,7 @@ static inline struct rvt_mr *to_imr(struct ib_mr *ibmr)
> /* Mem Regions */
> struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc);
> struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int mr_access_flags,
> + u64 virt_addr, int fd, int mr_access_flags,
> struct ib_udata *udata);
> int rvt_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
> struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
> diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
> index 9dd4bd7..f5f4cbe 100644
> --- a/drivers/infiniband/sw/rxe/rxe_verbs.c
> +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
> @@ -930,6 +930,7 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
> u64 start,
> u64 length,
> u64 iova,
> + int fd,
> int access, struct ib_udata *udata)
> {
> int err;
> @@ -947,6 +948,11 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
>
> rxe_add_ref(pd);
>
> + if (fd >= 0) {
> + err = -EOPNOTSUPP;
> + goto err3;
> + }
> +
> err = rxe_mem_init_user(pd, start, length, iova,
> access, udata, mr);
> if (err)
> diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
> index aeb842b..e88c077 100644
> --- a/drivers/infiniband/sw/siw/siw_verbs.c
> +++ b/drivers/infiniband/sw/siw/siw_verbs.c
> @@ -1275,11 +1275,13 @@ int siw_dereg_mr(struct ib_mr *base_mr, struct ib_udata *udata)
> * @start: starting address of MR (virtual address)
> * @len: len of MR
> * @rnic_va: not used by siw
> + * @fd: file descriptor (for dma-buf)
> * @rights: MR access rights
> * @udata: user buffer to communicate STag and Key.
> */
> struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
> - u64 rnic_va, int rights, struct ib_udata *udata)
> + u64 rnic_va, int fd, int rights,
> + struct ib_udata *udata)
> {
> struct siw_mr *mr = NULL;
> struct siw_umem *umem = NULL;
> @@ -1315,6 +1317,10 @@ struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
> goto err_out;
> }
> }
> + if (fd >= 0) {
> + rv = -EOPNOTSPP;
> + goto err_out;
> + }
> umem = siw_umem_get(start, len, ib_access_writable(rights));
> if (IS_ERR(umem)) {
> rv = PTR_ERR(umem);
> diff --git a/drivers/infiniband/sw/siw/siw_verbs.h b/drivers/infiniband/sw/siw/siw_verbs.h
> index 1a73198..e08bf51 100644
> --- a/drivers/infiniband/sw/siw/siw_verbs.h
> +++ b/drivers/infiniband/sw/siw/siw_verbs.h
> @@ -67,7 +67,8 @@ int siw_post_receive(struct ib_qp *base_qp, const struct ib_recv_wr *wr,
> int siw_poll_cq(struct ib_cq *base_cq, int num_entries, struct ib_wc *wc);
> int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags);
> struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd, u64 start, u64 len,
> - u64 rnic_va, int rights, struct ib_udata *udata);
> + u64 rnic_va, int fd, int rights,
> + struct ib_udata *udata);
> struct ib_mr *siw_alloc_mr(struct ib_pd *base_pd, enum ib_mr_type mr_type,
> u32 max_sge, struct ib_udata *udata);
> struct ib_mr *siw_get_dma_mr(struct ib_pd *base_pd, int rights);
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index bbc5cfb..12a45a7 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1,7 +1,7 @@
> /*
> * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
> * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
> - * Copyright (c) 2004 Intel Corporation. All rights reserved.
> + * Copyright (c) 2004, 2020 Intel Corporation. All rights reserved.
> * Copyright (c) 2004 Topspin Corporation. All rights reserved.
> * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
> * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
> @@ -2431,7 +2431,7 @@ struct ib_device_ops {
> int (*resize_cq)(struct ib_cq *cq, int cqe, struct ib_udata *udata);
> struct ib_mr *(*get_dma_mr)(struct ib_pd *pd, int mr_access_flags);
> struct ib_mr *(*reg_user_mr)(struct ib_pd *pd, u64 start, u64 length,
> - u64 virt_addr, int mr_access_flags,
> + u64 virt_addr, int fd, int mr_access_flags,
> struct ib_udata *udata);
> int (*rereg_user_mr)(struct ib_mr *mr, int flags, u64 start, u64 length,
> u64 virt_addr, int mr_access_flags,
> --
> 1.8.3.1
More information about the dri-devel
mailing list