Commit a06165a7 authored by Sriharsha Basavapatna's avatar Sriharsha Basavapatna Committed by Jason Gunthorpe
Browse files

RDMA/bnxt_re: Support application specific CQs

This patch supports application allocated memory for CQs.

The application allocates and manages the CQs directly. To support
this, the driver exports a new comp_mask to indicate direct control
of the CQ. When this comp_mask bit is set in the ureq, the driver
maps this application allocated CQ memory into hardware. As the
application manages this memory, the CQ depth ('cqe') passed by it
must be used as is and the driver shouldn't update it.

For CQs, ib_core supports pinning dmabuf based application memory,
specified through provider attributes. This umem is mananged by the
ib_core and is available in ib_cq. Register 'create_cq_user' devop
to process this umem. The driver also supports the legacy interface
that allocates umem internally.

Link: https://patch.msgid.link/r/20260302110036.36387-7-sriharsha.basavapatna@broadcom.com


Signed-off-by: default avatarSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent cec5157b
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -3342,7 +3342,6 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
	bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);

	bnxt_re_put_nq(rdev, nq);
	ib_umem_release(cq->umem);

	atomic_dec(&rdev->stats.res.cq_count);
	kfree(cq->cql);
@@ -3369,7 +3368,7 @@ static int bnxt_re_setup_sginfo(struct bnxt_re_dev *rdev,
	return 0;
}

static int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
			   struct uverbs_attr_bundle *attrs)
{
	struct bnxt_re_cq *cq = container_of(ibcq, struct bnxt_re_cq, ib_cq);
@@ -3402,19 +3401,25 @@ static int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_at
	if (entries > dev_attr->max_cq_wqes + 1)
		entries = dev_attr->max_cq_wqes + 1;

	rc = ib_copy_validate_udata_in(udata, req, cq_handle);
	rc = ib_copy_validate_udata_in_cm(udata, req, cq_handle,
					  BNXT_RE_CQ_FIXED_NUM_CQE_ENABLE);
	if (rc)
		return rc;

	cq->umem = ib_umem_get(&rdev->ibdev, req.cq_va,
	if (req.comp_mask & BNXT_RE_CQ_FIXED_NUM_CQE_ENABLE)
		entries = cqe;

	if (!ibcq->umem) {
		ibcq->umem = ib_umem_get(&rdev->ibdev, req.cq_va,
					 entries * sizeof(struct cq_base),
					 IB_ACCESS_LOCAL_WRITE);
	if (IS_ERR(cq->umem)) {
		rc = PTR_ERR(cq->umem);
		return rc;
		if (IS_ERR(ibcq->umem)) {
			rc = PTR_ERR(ibcq->umem);
			goto fail;
		}
	}

	rc = bnxt_re_setup_sginfo(rdev, cq->umem, &cq->qplib_cq.sg_info);
	rc = bnxt_re_setup_sginfo(rdev, ibcq->umem, &cq->qplib_cq.sg_info);
	if (rc)
		goto fail;

@@ -3462,7 +3467,6 @@ static int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_at
free_mem:
	free_page((unsigned long)cq->uctx_cq_page);
fail:
	ib_umem_release(cq->umem);
	return rc;
}

@@ -3475,7 +3479,6 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	struct bnxt_re_ucontext *uctx =
		rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
	struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
	struct bnxt_qplib_chip_ctx *cctx;
	int cqe = attr->cqe;
	int rc, entries;
	u32 active_cqs;
@@ -3493,7 +3496,6 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	}

	cq->rdev = rdev;
	cctx = rdev->chip_ctx;
	cq->qplib_cq.cq_handle = (u64)(unsigned long)(&cq->qplib_cq);

	entries = bnxt_re_init_depth(cqe + 1, uctx);
@@ -3542,8 +3544,8 @@ static void bnxt_re_resize_cq_complete(struct bnxt_re_cq *cq)

	cq->qplib_cq.max_wqe = cq->resize_cqe;
	if (cq->resize_umem) {
		ib_umem_release(cq->umem);
		cq->umem = cq->resize_umem;
		ib_umem_release(cq->ib_cq.umem);
		cq->ib_cq.umem = cq->resize_umem;
		cq->resize_umem = NULL;
		cq->resize_cqe = 0;
	}
@@ -4142,7 +4144,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
	/* User CQ; the only processing we do is to
	 * complete any pending CQ resize operation.
	 */
	if (cq->umem) {
	if (cq->ib_cq.umem) {
		if (cq->resize_umem)
			bnxt_re_resize_cq_complete(cq);
		return 0;
+2 −1
Original line number Diff line number Diff line
@@ -108,7 +108,6 @@ struct bnxt_re_cq {
	struct bnxt_qplib_cqe	*cql;
#define MAX_CQL_PER_POLL	1024
	u32			max_cql;
	struct ib_umem		*umem;
	struct ib_umem		*resize_umem;
	int			resize_cqe;
	void			*uctx_cq_page;
@@ -254,6 +253,8 @@ int bnxt_re_post_recv(struct ib_qp *qp, const struct ib_recv_wr *recv_wr,
		      const struct ib_recv_wr **bad_recv_wr);
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
		      struct uverbs_attr_bundle *attrs);
int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
			   struct uverbs_attr_bundle *attrs);
int bnxt_re_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
int bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
int bnxt_re_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
+1 −0
Original line number Diff line number Diff line
@@ -1335,6 +1335,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = {
	.alloc_ucontext = bnxt_re_alloc_ucontext,
	.create_ah = bnxt_re_create_ah,
	.create_cq = bnxt_re_create_cq,
	.create_user_cq = bnxt_re_create_user_cq,
	.create_qp = bnxt_re_create_qp,
	.create_srq = bnxt_re_create_srq,
	.create_user_ah = bnxt_re_create_ah,
+6 −1
Original line number Diff line number Diff line
@@ -102,12 +102,17 @@ struct bnxt_re_pd_resp {
struct bnxt_re_cq_req {
	__aligned_u64 cq_va;
	__aligned_u64 cq_handle;
	__aligned_u64 comp_mask;
};

enum bnxt_re_cq_mask {
enum bnxt_re_resp_cq_mask {
	BNXT_RE_CQ_TOGGLE_PAGE_SUPPORT = 0x1,
};

enum bnxt_re_req_cq_mask {
	BNXT_RE_CQ_FIXED_NUM_CQE_ENABLE = 0x1,
};

struct bnxt_re_cq_resp {
	__u32 cqid;
	__u32 tail;