svn commit: r331012 - projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib

Hans Petter Selasky hselasky at FreeBSD.org
Thu Mar 15 17:15:41 UTC 2018


Author: hselasky
Date: Thu Mar 15 17:15:40 2018
New Revision: 331012
URL: https://svnweb.freebsd.org/changeset/base/331012

Log:
  Implement support for missing ib_reg_phys_mr() in mlx5ib(4).
  
  Sponsored by:	Mellanox Technologies

Modified:
  projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
  projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
  projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_mr.c

Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib.h	Thu Mar 15 17:14:50 2018	(r331011)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib.h	Thu Mar 15 17:15:40 2018	(r331012)
@@ -783,6 +783,11 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 star
 int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
 			  u64 length, u64 virt_addr, int access_flags,
 			  struct ib_pd *pd, struct ib_udata *udata);
+struct ib_mr *mlx5_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 mlx5_ib_dereg_mr(struct ib_mr *ibmr);
 struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
 			       enum ib_mr_type mr_type,

Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c	Thu Mar 15 17:14:50 2018	(r331011)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c	Thu Mar 15 17:15:40 2018	(r331012)
@@ -3037,6 +3037,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
 	dev->ib_dev.get_dma_mr		= mlx5_ib_get_dma_mr;
 	dev->ib_dev.reg_user_mr		= mlx5_ib_reg_user_mr;
 	dev->ib_dev.rereg_user_mr	= mlx5_ib_rereg_user_mr;
+	dev->ib_dev.reg_phys_mr		= mlx5_ib_reg_phys_mr;
 	dev->ib_dev.dereg_mr		= mlx5_ib_dereg_mr;
 	dev->ib_dev.attach_mcast	= mlx5_ib_mcg_attach;
 	dev->ib_dev.detach_mcast	= mlx5_ib_mcg_detach;

Modified: projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_mr.c
==============================================================================
--- projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_mr.c	Thu Mar 15 17:14:50 2018	(r331011)
+++ projects/bsd_rdma_4_9_stable_11/sys/dev/mlx5/mlx5_ib/mlx5_ib_mr.c	Thu Mar 15 17:15:40 2018	(r331012)
@@ -1309,6 +1309,129 @@ static int clean_mr(struct mlx5_ib_mr *mr)
 	return 0;
 }
 
+CTASSERT(sizeof(((struct ib_phys_buf *)0)->size) == 8);
+
+struct ib_mr *
+mlx5_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 mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_ib_mr *mr;
+	__be64 *pas;
+	void *mkc;
+	u32 *in;
+	u64 total_size;
+	u32 octo_len;
+	bool pg_cap = !!(MLX5_CAP_GEN(dev->mdev, pg));
+	unsigned long mask;
+	int shift;
+	int npages;
+	int inlen;
+	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) {
+		mlx5_ib_warn(dev, "avoid zero region\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	mr = kzalloc(sizeof *mr, GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	octo_len = get_octo_len(*virt_addr, total_size, 1ULL << shift);
+	octo_len = ALIGN(octo_len, 4);
+
+	inlen = MLX5_ST_SZ_BYTES(create_mkey_in) + (octo_len * 16);
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		kfree(mr);
+		return ERR_PTR(-ENOMEM);
+	}
+	pas = (__be64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
+
+	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);
+			if (pg_cap)
+				temp |= MLX5_IB_MTT_PRESENT;
+			pas[n++] = cpu_to_be64(temp);
+		}
+	}
+
+	/*
+	 * The MLX5_MKEY_INBOX_PG_ACCESS bit allows setting the access
+	 * flags in the page list submitted with the command:
+	 */
+	MLX5_SET(create_mkey_in, in, pg_access, !!(pg_cap));
+
+	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+	MLX5_SET(mkc, mkc, access_mode, MLX5_ACCESS_MODE_MTT);
+	MLX5_SET(mkc, mkc, a, !!(access_flags & IB_ACCESS_REMOTE_ATOMIC));
+	MLX5_SET(mkc, mkc, rw, !!(access_flags & IB_ACCESS_REMOTE_WRITE));
+	MLX5_SET(mkc, mkc, rr, !!(access_flags & IB_ACCESS_REMOTE_READ));
+	MLX5_SET(mkc, mkc, lw, !!(access_flags & IB_ACCESS_LOCAL_WRITE));
+	MLX5_SET(mkc, mkc, lr, 1);
+
+	MLX5_SET64(mkc, mkc, start_addr, *virt_addr);
+	MLX5_SET64(mkc, mkc, len, total_size);
+	MLX5_SET(mkc, mkc, pd, to_mpd(pd)->pdn);
+	MLX5_SET(mkc, mkc, bsf_octword_size, 0);
+	MLX5_SET(mkc, mkc, translations_octword_size, octo_len);
+	MLX5_SET(mkc, mkc, log_page_size, shift);
+	MLX5_SET(mkc, mkc, qpn, 0xffffff);
+	MLX5_SET(create_mkey_in, in, translations_octword_actual_size, octo_len);
+
+	err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey,
+				    (struct mlx5_create_mkey_mbox_in *)in, inlen,
+				    NULL, NULL, NULL);
+	mr->umem = NULL;
+	mr->dev = dev;
+	mr->live = 1;
+	mr->npages = npages;
+	mr->ibmr.lkey = mr->mmkey.key;
+	mr->ibmr.rkey = mr->mmkey.key;
+	mr->ibmr.length = total_size;
+	mr->access_flags = access_flags;
+
+	kvfree(in);
+
+	if (err) {
+		kfree(mr);
+		return ERR_PTR(err);
+	}
+	return &mr->ibmr;
+}
+
 int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
 {
 	struct mlx5_ib_dev *dev = to_mdev(ibmr->device);


More information about the svn-src-projects mailing list