Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20e5a59b authored by Guy Levi's avatar Guy Levi Committed by Jason Gunthorpe
Browse files

IB/mlx5: Use fragmented SRQ's buffer for in-kernel users



The current implementation of create SRQ requires contiguous memory, such
a requirement is problematic once the memory is fragmented or the system
is low in memory, it causes failures in dma_zalloc_coherent().

This patch takes the advantage of the new mlx5_core API which allocates a
fragmented buffer, and makes the SRQ creation much more resilient to
memory fragmentation. Data-path code was adapted to the fact that WQEs can
cross buffers.

Signed-off-by: default avatarGuy Levi <guyle@mellanox.com>
Reviewed-by: default avatarMajd Dibbiny <majd@mellanox.com>
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent b024dd0e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -523,6 +523,7 @@ struct mlx5_ib_srq {
	struct mlx5_core_srq	msrq;
	struct mlx5_frag_buf	buf;
	struct mlx5_db		db;
	struct mlx5_frag_buf_ctrl fbc;
	u64		       *wrid;
	/* protect SRQ hanlding
	 */
+9 −5
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ static int srq_signature;

static void *get_wqe(struct mlx5_ib_srq *srq, int n)
{
	return mlx5_buf_offset(&srq->buf, n << srq->msrq.wqe_shift);
	return mlx5_frag_buf_get_wqe(&srq->fbc, n);
}

static void mlx5_ib_srq_event(struct mlx5_core_srq *srq, enum mlx5_event type)
@@ -173,12 +173,16 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
		return err;
	}

	if (mlx5_buf_alloc(dev->mdev, buf_size, &srq->buf)) {
	if (mlx5_frag_buf_alloc_node(dev->mdev, buf_size, &srq->buf,
				     dev->mdev->priv.numa_node)) {
		mlx5_ib_dbg(dev, "buf alloc failed\n");
		err = -ENOMEM;
		goto err_db;
	}

	mlx5_init_fbc(srq->buf.frags, srq->msrq.wqe_shift, ilog2(srq->msrq.max),
		      &srq->fbc);

	srq->head    = 0;
	srq->tail    = srq->msrq.max - 1;
	srq->wqe_ctr = 0;
@@ -195,7 +199,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
		err = -ENOMEM;
		goto err_buf;
	}
	mlx5_fill_page_array(&srq->buf, in->pas);
	mlx5_fill_page_frag_array(&srq->buf, in->pas);

	srq->wrid = kvmalloc_array(srq->msrq.max, sizeof(u64), GFP_KERNEL);
	if (!srq->wrid) {
@@ -215,7 +219,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
	kvfree(in->pas);

err_buf:
	mlx5_buf_free(dev->mdev, &srq->buf);
	mlx5_frag_buf_free(dev->mdev, &srq->buf);

err_db:
	mlx5_db_free(dev->mdev, &srq->db);
@@ -232,7 +236,7 @@ static void destroy_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq)
static void destroy_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq)
{
	kvfree(srq->wrid);
	mlx5_buf_free(dev->mdev, &srq->buf);
	mlx5_frag_buf_free(dev->mdev, &srq->buf);
	mlx5_db_free(dev->mdev, &srq->db);
}