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