svn commit: r331011 - projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Mar 15 17:14:52 UTC 2018
Author: hselasky
Date: Thu Mar 15 17:14:50 2018
New Revision: 331011
URL: https://svnweb.freebsd.org/changeset/base/331011
Log:
Implement support for missing ib_reg_phys_mr() in mlx4ib(4).
Sponsored by: Mellanox Technologies
Modified:
projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_mr.c
Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib.h Thu Mar 15 17:12:09 2018 (r331010)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib.h Thu Mar 15 17:14:50 2018 (r331011)
@@ -726,6 +726,11 @@ int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, st
struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
u64 virt_addr, int access_flags,
struct ib_udata *udata);
+struct ib_mr *mlx4_ib_reg_phys_mr(struct ib_pd *pd,
+ struct ib_phys_buf *buffer_list,
+ int num_phys_buf,
+ int access_flags,
+ u64 *virt_addr);
int mlx4_ib_dereg_mr(struct ib_mr *mr);
struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
struct ib_udata *udata);
Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c Thu Mar 15 17:12:09 2018 (r331010)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c Thu Mar 15 17:14:50 2018 (r331011)
@@ -2686,6 +2686,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->ib_dev.get_dma_mr = mlx4_ib_get_dma_mr;
ibdev->ib_dev.reg_user_mr = mlx4_ib_reg_user_mr;
ibdev->ib_dev.rereg_user_mr = mlx4_ib_rereg_user_mr;
+ ibdev->ib_dev.reg_phys_mr = mlx4_ib_reg_phys_mr;
ibdev->ib_dev.dereg_mr = mlx4_ib_dereg_mr;
ibdev->ib_dev.alloc_mr = mlx4_ib_alloc_mr;
ibdev->ib_dev.map_mr_sg = mlx4_ib_map_mr_sg;
Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_mr.c
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_mr.c Thu Mar 15 17:12:09 2018 (r331010)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx4/mlx4_ib/mlx4_ib_mr.c Thu Mar 15 17:14:50 2018 (r331011)
@@ -551,3 +551,104 @@ int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatt
return rc;
}
+
+CTASSERT(sizeof(((struct ib_phys_buf *)0)->size) == 8);
+
+struct ib_mr *
+mlx4_ib_reg_phys_mr(struct ib_pd *pd,
+ struct ib_phys_buf *buffer_list,
+ int num_phys_buf,
+ int access_flags,
+ u64 *virt_addr)
+{
+ struct mlx4_ib_dev *dev = to_mdev(pd->device);
+ struct mlx4_ib_mr *mr;
+ u64 *pages;
+ u64 total_size;
+ unsigned long mask;
+ int shift;
+ int npages;
+ int err;
+ int i, j, n;
+
+ mask = buffer_list[0].addr ^ *virt_addr;
+ total_size = 0;
+ for (i = 0; i < num_phys_buf; ++i) {
+ if (i != 0)
+ mask |= buffer_list[i].addr;
+ if (i != num_phys_buf - 1)
+ mask |= buffer_list[i].addr + buffer_list[i].size;
+
+ total_size += buffer_list[i].size;
+ }
+
+ if (mask & ~PAGE_MASK)
+ return ERR_PTR(-EINVAL);
+
+ shift = __ffs(mask | 1 << 31);
+
+ buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
+ buffer_list[0].addr &= ~0ULL << shift;
+
+ npages = 0;
+ for (i = 0; i < num_phys_buf; ++i)
+ npages += (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
+
+ if (!npages)
+ return ERR_PTR(-EINVAL);
+
+ mr = kzalloc(sizeof *mr, GFP_KERNEL);
+ if (!mr)
+ return ERR_PTR(-ENOMEM);
+
+ pages = kzalloc(sizeof(pages[0]) * npages, GFP_KERNEL);
+ if (!pages) {
+ kfree(mr);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ err = mlx4_mr_alloc(dev->dev, to_mpd(pd)->pdn, *virt_addr, total_size,
+ convert_access(access_flags), npages, shift, &mr->mmr);
+ if (err) {
+ kfree(mr);
+ kfree(pages);
+ return ERR_PTR(err);
+ }
+
+ n = 0;
+ for (i = 0; i < num_phys_buf; ++i) {
+ for (j = 0;
+ j < (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
+ ++j) {
+ u64 temp = buffer_list[i].addr + ((u64) j << shift);
+ pages[n++] = temp;
+ }
+ }
+
+ mr->npages = npages;
+ mr->max_pages = npages;
+
+ err = mlx4_write_mtt(dev->dev, &mr->mmr.mtt, 0, npages, pages);
+ if (err)
+ goto err_mr;
+
+ err = mlx4_mr_enable(dev->dev, &mr->mmr);
+ if (err)
+ goto err_mr;
+
+ mr->umem = NULL;
+ mr->ibmr.lkey = mr->mmr.key;
+ mr->ibmr.rkey = mr->mmr.key;
+ mr->ibmr.length = total_size;
+
+ kfree(pages);
+
+ return &mr->ibmr;
+
+err_mr:
+ (void) mlx4_mr_free(dev->dev, &mr->mmr);
+ kfree(mr);
+ kfree(pages);
+
+ return ERR_PTR(err);
+}
More information about the svn-src-projects
mailing list