linux-rdma.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH for-next 0/7] Refactor control path of bnxt_re driver
@ 2020-01-24  5:52 Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
                   ` (7 more replies)
  0 siblings, 8 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

This is the first series out of few more forthcoming series to refactor
Broadcom's RoCE driver. This series contains patches to refactor control
path. Since this is first series, there may be few code section which may
look redundant or overkill but those will be taken care in future patche
series.

These patches apply clean on tip of for-next branch.
Each patch in this series is tested against user and kernel functionality.

Devesh Sharma (7):
  RDMA/bnxt_re: Refactor queue pair creation code
  RDMA/bnxt_re: Replace chip context structure with pointer
  RDMA/bnxt_re: Refactor hardware queue memory allocation
  RDMA/bnxt_re: Refactor net ring allocation function
  RDMA/bnxt_re: Refactor command queue management code
  RDMA/bnxt_re: Refactor notification queue management code
  RDMA/bnxt_re: Refactor doorbell management functions

 drivers/infiniband/hw/bnxt_re/bnxt_re.h    |  24 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.c   | 670 +++++++++++++++++++----------
 drivers/infiniband/hw/bnxt_re/main.c       | 134 +++---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c   | 423 +++++++++---------
 drivers/infiniband/hw/bnxt_re/qplib_fp.h   |  94 ++--
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 474 ++++++++++++--------
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |  85 ++--
 drivers/infiniband/hw/bnxt_re/qplib_res.c  | 475 ++++++++++++--------
 drivers/infiniband/hw/bnxt_re/qplib_res.h  | 145 ++++++-
 drivers/infiniband/hw/bnxt_re/qplib_sp.c   |  52 ++-
 10 files changed, 1579 insertions(+), 997 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-24 11:23   ` Leon Romanovsky
                     ` (2 more replies)
  2020-01-24  5:52 ` [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer Devesh Sharma
                   ` (6 subsequent siblings)
  7 siblings, 3 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

Restructuring the bnxt_re_create_qp function. Listing below
the major changes:
 --Monolithic central part of create_qp where attributes are
   initialized is now enclosed in one function and this new
   function has few more sub-functions.
 --Top level qp limit checking code moved to a function.
 --GSI QP creation and GSI Shadow qp creation code is handled
   in a sub function.

Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
 drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
 3 files changed, 434 insertions(+), 217 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index 725b235..c2805384 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -104,6 +104,14 @@ struct bnxt_re_sqp_entries {
 	struct bnxt_re_qp *qp1_qp;
 };
 
+#define BNXT_RE_MAX_GSI_SQP_ENTRIES	1024
+struct bnxt_re_gsi_context {
+	struct	bnxt_re_qp *gsi_qp;
+	struct	bnxt_re_qp *gsi_sqp;
+	struct	bnxt_re_ah *gsi_sah;
+	struct	bnxt_re_sqp_entries *sqp_tbl;
+};
+
 #define BNXT_RE_MIN_MSIX		2
 #define BNXT_RE_MAX_MSIX		9
 #define BNXT_RE_AEQ_IDX			0
@@ -165,10 +173,7 @@ struct bnxt_re_dev {
 	u16				cosq[2];
 
 	/* QP for for handling QP1 packets */
-	u32				sqp_id;
-	struct bnxt_re_qp		*qp1_sqp;
-	struct bnxt_re_ah		*sqp_ah;
-	struct bnxt_re_sqp_entries sqp_tbl[1024];
+	struct bnxt_re_gsi_context	gsi_ctx;
 	atomic_t nq_alloc_cnt;
 	u32 is_virtfn;
 	u32 num_vfs;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 9b6ca15..127eb8f 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -312,7 +312,7 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
 		 */
 		if (ctx->idx == 0 &&
 		    rdma_link_local_addr((struct in6_addr *)gid_to_del) &&
-		    ctx->refcnt == 1 && rdev->qp1_sqp) {
+		    ctx->refcnt == 1 && rdev->gsi_ctx.gsi_sqp) {
 			dev_dbg(rdev_to_dev(rdev),
 				"Trying to delete GID0 while QP1 is alive\n");
 			return -EFAULT;
@@ -742,6 +742,53 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
 	spin_unlock_irqrestore(&qp->scq->cq_lock, flags);
 }
 
+static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
+{
+	struct bnxt_re_qp *gsi_sqp;
+	struct bnxt_re_ah *gsi_sah;
+	struct bnxt_re_dev *rdev;
+	int rc = 0;
+
+	rdev = qp->rdev;
+	gsi_sqp = rdev->gsi_ctx.gsi_sqp;
+	gsi_sah = rdev->gsi_ctx.gsi_sah;
+
+	/* remove from active qp list */
+	mutex_lock(&rdev->qp_lock);
+	list_del(&gsi_sqp->list);
+	atomic_dec(&rdev->qp_count);
+	mutex_unlock(&rdev->qp_lock);
+
+	dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
+	bnxt_qplib_destroy_ah(&rdev->qplib_res,
+			      &gsi_sah->qplib_ah,
+			      true);
+	bnxt_qplib_clean_qp(&qp->qplib_qp);
+
+	dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
+	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
+	if (rc) {
+		dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
+		goto fail;
+	}
+	bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
+
+	kfree(rdev->gsi_ctx.sqp_tbl);
+	kfree(gsi_sah);
+	kfree(gsi_sqp);
+	rdev->gsi_ctx.gsi_sqp = NULL;
+	rdev->gsi_ctx.gsi_sah = NULL;
+	rdev->gsi_ctx.sqp_tbl = NULL;
+
+	return 0;
+fail:
+	mutex_lock(&rdev->qp_lock);
+	list_add_tail(&gsi_sqp->list, &rdev->qp_list);
+	atomic_inc(&rdev->qp_count);
+	mutex_unlock(&rdev->qp_lock);
+	return rc;
+}
+
 /* Queue Pairs */
 int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
 {
@@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
 	unsigned int flags;
 	int rc;
 
+	mutex_lock(&rdev->qp_lock);
+	list_del(&qp->list);
+	atomic_dec(&rdev->qp_count);
+	mutex_unlock(&rdev->qp_lock);
 	bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
 	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
 	if (rc) {
 		dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
+		mutex_lock(&rdev->qp_lock);
+		list_add_tail(&qp->list, &rdev->qp_list);
+		atomic_inc(&rdev->qp_count);
+		mutex_unlock(&rdev->qp_lock);
 		return rc;
 	}
 
@@ -765,40 +820,19 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
 
 	bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp);
 
-	if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) {
-		bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah,
-				      false);
-
-		bnxt_qplib_clean_qp(&qp->qplib_qp);
-		rc = bnxt_qplib_destroy_qp(&rdev->qplib_res,
-					   &rdev->qp1_sqp->qplib_qp);
-		if (rc) {
-			dev_err(rdev_to_dev(rdev),
-				"Failed to destroy Shadow QP");
-			return rc;
-		}
-		bnxt_qplib_free_qp_res(&rdev->qplib_res,
-				       &rdev->qp1_sqp->qplib_qp);
-		mutex_lock(&rdev->qp_lock);
-		list_del(&rdev->qp1_sqp->list);
-		atomic_dec(&rdev->qp_count);
-		mutex_unlock(&rdev->qp_lock);
-
-		kfree(rdev->sqp_ah);
-		kfree(rdev->qp1_sqp);
-		rdev->qp1_sqp = NULL;
-		rdev->sqp_ah = NULL;
+	if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) {
+		rc = bnxt_re_destroy_gsi_sqp(qp);
+		if (rc)
+			goto sh_fail;
 	}
 
 	ib_umem_release(qp->rumem);
 	ib_umem_release(qp->sumem);
 
-	mutex_lock(&rdev->qp_lock);
-	list_del(&qp->list);
-	atomic_dec(&rdev->qp_count);
-	mutex_unlock(&rdev->qp_lock);
 	kfree(qp);
 	return 0;
+sh_fail:
+	return rc;
 }
 
 static u8 __from_ib_qp_type(enum ib_qp_type type)
@@ -966,8 +1000,6 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	if (rc)
 		goto fail;
 
-	rdev->sqp_id = qp->qplib_qp.id;
-
 	spin_lock_init(&qp->sq_lock);
 	INIT_LIST_HEAD(&qp->list);
 	mutex_lock(&rdev->qp_lock);
@@ -980,205 +1012,377 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	return NULL;
 }
 
-struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
-				struct ib_qp_init_attr *qp_init_attr,
-				struct ib_udata *udata)
+static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
+				struct ib_qp_init_attr *init_attr)
 {
-	struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
-	struct bnxt_re_dev *rdev = pd->rdev;
-	struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
-	struct bnxt_re_qp *qp;
-	struct bnxt_re_cq *cq;
-	struct bnxt_re_srq *srq;
-	int rc, entries;
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_qplib_qp *qplqp;
+	struct bnxt_re_dev *rdev;
+	int entries;
 
-	if ((qp_init_attr->cap.max_send_wr > dev_attr->max_qp_wqes) ||
-	    (qp_init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes) ||
-	    (qp_init_attr->cap.max_send_sge > dev_attr->max_qp_sges) ||
-	    (qp_init_attr->cap.max_recv_sge > dev_attr->max_qp_sges) ||
-	    (qp_init_attr->cap.max_inline_data > dev_attr->max_inline_data))
-		return ERR_PTR(-EINVAL);
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
 
-	qp = kzalloc(sizeof(*qp), GFP_KERNEL);
-	if (!qp)
-		return ERR_PTR(-ENOMEM);
+	if (init_attr->srq) {
+		struct bnxt_re_srq *srq;
 
-	qp->rdev = rdev;
-	ether_addr_copy(qp->qplib_qp.smac, rdev->netdev->dev_addr);
-	qp->qplib_qp.pd = &pd->qplib_pd;
-	qp->qplib_qp.qp_handle = (u64)(unsigned long)(&qp->qplib_qp);
-	qp->qplib_qp.type = __from_ib_qp_type(qp_init_attr->qp_type);
+		srq = container_of(init_attr->srq, struct bnxt_re_srq, ib_srq);
+		if (!srq) {
+			dev_err(rdev_to_dev(rdev), "SRQ not found");
+			return -EINVAL;
+		}
+		qplqp->srq = &srq->qplib_srq;
+		qplqp->rq.max_wqe = 0;
+	} else {
+		/* Allocate 1 more than what's provided so posting max doesn't
+		 * mean empty.
+		 */
+		entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1);
+		qplqp->rq.max_wqe = min_t(u32, entries,
+					  dev_attr->max_qp_wqes + 1);
 
-	if (qp_init_attr->qp_type == IB_QPT_GSI &&
-	    bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))
-		qp->qplib_qp.type = CMDQ_CREATE_QP_TYPE_GSI;
-	if (qp->qplib_qp.type == IB_QPT_MAX) {
+		qplqp->rq.q_full_delta = qplqp->rq.max_wqe -
+					 init_attr->cap.max_recv_wr;
+		qplqp->rq.max_sge = init_attr->cap.max_recv_sge;
+		if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
+			qplqp->rq.max_sge = dev_attr->max_qp_sges;
+	}
+
+	return 0;
+}
+
+static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
+{
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_qplib_qp *qplqp;
+	struct bnxt_re_dev *rdev;
+
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
+
+	qplqp->rq.max_sge = dev_attr->max_qp_sges;
+	if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
+		qplqp->rq.max_sge = dev_attr->max_qp_sges;
+}
+
+static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
+				 struct ib_qp_init_attr *init_attr,
+				 struct ib_udata *udata)
+{
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_qplib_qp *qplqp;
+	struct bnxt_re_dev *rdev;
+	int entries;
+
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
+
+	qplqp->sq.max_sge = init_attr->cap.max_send_sge;
+	if (qplqp->sq.max_sge > dev_attr->max_qp_sges)
+		qplqp->sq.max_sge = dev_attr->max_qp_sges;
+	/*
+	 * Change the SQ depth if user has requested minimum using
+	 * configfs. Only supported for kernel consumers
+	 */
+	entries = init_attr->cap.max_send_wr;
+	/* Allocate 128 + 1 more than what's provided */
+	entries = roundup_pow_of_two(entries + BNXT_QPLIB_RESERVED_QP_WRS + 1);
+	qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes +
+			BNXT_QPLIB_RESERVED_QP_WRS + 1);
+	qplqp->sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1;
+	/*
+	 * Reserving one slot for Phantom WQE. Application can
+	 * post one extra entry in this case. But allowing this to avoid
+	 * unexpected Queue full condition
+	 */
+	qplqp->sq.q_full_delta -= 1;
+}
+
+static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
+				       struct ib_qp_init_attr *init_attr)
+{
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_qplib_qp *qplqp;
+	struct bnxt_re_dev *rdev;
+	int entries;
+
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
+
+	entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1);
+	qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+	qplqp->sq.q_full_delta = qplqp->sq.max_wqe -
+				 init_attr->cap.max_send_wr;
+	qplqp->sq.max_sge++; /* Need one extra sge to put UD header */
+	if (qplqp->sq.max_sge > dev_attr->max_qp_sges)
+		qplqp->sq.max_sge = dev_attr->max_qp_sges;
+}
+
+static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,
+				struct ib_qp_init_attr *init_attr)
+{
+	struct bnxt_qplib_chip_ctx *chip_ctx;
+	int qptype;
+
+	chip_ctx = &rdev->chip_ctx;
+
+	qptype = __from_ib_qp_type(init_attr->qp_type);
+	if (qptype == IB_QPT_MAX) {
 		dev_err(rdev_to_dev(rdev), "QP type 0x%x not supported",
-			qp->qplib_qp.type);
-		rc = -EINVAL;
-		goto fail;
+			qptype);
+		qptype = -EINVAL;
+		goto out;
 	}
 
-	qp->qplib_qp.max_inline_data = qp_init_attr->cap.max_inline_data;
-	qp->qplib_qp.sig_type = ((qp_init_attr->sq_sig_type ==
-				  IB_SIGNAL_ALL_WR) ? true : false);
+	if (bnxt_qplib_is_chip_gen_p5(chip_ctx) &&
+	    init_attr->qp_type == IB_QPT_GSI)
+		qptype = CMDQ_CREATE_QP_TYPE_GSI;
+out:
+	return qptype;
+}
+
+static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
+				struct ib_qp_init_attr *init_attr,
+				struct ib_udata *udata)
+{
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_qplib_qp *qplqp;
+	struct bnxt_re_dev *rdev;
+	struct bnxt_re_cq *cq;
+	int rc = 0, qptype;
+
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
+
+	/* Setup misc params */
+	ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr);
+	qplqp->pd = &pd->qplib_pd;
+	qplqp->qp_handle = (u64)qplqp;
+	qplqp->max_inline_data = init_attr->cap.max_inline_data;
+	qplqp->sig_type = ((init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ?
+			    true : false);
+	qptype = bnxt_re_init_qp_type(rdev, init_attr);
+	if (qptype < 0) {
+		rc = qptype;
+		goto out;
+	}
+	qplqp->type = (u8)qptype;
 
-	qp->qplib_qp.sq.max_sge = qp_init_attr->cap.max_send_sge;
-	if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges)
-		qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges;
+	if (init_attr->qp_type == IB_QPT_RC) {
+		qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom;
+		qplqp->max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom;
+	}
+	qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu));
+	qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */
+	if (init_attr->create_flags)
+		dev_dbg(rdev_to_dev(rdev),
+			"QP create flags 0x%x not supported",
+			init_attr->create_flags);
 
-	if (qp_init_attr->send_cq) {
-		cq = container_of(qp_init_attr->send_cq, struct bnxt_re_cq,
-				  ib_cq);
+	/* Setup CQs */
+	if (init_attr->send_cq) {
+		cq = container_of(init_attr->send_cq, struct bnxt_re_cq, ib_cq);
 		if (!cq) {
 			dev_err(rdev_to_dev(rdev), "Send CQ not found");
 			rc = -EINVAL;
-			goto fail;
+			goto out;
 		}
-		qp->qplib_qp.scq = &cq->qplib_cq;
+		qplqp->scq = &cq->qplib_cq;
 		qp->scq = cq;
 	}
 
-	if (qp_init_attr->recv_cq) {
-		cq = container_of(qp_init_attr->recv_cq, struct bnxt_re_cq,
-				  ib_cq);
+	if (init_attr->recv_cq) {
+		cq = container_of(init_attr->recv_cq, struct bnxt_re_cq, ib_cq);
 		if (!cq) {
 			dev_err(rdev_to_dev(rdev), "Receive CQ not found");
 			rc = -EINVAL;
-			goto fail;
+			goto out;
 		}
-		qp->qplib_qp.rcq = &cq->qplib_cq;
+		qplqp->rcq = &cq->qplib_cq;
 		qp->rcq = cq;
 	}
 
-	if (qp_init_attr->srq) {
-		srq = container_of(qp_init_attr->srq, struct bnxt_re_srq,
-				   ib_srq);
-		if (!srq) {
-			dev_err(rdev_to_dev(rdev), "SRQ not found");
-			rc = -EINVAL;
-			goto fail;
-		}
-		qp->qplib_qp.srq = &srq->qplib_srq;
-		qp->qplib_qp.rq.max_wqe = 0;
-	} else {
-		/* Allocate 1 more than what's provided so posting max doesn't
-		 * mean empty
-		 */
-		entries = roundup_pow_of_two(qp_init_attr->cap.max_recv_wr + 1);
-		qp->qplib_qp.rq.max_wqe = min_t(u32, entries,
-						dev_attr->max_qp_wqes + 1);
+	/* Setup RQ/SRQ */
+	rc = bnxt_re_init_rq_attr(qp, init_attr);
+	if (rc)
+		goto out;
+	if (init_attr->qp_type == IB_QPT_GSI)
+		bnxt_re_adjust_gsi_rq_attr(qp);
+
+	/* Setup SQ */
+	bnxt_re_init_sq_attr(qp, init_attr, udata);
+	if (init_attr->qp_type == IB_QPT_GSI)
+		bnxt_re_adjust_gsi_sq_attr(qp, init_attr);
 
-		qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe -
-						qp_init_attr->cap.max_recv_wr;
+	if (udata) /* This will update DPI and qp_handle */
+		rc = bnxt_re_init_user_qp(rdev, pd, qp, udata);
+out:
+	return rc;
+}
+
+static int bnxt_re_create_shadow_gsi(struct bnxt_re_qp *qp,
+				     struct bnxt_re_pd *pd)
+{
+	struct bnxt_re_sqp_entries *sqp_tbl = NULL;
+	struct bnxt_re_dev *rdev;
+	struct bnxt_re_qp *sqp;
+	struct bnxt_re_ah *sah;
+	int rc = 0;
 
-		qp->qplib_qp.rq.max_sge = qp_init_attr->cap.max_recv_sge;
-		if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges)
-			qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
+	rdev = qp->rdev;
+	/* Create a shadow QP to handle the QP1 traffic */
+	sqp_tbl = kzalloc(sizeof(*sqp_tbl) * BNXT_RE_MAX_GSI_SQP_ENTRIES,
+			  GFP_KERNEL);
+	if (!sqp_tbl)
+		return -ENOMEM;
+	rdev->gsi_ctx.sqp_tbl = sqp_tbl;
+
+	sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, &qp->qplib_qp);
+	if (!sqp) {
+		rc = -ENODEV;
+		dev_err(rdev_to_dev(rdev),
+			"Failed to create Shadow QP for QP1");
+		goto out;
 	}
+	rdev->gsi_ctx.gsi_sqp = sqp;
 
-	qp->qplib_qp.mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu));
+	sqp->rcq = qp->rcq;
+	sqp->scq = qp->scq;
+	sah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res,
+					  &qp->qplib_qp);
+	if (!sah) {
+		bnxt_qplib_destroy_qp(&rdev->qplib_res,
+				      &sqp->qplib_qp);
+		rc = -ENODEV;
+		dev_err(rdev_to_dev(rdev),
+			"Failed to create AH entry for ShadowQP");
+		goto out;
+	}
+	rdev->gsi_ctx.gsi_sah = sah;
 
-	if (qp_init_attr->qp_type == IB_QPT_GSI &&
-	    !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) {
-		/* Allocate 1 more than what's provided */
-		entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1);
-		qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
-						dev_attr->max_qp_wqes + 1);
-		qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe -
-						qp_init_attr->cap.max_send_wr;
-		qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
-		if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges)
-			qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges;
-		qp->qplib_qp.sq.max_sge++;
-		if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges)
-			qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges;
-
-		qp->qplib_qp.rq_hdr_buf_size =
-					BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2;
-
-		qp->qplib_qp.sq_hdr_buf_size =
-					BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2;
-		qp->qplib_qp.dpi = &rdev->dpi_privileged;
-		rc = bnxt_qplib_create_qp1(&rdev->qplib_res, &qp->qplib_qp);
-		if (rc) {
-			dev_err(rdev_to_dev(rdev), "Failed to create HW QP1");
-			goto fail;
-		}
-		/* Create a shadow QP to handle the QP1 traffic */
-		rdev->qp1_sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res,
-							 &qp->qplib_qp);
-		if (!rdev->qp1_sqp) {
-			rc = -EINVAL;
-			dev_err(rdev_to_dev(rdev),
-				"Failed to create Shadow QP for QP1");
-			goto qp_destroy;
-		}
-		rdev->sqp_ah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res,
-							   &qp->qplib_qp);
-		if (!rdev->sqp_ah) {
-			bnxt_qplib_destroy_qp(&rdev->qplib_res,
-					      &rdev->qp1_sqp->qplib_qp);
-			rc = -EINVAL;
-			dev_err(rdev_to_dev(rdev),
-				"Failed to create AH entry for ShadowQP");
-			goto qp_destroy;
-		}
+	return 0;
+out:
+	kfree(sqp_tbl);
+	return rc;
+}
 
-	} else {
-		/* Allocate 128 + 1 more than what's provided */
-		entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr +
-					     BNXT_QPLIB_RESERVED_QP_WRS + 1);
-		qp->qplib_qp.sq.max_wqe = min_t(u32, entries,
-						dev_attr->max_qp_wqes +
-						BNXT_QPLIB_RESERVED_QP_WRS + 1);
-		qp->qplib_qp.sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1;
+static int bnxt_re_create_gsi_qp(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
+				 struct ib_qp_init_attr *init_attr)
+{
+	struct bnxt_qplib_dev_attr *dev_attr;
+	struct bnxt_re_dev *rdev;
+	struct bnxt_qplib_qp *qplqp;
+	int rc = 0;
 
-		/*
-		 * Reserving one slot for Phantom WQE. Application can
-		 * post one extra entry in this case. But allowing this to avoid
-		 * unexpected Queue full condition
-		 */
+	rdev = qp->rdev;
+	qplqp = &qp->qplib_qp;
+	dev_attr = &rdev->dev_attr;
 
-		qp->qplib_qp.sq.q_full_delta -= 1;
+	qplqp->rq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2;
+	qplqp->sq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2;
 
-		qp->qplib_qp.max_rd_atomic = dev_attr->max_qp_rd_atom;
-		qp->qplib_qp.max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom;
-		if (udata) {
-			rc = bnxt_re_init_user_qp(rdev, pd, qp, udata);
-			if (rc)
-				goto fail;
-		} else {
-			qp->qplib_qp.dpi = &rdev->dpi_privileged;
-		}
+	rc = bnxt_qplib_create_qp1(&rdev->qplib_res, qplqp);
+	if (rc) {
+		dev_err(rdev_to_dev(rdev), "create HW QP1 failed!");
+		goto out;
+	}
+
+	rc = bnxt_re_create_shadow_gsi(qp, pd);
+out:
+	return rc;
+}
 
+static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev,
+				   struct ib_qp_init_attr *init_attr,
+				   struct bnxt_qplib_dev_attr *dev_attr)
+{
+	bool rc = true;
+
+	if (init_attr->cap.max_send_wr > dev_attr->max_qp_wqes ||
+	    init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes ||
+	    init_attr->cap.max_send_sge > dev_attr->max_qp_sges ||
+	    init_attr->cap.max_recv_sge > dev_attr->max_qp_sges ||
+	    init_attr->cap.max_inline_data > dev_attr->max_inline_data) {
+		dev_err(rdev_to_dev(rdev),
+			"Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x",
+			init_attr->cap.max_send_wr, dev_attr->max_qp_wqes,
+			init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes,
+			init_attr->cap.max_send_sge, dev_attr->max_qp_sges,
+			init_attr->cap.max_recv_sge, dev_attr->max_qp_sges,
+			init_attr->cap.max_inline_data,
+			dev_attr->max_inline_data);
+		rc = false;
+	}
+	return rc;
+}
+
+struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
+				struct ib_qp_init_attr *qp_init_attr,
+				struct ib_udata *udata)
+{
+	struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
+	struct bnxt_re_dev *rdev = pd->rdev;
+	struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
+	struct bnxt_re_qp *qp;
+	int rc;
+
+	rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr);
+	if (!rc) {
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+	if (!qp) {
+		rc = -ENOMEM;
+		goto exit;
+	}
+	qp->rdev = rdev;
+	rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata);
+	if (rc)
+		goto fail;
+
+	if (qp_init_attr->qp_type == IB_QPT_GSI &&
+	    !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) {
+		rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr);
+		if (rc == -ENODEV)
+			goto qp_destroy;
+		if (rc)
+			goto fail;
+	} else {
 		rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp);
 		if (rc) {
 			dev_err(rdev_to_dev(rdev), "Failed to create HW QP");
 			goto free_umem;
 		}
+		if (udata) {
+			struct bnxt_re_qp_resp resp;
+
+			resp.qpid = qp->qplib_qp.id;
+			resp.rsvd = 0;
+			rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
+			if (rc) {
+				dev_err(rdev_to_dev(rdev), "Failed to copy QP udata");
+				goto qp_destroy;
+			}
+		}
 	}
 
 	qp->ib_qp.qp_num = qp->qplib_qp.id;
+	if (qp_init_attr->qp_type == IB_QPT_GSI)
+		rdev->gsi_ctx.gsi_qp = qp;
 	spin_lock_init(&qp->sq_lock);
 	spin_lock_init(&qp->rq_lock);
-
-	if (udata) {
-		struct bnxt_re_qp_resp resp;
-
-		resp.qpid = qp->ib_qp.qp_num;
-		resp.rsvd = 0;
-		rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
-		if (rc) {
-			dev_err(rdev_to_dev(rdev), "Failed to copy QP udata");
-			goto qp_destroy;
-		}
-	}
 	INIT_LIST_HEAD(&qp->list);
 	mutex_lock(&rdev->qp_lock);
 	list_add_tail(&qp->list, &rdev->qp_list);
-	atomic_inc(&rdev->qp_count);
 	mutex_unlock(&rdev->qp_lock);
+	atomic_inc(&rdev->qp_count);
 
 	return &qp->ib_qp;
 qp_destroy:
@@ -1188,6 +1392,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
 	ib_umem_release(qp->sumem);
 fail:
 	kfree(qp);
+exit:
 	return ERR_PTR(rc);
 }
 
@@ -1485,7 +1690,7 @@ static int bnxt_re_modify_shadow_qp(struct bnxt_re_dev *rdev,
 				    struct bnxt_re_qp *qp1_qp,
 				    int qp_attr_mask)
 {
-	struct bnxt_re_qp *qp = rdev->qp1_sqp;
+	struct bnxt_re_qp *qp = rdev->gsi_ctx.gsi_sqp;
 	int rc = 0;
 
 	if (qp_attr_mask & IB_QP_STATE) {
@@ -1749,7 +1954,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
 		dev_err(rdev_to_dev(rdev), "Failed to modify HW QP");
 		return rc;
 	}
-	if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp)
+	if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp)
 		rc = bnxt_re_modify_shadow_qp(rdev, qp, qp_attr_mask);
 	return rc;
 }
@@ -1993,9 +2198,12 @@ static int bnxt_re_build_qp1_shadow_qp_recv(struct bnxt_re_qp *qp,
 					    struct bnxt_qplib_swqe *wqe,
 					    int payload_size)
 {
+	struct bnxt_re_sqp_entries *sqp_entry;
 	struct bnxt_qplib_sge ref, sge;
+	struct bnxt_re_dev *rdev;
 	u32 rq_prod_index;
-	struct bnxt_re_sqp_entries *sqp_entry;
+
+	rdev = qp->rdev;
 
 	rq_prod_index = bnxt_qplib_get_rq_prod_index(&qp->qplib_qp);
 
@@ -2010,7 +2218,7 @@ static int bnxt_re_build_qp1_shadow_qp_recv(struct bnxt_re_qp *qp,
 	ref.lkey = wqe->sg_list[0].lkey;
 	ref.size = wqe->sg_list[0].size;
 
-	sqp_entry = &qp->rdev->sqp_tbl[rq_prod_index];
+	sqp_entry = &rdev->gsi_ctx.sqp_tbl[rq_prod_index];
 
 	/* SGE 1 */
 	wqe->sg_list[0].addr = sge.addr;
@@ -2830,12 +3038,13 @@ static bool bnxt_re_is_loopback_packet(struct bnxt_re_dev *rdev,
 	return rc;
 }
 
-static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp,
+static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *gsi_qp,
 					 struct bnxt_qplib_cqe *cqe)
 {
-	struct bnxt_re_dev *rdev = qp1_qp->rdev;
+	struct bnxt_re_dev *rdev = gsi_qp->rdev;
 	struct bnxt_re_sqp_entries *sqp_entry = NULL;
-	struct bnxt_re_qp *qp = rdev->qp1_sqp;
+	struct bnxt_re_qp *gsi_sqp = rdev->gsi_ctx.gsi_sqp;
+	struct bnxt_re_ah *gsi_sah;
 	struct ib_send_wr *swr;
 	struct ib_ud_wr udwr;
 	struct ib_recv_wr rwr;
@@ -2858,19 +3067,19 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp,
 	swr = &udwr.wr;
 	tbl_idx = cqe->wr_id;
 
-	rq_hdr_buf = qp1_qp->qplib_qp.rq_hdr_buf +
-			(tbl_idx * qp1_qp->qplib_qp.rq_hdr_buf_size);
-	rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp1_qp->qplib_qp,
+	rq_hdr_buf = gsi_qp->qplib_qp.rq_hdr_buf +
+			(tbl_idx * gsi_qp->qplib_qp.rq_hdr_buf_size);
+	rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp,
 							  tbl_idx);
 
 	/* Shadow QP header buffer */
-	shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp->qplib_qp,
+	shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp,
 							    tbl_idx);
-	sqp_entry = &rdev->sqp_tbl[tbl_idx];
+	sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx];
 
 	/* Store this cqe */
 	memcpy(&sqp_entry->cqe, cqe, sizeof(struct bnxt_qplib_cqe));
-	sqp_entry->qp1_qp = qp1_qp;
+	sqp_entry->qp1_qp = gsi_qp;
 
 	/* Find packet type from the cqe */
 
@@ -2924,7 +3133,7 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp,
 	rwr.wr_id = tbl_idx;
 	rwr.next = NULL;
 
-	rc = bnxt_re_post_recv_shadow_qp(rdev, qp, &rwr);
+	rc = bnxt_re_post_recv_shadow_qp(rdev, gsi_sqp, &rwr);
 	if (rc) {
 		dev_err(rdev_to_dev(rdev),
 			"Failed to post Rx buffers to shadow QP");
@@ -2936,13 +3145,13 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp,
 	swr->wr_id = tbl_idx;
 	swr->opcode = IB_WR_SEND;
 	swr->next = NULL;
-
-	udwr.ah = &rdev->sqp_ah->ib_ah;
-	udwr.remote_qpn = rdev->qp1_sqp->qplib_qp.id;
-	udwr.remote_qkey = rdev->qp1_sqp->qplib_qp.qkey;
+	gsi_sah = rdev->gsi_ctx.gsi_sah;
+	udwr.ah = &gsi_sah->ib_ah;
+	udwr.remote_qpn = gsi_sqp->qplib_qp.id;
+	udwr.remote_qkey = gsi_sqp->qplib_qp.qkey;
 
 	/* post data received  in the send queue */
-	rc = bnxt_re_post_send_shadow_qp(rdev, qp, swr);
+	rc = bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr);
 
 	return 0;
 }
@@ -2996,12 +3205,12 @@ static void bnxt_re_process_res_rc_wc(struct ib_wc *wc,
 		wc->opcode = IB_WC_RECV_RDMA_WITH_IMM;
 }
 
-static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp,
+static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
 					     struct ib_wc *wc,
 					     struct bnxt_qplib_cqe *cqe)
 {
-	struct bnxt_re_dev *rdev = qp->rdev;
-	struct bnxt_re_qp *qp1_qp = NULL;
+	struct bnxt_re_dev *rdev = gsi_sqp->rdev;
+	struct bnxt_re_qp *gsi_qp = NULL;
 	struct bnxt_qplib_cqe *orig_cqe = NULL;
 	struct bnxt_re_sqp_entries *sqp_entry = NULL;
 	int nw_type;
@@ -3011,13 +3220,13 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp,
 
 	tbl_idx = cqe->wr_id;
 
-	sqp_entry = &rdev->sqp_tbl[tbl_idx];
-	qp1_qp = sqp_entry->qp1_qp;
+	sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx];
+	gsi_qp = sqp_entry->qp1_qp;
 	orig_cqe = &sqp_entry->cqe;
 
 	wc->wr_id = sqp_entry->wrid;
 	wc->byte_len = orig_cqe->length;
-	wc->qp = &qp1_qp->ib_qp;
+	wc->qp = &gsi_qp->ib_qp;
 
 	wc->ex.imm_data = orig_cqe->immdata;
 	wc->src_qp = orig_cqe->src_qp;
@@ -3096,7 +3305,7 @@ static int send_phantom_wqe(struct bnxt_re_qp *qp)
 int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
 {
 	struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq);
-	struct bnxt_re_qp *qp;
+	struct bnxt_re_qp *qp, *sh_qp;
 	struct bnxt_qplib_cqe *cqe;
 	int i, ncqe, budget;
 	struct bnxt_qplib_q *sq;
@@ -3160,8 +3369,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
 
 			switch (cqe->opcode) {
 			case CQ_BASE_CQE_TYPE_REQ:
-				if (qp->rdev->qp1_sqp && qp->qplib_qp.id ==
-				    qp->rdev->qp1_sqp->qplib_qp.id) {
+				sh_qp = qp->rdev->gsi_ctx.gsi_sqp;
+				if (sh_qp &&
+				    qp->qplib_qp.id == sh_qp->qplib_qp.id) {
 					/* Handle this completion with
 					 * the stored completion
 					 */
@@ -3187,7 +3397,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
 				 * stored in the table
 				 */
 				tbl_idx = cqe->wr_id;
-				sqp_entry = &cq->rdev->sqp_tbl[tbl_idx];
+				sqp_entry = &cq->rdev->gsi_ctx.sqp_tbl[tbl_idx];
 				wc->wr_id = sqp_entry->wrid;
 				bnxt_re_process_res_rawqp1_wc(wc, cqe);
 				break;
@@ -3195,8 +3405,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
 				bnxt_re_process_res_rc_wc(wc, cqe);
 				break;
 			case CQ_BASE_CQE_TYPE_RES_UD:
-				if (qp->rdev->qp1_sqp && qp->qplib_qp.id ==
-				    qp->rdev->qp1_sqp->qplib_qp.id) {
+				sh_qp = qp->rdev->gsi_ctx.gsi_sqp;
+				if (sh_qp &&
+				    qp->qplib_qp.id == sh_qp->qplib_qp.id) {
 					/* Handle this completion with
 					 * the stored completion
 					 */
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 793c972..82a5350 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -1125,7 +1125,8 @@ static int bnxt_re_query_hwrm_pri2cos(struct bnxt_re_dev *rdev, u8 dir,
 static bool bnxt_re_is_qp1_or_shadow_qp(struct bnxt_re_dev *rdev,
 					struct bnxt_re_qp *qp)
 {
-	return (qp->ib_qp.qp_type == IB_QPT_GSI) || (qp == rdev->qp1_sqp);
+	return (qp->ib_qp.qp_type == IB_QPT_GSI) ||
+	       (qp == rdev->gsi_ctx.gsi_sqp);
 }
 
 static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-25 18:03   ` Jason Gunthorpe
  2020-01-24  5:52 ` [PATCH for-next 3/7] RDMA/bnxt_re: Refactor hardware queue memory allocation Devesh Sharma
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

The chip_ctx member in bnxt_re_dev structure is now a pointer
to struct bnxt_qplib_chip_ctx. Since the member type has changed
there are changes in rest of the code wherever dev->chip_ctx is
used.

Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  2 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 13 ++++++-----
 drivers/infiniband/hw/bnxt_re/main.c     | 40 +++++++++++++++++++++-----------
 drivers/infiniband/hw/bnxt_re/qplib_fp.c |  2 +-
 4 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index c2805384..86274f4 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -133,7 +133,7 @@ struct bnxt_re_dev {
 #define BNXT_RE_FLAG_ISSUE_ROCE_STATS          29
 	struct net_device		*netdev;
 	unsigned int			version, major, minor;
-	struct bnxt_qplib_chip_ctx	chip_ctx;
+	struct bnxt_qplib_chip_ctx	*chip_ctx;
 	struct bnxt_en_dev		*en_dev;
 	struct bnxt_msix_entry		msix_entries[BNXT_RE_MAX_MSIX];
 	int				num_msix;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 127eb8f..865728c 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -865,7 +865,7 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	bytes = (qplib_qp->sq.max_wqe * BNXT_QPLIB_MAX_SQE_ENTRY_SIZE);
 	/* Consider mapping PSN search memory only for RC QPs. */
 	if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) {
-		psn_sz = bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ?
+		psn_sz = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
 					sizeof(struct sq_psn_search_ext) :
 					sizeof(struct sq_psn_search);
 		bytes += (qplib_qp->sq.max_wqe * psn_sz);
@@ -1065,6 +1065,7 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
 	qplqp->rq.max_sge = dev_attr->max_qp_sges;
 	if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
 		qplqp->rq.max_sge = dev_attr->max_qp_sges;
+	qplqp->rq.max_sge = 6;
 }
 
 static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
@@ -1128,7 +1129,7 @@ static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,
 	struct bnxt_qplib_chip_ctx *chip_ctx;
 	int qptype;
 
-	chip_ctx = &rdev->chip_ctx;
+	chip_ctx = rdev->chip_ctx;
 
 	qptype = __from_ib_qp_type(init_attr->qp_type);
 	if (qptype == IB_QPT_MAX) {
@@ -1348,7 +1349,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
 		goto fail;
 
 	if (qp_init_attr->qp_type == IB_QPT_GSI &&
-	    !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) {
+	    !(bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))) {
 		rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr);
 		if (rc == -ENODEV)
 			goto qp_destroy;
@@ -3821,10 +3822,10 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
 	spin_lock_init(&uctx->sh_lock);
 
 	resp.comp_mask = BNXT_RE_UCNTX_CMASK_HAVE_CCTX;
-	chip_met_rev_num = rdev->chip_ctx.chip_num;
-	chip_met_rev_num |= ((u32)rdev->chip_ctx.chip_rev & 0xFF) <<
+	chip_met_rev_num = rdev->chip_ctx->chip_num;
+	chip_met_rev_num |= ((u32)rdev->chip_ctx->chip_rev & 0xFF) <<
 			     BNXT_RE_CHIP_ID0_CHIP_REV_SFT;
-	chip_met_rev_num |= ((u32)rdev->chip_ctx.chip_metal & 0xFF) <<
+	chip_met_rev_num |= ((u32)rdev->chip_ctx->chip_metal & 0xFF) <<
 			     BNXT_RE_CHIP_ID0_CHIP_MET_SFT;
 	resp.chip_id0 = chip_met_rev_num;
 	/* Future extension of chip info */
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 82a5350..390daeb 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -82,22 +82,35 @@
 
 static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
 {
+	struct bnxt_qplib_chip_ctx *chip_ctx;
+
+	if (!rdev->chip_ctx)
+		return;
+	chip_ctx = rdev->chip_ctx;
+	rdev->chip_ctx = NULL;
 	rdev->rcfw.res = NULL;
 	rdev->qplib_res.cctx = NULL;
+	kfree(chip_ctx);
 }
 
 static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
 {
+	struct bnxt_qplib_chip_ctx *chip_ctx;
 	struct bnxt_en_dev *en_dev;
 	struct bnxt *bp;
 
 	en_dev = rdev->en_dev;
 	bp = netdev_priv(en_dev->net);
 
-	rdev->chip_ctx.chip_num = bp->chip_num;
+	chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL);
+	if (!chip_ctx)
+		return -ENOMEM;
+	chip_ctx->chip_num = bp->chip_num;
+
+	rdev->chip_ctx = chip_ctx;
 	/* rest members to follow eventually */
 
-	rdev->qplib_res.cctx = &rdev->chip_ctx;
+	rdev->qplib_res.cctx = rdev->chip_ctx;
 	rdev->rcfw.res = &rdev->qplib_res;
 
 	return 0;
@@ -136,7 +149,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
 	ctx->srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT,
 				attr->max_srq);
 	ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq);
-	if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))
+	if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))
 		for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
 			rdev->qplib_ctx.tqm_count[i] =
 			rdev->dev_attr.tqm_alloc_reqs[i];
@@ -185,7 +198,7 @@ static void bnxt_re_set_resource_limits(struct bnxt_re_dev *rdev)
 	memset(&rdev->qplib_ctx.vf_res, 0, sizeof(struct bnxt_qplib_vf_res));
 	bnxt_re_limit_pf_res(rdev);
 
-	num_vfs =  bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ?
+	num_vfs =  bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
 			BNXT_RE_GEN_P5_MAX_VF : rdev->num_vfs;
 	if (num_vfs)
 		bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs);
@@ -208,7 +221,7 @@ static void bnxt_re_sriov_config(void *p, int num_vfs)
 		return;
 
 	rdev->num_vfs = num_vfs;
-	if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) {
+	if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) {
 		bnxt_re_set_resource_limits(rdev);
 		bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw,
 					      &rdev->qplib_ctx);
@@ -916,7 +929,7 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq,
 #define BNXT_RE_GEN_P5_VF_NQ_DB		0x4000
 static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx)
 {
-	return bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ?
+	return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
 		(rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB :
 				   BNXT_RE_GEN_P5_PF_NQ_DB) :
 				   rdev->msix_entries[indx].db_offset;
@@ -967,7 +980,7 @@ static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev)
 	int i;
 
 	for (i = 0; i < rdev->num_msix - 1; i++) {
-		type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
 		rdev->nq[i].res = NULL;
 		bnxt_qplib_free_nq(&rdev->nq[i]);
@@ -1025,7 +1038,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 				i, rc);
 			goto free_nq;
 		}
-		type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr;
 		pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count;
 		rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
@@ -1044,7 +1057,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 	return 0;
 free_nq:
 	for (i = num_vec_created; i >= 0; i--) {
-		type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
 		bnxt_qplib_free_nq(&rdev->nq[i]);
 	}
@@ -1324,7 +1337,7 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
 		bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
 		bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
 		bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
-		type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
 		bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
 	}
@@ -1405,7 +1418,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 		pr_err("Failed to allocate RCFW Channel: %#x\n", rc);
 		goto fail;
 	}
-	type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+
+	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 	pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
 	pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
 	ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
@@ -1434,7 +1448,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	bnxt_re_set_resource_limits(rdev);
 
 	rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0,
-				  bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx));
+				  bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx));
 	if (rc) {
 		pr_err("Failed to allocate QPLIB context: %#x\n", rc);
 		goto disable_rcfw;
@@ -1504,7 +1518,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 disable_rcfw:
 	bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 free_ring:
-	type = bnxt_qplib_get_ring_type(&rdev->chip_ctx);
+	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 	bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
 free_rcfw:
 	bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 958c1ff..bc9f747 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -2426,7 +2426,7 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
 	}
 	cqe = *pcqe;
 	cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
-	cqe->length = (u32)le16_to_cpu(hwcqe->length);
+	cqe->length = le16_to_cpu(hwcqe->length) & CQ_RES_UD_LENGTH_MASK;
 	cqe->cfa_meta = le16_to_cpu(hwcqe->cfa_metadata);
 	cqe->invrkey = le32_to_cpu(hwcqe->imm_data);
 	cqe->flags = le16_to_cpu(hwcqe->flags);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 3/7] RDMA/bnxt_re: Refactor hardware queue memory allocation
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function Devesh Sharma
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

At top level there are three major data structure addition.
viz bnxt_qplib_hwq_attr, bnxt_qplib_sg_info and bnxt_qplib_tqm_ctx

Intorduction of first data structure reduces the arguments list
to bnxt_re_alloc_init_hwq() function. There are changes all over
the driver code to incorporate this new structure. The caller
needs to fill the attribute data structure and pass to this function.

The second data structure is to pass memory region description
viz. sghead, page_size and page_shift. There are changes all over
the driver code to initialize bnxt_re_sg_info data structure. The
new data structure helps to reduce the argument list of
__alloc_pbl() function call.

Till now the TQM rings related members were not collected under any
specific data-structure making it hard to manage. The third data
sctructure bnxt_qplib_tqm_ctx is added to refactor the TQM queue
allocation and initialization.

Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c   |  26 +-
 drivers/infiniband/hw/bnxt_re/main.c       |  20 +-
 drivers/infiniband/hw/bnxt_re/qplib_fp.c   | 176 ++++++-----
 drivers/infiniband/hw/bnxt_re/qplib_fp.h   |   2 +-
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.c |  59 ++--
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |   5 +-
 drivers/infiniband/hw/bnxt_re/qplib_res.c  | 475 ++++++++++++++++++-----------
 drivers/infiniband/hw/bnxt_re/qplib_res.h  |  60 ++--
 drivers/infiniband/hw/bnxt_re/qplib_sp.c   |  52 ++--
 9 files changed, 543 insertions(+), 332 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 865728c..e589c98 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -876,9 +876,11 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 		return PTR_ERR(umem);
 
 	qp->sumem = umem;
-	qplib_qp->sq.sg_info.sglist = umem->sg_head.sgl;
+	qplib_qp->sq.sg_info.sghead = umem->sg_head.sgl;
 	qplib_qp->sq.sg_info.npages = ib_umem_num_pages(umem);
 	qplib_qp->sq.sg_info.nmap = umem->nmap;
+	qplib_qp->sq.sg_info.pgsize = PAGE_SIZE;
+	qplib_qp->sq.sg_info.pgshft = PAGE_SHIFT;
 	qplib_qp->qp_handle = ureq.qp_handle;
 
 	if (!qp->qplib_qp.srq) {
@@ -889,9 +891,11 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 		if (IS_ERR(umem))
 			goto rqfail;
 		qp->rumem = umem;
-		qplib_qp->rq.sg_info.sglist = umem->sg_head.sgl;
+		qplib_qp->rq.sg_info.sghead = umem->sg_head.sgl;
 		qplib_qp->rq.sg_info.npages = ib_umem_num_pages(umem);
 		qplib_qp->rq.sg_info.nmap = umem->nmap;
+		qplib_qp->rq.sg_info.pgsize = PAGE_SIZE;
+		qplib_qp->rq.sg_info.pgshft = PAGE_SHIFT;
 	}
 
 	qplib_qp->dpi = &cntx->dpi;
@@ -981,6 +985,8 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	qp->qplib_qp.sq.max_sge = 2;
 	/* Q full delta can be 1 since it is internal QP */
 	qp->qplib_qp.sq.q_full_delta = 1;
+	qp->qplib_qp.sq.sg_info.pgsize = PAGE_SIZE;
+	qp->qplib_qp.sq.sg_info.pgshft = PAGE_SHIFT;
 
 	qp->qplib_qp.scq = qp1_qp->scq;
 	qp->qplib_qp.rcq = qp1_qp->rcq;
@@ -989,6 +995,8 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;
 	/* Q full delta can be 1 since it is internal QP */
 	qp->qplib_qp.rq.q_full_delta = 1;
+	qp->qplib_qp.rq.sg_info.pgsize = PAGE_SIZE;
+	qp->qplib_qp.rq.sg_info.pgshft = PAGE_SHIFT;
 
 	qp->qplib_qp.mtu = qp1_qp->mtu;
 
@@ -1048,6 +1056,8 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
 		if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
 			qplqp->rq.max_sge = dev_attr->max_qp_sges;
 	}
+	qplqp->rq.sg_info.pgsize = PAGE_SIZE;
+	qplqp->rq.sg_info.pgshft = PAGE_SHIFT;
 
 	return 0;
 }
@@ -1100,6 +1110,8 @@ static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
 	 * unexpected Queue full condition
 	 */
 	qplqp->sq.q_full_delta -= 1;
+	qplqp->sq.sg_info.pgsize = PAGE_SIZE;
+	qplqp->sq.sg_info.pgshft = PAGE_SHIFT;
 }
 
 static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
@@ -1515,9 +1527,11 @@ static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
 		return PTR_ERR(umem);
 
 	srq->umem = umem;
-	qplib_srq->sg_info.sglist = umem->sg_head.sgl;
+	qplib_srq->sg_info.sghead = umem->sg_head.sgl;
 	qplib_srq->sg_info.npages = ib_umem_num_pages(umem);
 	qplib_srq->sg_info.nmap = umem->nmap;
+	qplib_srq->sg_info.pgsize = PAGE_SIZE;
+	qplib_srq->sg_info.pgshft = PAGE_SHIFT;
 	qplib_srq->srq_handle = ureq.srq_handle;
 	qplib_srq->dpi = &cntx->dpi;
 
@@ -2371,7 +2385,7 @@ static int bnxt_re_build_reg_wqe(const struct ib_reg_wr *wr,
 	wqe->frmr.pbl_dma_ptr = qplib_frpl->hwq.pbl_dma_ptr[0];
 	wqe->frmr.page_list = mr->pages;
 	wqe->frmr.page_list_len = mr->npages;
-	wqe->frmr.levels = qplib_frpl->hwq.level + 1;
+	wqe->frmr.levels = qplib_frpl->hwq.level;
 	wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;
 
 	/* Need unconditional fence for reg_mr
@@ -2745,6 +2759,8 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
 	if (entries > dev_attr->max_cq_wqes + 1)
 		entries = dev_attr->max_cq_wqes + 1;
 
+	cq->qplib_cq.sg_info.pgsize = PAGE_SIZE;
+	cq->qplib_cq.sg_info.pgshft = PAGE_SHIFT;
 	if (udata) {
 		struct bnxt_re_cq_req req;
 		struct bnxt_re_ucontext *uctx = rdma_udata_to_drv_context(
@@ -2761,7 +2777,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
 			rc = PTR_ERR(cq->umem);
 			goto fail;
 		}
-		cq->qplib_cq.sg_info.sglist = cq->umem->sg_head.sgl;
+		cq->qplib_cq.sg_info.sghead = cq->umem->sg_head.sgl;
 		cq->qplib_cq.sg_info.npages = ib_umem_num_pages(cq->umem);
 		cq->qplib_cq.sg_info.nmap = cq->umem->nmap;
 		cq->qplib_cq.dpi = &uctx->dpi;
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 390daeb..a966c68 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -90,6 +90,8 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
 	rdev->chip_ctx = NULL;
 	rdev->rcfw.res = NULL;
 	rdev->qplib_res.cctx = NULL;
+	rdev->qplib_res.pdev = NULL;
+	rdev->qplib_res.netdev = NULL;
 	kfree(chip_ctx);
 }
 
@@ -151,7 +153,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
 	ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq);
 	if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))
 		for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
-			rdev->qplib_ctx.tqm_count[i] =
+			rdev->qplib_ctx.tqm_ctx.qcount[i] =
 			rdev->dev_attr.tqm_alloc_reqs[i];
 }
 
@@ -982,8 +984,8 @@ static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev)
 	for (i = 0; i < rdev->num_msix - 1; i++) {
 		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
-		rdev->nq[i].res = NULL;
 		bnxt_qplib_free_nq(&rdev->nq[i]);
+		rdev->nq[i].res = NULL;
 	}
 }
 
@@ -1032,7 +1034,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 		rdev->nq[i].res = &rdev->qplib_res;
 		rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
 			BNXT_RE_MAX_SRQC_COUNT + 2;
-		rc = bnxt_qplib_alloc_nq(rdev->en_dev->pdev, &rdev->nq[i]);
+		rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]);
 		if (rc) {
 			dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
 				i, rc);
@@ -1056,7 +1058,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 	}
 	return 0;
 free_nq:
-	for (i = num_vec_created; i >= 0; i--) {
+	for (i = num_vec_created - 1; i >= 0; i--) {
 		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
 		bnxt_qplib_free_nq(&rdev->nq[i]);
@@ -1335,7 +1337,7 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
 			dev_warn(rdev_to_dev(rdev),
 				 "Failed to deinitialize RCFW: %#x", rc);
 		bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
-		bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
+		bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx);
 		bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
 		bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
@@ -1411,7 +1413,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	/* Establish RCFW Communication Channel to initialize the context
 	 * memory for the function and all child VFs
 	 */
-	rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw,
+	rc = bnxt_qplib_alloc_rcfw_channel(&rdev->qplib_res, &rdev->rcfw,
 					   &rdev->qplib_ctx,
 					   BNXT_RE_MAX_QPC_COUNT);
 	if (rc) {
@@ -1432,7 +1434,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	}
 	db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX);
 	vid = rdev->msix_entries[BNXT_RE_AEQ_IDX].vector;
-	rc = bnxt_qplib_enable_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw,
+	rc = bnxt_qplib_enable_rcfw_channel(&rdev->rcfw,
 					    vid, db_offt, rdev->is_virtfn,
 					    &bnxt_re_aeq_handler);
 	if (rc) {
@@ -1447,7 +1449,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 
 	bnxt_re_set_resource_limits(rdev);
 
-	rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0,
+	rc = bnxt_qplib_alloc_ctx(&rdev->qplib_res, &rdev->qplib_ctx, 0,
 				  bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx));
 	if (rc) {
 		pr_err("Failed to allocate QPLIB context: %#x\n", rc);
@@ -1514,7 +1516,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 free_sctx:
 	bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
 free_ctx:
-	bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
+	bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx);
 disable_rcfw:
 	bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 free_ring:
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index bc9f747..792fc6b 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -464,26 +464,35 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
 void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq)
 {
 	if (nq->hwq.max_elements) {
-		bnxt_qplib_free_hwq(nq->pdev, &nq->hwq);
+		bnxt_qplib_free_hwq(nq->res, &nq->hwq);
 		nq->hwq.max_elements = 0;
 	}
 }
 
-int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq)
+int bnxt_qplib_alloc_nq(struct bnxt_qplib_res *res, struct bnxt_qplib_nq *nq)
 {
-	u8 hwq_type;
+	struct bnxt_qplib_hwq_attr hwq_attr;
+	struct bnxt_qplib_sg_info sginfo;
 
-	nq->pdev = pdev;
+	nq->pdev = res->pdev;
+	nq->res = res;
 	if (!nq->hwq.max_elements ||
 	    nq->hwq.max_elements > BNXT_QPLIB_NQE_MAX_CNT)
 		nq->hwq.max_elements = BNXT_QPLIB_NQE_MAX_CNT;
-	hwq_type = bnxt_qplib_get_hwq_type(nq->res);
-	if (bnxt_qplib_alloc_init_hwq(nq->pdev, &nq->hwq, NULL,
-				      &nq->hwq.max_elements,
-				      BNXT_QPLIB_MAX_NQE_ENTRY_SIZE, 0,
-				      PAGE_SIZE, hwq_type))
-		return -ENOMEM;
 
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
+	sginfo.pgsize = PAGE_SIZE;
+	sginfo.pgshft = PAGE_SHIFT;
+	hwq_attr.res = res;
+	hwq_attr.sginfo = &sginfo;
+	hwq_attr.depth = nq->hwq.max_elements;
+	hwq_attr.stride = sizeof(struct nq_base);
+	hwq_attr.type = bnxt_qplib_get_hwq_type(nq->res);
+	if (bnxt_qplib_alloc_init_hwq(&nq->hwq, &hwq_attr)) {
+		dev_err(&nq->pdev->dev, "FP NQ allocation failed");
+		return -ENOMEM;
+	}
 	nq->budget = 8;
 	return 0;
 }
@@ -526,24 +535,27 @@ void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
 	kfree(srq->swq);
 	if (rc)
 		return;
-	bnxt_qplib_free_hwq(res->pdev, &srq->hwq);
+	bnxt_qplib_free_hwq(res, &srq->hwq);
 }
 
 int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 			  struct bnxt_qplib_srq *srq)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
-	struct cmdq_create_srq req;
+	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct creq_create_srq_resp resp;
+	struct cmdq_create_srq req;
 	struct bnxt_qplib_pbl *pbl;
 	u16 cmd_flags = 0;
 	int rc, idx;
 
-	srq->hwq.max_elements = srq->max_wqe;
-	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &srq->hwq, &srq->sg_info,
-				       &srq->hwq.max_elements,
-				       BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_QUEUE);
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	hwq_attr.res = res;
+	hwq_attr.sginfo = &srq->sg_info;
+	hwq_attr.depth = srq->max_wqe;
+	hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
+	hwq_attr.type = HWQ_TYPE_QUEUE;
+	rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr);
 	if (rc)
 		goto exit;
 
@@ -602,7 +614,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 
 	return 0;
 fail:
-	bnxt_qplib_free_hwq(res->pdev, &srq->hwq);
+	bnxt_qplib_free_hwq(res, &srq->hwq);
 	kfree(srq->swq);
 exit:
 	return rc;
@@ -722,14 +734,15 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,
 int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
-	struct cmdq_create_qp1 req;
-	struct creq_create_qp1_resp resp;
-	struct bnxt_qplib_pbl *pbl;
+	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct bnxt_qplib_q *sq = &qp->sq;
 	struct bnxt_qplib_q *rq = &qp->rq;
-	int rc;
+	struct creq_create_qp1_resp resp;
+	struct cmdq_create_qp1 req;
+	struct bnxt_qplib_pbl *pbl;
 	u16 cmd_flags = 0;
 	u32 qp_flags = 0;
+	int rc;
 
 	RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags);
 
@@ -738,12 +751,14 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 	req.dpi = cpu_to_le32(qp->dpi->dpi);
 	req.qp_handle = cpu_to_le64(qp->qp_handle);
 
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
 	/* SQ */
-	sq->hwq.max_elements = sq->max_wqe;
-	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, NULL,
-				       &sq->hwq.max_elements,
-				       BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_QUEUE);
+	hwq_attr.res = res;
+	hwq_attr.sginfo = &sq->sg_info;
+	hwq_attr.depth = sq->max_wqe;
+	hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE;
+	hwq_attr.type = HWQ_TYPE_QUEUE;
+	rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
 	if (rc)
 		goto exit;
 
@@ -778,11 +793,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
 	/* RQ */
 	if (rq->max_wqe) {
-		rq->hwq.max_elements = qp->rq.max_wqe;
-		rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, NULL,
-					       &rq->hwq.max_elements,
-					       BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0,
-					       PAGE_SIZE, HWQ_TYPE_QUEUE);
+		hwq_attr.res = res;
+		hwq_attr.sginfo = &rq->sg_info;
+		hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
+		hwq_attr.depth = qp->rq.max_wqe;
+		hwq_attr.type = HWQ_TYPE_QUEUE;
+		rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
 		if (rc)
 			goto fail_sq;
 
@@ -848,10 +864,10 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 fail:
 	bnxt_qplib_free_qp_hdr_buf(res, qp);
 fail_rq:
-	bnxt_qplib_free_hwq(res->pdev, &rq->hwq);
+	bnxt_qplib_free_hwq(res, &rq->hwq);
 	kfree(rq->swq);
 fail_sq:
-	bnxt_qplib_free_hwq(res->pdev, &sq->hwq);
+	bnxt_qplib_free_hwq(res, &sq->hwq);
 	kfree(sq->swq);
 exit:
 	return rc;
@@ -861,9 +877,11 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
 	unsigned long int psn_search, poff = 0;
+	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct sq_psn_search **psn_search_ptr;
 	struct bnxt_qplib_q *sq = &qp->sq;
 	struct bnxt_qplib_q *rq = &qp->rq;
+	struct bnxt_qplib_sg_info sginfo;
 	int i, rc, req_size, psn_sz = 0;
 	struct sq_send **hw_sq_send_ptr;
 	struct creq_create_qp_resp resp;
@@ -881,18 +899,23 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 	req.dpi = cpu_to_le32(qp->dpi->dpi);
 	req.qp_handle = cpu_to_le64(qp->qp_handle);
 
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
 	/* SQ */
 	if (qp->type == CMDQ_CREATE_QP_TYPE_RC) {
 		psn_sz = bnxt_qplib_is_chip_gen_p5(res->cctx) ?
 			 sizeof(struct sq_psn_search_ext) :
 			 sizeof(struct sq_psn_search);
 	}
-	sq->hwq.max_elements = sq->max_wqe;
-	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, &sq->sg_info,
-				       &sq->hwq.max_elements,
-				       BNXT_QPLIB_MAX_SQE_ENTRY_SIZE,
-				       psn_sz,
-				       PAGE_SIZE, HWQ_TYPE_QUEUE);
+
+	hwq_attr.res = res;
+	hwq_attr.sginfo = &sq->sg_info;
+	hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE;
+	hwq_attr.depth = sq->max_wqe;
+	hwq_attr.aux_stride = psn_sz;
+	hwq_attr.aux_depth = hwq_attr.depth;
+	hwq_attr.type = HWQ_TYPE_QUEUE;
+	rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
 	if (rc)
 		goto exit;
 
@@ -956,12 +979,14 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
 	/* RQ */
 	if (rq->max_wqe) {
-		rq->hwq.max_elements = rq->max_wqe;
-		rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq,
-					       &rq->sg_info,
-					       &rq->hwq.max_elements,
-					       BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0,
-					       PAGE_SIZE, HWQ_TYPE_QUEUE);
+		hwq_attr.res = res;
+		hwq_attr.sginfo = &rq->sg_info;
+		hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
+		hwq_attr.depth = rq->max_wqe;
+		hwq_attr.aux_stride = 0;
+		hwq_attr.aux_depth = 0;
+		hwq_attr.type = HWQ_TYPE_QUEUE;
+		rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
 		if (rc)
 			goto fail_sq;
 
@@ -1029,10 +1054,17 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 		req_size = xrrq->max_elements *
 			   BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE + PAGE_SIZE - 1;
 		req_size &= ~(PAGE_SIZE - 1);
-		rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL,
-					       &xrrq->max_elements,
-					       BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE,
-					       0, req_size, HWQ_TYPE_CTX);
+		sginfo.pgsize = req_size;
+		sginfo.pgshft = PAGE_SHIFT;
+
+		hwq_attr.res = res;
+		hwq_attr.sginfo = &sginfo;
+		hwq_attr.depth = xrrq->max_elements;
+		hwq_attr.stride = BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE;
+		hwq_attr.aux_stride = 0;
+		hwq_attr.aux_depth = 0;
+		hwq_attr.type = HWQ_TYPE_CTX;
+		rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr);
 		if (rc)
 			goto fail_buf_free;
 		pbl = &xrrq->pbl[PBL_LVL_0];
@@ -1044,11 +1076,10 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 		req_size = xrrq->max_elements *
 			   BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE + PAGE_SIZE - 1;
 		req_size &= ~(PAGE_SIZE - 1);
-
-		rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL,
-					       &xrrq->max_elements,
-					       BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE,
-					       0, req_size, HWQ_TYPE_CTX);
+		sginfo.pgsize = req_size;
+		hwq_attr.depth =  xrrq->max_elements;
+		hwq_attr.stride = BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE;
+		rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr);
 		if (rc)
 			goto fail_orrq;
 
@@ -1074,17 +1105,17 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
 fail:
 	if (qp->irrq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &qp->irrq);
+		bnxt_qplib_free_hwq(res, &qp->irrq);
 fail_orrq:
 	if (qp->orrq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &qp->orrq);
+		bnxt_qplib_free_hwq(res, &qp->orrq);
 fail_buf_free:
 	bnxt_qplib_free_qp_hdr_buf(res, qp);
 fail_rq:
-	bnxt_qplib_free_hwq(res->pdev, &rq->hwq);
+	bnxt_qplib_free_hwq(res, &rq->hwq);
 	kfree(rq->swq);
 fail_sq:
-	bnxt_qplib_free_hwq(res->pdev, &sq->hwq);
+	bnxt_qplib_free_hwq(res, &sq->hwq);
 	kfree(sq->swq);
 exit:
 	return rc;
@@ -1440,16 +1471,16 @@ void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res,
 			    struct bnxt_qplib_qp *qp)
 {
 	bnxt_qplib_free_qp_hdr_buf(res, qp);
-	bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq);
+	bnxt_qplib_free_hwq(res, &qp->sq.hwq);
 	kfree(qp->sq.swq);
 
-	bnxt_qplib_free_hwq(res->pdev, &qp->rq.hwq);
+	bnxt_qplib_free_hwq(res, &qp->rq.hwq);
 	kfree(qp->rq.swq);
 
 	if (qp->irrq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &qp->irrq);
+		bnxt_qplib_free_hwq(res, &qp->irrq);
 	if (qp->orrq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &qp->orrq);
+		bnxt_qplib_free_hwq(res, &qp->orrq);
 
 }
 
@@ -1927,17 +1958,20 @@ static void bnxt_qplib_arm_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
 int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
-	struct cmdq_create_cq req;
+	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct creq_create_cq_resp resp;
+	struct cmdq_create_cq req;
 	struct bnxt_qplib_pbl *pbl;
 	u16 cmd_flags = 0;
 	int rc;
 
-	cq->hwq.max_elements = cq->max_wqe;
-	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &cq->hwq, &cq->sg_info,
-				       &cq->hwq.max_elements,
-				       BNXT_QPLIB_MAX_CQE_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_QUEUE);
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	hwq_attr.res = res;
+	hwq_attr.depth = cq->max_wqe;
+	hwq_attr.stride = sizeof(struct cq_base);
+	hwq_attr.type = HWQ_TYPE_QUEUE;
+	hwq_attr.sginfo = &cq->sg_info;
+	rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr);
 	if (rc)
 		goto exit;
 
@@ -1988,7 +2022,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 	return 0;
 
 fail:
-	bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
+	bnxt_qplib_free_hwq(res, &cq->hwq);
 exit:
 	return rc;
 }
@@ -2008,7 +2042,7 @@ int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 					  (void *)&resp, NULL, 0);
 	if (rc)
 		return rc;
-	bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
+	bnxt_qplib_free_hwq(res, &cq->hwq);
 	return 0;
 }
 
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 99e0a13..d3f080c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -550,7 +550,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
 bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq);
 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
 void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq);
-int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq);
+int bnxt_qplib_alloc_nq(struct bnxt_qplib_res *res, struct bnxt_qplib_nq *nq);
 void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp);
 void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
 				 unsigned long *flags);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index 5cdfa84..d2464dc 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -520,9 +520,10 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 	level = ctx->tim_tbl.level;
 	req.tim_pg_size_tim_lvl = (level << CMDQ_INITIALIZE_FW_TIM_LVL_SFT) |
 				  __get_pbl_pg_idx(&ctx->tim_tbl.pbl[level]);
-	level = ctx->tqm_pde_level;
-	req.tqm_pg_size_tqm_lvl = (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) |
-				  __get_pbl_pg_idx(&ctx->tqm_pde.pbl[level]);
+	level = ctx->tqm_ctx.pde.level;
+	req.tqm_pg_size_tqm_lvl =
+		(level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) |
+		 __get_pbl_pg_idx(&ctx->tqm_ctx.pde.pbl[level]);
 
 	req.qpc_page_dir =
 		cpu_to_le64(ctx->qpc_tbl.pbl[PBL_LVL_0].pg_map_arr[0]);
@@ -535,7 +536,7 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 	req.tim_page_dir =
 		cpu_to_le64(ctx->tim_tbl.pbl[PBL_LVL_0].pg_map_arr[0]);
 	req.tqm_page_dir =
-		cpu_to_le64(ctx->tqm_pde.pbl[PBL_LVL_0].pg_map_arr[0]);
+		cpu_to_le64(ctx->tqm_ctx.pde.pbl[PBL_LVL_0].pg_map_arr[0]);
 
 	req.number_of_qp = cpu_to_le32(ctx->qpc_tbl.max_elements);
 	req.number_of_mrw = cpu_to_le32(ctx->mrw_tbl.max_elements);
@@ -563,25 +564,34 @@ void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 {
 	kfree(rcfw->qp_tbl);
 	kfree(rcfw->crsqe_tbl);
-	bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq);
-	bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq);
+	bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq);
+	bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq);
 	rcfw->pdev = NULL;
 }
 
-int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
+int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 				  struct bnxt_qplib_rcfw *rcfw,
 				  struct bnxt_qplib_ctx *ctx,
 				  int qp_tbl_sz)
 {
-	u8 hwq_type;
-
-	rcfw->pdev = pdev;
-	rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT;
-	hwq_type = bnxt_qplib_get_hwq_type(rcfw->res);
-	if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->creq, NULL,
-				      &rcfw->creq.max_elements,
-				      BNXT_QPLIB_CREQE_UNITS,
-				      0, PAGE_SIZE, hwq_type)) {
+	struct bnxt_qplib_hwq_attr hwq_attr;
+	struct bnxt_qplib_sg_info sginfo;
+
+	rcfw->pdev = res->pdev;
+	rcfw->res = res;
+
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
+	sginfo.pgsize = PAGE_SIZE;
+	sginfo.pgshft = PAGE_SHIFT;
+
+	hwq_attr.sginfo = &sginfo;
+	hwq_attr.res = rcfw->res;
+	hwq_attr.depth = BNXT_QPLIB_CREQE_MAX_CNT;
+	hwq_attr.stride = BNXT_QPLIB_CREQE_UNITS;
+	hwq_attr.type = bnxt_qplib_get_hwq_type(res);
+
+	if (bnxt_qplib_alloc_init_hwq(&rcfw->creq, &hwq_attr)) {
 		dev_err(&rcfw->pdev->dev,
 			"HW channel CREQ allocation failed\n");
 		goto fail;
@@ -591,13 +601,11 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
 	else
 		rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
 
-	rcfw->cmdq.max_elements = rcfw->cmdq_depth;
-	if (bnxt_qplib_alloc_init_hwq
-			(rcfw->pdev, &rcfw->cmdq, NULL,
-			 &rcfw->cmdq.max_elements,
-			 BNXT_QPLIB_CMDQE_UNITS, 0,
-			 bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth),
-			 HWQ_TYPE_CTX)) {
+	sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth);
+	hwq_attr.depth = rcfw->cmdq_depth;
+	hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS;
+	hwq_attr.type = HWQ_TYPE_CTX;
+	if (bnxt_qplib_alloc_init_hwq(&rcfw->cmdq, &hwq_attr)) {
 		dev_err(&rcfw->pdev->dev,
 			"HW channel CMDQ allocation failed\n");
 		goto fail;
@@ -690,8 +698,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 	return 0;
 }
 
-int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
-				   struct bnxt_qplib_rcfw *rcfw,
+int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
 				   int msix_vector,
 				   int cp_bar_reg_off, int virt_fn,
 				   int (*aeq_handler)(struct bnxt_qplib_rcfw *,
@@ -699,10 +706,12 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
 {
 	resource_size_t res_base;
 	struct cmdq_init init;
+	struct pci_dev *pdev;
 	u16 bmap_size;
 	int rc;
 
 	/* General */
+	pdev = rcfw->pdev;
 	rcfw->seq_num = 0;
 	set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags);
 	bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
index dfeadc1..ab1531c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -268,7 +268,7 @@ struct bnxt_qplib_rcfw {
 };
 
 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
-int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
+int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 				  struct bnxt_qplib_rcfw *rcfw,
 				  struct bnxt_qplib_ctx *ctx,
 				  int qp_tbl_sz);
@@ -276,8 +276,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
 void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
 int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 			      bool need_init);
-int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
-				   struct bnxt_qplib_rcfw *rcfw,
+int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
 				   int msix_vector,
 				   int cp_bar_reg_off, int virt_fn,
 				   int (*aeq_handler)(struct bnxt_qplib_rcfw *,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
index bdbde8e..1fa8e79 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -55,9 +55,10 @@ static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev,
 				      struct bnxt_qplib_stats *stats);
 
 /* PBL */
-static void __free_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
+static void __free_pbl(struct bnxt_qplib_res *res, struct bnxt_qplib_pbl *pbl,
 		       bool is_umem)
 {
+	struct pci_dev *pdev = res->pdev;
 	int i;
 
 	if (!is_umem) {
@@ -74,35 +75,57 @@ static void __free_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
 			pbl->pg_arr[i] = NULL;
 		}
 	}
-	kfree(pbl->pg_arr);
+	vfree(pbl->pg_arr);
 	pbl->pg_arr = NULL;
-	kfree(pbl->pg_map_arr);
+	vfree(pbl->pg_map_arr);
 	pbl->pg_map_arr = NULL;
 	pbl->pg_count = 0;
 	pbl->pg_size = 0;
 }
 
-static int __alloc_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
-		       struct scatterlist *sghead, u32 pages,
-		       u32 nmaps, u32 pg_size)
+static void bnxt_qplib_fill_user_dma_pages(struct bnxt_qplib_pbl *pbl,
+					   struct bnxt_qplib_sg_info *sginfo)
 {
+	struct scatterlist *sghead = sginfo->sghead;
 	struct sg_dma_page_iter sg_iter;
+	int i = 0;
+
+	for_each_sg_dma_page(sghead, &sg_iter, sginfo->nmap, 0) {
+		pbl->pg_map_arr[i] = sg_page_iter_dma_address(&sg_iter);
+		pbl->pg_arr[i] = NULL;
+		pbl->pg_count++;
+		i++;
+	}
+}
+
+static int __alloc_pbl(struct bnxt_qplib_res *res,
+		       struct bnxt_qplib_pbl *pbl,
+		       struct bnxt_qplib_sg_info *sginfo)
+{
+	struct pci_dev *pdev = res->pdev;
+	struct scatterlist *sghead;
 	bool is_umem = false;
+	u32 pages, pg_size;
 	int i;
 
+	if (sginfo->nopte)
+		return 0;
+	pages = sginfo->npages;
+	pg_size = sginfo->pgsize;
+	sghead = sginfo->sghead;
 	/* page ptr arrays */
-	pbl->pg_arr = kcalloc(pages, sizeof(void *), GFP_KERNEL);
+	pbl->pg_arr = vmalloc(pages * sizeof(void *));
 	if (!pbl->pg_arr)
 		return -ENOMEM;
 
-	pbl->pg_map_arr = kcalloc(pages, sizeof(dma_addr_t), GFP_KERNEL);
+	pbl->pg_map_arr = vmalloc(pages * sizeof(dma_addr_t));
 	if (!pbl->pg_map_arr) {
-		kfree(pbl->pg_arr);
+		vfree(pbl->pg_arr);
 		pbl->pg_arr = NULL;
 		return -ENOMEM;
 	}
 	pbl->pg_count = 0;
-	pbl->pg_size = pg_size;
+	pbl->pg_size = sginfo->pgsize;
 
 	if (!sghead) {
 		for (i = 0; i < pages; i++) {
@@ -115,25 +138,19 @@ static int __alloc_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
 			pbl->pg_count++;
 		}
 	} else {
-		i = 0;
 		is_umem = true;
-		for_each_sg_dma_page(sghead, &sg_iter, nmaps, 0) {
-			pbl->pg_map_arr[i] = sg_page_iter_dma_address(&sg_iter);
-			pbl->pg_arr[i] = NULL;
-			pbl->pg_count++;
-			i++;
-		}
+		bnxt_qplib_fill_user_dma_pages(pbl, sginfo);
 	}
 
 	return 0;
-
 fail:
-	__free_pbl(pdev, pbl, is_umem);
+	__free_pbl(res, pbl, is_umem);
 	return -ENOMEM;
 }
 
 /* HWQ */
-void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq)
+void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res,
+			 struct bnxt_qplib_hwq *hwq)
 {
 	int i;
 
@@ -144,9 +161,9 @@ void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq)
 
 	for (i = 0; i < hwq->level + 1; i++) {
 		if (i == hwq->level)
-			__free_pbl(pdev, &hwq->pbl[i], hwq->is_user);
+			__free_pbl(res, &hwq->pbl[i], hwq->is_user);
 		else
-			__free_pbl(pdev, &hwq->pbl[i], false);
+			__free_pbl(res, &hwq->pbl[i], false);
 	}
 
 	hwq->level = PBL_LVL_MAX;
@@ -158,79 +175,114 @@ void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq)
 }
 
 /* All HWQs are power of 2 in size */
-int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
-			      struct bnxt_qplib_sg_info *sg_info,
-			      u32 *elements, u32 element_size, u32 aux,
-			      u32 pg_size, enum bnxt_qplib_hwq_type hwq_type)
+
+int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
+			      struct bnxt_qplib_hwq_attr *hwq_attr)
 {
-	u32 pages, maps, slots, size, aux_pages = 0, aux_size = 0;
+	u32 npages, aux_slots, pg_size, aux_pages = 0, aux_size = 0;
+	u32 depth, stride, npbl, npde;
+	struct bnxt_qplib_sg_info sginfo;
 	dma_addr_t *src_phys_ptr, **dst_virt_ptr;
 	struct scatterlist *sghead = NULL;
-	int i, rc;
-
+	struct bnxt_qplib_res *res;
+	struct pci_dev *pdev;
+	int i, rc, lvl;
+
+	res = hwq_attr->res;
+	pdev = res->pdev;
+	sghead = hwq_attr->sginfo->sghead;
+	pg_size = hwq_attr->sginfo->pgsize;
+	memset(&sginfo, 0, sizeof(sginfo));
 	hwq->level = PBL_LVL_MAX;
 
-	slots = roundup_pow_of_two(*elements);
-	if (aux) {
-		aux_size = roundup_pow_of_two(aux);
-		aux_pages = (slots * aux_size) / pg_size;
-		if ((slots * aux_size) % pg_size)
+	depth = roundup_pow_of_two(hwq_attr->depth);
+	stride = roundup_pow_of_two(hwq_attr->stride);
+	if (hwq_attr->aux_depth) {
+		aux_slots = hwq_attr->aux_depth;
+		aux_size = roundup_pow_of_two(hwq_attr->aux_stride);
+		aux_pages = (aux_slots * aux_size) / pg_size;
+		if ((aux_slots * aux_size) % pg_size)
 			aux_pages++;
 	}
-	size = roundup_pow_of_two(element_size);
-
-	if (sg_info)
-		sghead = sg_info->sglist;
 
 	if (!sghead) {
 		hwq->is_user = false;
-		pages = (slots * size) / pg_size + aux_pages;
-		if ((slots * size) % pg_size)
-			pages++;
-		if (!pages)
+		npages = (depth * stride) / pg_size + aux_pages;
+		if ((depth * stride) % pg_size)
+			npages++;
+		if (!npages)
 			return -EINVAL;
-		maps = 0;
+		hwq_attr->sginfo->npages = npages;
 	} else {
 		hwq->is_user = true;
-		pages = sg_info->npages;
-		maps = sg_info->nmap;
+		npages = hwq_attr->sginfo->npages;
+		npages = (npages * PAGE_SIZE) /
+			  BIT_ULL(hwq_attr->sginfo->pgshft);
+		if ((hwq_attr->sginfo->npages * PAGE_SIZE) %
+		     BIT_ULL(hwq_attr->sginfo->pgshft))
+			if (!npages)
+				npages++;
 	}
 
-	/* Alloc the 1st memory block; can be a PDL/PTL/PBL */
-	if (sghead && (pages == MAX_PBL_LVL_0_PGS))
-		rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], sghead,
-				 pages, maps, pg_size);
-	else
-		rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], NULL,
-				 1, 0, pg_size);
-	if (rc)
-		goto fail;
-
-	hwq->level = PBL_LVL_0;
+	if (npages == MAX_PBL_LVL_0_PGS) {
+		/* This request is Level 0, map PTE */
+		rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], hwq_attr->sginfo);
+		if (rc)
+			goto fail;
+		hwq->level = PBL_LVL_0;
+	}
 
-	if (pages > MAX_PBL_LVL_0_PGS) {
-		if (pages > MAX_PBL_LVL_1_PGS) {
+	if (npages > MAX_PBL_LVL_0_PGS) {
+		if (npages > MAX_PBL_LVL_1_PGS) {
+			u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
+				    0 : PTU_PTE_VALID;
 			/* 2 levels of indirection */
-			rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], NULL,
-					 MAX_PBL_LVL_1_PGS_FOR_LVL_2,
-					 0, pg_size);
+			npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
+			if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT))
+				npbl++;
+			npde = npbl >> MAX_PDL_LVL_SHIFT;
+			if (npbl % BIT(MAX_PDL_LVL_SHIFT))
+				npde++;
+			/* Alloc PDE pages */
+			sginfo.pgsize = npde * pg_size;
+			sginfo.npages = 1;
+			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
+
+			/* Alloc PBL pages */
+			sginfo.npages = npbl;
+			sginfo.pgsize = PAGE_SIZE;
+			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1], &sginfo);
 			if (rc)
 				goto fail;
-			/* Fill in lvl0 PBL */
+			/* Fill PDL with PBL page pointers */
 			dst_virt_ptr =
 				(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
 			src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
-			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
-				dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
-					src_phys_ptr[i] | PTU_PDE_VALID;
-			hwq->level = PBL_LVL_1;
-
-			rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_2], sghead,
-					 pages, maps, pg_size);
+			if (hwq_attr->type == HWQ_TYPE_MR) {
+			/* For MR it is expected that we supply only 1 contigous
+			 * page i.e only 1 entry in the PDL that will contain
+			 * all the PBLs for the user supplied memory region
+			 */
+				for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
+				     i++)
+					dst_virt_ptr[0][i] = src_phys_ptr[i] |
+						flag;
+			} else {
+				for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
+				     i++)
+					dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
+						src_phys_ptr[i] |
+						PTU_PDE_VALID;
+			}
+			/* Alloc or init PTEs */
+			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2],
+					 hwq_attr->sginfo);
 			if (rc)
 				goto fail;
-
-			/* Fill in lvl1 PBL */
+			hwq->level = PBL_LVL_2;
+			if (hwq_attr->sginfo->nopte)
+				goto done;
+			/* Fill PBLs with PTE pointers */
 			dst_virt_ptr =
 				(dma_addr_t **)hwq->pbl[PBL_LVL_1].pg_arr;
 			src_phys_ptr = hwq->pbl[PBL_LVL_2].pg_map_arr;
@@ -238,7 +290,7 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
 				dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
 					src_phys_ptr[i] | PTU_PTE_VALID;
 			}
-			if (hwq_type == HWQ_TYPE_QUEUE) {
+			if (hwq_attr->type == HWQ_TYPE_QUEUE) {
 				/* Find the last pg of the size */
 				i = hwq->pbl[PBL_LVL_2].pg_count;
 				dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
@@ -248,25 +300,36 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
 						    [PTR_IDX(i - 2)] |=
 						    PTU_PTE_NEXT_TO_LAST;
 			}
-			hwq->level = PBL_LVL_2;
-		} else {
-			u32 flag = hwq_type == HWQ_TYPE_L2_CMPL ? 0 :
-						PTU_PTE_VALID;
+		} else { /* pages < 512 npbl = 1, npde = 0 */
+			u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
+				    0 : PTU_PTE_VALID;
 
 			/* 1 level of indirection */
-			rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], sghead,
-					 pages, maps, pg_size);
+			npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
+			if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT))
+				npbl++;
+			sginfo.npages = npbl;
+			sginfo.pgsize = PAGE_SIZE;
+			/* Alloc PBL page */
+			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
 			if (rc)
 				goto fail;
-			/* Fill in lvl0 PBL */
+			/* Alloc or init  PTEs */
+			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1],
+					 hwq_attr->sginfo);
+			if (rc)
+				goto fail;
+			hwq->level = PBL_LVL_1;
+			if (hwq_attr->sginfo->nopte)
+				goto done;
+			/* Fill PBL with PTE pointers */
 			dst_virt_ptr =
 				(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
 			src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
-			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) {
+			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
 				dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
 					src_phys_ptr[i] | flag;
-			}
-			if (hwq_type == HWQ_TYPE_QUEUE) {
+			if (hwq_attr->type == HWQ_TYPE_QUEUE) {
 				/* Find the last pg of the size */
 				i = hwq->pbl[PBL_LVL_1].pg_count;
 				dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
@@ -276,42 +339,143 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
 						    [PTR_IDX(i - 2)] |=
 						    PTU_PTE_NEXT_TO_LAST;
 			}
-			hwq->level = PBL_LVL_1;
 		}
 	}
-	hwq->pdev = pdev;
-	spin_lock_init(&hwq->lock);
+done:
 	hwq->prod = 0;
 	hwq->cons = 0;
-	*elements = hwq->max_elements = slots;
-	hwq->element_size = size;
-
+	hwq->pdev = pdev;
+	hwq->depth = hwq_attr->depth;
+	hwq->max_elements = depth;
+	hwq->element_size = stride;
 	/* For direct access to the elements */
-	hwq->pbl_ptr = hwq->pbl[hwq->level].pg_arr;
-	hwq->pbl_dma_ptr = hwq->pbl[hwq->level].pg_map_arr;
+	lvl = hwq->level;
+	if (hwq_attr->sginfo->nopte && hwq->level)
+		lvl = hwq->level - 1;
+	hwq->pbl_ptr = hwq->pbl[lvl].pg_arr;
+	hwq->pbl_dma_ptr = hwq->pbl[lvl].pg_map_arr;
+	spin_lock_init(&hwq->lock);
 
 	return 0;
-
 fail:
-	bnxt_qplib_free_hwq(pdev, hwq);
+	bnxt_qplib_free_hwq(res, hwq);
 	return -ENOMEM;
 }
 
 /* Context Tables */
-void bnxt_qplib_free_ctx(struct pci_dev *pdev,
+void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_ctx *ctx)
 {
 	int i;
 
-	bnxt_qplib_free_hwq(pdev, &ctx->qpc_tbl);
-	bnxt_qplib_free_hwq(pdev, &ctx->mrw_tbl);
-	bnxt_qplib_free_hwq(pdev, &ctx->srqc_tbl);
-	bnxt_qplib_free_hwq(pdev, &ctx->cq_tbl);
-	bnxt_qplib_free_hwq(pdev, &ctx->tim_tbl);
+	bnxt_qplib_free_hwq(res, &ctx->qpc_tbl);
+	bnxt_qplib_free_hwq(res, &ctx->mrw_tbl);
+	bnxt_qplib_free_hwq(res, &ctx->srqc_tbl);
+	bnxt_qplib_free_hwq(res, &ctx->cq_tbl);
+	bnxt_qplib_free_hwq(res, &ctx->tim_tbl);
 	for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
-		bnxt_qplib_free_hwq(pdev, &ctx->tqm_tbl[i]);
-	bnxt_qplib_free_hwq(pdev, &ctx->tqm_pde);
-	bnxt_qplib_free_stats_ctx(pdev, &ctx->stats);
+		bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.qtbl[i]);
+	/* restore original pde level before destroy */
+	ctx->tqm_ctx.pde.level = ctx->tqm_ctx.pde_level;
+	bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.pde);
+	bnxt_qplib_free_stats_ctx(res->pdev, &ctx->stats);
+}
+
+static int bnxt_qplib_alloc_tqm_rings(struct bnxt_qplib_res *res,
+				      struct bnxt_qplib_ctx *ctx)
+{
+	struct bnxt_qplib_hwq_attr hwq_attr;
+	struct bnxt_qplib_sg_info sginfo;
+	struct bnxt_qplib_tqm_ctx *tqmctx;
+	int rc = 0;
+	int i;
+
+	tqmctx = &ctx->tqm_ctx;
+
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
+	sginfo.pgsize = PAGE_SIZE;
+	sginfo.pgshft = PAGE_SHIFT;
+	hwq_attr.sginfo = &sginfo;
+	hwq_attr.res = res;
+	hwq_attr.type = HWQ_TYPE_CTX;
+	hwq_attr.depth = 512;
+	hwq_attr.stride = sizeof(u64);
+	/* Alloc pdl buffer */
+	rc = bnxt_qplib_alloc_init_hwq(&tqmctx->pde, &hwq_attr);
+	if (rc)
+		goto out;
+	/* Save original pdl level */
+	tqmctx->pde_level = tqmctx->pde.level;
+
+	hwq_attr.stride = 1;
+	for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) {
+		if (!tqmctx->qcount[i])
+			continue;
+		hwq_attr.depth = ctx->qpc_count * tqmctx->qcount[i];
+		rc = bnxt_qplib_alloc_init_hwq(&tqmctx->qtbl[i], &hwq_attr);
+		if (rc)
+			goto out;
+	}
+out:
+	return rc;
+}
+
+static void bnxt_qplib_map_tqm_pgtbl(struct bnxt_qplib_tqm_ctx *ctx)
+{
+	struct bnxt_qplib_hwq *tbl;
+	dma_addr_t *dma_ptr;
+	__le64 **pbl_ptr, *ptr;
+	int i, j, k;
+	int fnz_idx = -1;
+	int pg_count;
+
+	pbl_ptr = (__le64 **)ctx->pde.pbl_ptr;
+
+	for (i = 0, j = 0; i < MAX_TQM_ALLOC_REQ;
+	     i++, j += MAX_TQM_ALLOC_BLK_SIZE) {
+		tbl = &ctx->qtbl[i];
+		if (!tbl->max_elements)
+			continue;
+		if (fnz_idx == -1)
+			fnz_idx = i; /* first non-zero index */
+		switch (tbl->level) {
+		case PBL_LVL_2:
+			pg_count = tbl->pbl[PBL_LVL_1].pg_count;
+			for (k = 0; k < pg_count; k++) {
+				ptr = &pbl_ptr[PTR_PG(j + k)][PTR_IDX(j + k)];
+				dma_ptr = &tbl->pbl[PBL_LVL_1].pg_map_arr[k];
+				*ptr = cpu_to_le64(*dma_ptr | PTU_PTE_VALID);
+			}
+			break;
+		case PBL_LVL_1:
+		case PBL_LVL_0:
+		default:
+			ptr = &pbl_ptr[PTR_PG(j)][PTR_IDX(j)];
+			*ptr = cpu_to_le64(tbl->pbl[PBL_LVL_0].pg_map_arr[0] |
+					   PTU_PTE_VALID);
+			break;
+		}
+	}
+	if (fnz_idx == -1)
+		fnz_idx = 0;
+	/* update pde level as per page table programming */
+	ctx->pde.level = (ctx->qtbl[fnz_idx].level == PBL_LVL_2) ? PBL_LVL_2 :
+			  ctx->qtbl[fnz_idx].level + 1;
+}
+
+static int bnxt_qplib_setup_tqm_rings(struct bnxt_qplib_res *res,
+				      struct bnxt_qplib_ctx *ctx)
+{
+	int rc = 0;
+
+	rc = bnxt_qplib_alloc_tqm_rings(res, ctx);
+	if (rc)
+		goto fail;
+
+	bnxt_qplib_map_tqm_pgtbl(&ctx->tqm_ctx);
+fail:
+	return rc;
 }
 
 /*
@@ -335,120 +499,74 @@ void bnxt_qplib_free_ctx(struct pci_dev *pdev,
  * Returns:
  *     0 if success, else -ERRORS
  */
-int bnxt_qplib_alloc_ctx(struct pci_dev *pdev,
+int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_ctx *ctx,
 			 bool virt_fn, bool is_p5)
 {
-	int i, j, k, rc = 0;
-	int fnz_idx = -1;
-	__le64 **pbl_ptr;
+	struct bnxt_qplib_hwq_attr hwq_attr;
+	struct bnxt_qplib_sg_info sginfo;
+	int rc = 0;
 
 	if (virt_fn || is_p5)
 		goto stats_alloc;
 
 	/* QPC Tables */
-	ctx->qpc_tbl.max_elements = ctx->qpc_count;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->qpc_tbl, NULL,
-				       &ctx->qpc_tbl.max_elements,
-				       BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_CTX);
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
+	sginfo.pgsize = PAGE_SIZE;
+	sginfo.pgshft = PAGE_SHIFT;
+	hwq_attr.sginfo = &sginfo;
+
+	hwq_attr.res = res;
+	hwq_attr.depth = ctx->qpc_count;
+	hwq_attr.stride = BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE;
+	hwq_attr.type = HWQ_TYPE_CTX;
+	rc = bnxt_qplib_alloc_init_hwq(&ctx->qpc_tbl, &hwq_attr);
 	if (rc)
 		goto fail;
 
 	/* MRW Tables */
-	ctx->mrw_tbl.max_elements = ctx->mrw_count;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->mrw_tbl, NULL,
-				       &ctx->mrw_tbl.max_elements,
-				       BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_CTX);
+	hwq_attr.depth = ctx->mrw_count;
+	hwq_attr.stride = BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE;
+	rc = bnxt_qplib_alloc_init_hwq(&ctx->mrw_tbl, &hwq_attr);
 	if (rc)
 		goto fail;
 
 	/* SRQ Tables */
-	ctx->srqc_tbl.max_elements = ctx->srqc_count;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->srqc_tbl, NULL,
-				       &ctx->srqc_tbl.max_elements,
-				       BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_CTX);
+	hwq_attr.depth = ctx->srqc_count;
+	hwq_attr.stride = BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE;
+	rc = bnxt_qplib_alloc_init_hwq(&ctx->srqc_tbl, &hwq_attr);
 	if (rc)
 		goto fail;
 
 	/* CQ Tables */
-	ctx->cq_tbl.max_elements = ctx->cq_count;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->cq_tbl, NULL,
-				       &ctx->cq_tbl.max_elements,
-				       BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_CTX);
+	hwq_attr.depth = ctx->cq_count;
+	hwq_attr.stride = BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE;
+	rc = bnxt_qplib_alloc_init_hwq(&ctx->cq_tbl, &hwq_attr);
 	if (rc)
 		goto fail;
 
 	/* TQM Buffer */
-	ctx->tqm_pde.max_elements = 512;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tqm_pde, NULL,
-				       &ctx->tqm_pde.max_elements, sizeof(u64),
-				       0, PAGE_SIZE, HWQ_TYPE_CTX);
+	rc = bnxt_qplib_setup_tqm_rings(res, ctx);
 	if (rc)
 		goto fail;
-
-	for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) {
-		if (!ctx->tqm_count[i])
-			continue;
-		ctx->tqm_tbl[i].max_elements = ctx->qpc_count *
-					       ctx->tqm_count[i];
-		rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tqm_tbl[i], NULL,
-					       &ctx->tqm_tbl[i].max_elements, 1,
-					       0, PAGE_SIZE, HWQ_TYPE_CTX);
-		if (rc)
-			goto fail;
-	}
-	pbl_ptr = (__le64 **)ctx->tqm_pde.pbl_ptr;
-	for (i = 0, j = 0; i < MAX_TQM_ALLOC_REQ;
-	     i++, j += MAX_TQM_ALLOC_BLK_SIZE) {
-		if (!ctx->tqm_tbl[i].max_elements)
-			continue;
-		if (fnz_idx == -1)
-			fnz_idx = i;
-		switch (ctx->tqm_tbl[i].level) {
-		case PBL_LVL_2:
-			for (k = 0; k < ctx->tqm_tbl[i].pbl[PBL_LVL_1].pg_count;
-			     k++)
-				pbl_ptr[PTR_PG(j + k)][PTR_IDX(j + k)] =
-				  cpu_to_le64(
-				    ctx->tqm_tbl[i].pbl[PBL_LVL_1].pg_map_arr[k]
-				    | PTU_PTE_VALID);
-			break;
-		case PBL_LVL_1:
-		case PBL_LVL_0:
-		default:
-			pbl_ptr[PTR_PG(j)][PTR_IDX(j)] = cpu_to_le64(
-				ctx->tqm_tbl[i].pbl[PBL_LVL_0].pg_map_arr[0] |
-				PTU_PTE_VALID);
-			break;
-		}
-	}
-	if (fnz_idx == -1)
-		fnz_idx = 0;
-	ctx->tqm_pde_level = ctx->tqm_tbl[fnz_idx].level == PBL_LVL_2 ?
-			     PBL_LVL_2 : ctx->tqm_tbl[fnz_idx].level + 1;
-
 	/* TIM Buffer */
 	ctx->tim_tbl.max_elements = ctx->qpc_count * 16;
-	rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tim_tbl, NULL,
-				       &ctx->tim_tbl.max_elements, 1,
-				       0, PAGE_SIZE, HWQ_TYPE_CTX);
+	hwq_attr.depth = ctx->qpc_count * 16;
+	hwq_attr.stride = 1;
+	rc = bnxt_qplib_alloc_init_hwq(&ctx->tim_tbl, &hwq_attr);
 	if (rc)
 		goto fail;
-
 stats_alloc:
 	/* Stats */
-	rc = bnxt_qplib_alloc_stats_ctx(pdev, &ctx->stats);
+	rc = bnxt_qplib_alloc_stats_ctx(res->pdev, &ctx->stats);
 	if (rc)
 		goto fail;
 
 	return 0;
 
 fail:
-	bnxt_qplib_free_ctx(pdev, ctx);
+	bnxt_qplib_free_ctx(res, ctx);
 	return rc;
 }
 
@@ -808,9 +926,6 @@ void bnxt_qplib_free_res(struct bnxt_qplib_res *res)
 	bnxt_qplib_free_sgid_tbl(res, &res->sgid_tbl);
 	bnxt_qplib_free_pd_tbl(&res->pd_tbl);
 	bnxt_qplib_free_dpi_tbl(res, &res->dpi_tbl);
-
-	res->netdev = NULL;
-	res->pdev = NULL;
 }
 
 int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
index aaa76d7..fe8a6dd 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
@@ -55,7 +55,8 @@
 enum bnxt_qplib_hwq_type {
 	HWQ_TYPE_CTX,
 	HWQ_TYPE_QUEUE,
-	HWQ_TYPE_L2_CMPL
+	HWQ_TYPE_L2_CMPL,
+	HWQ_TYPE_MR
 };
 
 #define MAX_PBL_LVL_0_PGS		1
@@ -63,6 +64,7 @@ enum bnxt_qplib_hwq_type {
 #define MAX_PBL_LVL_1_PGS_SHIFT		9
 #define MAX_PBL_LVL_1_PGS_FOR_LVL_2	256
 #define MAX_PBL_LVL_2_PGS		(256 * 512)
+#define MAX_PDL_LVL_SHIFT               9
 
 enum bnxt_qplib_pbl_lvl {
 	PBL_LVL_0,
@@ -85,17 +87,37 @@ struct bnxt_qplib_pbl {
 	dma_addr_t			*pg_map_arr;
 };
 
+struct bnxt_qplib_sg_info {
+	struct scatterlist		*sghead;
+	u32				nmap;
+	u32				npages;
+	u32				pgshft;
+	u32				pgsize;
+	bool				nopte;
+};
+
+struct bnxt_qplib_hwq_attr {
+	struct bnxt_qplib_res		*res;
+	struct bnxt_qplib_sg_info	*sginfo;
+	enum bnxt_qplib_hwq_type	type;
+	u32				depth;
+	u32				stride;
+	u32				aux_stride;
+	u32				aux_depth;
+};
+
 struct bnxt_qplib_hwq {
 	struct pci_dev			*pdev;
 	/* lock to protect qplib_hwq */
 	spinlock_t			lock;
-	struct bnxt_qplib_pbl		pbl[PBL_LVL_MAX];
+	struct bnxt_qplib_pbl		pbl[PBL_LVL_MAX + 1];
 	enum bnxt_qplib_pbl_lvl		level;		/* 0, 1, or 2 */
 	/* ptr for easy access to the PBL entries */
 	void				**pbl_ptr;
 	/* ptr for easy access to the dma_addr */
 	dma_addr_t			*pbl_dma_ptr;
 	u32				max_elements;
+	u32				depth;
 	u16				element_size;	/* Size of each entry */
 
 	u32				prod;		/* raw */
@@ -159,6 +181,15 @@ struct bnxt_qplib_vf_res {
 #define BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE	64
 #define BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE	128
 
+#define MAX_TQM_ALLOC_REQ               48
+#define MAX_TQM_ALLOC_BLK_SIZE          8
+struct bnxt_qplib_tqm_ctx {
+	struct bnxt_qplib_hwq           pde;
+	u8                              pde_level; /* Original level */
+	struct bnxt_qplib_hwq           qtbl[MAX_TQM_ALLOC_REQ];
+	u8                              qcount[MAX_TQM_ALLOC_REQ];
+};
+
 struct bnxt_qplib_ctx {
 	u32				qpc_count;
 	struct bnxt_qplib_hwq		qpc_tbl;
@@ -169,12 +200,7 @@ struct bnxt_qplib_ctx {
 	u32				cq_count;
 	struct bnxt_qplib_hwq		cq_tbl;
 	struct bnxt_qplib_hwq		tim_tbl;
-#define MAX_TQM_ALLOC_REQ		48
-#define MAX_TQM_ALLOC_BLK_SIZE		8
-	u8				tqm_count[MAX_TQM_ALLOC_REQ];
-	struct bnxt_qplib_hwq		tqm_pde;
-	u32				tqm_pde_level;
-	struct bnxt_qplib_hwq		tqm_tbl[MAX_TQM_ALLOC_REQ];
+	struct bnxt_qplib_tqm_ctx	tqm_ctx;
 	struct bnxt_qplib_stats		stats;
 	struct bnxt_qplib_vf_res	vf_res;
 	u64				hwrm_intf_ver;
@@ -223,11 +249,6 @@ static inline u8 bnxt_qplib_get_ring_type(struct bnxt_qplib_chip_ctx *cctx)
 	       RING_ALLOC_REQ_RING_TYPE_ROCE_CMPL;
 }
 
-struct bnxt_qplib_sg_info {
-	struct scatterlist		*sglist;
-	u32				nmap;
-	u32				npages;
-};
 
 #define to_bnxt_qplib(ptr, type, member)	\
 	container_of(ptr, type, member)
@@ -235,11 +256,10 @@ struct bnxt_qplib_sg_info {
 struct bnxt_qplib_pd;
 struct bnxt_qplib_dev_attr;
 
-void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq);
-int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
-			      struct bnxt_qplib_sg_info *sg_info, u32 *elements,
-			      u32 elements_per_page, u32 aux, u32 pg_size,
-			      enum bnxt_qplib_hwq_type hwq_type);
+void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res,
+			 struct bnxt_qplib_hwq *hwq);
+int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
+			      struct bnxt_qplib_hwq_attr *hwq_attr);
 void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid);
 int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl *pd_tbl,
 			struct bnxt_qplib_pd *pd);
@@ -258,9 +278,9 @@ int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
 int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
 			 struct net_device *netdev,
 			 struct bnxt_qplib_dev_attr *dev_attr);
-void bnxt_qplib_free_ctx(struct pci_dev *pdev,
+void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_ctx *ctx);
-int bnxt_qplib_alloc_ctx(struct pci_dev *pdev,
+int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_ctx *ctx,
 			 bool virt_fn, bool is_p5);
 #endif /* __BNXT_QPLIB_RES_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index 40296b9..a5d4cb9 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -585,7 +585,7 @@ int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
 
 	/* Free the qplib's MRW memory */
 	if (mrw->hwq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
+		bnxt_qplib_free_hwq(res, &mrw->hwq);
 
 	return 0;
 }
@@ -646,7 +646,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
 	if (mrw->hwq.max_elements) {
 		mrw->va = 0;
 		mrw->total_size = 0;
-		bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
+		bnxt_qplib_free_hwq(res, &mrw->hwq);
 	}
 
 	return 0;
@@ -656,13 +656,17 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
 		      u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
-	struct cmdq_register_mr req;
+	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct creq_register_mr_resp resp;
-	u16 cmd_flags = 0, level;
+	struct bnxt_qplib_sg_info sginfo;
+	struct cmdq_register_mr req;
 	int pg_ptrs, pages, i, rc;
+	u16 cmd_flags = 0, level;
 	dma_addr_t **pbl_ptr;
 	u32 pg_size;
 
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	memset(&sginfo, 0, sizeof(sginfo));
 	if (num_pbls) {
 		/* Allocate memory for the non-leaf pages to store buf ptrs.
 		 * Non-leaf pages always uses system PAGE_SIZE
@@ -674,20 +678,23 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
 
 		if (pages > MAX_PBL_LVL_1_PGS) {
 			dev_err(&res->pdev->dev,
-				"SP: Reg MR pages requested (0x%x) exceeded max (0x%x)\n",
+				"SP: Reg MR: pages requested (0x%x) exceeded max (0x%x)\n",
 				pages, MAX_PBL_LVL_1_PGS);
 			return -ENOMEM;
 		}
 		/* Free the hwq if it already exist, must be a rereg */
 		if (mr->hwq.max_elements)
-			bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
-
-		mr->hwq.max_elements = pages;
+			bnxt_qplib_free_hwq(res, &mr->hwq);
 		/* Use system PAGE_SIZE */
-		rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL,
-					       &mr->hwq.max_elements,
-					       PAGE_SIZE, 0, PAGE_SIZE,
-					       HWQ_TYPE_CTX);
+		hwq_attr.res = res;
+		hwq_attr.depth = pages;
+		hwq_attr.stride = PAGE_SIZE;
+		hwq_attr.type = HWQ_TYPE_MR;
+		hwq_attr.sginfo = &sginfo;
+		hwq_attr.sginfo->npages = pages;
+		hwq_attr.sginfo->pgsize = PAGE_SIZE;
+		hwq_attr.sginfo->pgshft = PAGE_SHIFT;
+		rc = bnxt_qplib_alloc_init_hwq(&mr->hwq, &hwq_attr);
 		if (rc) {
 			dev_err(&res->pdev->dev,
 				"SP: Reg MR memory allocation failed\n");
@@ -734,7 +741,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
 
 fail:
 	if (mr->hwq.max_elements)
-		bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
+		bnxt_qplib_free_hwq(res, &mr->hwq);
 	return rc;
 }
 
@@ -742,6 +749,8 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
 					struct bnxt_qplib_frpl *frpl,
 					int max_pg_ptrs)
 {
+	struct bnxt_qplib_hwq_attr hwq_attr;
+	struct bnxt_qplib_sg_info sginfo;
 	int pg_ptrs, pages, rc;
 
 	/* Re-calculate the max to fit the HWQ allocation model */
@@ -753,10 +762,17 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
 	if (pages > MAX_PBL_LVL_1_PGS)
 		return -ENOMEM;
 
-	frpl->hwq.max_elements = pages;
-	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &frpl->hwq, NULL,
-				       &frpl->hwq.max_elements, PAGE_SIZE, 0,
-				       PAGE_SIZE, HWQ_TYPE_CTX);
+	memset(&sginfo, 0, sizeof(sginfo));
+	sginfo.pgsize = PAGE_SIZE;
+	sginfo.nopte = true;
+
+	memset(&hwq_attr, 0, sizeof(hwq_attr));
+	hwq_attr.res = res;
+	hwq_attr.depth = pg_ptrs;
+	hwq_attr.stride = PAGE_SIZE;
+	hwq_attr.sginfo = &sginfo;
+	hwq_attr.type = HWQ_TYPE_CTX;
+	rc = bnxt_qplib_alloc_init_hwq(&frpl->hwq, &hwq_attr);
 	if (!rc)
 		frpl->max_pg_ptrs = pg_ptrs;
 
@@ -766,7 +782,7 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
 int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
 				       struct bnxt_qplib_frpl *frpl)
 {
-	bnxt_qplib_free_hwq(res->pdev, &frpl->hwq);
+	bnxt_qplib_free_hwq(res, &frpl->hwq);
 	return 0;
 }
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
                   ` (2 preceding siblings ...)
  2020-01-24  5:52 ` [PATCH for-next 3/7] RDMA/bnxt_re: Refactor hardware queue memory allocation Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-26 14:29   ` Leon Romanovsky
  2020-01-24  5:52 ` [PATCH for-next 5/7] RDMA/bnxt_re: Refactor command queue management code Devesh Sharma
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

Introducing a new attribute structure to reduce
the long list of arguments passed in bnxt_re_net_ring_alloc()
function.

The caller of bnxt_re_net_ring_alloc should fill in
the list of attributes in bnxt_re_ring_attr structure
and then pass the pointer to the function.

Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
 drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
 2 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index 86274f4..c736e82 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -89,6 +89,15 @@
 
 #define BNXT_RE_DEFAULT_ACK_DELAY	16
 
+struct bnxt_re_ring_attr {
+	dma_addr_t	*dma_arr;
+	int		pages;
+	int		type;
+	u32		depth;
+	u32		lrid; /* Logical ring id */
+	u8		mode;
+};
+
 struct bnxt_re_work {
 	struct work_struct	work;
 	unsigned long		event;
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index a966c68..648a5ea 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
 	return rc;
 }
 
-static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
-				  int pages, int type, u32 ring_mask,
-				  u32 map_index, u16 *fw_ring_id)
+static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
+				  struct bnxt_re_ring_attr *ring_attr,
+				  u16 *fw_ring_id)
 {
 	struct bnxt_en_dev *en_dev = rdev->en_dev;
 	struct hwrm_ring_alloc_input req = {0};
@@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
 	memset(&fw_msg, 0, sizeof(fw_msg));
 	bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
 	req.enables = 0;
-	req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
-	if (pages > 1) {
+	req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
+	if (ring_attr->pages > 1) {
 		/* Page size is in log2 units */
 		req.page_size = BNXT_PAGE_SHIFT;
 		req.page_tbl_depth = 1;
 	}
 	req.fbo = 0;
 	/* Association of ring index with doorbell index and MSIX number */
-	req.logical_id = cpu_to_le16(map_index);
-	req.length = cpu_to_le32(ring_mask + 1);
-	req.ring_type = type;
-	req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
+	req.logical_id = cpu_to_le16(ring_attr->lrid);
+	req.length = cpu_to_le32(ring_attr->depth + 1);
+	req.ring_type = ring_attr->type;
+	req.int_mode = ring_attr->mode;
 	bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
 			    sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
 	rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
@@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
 
 static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 {
+	struct bnxt_qplib_ctx *qplib_ctx;
+	struct bnxt_re_ring_attr rattr;
 	int num_vec_created = 0;
-	dma_addr_t *pg_map;
 	int rc = 0, i;
-	int pages;
 	u8 type;
 
+	memset(&rattr, 0, sizeof(rattr));
 	/* Configure and allocate resources for qplib */
 	rdev->qplib_res.rcfw = &rdev->rcfw;
 	rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr,
@@ -1030,10 +1031,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 	if (rc)
 		goto dealloc_res;
 
+	qplib_ctx = &rdev->qplib_ctx;
 	for (i = 0; i < rdev->num_msix - 1; i++) {
-		rdev->nq[i].res = &rdev->qplib_res;
-		rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
-			BNXT_RE_MAX_SRQC_COUNT + 2;
+		struct bnxt_qplib_nq *nq;
+
+		nq = &rdev->nq[i];
+		nq->hwq.max_elements = (qplib_ctx->cq_count +
+					qplib_ctx->srqc_count + 2);
 		rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]);
 		if (rc) {
 			dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
@@ -1041,12 +1045,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
 			goto free_nq;
 		}
 		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
-		pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr;
-		pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count;
-		rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
-					    BNXT_QPLIB_NQE_MAX_CNT - 1,
-					    rdev->msix_entries[i + 1].ring_idx,
-					    &rdev->nq[i].ring_id);
+		rattr.dma_arr = nq->hwq.pbl[PBL_LVL_0].pg_map_arr;
+		rattr.pages = nq->hwq.pbl[rdev->nq[i].hwq.level].pg_count;
+		rattr.type = type;
+		rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
+		rattr.depth = BNXT_QPLIB_NQE_MAX_CNT - 1;
+		rattr.lrid = rdev->msix_entries[i + 1].ring_idx;
+		rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id);
 		if (rc) {
 			dev_err(rdev_to_dev(rdev),
 				"Failed to allocate NQ fw id with rc = 0x%x",
@@ -1371,10 +1376,10 @@ static void bnxt_re_worker(struct work_struct *work)
 
 static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 {
-	dma_addr_t *pg_map;
-	u32 db_offt, ridx;
-	int pages, vid;
+	struct bnxt_re_ring_attr rattr;
+	u32 db_offt;
 	bool locked;
+	int vid;
 	u8 type;
 	int rc;
 
@@ -1383,6 +1388,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	locked = true;
 
 	/* Registered a new RoCE device instance to netdev */
+	memset(&rattr, 0, sizeof(rattr));
 	rc = bnxt_re_register_netdev(rdev);
 	if (rc) {
 		rtnl_unlock();
@@ -1422,12 +1428,13 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	}
 
 	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
-	pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
-	pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
-	ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
-	rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
-				    BNXT_QPLIB_CREQE_MAX_CNT - 1,
-				    ridx, &rdev->rcfw.creq_ring_id);
+	rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
+	rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
+	rattr.type = type;
+	rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
+	rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1;
+	rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
+	rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id);
 	if (rc) {
 		pr_err("Failed to allocate CREQ: %#x\n", rc);
 		goto free_rcfw;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 5/7] RDMA/bnxt_re: Refactor command queue management code
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
                   ` (3 preceding siblings ...)
  2020-01-24  5:52 ` [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 6/7] RDMA/bnxt_re: Refactor notification " Devesh Sharma
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

Refactoring the command queue (rcfw) management code. A new
data-structure is introduced to describe the bar register.
each object which deals with mmio space should have a descriptor
structure. This structure specifically hold DB register information.
Thus, slow path creq structure now hold a bar register descriptor.

Further cleanup the rcfw structure to introduce the command queue
context and command response event queue context structures. Rest
of the rcfw related code has been touched to incorporate these three
structures.

Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/main.c       |  12 +-
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 422 +++++++++++++++++------------
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |  80 +++---
 drivers/infiniband/hw/bnxt_re/qplib_res.h  |   7 +
 4 files changed, 315 insertions(+), 206 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 648a5ea..7b7553b 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -1345,7 +1345,7 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
 		bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx);
 		bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
-		bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
+		bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type);
 		bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
 	}
 	if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) {
@@ -1376,6 +1376,7 @@ static void bnxt_re_worker(struct work_struct *work)
 
 static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 {
+	struct bnxt_qplib_creq_ctx *creq;
 	struct bnxt_re_ring_attr rattr;
 	u32 db_offt;
 	bool locked;
@@ -1428,13 +1429,14 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	}
 
 	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
-	rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
-	rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
+	creq = &rdev->rcfw.creq;
+	rattr.dma_arr = creq->hwq.pbl[PBL_LVL_0].pg_map_arr;
+	rattr.pages = creq->hwq.pbl[creq->hwq.level].pg_count;
 	rattr.type = type;
 	rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
 	rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1;
 	rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
-	rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id);
+	rc = bnxt_re_net_ring_alloc(rdev, &rattr, &creq->ring_id);
 	if (rc) {
 		pr_err("Failed to allocate CREQ: %#x\n", rc);
 		goto free_rcfw;
@@ -1528,7 +1530,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 	bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 free_ring:
 	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
-	bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
+	bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type);
 free_rcfw:
 	bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
 fail:
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index d2464dc..8160404 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -55,12 +55,14 @@
 /* Hardware communication channel */
 static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 {
+	struct bnxt_qplib_cmdq_ctx *cmdq;
 	u16 cbit;
 	int rc;
 
+	cmdq = &rcfw->cmdq;
 	cbit = cookie % rcfw->cmdq_depth;
-	rc = wait_event_timeout(rcfw->waitq,
-				!test_bit(cbit, rcfw->cmdq_bitmap),
+	rc = wait_event_timeout(cmdq->waitq,
+				!test_bit(cbit, cmdq->cmdq_bitmap),
 				msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS));
 	return rc ? 0 : -ETIMEDOUT;
 };
@@ -68,15 +70,17 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 {
 	u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
+	struct bnxt_qplib_cmdq_ctx *cmdq;
 	u16 cbit;
 
+	cmdq = &rcfw->cmdq;
 	cbit = cookie % rcfw->cmdq_depth;
-	if (!test_bit(cbit, rcfw->cmdq_bitmap))
+	if (!test_bit(cbit, cmdq->cmdq_bitmap))
 		goto done;
 	do {
 		mdelay(1); /* 1m sec */
 		bnxt_qplib_service_creq((unsigned long)rcfw);
-	} while (test_bit(cbit, rcfw->cmdq_bitmap) && --count);
+	} while (test_bit(cbit, cmdq->cmdq_bitmap) && --count);
 done:
 	return count ? 0 : -ETIMEDOUT;
 };
@@ -84,56 +88,61 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
 static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
 			  struct creq_base *resp, void *sb, u8 is_block)
 {
-	struct bnxt_qplib_cmdqe *cmdqe, **cmdq_ptr;
-	struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
+	struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
+	struct bnxt_qplib_cmdqe *cmdqe, **hwq_ptr;
+	struct bnxt_qplib_hwq *hwq = &cmdq->hwq;
+	struct bnxt_qplib_crsqe *crsqe;
 	u32 cmdq_depth = rcfw->cmdq_depth;
-	struct bnxt_qplib_crsq *crsqe;
 	u32 sw_prod, cmdq_prod;
+	struct pci_dev *pdev;
 	unsigned long flags;
 	u32 size, opcode;
 	u16 cookie, cbit;
+	int pg, idx;
 	u8 *preq;
 
+	pdev = rcfw->pdev;
+
 	opcode = req->opcode;
-	if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) &&
+	if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
 	    (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
 	     opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW &&
 	     opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) {
-		dev_err(&rcfw->pdev->dev,
+		dev_err(&pdev->dev,
 			"RCFW not initialized, reject opcode 0x%x\n", opcode);
 		return -EINVAL;
 	}
 
-	if (test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) &&
+	if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
 	    opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
-		dev_err(&rcfw->pdev->dev, "RCFW already initialized!\n");
+		dev_err(&pdev->dev, "RCFW already initialized!\n");
 		return -EINVAL;
 	}
 
-	if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags))
+	if (test_bit(FIRMWARE_TIMED_OUT, &cmdq->flags))
 		return -ETIMEDOUT;
 
 	/* Cmdq are in 16-byte units, each request can consume 1 or more
 	 * cmdqe
 	 */
-	spin_lock_irqsave(&cmdq->lock, flags);
-	if (req->cmd_size >= HWQ_FREE_SLOTS(cmdq)) {
-		dev_err(&rcfw->pdev->dev, "RCFW: CMDQ is full!\n");
-		spin_unlock_irqrestore(&cmdq->lock, flags);
+	spin_lock_irqsave(&hwq->lock, flags);
+	if (req->cmd_size >= HWQ_FREE_SLOTS(hwq)) {
+		dev_err(&pdev->dev, "RCFW: CMDQ is full!\n");
+		spin_unlock_irqrestore(&hwq->lock, flags);
 		return -EAGAIN;
 	}
 
 
-	cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE;
+	cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
 	cbit = cookie % rcfw->cmdq_depth;
 	if (is_block)
 		cookie |= RCFW_CMD_IS_BLOCKING;
 
-	set_bit(cbit, rcfw->cmdq_bitmap);
+	set_bit(cbit, cmdq->cmdq_bitmap);
 	req->cookie = cpu_to_le16(cookie);
 	crsqe = &rcfw->crsqe_tbl[cbit];
 	if (crsqe->resp) {
-		spin_unlock_irqrestore(&cmdq->lock, flags);
+		spin_unlock_irqrestore(&hwq->lock, flags);
 		return -EBUSY;
 	}
 
@@ -155,15 +164,18 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
 				  BNXT_QPLIB_CMDQE_UNITS;
 	}
 
-	cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr;
+	hwq_ptr = (struct bnxt_qplib_cmdqe **)hwq->pbl_ptr;
 	preq = (u8 *)req;
 	do {
+		pg = 0;
+		idx = 0;
+
 		/* Locate the next cmdq slot */
-		sw_prod = HWQ_CMP(cmdq->prod, cmdq);
-		cmdqe = &cmdq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)]
+		sw_prod = HWQ_CMP(hwq->prod, hwq);
+		cmdqe = &hwq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)]
 				[get_cmdq_idx(sw_prod, cmdq_depth)];
 		if (!cmdqe) {
-			dev_err(&rcfw->pdev->dev,
+			dev_err(&pdev->dev,
 				"RCFW request failed with no cmdqe!\n");
 			goto done;
 		}
@@ -172,31 +184,27 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
 		memcpy(cmdqe, preq, min_t(u32, size, sizeof(*cmdqe)));
 		preq += min_t(u32, size, sizeof(*cmdqe));
 		size -= min_t(u32, size, sizeof(*cmdqe));
-		cmdq->prod++;
-		rcfw->seq_num++;
+		hwq->prod++;
 	} while (size > 0);
+	cmdq->seq_num++;
 
-	rcfw->seq_num++;
-
-	cmdq_prod = cmdq->prod;
-	if (test_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags)) {
+	cmdq_prod = hwq->prod;
+	if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) {
 		/* The very first doorbell write
 		 * is required to set this flag
 		 * which prompts the FW to reset
 		 * its internal pointers
 		 */
 		cmdq_prod |= BIT(FIRMWARE_FIRST_FLAG);
-		clear_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags);
+		clear_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags);
 	}
 
 	/* ring CMDQ DB */
 	wmb();
-	writel(cmdq_prod, rcfw->cmdq_bar_reg_iomem +
-	       rcfw->cmdq_bar_reg_prod_off);
-	writel(RCFW_CMDQ_TRIG_VAL, rcfw->cmdq_bar_reg_iomem +
-	       rcfw->cmdq_bar_reg_trig_off);
+	writel(cmdq_prod, cmdq->cmdq_mbox.prod);
+	writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
 done:
-	spin_unlock_irqrestore(&cmdq->lock, flags);
+	spin_unlock_irqrestore(&hwq->lock, flags);
 	/* Return the CREQ response pointer */
 	return 0;
 }
@@ -236,7 +244,7 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
 		/* timed out */
 		dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n",
 			cookie, opcode, RCFW_CMD_WAIT_TIME_MS);
-		set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags);
+		set_bit(FIRMWARE_TIMED_OUT, &rcfw->cmdq.flags);
 		return rc;
 	}
 
@@ -253,6 +261,8 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
 static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
 					 struct creq_func_event *func_event)
 {
+	int rc;
+
 	switch (func_event->event) {
 	case CREQ_FUNC_EVENT_EVENT_TX_WQE_ERROR:
 		break;
@@ -286,37 +296,41 @@ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
 	default:
 		return -EINVAL;
 	}
-	return 0;
+
+	rc = rcfw->creq.aeq_handler(rcfw, (void *)func_event, NULL);
+	return rc;
 }
 
 static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
 				       struct creq_qp_event *qp_event)
 {
-	struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
 	struct creq_qp_error_notification *err_event;
-	struct bnxt_qplib_crsq *crsqe;
-	unsigned long flags;
+	struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq;
+	struct bnxt_qplib_crsqe *crsqe;
 	struct bnxt_qplib_qp *qp;
 	u16 cbit, blocked = 0;
-	u16 cookie;
+	struct pci_dev *pdev;
+	unsigned long flags;
 	__le16  mcookie;
+	u16 cookie;
+	int rc = 0;
 	u32 qp_id;
 
+	pdev = rcfw->pdev;
 	switch (qp_event->event) {
 	case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
 		err_event = (struct creq_qp_error_notification *)qp_event;
 		qp_id = le32_to_cpu(err_event->xid);
 		qp = rcfw->qp_tbl[qp_id].qp_handle;
-		dev_dbg(&rcfw->pdev->dev,
-			"Received QP error notification\n");
-		dev_dbg(&rcfw->pdev->dev,
+		dev_dbg(&pdev->dev, "Received QP error notification\n");
+		dev_dbg(&pdev->dev,
 			"qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
 			qp_id, err_event->req_err_state_reason,
 			err_event->res_err_state_reason);
 		if (!qp)
 			break;
 		bnxt_qplib_mark_qp_error(qp);
-		rcfw->aeq_handler(rcfw, qp_event, qp);
+		rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
 		break;
 	default:
 		/*
@@ -328,7 +342,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
 		 *
 		 */
 
-		spin_lock_irqsave_nested(&cmdq->lock, flags,
+		spin_lock_irqsave_nested(&hwq->lock, flags,
 					 SINGLE_DEPTH_NESTING);
 		cookie = le16_to_cpu(qp_event->cookie);
 		mcookie = qp_event->cookie;
@@ -342,23 +356,23 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
 			crsqe->resp = NULL;
 		} else {
 			if (crsqe->resp && crsqe->resp->cookie)
-				dev_err(&rcfw->pdev->dev,
+				dev_err(&pdev->dev,
 					"CMD %s cookie sent=%#x, recd=%#x\n",
 					crsqe->resp ? "mismatch" : "collision",
 					crsqe->resp ? crsqe->resp->cookie : 0,
 					mcookie);
 		}
-		if (!test_and_clear_bit(cbit, rcfw->cmdq_bitmap))
-			dev_warn(&rcfw->pdev->dev,
+		if (!test_and_clear_bit(cbit, rcfw->cmdq.cmdq_bitmap))
+			dev_warn(&pdev->dev,
 				 "CMD bit %d was not requested\n", cbit);
-		cmdq->cons += crsqe->req_size;
+		hwq->cons += crsqe->req_size;
 		crsqe->req_size = 0;
 
 		if (!blocked)
-			wake_up(&rcfw->waitq);
-		spin_unlock_irqrestore(&cmdq->lock, flags);
+			wake_up(&rcfw->cmdq.waitq);
+		spin_unlock_irqrestore(&hwq->lock, flags);
 	}
-	return 0;
+	return rc;
 }
 
 /* SP - CREQ Completion handlers */
@@ -366,20 +380,21 @@ static void bnxt_qplib_service_creq(unsigned long data)
 {
 	struct bnxt_qplib_rcfw *rcfw = (struct bnxt_qplib_rcfw *)data;
 	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
-	struct bnxt_qplib_hwq *creq = &rcfw->creq;
+	struct bnxt_qplib_creq_ctx *creq = &rcfw->creq;
 	u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
-	struct creq_base *creqe, **creq_ptr;
+	struct bnxt_qplib_hwq *hwq = &creq->hwq;
+	struct creq_base *creqe, **hwq_ptr;
 	u32 sw_cons, raw_cons;
 	unsigned long flags;
 
 	/* Service the CREQ until budget is over */
-	spin_lock_irqsave(&creq->lock, flags);
-	raw_cons = creq->cons;
+	spin_lock_irqsave(&hwq->lock, flags);
+	raw_cons = hwq->cons;
 	while (budget > 0) {
-		sw_cons = HWQ_CMP(raw_cons, creq);
-		creq_ptr = (struct creq_base **)creq->pbl_ptr;
-		creqe = &creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)];
-		if (!CREQ_CMP_VALID(creqe, raw_cons, creq->max_elements))
+		sw_cons = HWQ_CMP(raw_cons, hwq);
+		hwq_ptr = (struct creq_base **)hwq->pbl_ptr;
+		creqe = &hwq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)];
+		if (!CREQ_CMP_VALID(creqe, raw_cons, hwq->max_elements))
 			break;
 		/* The valid test of the entry must be done first before
 		 * reading any further.
@@ -391,12 +406,12 @@ static void bnxt_qplib_service_creq(unsigned long data)
 		case CREQ_BASE_TYPE_QP_EVENT:
 			bnxt_qplib_process_qp_event
 				(rcfw, (struct creq_qp_event *)creqe);
-			rcfw->creq_qp_event_processed++;
+			creq->stats.creq_qp_event_processed++;
 			break;
 		case CREQ_BASE_TYPE_FUNC_EVENT:
 			if (!bnxt_qplib_process_func_event
 			    (rcfw, (struct creq_func_event *)creqe))
-				rcfw->creq_func_event_processed++;
+				creq->stats.creq_func_event_processed++;
 			else
 				dev_warn(&rcfw->pdev->dev,
 					 "aeqe:%#x Not handled\n", type);
@@ -412,28 +427,31 @@ static void bnxt_qplib_service_creq(unsigned long data)
 		budget--;
 	}
 
-	if (creq->cons != raw_cons) {
-		creq->cons = raw_cons;
-		bnxt_qplib_ring_creq_db_rearm(rcfw->creq_bar_reg_iomem,
-					      raw_cons, creq->max_elements,
-					      rcfw->creq_ring_id, gen_p5);
+	if (hwq->cons != raw_cons) {
+		hwq->cons = raw_cons;
+		bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db,
+					      raw_cons, hwq->max_elements,
+					      creq->ring_id, gen_p5);
 	}
-	spin_unlock_irqrestore(&creq->lock, flags);
+	spin_unlock_irqrestore(&hwq->lock, flags);
 }
 
 static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
 {
 	struct bnxt_qplib_rcfw *rcfw = dev_instance;
-	struct bnxt_qplib_hwq *creq = &rcfw->creq;
+	struct bnxt_qplib_creq_ctx *creq;
 	struct creq_base **creq_ptr;
+	struct bnxt_qplib_hwq *hwq;
 	u32 sw_cons;
 
+	creq = &rcfw->creq;
+	hwq = &creq->hwq;
 	/* Prefetch the CREQ element */
-	sw_cons = HWQ_CMP(creq->cons, creq);
-	creq_ptr = (struct creq_base **)rcfw->creq.pbl_ptr;
+	sw_cons = HWQ_CMP(hwq->cons, hwq);
+	creq_ptr = (struct creq_base **)creq->hwq.pbl_ptr;
 	prefetch(&creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]);
 
-	tasklet_schedule(&rcfw->worker);
+	tasklet_schedule(&creq->creq_tasklet);
 
 	return IRQ_HANDLED;
 }
@@ -452,7 +470,7 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw)
 	if (rc)
 		return rc;
 
-	clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags);
+	clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->cmdq.flags);
 	return 0;
 }
 
@@ -556,16 +574,17 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 					  NULL, 0);
 	if (rc)
 		return rc;
-	set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags);
+	set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->cmdq.flags);
 	return 0;
 }
 
 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 {
+	kfree(rcfw->cmdq.cmdq_bitmap);
 	kfree(rcfw->qp_tbl);
 	kfree(rcfw->crsqe_tbl);
-	bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq);
-	bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq);
+	bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq.hwq);
+	bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq.hwq);
 	rcfw->pdev = NULL;
 }
 
@@ -576,8 +595,13 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 {
 	struct bnxt_qplib_hwq_attr hwq_attr;
 	struct bnxt_qplib_sg_info sginfo;
+	struct bnxt_qplib_cmdq_ctx *cmdq;
+	struct bnxt_qplib_creq_ctx *creq;
+	u32 bmap_size = 0;
 
 	rcfw->pdev = res->pdev;
+	cmdq = &rcfw->cmdq;
+	creq = &rcfw->creq;
 	rcfw->res = res;
 
 	memset(&hwq_attr, 0, sizeof(hwq_attr));
@@ -591,7 +615,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 	hwq_attr.stride = BNXT_QPLIB_CREQE_UNITS;
 	hwq_attr.type = bnxt_qplib_get_hwq_type(res);
 
-	if (bnxt_qplib_alloc_init_hwq(&rcfw->creq, &hwq_attr)) {
+	if (bnxt_qplib_alloc_init_hwq(&creq->hwq, &hwq_attr)) {
 		dev_err(&rcfw->pdev->dev,
 			"HW channel CREQ allocation failed\n");
 		goto fail;
@@ -605,17 +629,24 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 	hwq_attr.depth = rcfw->cmdq_depth;
 	hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS;
 	hwq_attr.type = HWQ_TYPE_CTX;
-	if (bnxt_qplib_alloc_init_hwq(&rcfw->cmdq, &hwq_attr)) {
+	if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
 		dev_err(&rcfw->pdev->dev,
 			"HW channel CMDQ allocation failed\n");
 		goto fail;
 	}
 
-	rcfw->crsqe_tbl = kcalloc(rcfw->cmdq.max_elements,
+	rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements,
 				  sizeof(*rcfw->crsqe_tbl), GFP_KERNEL);
 	if (!rcfw->crsqe_tbl)
 		goto fail;
 
+	bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long);
+	cmdq->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL);
+	if (!cmdq->cmdq_bitmap)
+		goto fail;
+
+	cmdq->bmap_size = bmap_size;
+
 	rcfw->qp_tbl_size = qp_tbl_sz;
 	rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node),
 			       GFP_KERNEL);
@@ -632,137 +663,202 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
 {
 	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
+	struct bnxt_qplib_creq_ctx *creq;
 
-	tasklet_disable(&rcfw->worker);
+	creq = &rcfw->creq;
+	tasklet_disable(&creq->creq_tasklet);
 	/* Mask h/w interrupts */
-	bnxt_qplib_ring_creq_db(rcfw->creq_bar_reg_iomem, rcfw->creq.cons,
-				rcfw->creq.max_elements, rcfw->creq_ring_id,
+	bnxt_qplib_ring_creq_db(creq->creq_db.db, creq->hwq.cons,
+				creq->hwq.max_elements, creq->ring_id,
 				gen_p5);
 	/* Sync with last running IRQ-handler */
-	synchronize_irq(rcfw->vector);
+	synchronize_irq(creq->msix_vec);
 	if (kill)
-		tasklet_kill(&rcfw->worker);
+		tasklet_kill(&creq->creq_tasklet);
 
-	if (rcfw->requested) {
-		free_irq(rcfw->vector, rcfw);
-		rcfw->requested = false;
+	if (creq->requested) {
+		free_irq(creq->msix_vec, rcfw);
+		creq->requested = false;
 	}
 }
 
 void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 {
+	struct bnxt_qplib_creq_ctx *creq;
+	struct bnxt_qplib_cmdq_ctx *cmdq;
 	unsigned long indx;
 
+	creq = &rcfw->creq;
+	cmdq = &rcfw->cmdq;
+	/* Make sure the HW channel is stopped! */
 	bnxt_qplib_rcfw_stop_irq(rcfw, true);
 
-	iounmap(rcfw->cmdq_bar_reg_iomem);
-	iounmap(rcfw->creq_bar_reg_iomem);
+	iounmap(cmdq->cmdq_mbox.reg.bar_reg);
+	iounmap(creq->creq_db.reg.bar_reg);
 
-	indx = find_first_bit(rcfw->cmdq_bitmap, rcfw->bmap_size);
-	if (indx != rcfw->bmap_size)
+	indx = find_first_bit(cmdq->cmdq_bitmap, cmdq->bmap_size);
+	if (indx != cmdq->bmap_size)
 		dev_err(&rcfw->pdev->dev,
 			"disabling RCFW with pending cmd-bit %lx\n", indx);
-	kfree(rcfw->cmdq_bitmap);
-	rcfw->bmap_size = 0;
 
-	rcfw->cmdq_bar_reg_iomem = NULL;
-	rcfw->creq_bar_reg_iomem = NULL;
-	rcfw->aeq_handler = NULL;
-	rcfw->vector = 0;
+	cmdq->cmdq_mbox.reg.bar_reg = NULL;
+	creq->creq_db.reg.bar_reg = NULL;
+	creq->aeq_handler = NULL;
+	creq->msix_vec = 0;
 }
 
 int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 			      bool need_init)
 {
 	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
+	struct bnxt_qplib_creq_ctx *creq;
 	int rc;
 
-	if (rcfw->requested)
+	creq = &rcfw->creq;
+
+	if (creq->requested)
 		return -EFAULT;
 
-	rcfw->vector = msix_vector;
+	creq->msix_vec = msix_vector;
 	if (need_init)
-		tasklet_init(&rcfw->worker,
+		tasklet_init(&creq->creq_tasklet,
 			     bnxt_qplib_service_creq, (unsigned long)rcfw);
 	else
-		tasklet_enable(&rcfw->worker);
-	rc = request_irq(rcfw->vector, bnxt_qplib_creq_irq, 0,
+		tasklet_enable(&creq->creq_tasklet);
+	rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0,
 			 "bnxt_qplib_creq", rcfw);
 	if (rc)
 		return rc;
-	rcfw->requested = true;
-	bnxt_qplib_ring_creq_db_rearm(rcfw->creq_bar_reg_iomem,
-				      rcfw->creq.cons, rcfw->creq.max_elements,
-				      rcfw->creq_ring_id, gen_p5);
+	creq->requested = true;
+	bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db,
+				      creq->hwq.cons, creq->hwq.max_elements,
+				      creq->ring_id, gen_p5);
 
 	return 0;
 }
 
-int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
-				   int msix_vector,
-				   int cp_bar_reg_off, int virt_fn,
-				   int (*aeq_handler)(struct bnxt_qplib_rcfw *,
-						      void *, void *))
+static int bnxt_qplib_map_cmdq_mbox(struct bnxt_qplib_rcfw *rcfw, bool is_vf)
 {
-	resource_size_t res_base;
-	struct cmdq_init init;
+	struct bnxt_qplib_cmdq_mbox *mbox;
+	resource_size_t bar_reg;
 	struct pci_dev *pdev;
-	u16 bmap_size;
-	int rc;
+	u16 prod_offt;
+	int rc = 0;
 
-	/* General */
 	pdev = rcfw->pdev;
-	rcfw->seq_num = 0;
-	set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags);
-	bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long);
-	rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL);
-	if (!rcfw->cmdq_bitmap)
-		return -ENOMEM;
-	rcfw->bmap_size = bmap_size;
-
-	/* CMDQ */
-	rcfw->cmdq_bar_reg = RCFW_COMM_PCI_BAR_REGION;
-	res_base = pci_resource_start(pdev, rcfw->cmdq_bar_reg);
-	if (!res_base)
+	mbox = &rcfw->cmdq.cmdq_mbox;
+
+	mbox->reg.bar_id = RCFW_COMM_PCI_BAR_REGION;
+	mbox->reg.len = RCFW_COMM_SIZE;
+	mbox->reg.bar_base = pci_resource_start(pdev, mbox->reg.bar_id);
+	if (!mbox->reg.bar_base) {
+		dev_err(&pdev->dev,
+			"QPLIB: CMDQ BAR region %d resc start is 0!\n",
+			mbox->reg.bar_id);
 		return -ENOMEM;
+	}
 
-	rcfw->cmdq_bar_reg_iomem = ioremap_nocache(res_base +
-					      RCFW_COMM_BASE_OFFSET,
-					      RCFW_COMM_SIZE);
-	if (!rcfw->cmdq_bar_reg_iomem) {
-		dev_err(&rcfw->pdev->dev, "CMDQ BAR region %d mapping failed\n",
-			rcfw->cmdq_bar_reg);
+	bar_reg = mbox->reg.bar_base + RCFW_COMM_BASE_OFFSET;
+	mbox->reg.len = RCFW_COMM_SIZE;
+	mbox->reg.bar_reg = ioremap_nocache(bar_reg, mbox->reg.len);
+	if (!mbox->reg.bar_reg) {
+		dev_err(&pdev->dev,
+			"QPLIB: CMDQ BAR region %d mapping failed\n",
+			mbox->reg.bar_id);
 		return -ENOMEM;
 	}
 
-	rcfw->cmdq_bar_reg_prod_off = virt_fn ? RCFW_VF_COMM_PROD_OFFSET :
-					RCFW_PF_COMM_PROD_OFFSET;
+	prod_offt = is_vf ? RCFW_VF_COMM_PROD_OFFSET :
+			    RCFW_PF_COMM_PROD_OFFSET;
+	mbox->prod = (void  __iomem *)(mbox->reg.bar_reg + prod_offt);
+	mbox->db = (void __iomem *)(mbox->reg.bar_reg + RCFW_COMM_TRIG_OFFSET);
+	return rc;
+}
 
-	rcfw->cmdq_bar_reg_trig_off = RCFW_COMM_TRIG_OFFSET;
+static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt)
+{
+	struct bnxt_qplib_creq_db *creq_db;
+	resource_size_t bar_reg;
+	struct pci_dev *pdev;
 
-	/* CREQ */
-	rcfw->creq_bar_reg = RCFW_COMM_CONS_PCI_BAR_REGION;
-	res_base = pci_resource_start(pdev, rcfw->creq_bar_reg);
-	if (!res_base)
-		dev_err(&rcfw->pdev->dev,
-			"CREQ BAR region %d resc start is 0!\n",
-			rcfw->creq_bar_reg);
-	/* Unconditionally map 8 bytes to support 57500 series */
-	rcfw->creq_bar_reg_iomem = ioremap_nocache(res_base + cp_bar_reg_off,
-						   8);
-	if (!rcfw->creq_bar_reg_iomem) {
-		dev_err(&rcfw->pdev->dev, "CREQ BAR region %d mapping failed\n",
-			rcfw->creq_bar_reg);
-		iounmap(rcfw->cmdq_bar_reg_iomem);
-		rcfw->cmdq_bar_reg_iomem = NULL;
+	pdev = rcfw->pdev;
+	creq_db = &rcfw->creq.creq_db;
+
+	creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION;
+	creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id);
+	if (!creq_db->reg.bar_id)
+		dev_err(&pdev->dev,
+			"QPLIB: CREQ BAR region %d resc start is 0!",
+			creq_db->reg.bar_id);
+
+	bar_reg = creq_db->reg.bar_base + reg_offt;
+	creq_db->reg.len = 8;
+	creq_db->reg.bar_reg = ioremap_nocache(bar_reg, creq_db->reg.len);
+	if (!creq_db->reg.bar_reg) {
+		dev_err(&pdev->dev,
+			"QPLIB: CREQ BAR region %d mapping failed",
+			creq_db->reg.bar_id);
 		return -ENOMEM;
 	}
-	rcfw->creq_qp_event_processed = 0;
-	rcfw->creq_func_event_processed = 0;
 
-	if (aeq_handler)
-		rcfw->aeq_handler = aeq_handler;
-	init_waitqueue_head(&rcfw->waitq);
+	creq_db->db = creq_db->reg.bar_reg;
+
+	return 0;
+}
+
+static void bnxt_qplib_start_rcfw(struct bnxt_qplib_rcfw *rcfw)
+{
+	struct bnxt_qplib_cmdq_ctx *cmdq;
+	struct bnxt_qplib_creq_ctx *creq;
+	struct bnxt_qplib_cmdq_mbox *mbox;
+	struct cmdq_init init = {0};
+
+	cmdq = &rcfw->cmdq;
+	creq = &rcfw->creq;
+	mbox = &cmdq->cmdq_mbox;
+
+	init.cmdq_pbl = cpu_to_le64(cmdq->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
+	init.cmdq_size_cmdq_lvl =
+			cpu_to_le16(((rcfw->cmdq_depth <<
+				      CMDQ_INIT_CMDQ_SIZE_SFT) &
+				    CMDQ_INIT_CMDQ_SIZE_MASK) |
+				    ((cmdq->hwq.level <<
+				      CMDQ_INIT_CMDQ_LVL_SFT) &
+				    CMDQ_INIT_CMDQ_LVL_MASK));
+	init.creq_ring_id = cpu_to_le16(creq->ring_id);
+	/* Write to the Bono mailbox register */
+	__iowrite32_copy(mbox->reg.bar_reg, &init, sizeof(init) / 4);
+}
+
+int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
+				   int msix_vector,
+				   int cp_bar_reg_off, int virt_fn,
+				   aeq_handler_t aeq_handler)
+{
+	struct bnxt_qplib_cmdq_ctx *cmdq;
+	struct bnxt_qplib_creq_ctx *creq;
+	int rc;
+
+	cmdq = &rcfw->cmdq;
+	creq = &rcfw->creq;
+
+	/* Clear to defaults */
+
+	cmdq->seq_num = 0;
+	set_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags);
+	init_waitqueue_head(&cmdq->waitq);
+
+	creq->stats.creq_qp_event_processed = 0;
+	creq->stats.creq_func_event_processed = 0;
+	creq->aeq_handler = aeq_handler;
+
+	rc = bnxt_qplib_map_cmdq_mbox(rcfw, virt_fn);
+	if (rc)
+		return rc;
+
+	rc = bnxt_qplib_map_creq_db(rcfw, cp_bar_reg_off);
+	if (rc)
+		return rc;
 
 	rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_vector, true);
 	if (rc) {
@@ -772,16 +868,8 @@ int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
 		return rc;
 	}
 
-	init.cmdq_pbl = cpu_to_le64(rcfw->cmdq.pbl[PBL_LVL_0].pg_map_arr[0]);
-	init.cmdq_size_cmdq_lvl = cpu_to_le16(
-		((rcfw->cmdq_depth << CMDQ_INIT_CMDQ_SIZE_SFT) &
-		 CMDQ_INIT_CMDQ_SIZE_MASK) |
-		((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) &
-		 CMDQ_INIT_CMDQ_LVL_MASK));
-	init.creq_ring_id = cpu_to_le16(rcfw->creq_ring_id);
+	bnxt_qplib_start_rcfw(rcfw);
 
-	/* Write to the Bono mailbox register */
-	__iowrite32_copy(rcfw->cmdq_bar_reg_iomem, &init, sizeof(init) / 4);
 	return 0;
 }
 
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
index ab1531c..1aff6d4 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -206,8 +206,9 @@ static inline void bnxt_qplib_ring_creq_db(void __iomem *db, u32 raw_cons,
 #define CREQ_ENTRY_POLL_BUDGET		0x100
 
 /* HWQ */
+typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *);
 
-struct bnxt_qplib_crsq {
+struct bnxt_qplib_crsqe {
 	struct creq_qp_event	*resp;
 	u32			req_size;
 };
@@ -225,41 +226,53 @@ struct bnxt_qplib_qp_node {
 
 #define BNXT_QPLIB_OOS_COUNT_MASK 0xFFFFFFFF
 
+#define FIRMWARE_INITIALIZED_FLAG	(0)
+#define FIRMWARE_FIRST_FLAG		(31)
+#define FIRMWARE_TIMED_OUT		(3)
+struct bnxt_qplib_cmdq_mbox {
+	struct bnxt_qplib_reg_desc	reg;
+	void __iomem			*prod;
+	void __iomem			*db;
+};
+
+struct bnxt_qplib_cmdq_ctx {
+	struct bnxt_qplib_hwq		hwq;
+	struct bnxt_qplib_cmdq_mbox	cmdq_mbox;
+	wait_queue_head_t		waitq;
+	unsigned long			flags;
+	unsigned long			*cmdq_bitmap;
+	u32				bmap_size;
+	u32				seq_num;
+};
+
+struct bnxt_qplib_creq_db {
+	struct bnxt_qplib_reg_desc	reg;
+	void __iomem			*db;
+};
+
+struct bnxt_qplib_creq_stat {
+	u64	creq_qp_event_processed;
+	u64	creq_func_event_processed;
+};
+
+struct bnxt_qplib_creq_ctx {
+	struct bnxt_qplib_hwq		hwq;
+	struct bnxt_qplib_creq_db	creq_db;
+	struct bnxt_qplib_creq_stat	stats;
+	struct tasklet_struct		creq_tasklet;
+	aeq_handler_t			aeq_handler;
+	u16				ring_id;
+	int				msix_vec;
+	bool				requested; /*irq handler installed */
+};
+
 /* RCFW Communication Channels */
 struct bnxt_qplib_rcfw {
 	struct pci_dev		*pdev;
 	struct bnxt_qplib_res	*res;
-	int			vector;
-	struct tasklet_struct	worker;
-	bool			requested;
-	unsigned long		*cmdq_bitmap;
-	u32			bmap_size;
-	unsigned long		flags;
-#define FIRMWARE_INITIALIZED_FLAG	0
-#define FIRMWARE_FIRST_FLAG		31
-#define FIRMWARE_TIMED_OUT		3
-	wait_queue_head_t	waitq;
-	int			(*aeq_handler)(struct bnxt_qplib_rcfw *,
-					       void *, void *);
-	u32			seq_num;
-
-	/* Bar region info */
-	void __iomem		*cmdq_bar_reg_iomem;
-	u16			cmdq_bar_reg;
-	u16			cmdq_bar_reg_prod_off;
-	u16			cmdq_bar_reg_trig_off;
-	u16			creq_ring_id;
-	u16			creq_bar_reg;
-	void __iomem		*creq_bar_reg_iomem;
-
-	/* Cmd-Resp and Async Event notification queue */
-	struct bnxt_qplib_hwq	creq;
-	u64			creq_qp_event_processed;
-	u64			creq_func_event_processed;
-
-	/* Actual Cmd and Resp Queues */
-	struct bnxt_qplib_hwq	cmdq;
-	struct bnxt_qplib_crsq	*crsqe_tbl;
+	struct bnxt_qplib_cmdq_ctx	cmdq;
+	struct bnxt_qplib_creq_ctx	creq;
+	struct bnxt_qplib_crsqe		*crsqe_tbl;
 	int qp_tbl_size;
 	struct bnxt_qplib_qp_node *qp_tbl;
 	u64 oos_prev;
@@ -279,8 +292,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
 				   int msix_vector,
 				   int cp_bar_reg_off, int virt_fn,
-				   int (*aeq_handler)(struct bnxt_qplib_rcfw *,
-						      void *aeqe, void *obj));
+				   aeq_handler_t aeq_handler);
 
 struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf(
 				struct bnxt_qplib_rcfw *rcfw,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
index fe8a6dd..5fa278e 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
@@ -80,6 +80,13 @@ enum bnxt_qplib_pbl_lvl {
 #define ROCE_PG_SIZE_8M		(8 * 1024 * 1024)
 #define ROCE_PG_SIZE_1G		(1024 * 1024 * 1024)
 
+struct bnxt_qplib_reg_desc {
+	u8		bar_id;
+	resource_size_t	bar_base;
+	void __iomem	*bar_reg;
+	size_t		len;
+};
+
 struct bnxt_qplib_pbl {
 	u32				pg_count;
 	u32				pg_size;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 6/7] RDMA/bnxt_re: Refactor notification queue management code
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
                   ` (4 preceding siblings ...)
  2020-01-24  5:52 ` [PATCH for-next 5/7] RDMA/bnxt_re: Refactor command queue management code Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-24  5:52 ` [PATCH for-next 7/7] RDMA/bnxt_re: Refactor doorbell management functions Devesh Sharma
  2020-01-25 18:04 ` [PATCH for-next 0/7] Refactor control path of bnxt_re driver Jason Gunthorpe
  7 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

Cleaning up the notification queue data structures and
management code. The CQ and SRQ event handlers have been
type defined instead of in-place declaration. NQ doorbell
register descriptor has been added in base NQ structure.
The nq->vector has been renamed to nq->msix_vec.

Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c | 113 ++++++++++++++++++-------------
 drivers/infiniband/hw/bnxt_re/qplib_fp.h |  54 +++++++--------
 2 files changed, 93 insertions(+), 74 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 792fc6b..549ab43 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -236,16 +236,16 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res,
 static void bnxt_qplib_service_nq(unsigned long data)
 {
 	struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data;
+	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
 	struct bnxt_qplib_hwq *hwq = &nq->hwq;
 	struct nq_base *nqe, **nq_ptr;
 	struct bnxt_qplib_cq *cq;
 	int num_cqne_processed = 0;
 	int num_srqne_processed = 0;
-	u32 sw_cons, raw_cons;
-	u16 type;
 	int budget = nq->budget;
+	u32 sw_cons, raw_cons;
 	uintptr_t q_handle;
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
+	u16 type;
 
 	/* Service the NQ until empty */
 	raw_cons = hwq->cons;
@@ -314,7 +314,7 @@ static void bnxt_qplib_service_nq(unsigned long data)
 	}
 	if (hwq->cons != raw_cons) {
 		hwq->cons = raw_cons;
-		bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, hwq->cons,
+		bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, hwq->cons,
 					    hwq->max_elements, nq->ring_id,
 					    gen_p5);
 	}
@@ -333,7 +333,7 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
 	prefetch(&nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]);
 
 	/* Fan out to CPU affinitized kthreads? */
-	tasklet_schedule(&nq->worker);
+	tasklet_schedule(&nq->nq_tasklet);
 
 	return IRQ_HANDLED;
 }
@@ -341,17 +341,17 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
 void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
 {
 	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
-	tasklet_disable(&nq->worker);
+	tasklet_disable(&nq->nq_tasklet);
 	/* Mask h/w interrupt */
-	bnxt_qplib_ring_nq_db(nq->bar_reg_iomem, nq->hwq.cons,
+	bnxt_qplib_ring_nq_db(nq->nq_db.db, nq->hwq.cons,
 			      nq->hwq.max_elements, nq->ring_id, gen_p5);
 	/* Sync with last running IRQ handler */
-	synchronize_irq(nq->vector);
+	synchronize_irq(nq->msix_vec);
 	if (kill)
-		tasklet_kill(&nq->worker);
+		tasklet_kill(&nq->nq_tasklet);
 	if (nq->requested) {
-		irq_set_affinity_hint(nq->vector, NULL);
-		free_irq(nq->vector, nq);
+		irq_set_affinity_hint(nq->msix_vec, NULL);
+		free_irq(nq->msix_vec, nq);
 		nq->requested = false;
 	}
 }
@@ -364,16 +364,17 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
 	}
 
 	/* Make sure the HW is stopped! */
-	if (nq->requested)
-		bnxt_qplib_nq_stop_irq(nq, true);
+	bnxt_qplib_nq_stop_irq(nq, true);
 
-	if (nq->bar_reg_iomem)
-		iounmap(nq->bar_reg_iomem);
-	nq->bar_reg_iomem = NULL;
+	if (nq->nq_db.reg.bar_reg) {
+		iounmap(nq->nq_db.reg.bar_reg);
+		nq->nq_db.reg.bar_reg = NULL;
+		nq->nq_db.db = NULL;
+	}
 
 	nq->cqn_handler = NULL;
 	nq->srqn_handler = NULL;
-	nq->vector = 0;
+	nq->msix_vec = 0;
 }
 
 int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
@@ -385,68 +386,86 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
 	if (nq->requested)
 		return -EFAULT;
 
-	nq->vector = msix_vector;
+	nq->msix_vec = msix_vector;
 	if (need_init)
-		tasklet_init(&nq->worker, bnxt_qplib_service_nq,
+		tasklet_init(&nq->nq_tasklet, bnxt_qplib_service_nq,
 			     (unsigned long)nq);
 	else
-		tasklet_enable(&nq->worker);
+		tasklet_enable(&nq->nq_tasklet);
 
 	snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx);
-	rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, nq->name, nq);
+	rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq);
 	if (rc)
 		return rc;
 
 	cpumask_clear(&nq->mask);
 	cpumask_set_cpu(nq_indx, &nq->mask);
-	rc = irq_set_affinity_hint(nq->vector, &nq->mask);
+	rc = irq_set_affinity_hint(nq->msix_vec, &nq->mask);
 	if (rc) {
 		dev_warn(&nq->pdev->dev,
 			 "set affinity failed; vector: %d nq_idx: %d\n",
-			 nq->vector, nq_indx);
+			 nq->msix_vec, nq_indx);
 	}
 	nq->requested = true;
-	bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, nq->hwq.cons,
+	bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, nq->hwq.cons,
 				    nq->hwq.max_elements, nq->ring_id, gen_p5);
 
 	return rc;
 }
 
+static int bnxt_qplib_map_nq_db(struct bnxt_qplib_nq *nq,  u32 reg_offt)
+{
+	resource_size_t reg_base;
+	struct bnxt_qplib_nq_db *nq_db;
+	struct pci_dev *pdev;
+	int rc = 0;
+
+	pdev = nq->pdev;
+	nq_db = &nq->nq_db;
+
+	nq_db->reg.bar_id = NQ_CONS_PCI_BAR_REGION;
+	nq_db->reg.bar_base = pci_resource_start(pdev, nq_db->reg.bar_id);
+	if (!nq_db->reg.bar_base) {
+		dev_err(&pdev->dev, "QPLIB: NQ BAR region %d resc start is 0!",
+			nq_db->reg.bar_id);
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	reg_base = nq_db->reg.bar_base + reg_offt;
+	nq_db->reg.len = 8;
+	nq_db->reg.bar_reg = ioremap_nocache(reg_base, nq_db->reg.len);
+	if (!nq_db->reg.bar_reg) {
+		dev_err(&pdev->dev, "QPLIB: NQ BAR region %d mapping failed",
+			nq_db->reg.bar_id);
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	nq_db->db = nq_db->reg.bar_reg;
+fail:
+	return rc;
+}
+
 int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
 			 int nq_idx, int msix_vector, int bar_reg_offset,
-			 int (*cqn_handler)(struct bnxt_qplib_nq *nq,
-					    struct bnxt_qplib_cq *),
-			 int (*srqn_handler)(struct bnxt_qplib_nq *nq,
-					     struct bnxt_qplib_srq *,
-					     u8 event))
+			 cqn_handler_t cqn_handler,
+			 srqn_handler_t srqn_handler)
 {
-	resource_size_t nq_base;
 	int rc = -1;
 
-	if (cqn_handler)
-		nq->cqn_handler = cqn_handler;
-
-	if (srqn_handler)
-		nq->srqn_handler = srqn_handler;
+	nq->pdev = pdev;
+	nq->cqn_handler = cqn_handler;
+	nq->srqn_handler = srqn_handler;
 
 	/* Have a task to schedule CQ notifiers in post send case */
 	nq->cqn_wq  = create_singlethread_workqueue("bnxt_qplib_nq");
 	if (!nq->cqn_wq)
 		return -ENOMEM;
 
-	nq->bar_reg = NQ_CONS_PCI_BAR_REGION;
-	nq->bar_reg_off = bar_reg_offset;
-	nq_base = pci_resource_start(pdev, nq->bar_reg);
-	if (!nq_base) {
-		rc = -ENOMEM;
-		goto fail;
-	}
-	/* Unconditionally map 8 bytes to support 57500 series */
-	nq->bar_reg_iomem = ioremap_nocache(nq_base + nq->bar_reg_off, 8);
-	if (!nq->bar_reg_iomem) {
-		rc = -ENOMEM;
+	rc = bnxt_qplib_map_nq_db(nq, bar_reg_offset);
+	if (rc)
 		goto fail;
-	}
 
 	rc = bnxt_qplib_nq_start_irq(nq, nq_idx, msix_vector, true);
 	if (rc) {
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index d3f080c..765e5d2 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -470,29 +470,32 @@ static inline void bnxt_qplib_ring_nq_db(void __iomem *db, u32 raw_cons,
 		writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db);
 }
 
+struct bnxt_qplib_nq_db {
+	struct bnxt_qplib_reg_desc	reg;
+	void __iomem			*db;
+};
+
+typedef int (*cqn_handler_t)(struct bnxt_qplib_nq *nq,
+		struct bnxt_qplib_cq *cq);
+typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq,
+		struct bnxt_qplib_srq *srq, u8 event);
+
 struct bnxt_qplib_nq {
-	struct pci_dev		*pdev;
-	struct bnxt_qplib_res	*res;
-
-	int			vector;
-	cpumask_t		mask;
-	int			budget;
-	bool			requested;
-	struct tasklet_struct	worker;
-	struct bnxt_qplib_hwq	hwq;
-
-	u16			bar_reg;
-	u32			bar_reg_off;
-	u16			ring_id;
-	void __iomem		*bar_reg_iomem;
-
-	int			(*cqn_handler)(struct bnxt_qplib_nq *nq,
-					       struct bnxt_qplib_cq *cq);
-	int			(*srqn_handler)(struct bnxt_qplib_nq *nq,
-						struct bnxt_qplib_srq *srq,
-						u8 event);
-	struct workqueue_struct	*cqn_wq;
-	char			name[32];
+	struct pci_dev			*pdev;
+	struct bnxt_qplib_res		*res;
+	char				name[32];
+	struct bnxt_qplib_hwq		hwq;
+	struct bnxt_qplib_nq_db		nq_db;
+	u16				ring_id;
+	int				msix_vec;
+	cpumask_t			mask;
+	struct tasklet_struct		nq_tasklet;
+	bool				requested;
+	int				budget;
+
+	cqn_handler_t			cqn_handler;
+	srqn_handler_t			srqn_handler;
+	struct workqueue_struct		*cqn_wq;
 };
 
 struct bnxt_qplib_nq_work {
@@ -507,11 +510,8 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
 			    int msix_vector, bool need_init);
 int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
 			 int nq_idx, int msix_vector, int bar_reg_offset,
-			 int (*cqn_handler)(struct bnxt_qplib_nq *nq,
-					    struct bnxt_qplib_cq *cq),
-			 int (*srqn_handler)(struct bnxt_qplib_nq *nq,
-					     struct bnxt_qplib_srq *srq,
-					     u8 event));
+			 cqn_handler_t cqn_handler,
+			 srqn_handler_t srq_handler);
 int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 			  struct bnxt_qplib_srq *srq);
 int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH for-next 7/7] RDMA/bnxt_re: Refactor doorbell management functions
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
                   ` (5 preceding siblings ...)
  2020-01-24  5:52 ` [PATCH for-next 6/7] RDMA/bnxt_re: Refactor notification " Devesh Sharma
@ 2020-01-24  5:52 ` Devesh Sharma
  2020-01-25 18:04 ` [PATCH for-next 0/7] Refactor control path of bnxt_re driver Jason Gunthorpe
  7 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-24  5:52 UTC (permalink / raw)
  To: linux-rdma; +Cc: jgg, dledford

Moving all the fast path doorbell functions at one place
under qplib_res.h. To pass doorbell record information
a new structure bnxt_qplib_db_info has been introduced.
Every roce object holds an instance of this structure and
doorbell information is initialized during resource creation.

When DB is rung only the current queue index is read from
hardware ring and rest of the data is taken from pre-initialized
dbinfo structure.

Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c   | 142 ++++++++++-------------------
 drivers/infiniband/hw/bnxt_re/qplib_fp.h   |  44 +--------
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.c |  21 ++---
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |   2 +-
 drivers/infiniband/hw/bnxt_re/qplib_res.h  |  78 ++++++++++++++++
 5 files changed, 141 insertions(+), 146 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 549ab43..83e566c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -53,9 +53,7 @@
 #include "qplib_sp.h"
 #include "qplib_fp.h"
 
-static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq);
 static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp);
-static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type);
 
 static void bnxt_qplib_cancel_phantom_processing(struct bnxt_qplib_qp *qp)
 {
@@ -236,7 +234,6 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res,
 static void bnxt_qplib_service_nq(unsigned long data)
 {
 	struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data;
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
 	struct bnxt_qplib_hwq *hwq = &nq->hwq;
 	struct nq_base *nqe, **nq_ptr;
 	struct bnxt_qplib_cq *cq;
@@ -272,7 +269,8 @@ static void bnxt_qplib_service_nq(unsigned long data)
 			q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high)
 						     << 32;
 			cq = (struct bnxt_qplib_cq *)(unsigned long)q_handle;
-			bnxt_qplib_arm_cq_enable(cq);
+			bnxt_qplib_armen_db(&cq->dbinfo,
+					    DBC_DBC_TYPE_CQ_ARMENA);
 			spin_lock_bh(&cq->compl_lock);
 			atomic_set(&cq->arm_state, 0);
 			if (!nq->cqn_handler(nq, (cq)))
@@ -285,14 +283,16 @@ static void bnxt_qplib_service_nq(unsigned long data)
 		}
 		case NQ_BASE_TYPE_SRQ_EVENT:
 		{
+			struct bnxt_qplib_srq *srq;
 			struct nq_srq_event *nqsrqe =
 						(struct nq_srq_event *)nqe;
 
 			q_handle = le32_to_cpu(nqsrqe->srq_handle_low);
 			q_handle |= (u64)le32_to_cpu(nqsrqe->srq_handle_high)
 				     << 32;
-			bnxt_qplib_arm_srq((struct bnxt_qplib_srq *)q_handle,
-					   DBC_DBC_TYPE_SRQ_ARMENA);
+			srq = (struct bnxt_qplib_srq *)q_handle;
+			bnxt_qplib_armen_db(&srq->dbinfo,
+					    DBC_DBC_TYPE_SRQ_ARMENA);
 			if (!nq->srqn_handler(nq,
 					      (struct bnxt_qplib_srq *)q_handle,
 					      nqsrqe->event))
@@ -314,9 +314,7 @@ static void bnxt_qplib_service_nq(unsigned long data)
 	}
 	if (hwq->cons != raw_cons) {
 		hwq->cons = raw_cons;
-		bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, hwq->cons,
-					    hwq->max_elements, nq->ring_id,
-					    gen_p5);
+		bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true);
 	}
 }
 
@@ -340,11 +338,9 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
 
 void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
 {
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
 	tasklet_disable(&nq->nq_tasklet);
 	/* Mask h/w interrupt */
-	bnxt_qplib_ring_nq_db(nq->nq_db.db, nq->hwq.cons,
-			      nq->hwq.max_elements, nq->ring_id, gen_p5);
+	bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
 	/* Sync with last running IRQ handler */
 	synchronize_irq(nq->msix_vec);
 	if (kill)
@@ -380,7 +376,6 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
 int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
 			    int msix_vector, bool need_init)
 {
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
 	int rc;
 
 	if (nq->requested)
@@ -407,8 +402,7 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
 			 nq->msix_vec, nq_indx);
 	}
 	nq->requested = true;
-	bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, nq->hwq.cons,
-				    nq->hwq.max_elements, nq->ring_id, gen_p5);
+	bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true);
 
 	return rc;
 }
@@ -442,7 +436,9 @@ static int bnxt_qplib_map_nq_db(struct bnxt_qplib_nq *nq,  u32 reg_offt)
 		goto fail;
 	}
 
-	nq_db->db = nq_db->reg.bar_reg;
+	nq_db->dbinfo.db = nq_db->reg.bar_reg;
+	nq_db->dbinfo.hwq = &nq->hwq;
+	nq_db->dbinfo.xid = nq->ring_id;
 fail:
 	return rc;
 }
@@ -517,24 +513,6 @@ int bnxt_qplib_alloc_nq(struct bnxt_qplib_res *res, struct bnxt_qplib_nq *nq)
 }
 
 /* SRQ */
-static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type)
-{
-	struct bnxt_qplib_hwq *srq_hwq = &srq->hwq;
-	void __iomem *db;
-	u32 sw_prod;
-	u64 val = 0;
-
-	/* Ring DB */
-	sw_prod = (arm_type == DBC_DBC_TYPE_SRQ_ARM) ?
-		   srq->threshold : HWQ_CMP(srq_hwq->prod, srq_hwq);
-	db = (arm_type == DBC_DBC_TYPE_SRQ_ARMENA) ? srq->dbr_base :
-						     srq->dpi->dbr;
-	val = ((srq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | arm_type;
-	val <<= 32;
-	val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK;
-	writeq(val, db);
-}
-
 void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
 			   struct bnxt_qplib_srq *srq)
 {
@@ -626,9 +604,12 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 	srq->swq[srq->last_idx].next_idx = -1;
 
 	srq->id = le32_to_cpu(resp.xid);
-	srq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
+	srq->dbinfo.hwq = &srq->hwq;
+	srq->dbinfo.xid = srq->id;
+	srq->dbinfo.db = srq->dpi->dbr;
+	srq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem;
 	if (srq->threshold)
-		bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARMENA);
+		bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA);
 	srq->arm_req = false;
 
 	return 0;
@@ -652,7 +633,7 @@ int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res,
 				    srq_hwq->max_elements - sw_cons + sw_prod;
 	if (count > srq->threshold) {
 		srq->arm_req = false;
-		bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARM);
+		bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold);
 	} else {
 		/* Deferred arming */
 		srq->arm_req = true;
@@ -740,10 +721,10 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,
 				    srq_hwq->max_elements - sw_cons + sw_prod;
 	spin_unlock(&srq_hwq->lock);
 	/* Ring DB */
-	bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ);
+	bnxt_qplib_ring_prod_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ);
 	if (srq->arm_req == true && count > srq->threshold) {
 		srq->arm_req = false;
-		bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARM);
+		bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold);
 	}
 done:
 	return rc;
@@ -875,6 +856,15 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
 	qp->id = le32_to_cpu(resp.xid);
 	qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
+	qp->cctx = res->cctx;
+	sq->dbinfo.hwq = &sq->hwq;
+	sq->dbinfo.xid = qp->id;
+	sq->dbinfo.db = qp->dpi->dbr;
+	if (rq->max_wqe) {
+		rq->dbinfo.hwq = &rq->hwq;
+		rq->dbinfo.xid = qp->id;
+		rq->dbinfo.db = qp->dpi->dbr;
+	}
 	rcfw->qp_tbl[qp->id].qp_id = qp->id;
 	rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
 
@@ -1114,9 +1104,17 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
 
 	qp->id = le32_to_cpu(resp.xid);
 	qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
-	qp->cctx = res->cctx;
 	INIT_LIST_HEAD(&qp->sq_flush);
 	INIT_LIST_HEAD(&qp->rq_flush);
+	qp->cctx = res->cctx;
+	sq->dbinfo.hwq = &sq->hwq;
+	sq->dbinfo.xid = qp->id;
+	sq->dbinfo.db = qp->dpi->dbr;
+	if (rq->max_wqe) {
+		rq->dbinfo.hwq = &rq->hwq;
+		rq->dbinfo.xid = qp->id;
+		rq->dbinfo.db = qp->dpi->dbr;
+	}
 	rcfw->qp_tbl[qp->id].qp_id = qp->id;
 	rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
 
@@ -1556,16 +1554,8 @@ void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp,
 void bnxt_qplib_post_send_db(struct bnxt_qplib_qp *qp)
 {
 	struct bnxt_qplib_q *sq = &qp->sq;
-	u32 sw_prod;
-	u64 val = 0;
 
-	val = (((qp->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) |
-	       DBC_DBC_TYPE_SQ);
-	val <<= 32;
-	sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
-	val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK;
-	/* Flush all the WQE writes to HW */
-	writeq(val, qp->dpi->dbr);
+	bnxt_qplib_ring_prod_db(&sq->dbinfo, DBC_DBC_TYPE_SQ);
 }
 
 int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
@@ -1857,16 +1847,8 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
 void bnxt_qplib_post_recv_db(struct bnxt_qplib_qp *qp)
 {
 	struct bnxt_qplib_q *rq = &qp->rq;
-	u32 sw_prod;
-	u64 val = 0;
 
-	val = (((qp->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) |
-	       DBC_DBC_TYPE_RQ);
-	val <<= 32;
-	sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
-	val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK;
-	/* Flush the writes to HW Rx WQE before the ringing Rx DB */
-	writeq(val, qp->dpi->dbr);
+	bnxt_qplib_ring_prod_db(&rq->dbinfo, DBC_DBC_TYPE_RQ);
 }
 
 int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
@@ -1946,34 +1928,6 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
 }
 
 /* CQ */
-
-/* Spinlock must be held */
-static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq)
-{
-	u64 val = 0;
-
-	val = ((cq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) |
-	       DBC_DBC_TYPE_CQ_ARMENA;
-	val <<= 32;
-	/* Flush memory writes before enabling the CQ */
-	writeq(val, cq->dbr_base);
-}
-
-static void bnxt_qplib_arm_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
-{
-	struct bnxt_qplib_hwq *cq_hwq = &cq->hwq;
-	u32 sw_cons;
-	u64 val = 0;
-
-	/* Ring DB */
-	val = ((cq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | arm_type;
-	val <<= 32;
-	sw_cons = HWQ_CMP(cq_hwq->cons, cq_hwq);
-	val |= (sw_cons << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK;
-	/* flush memory writes before arming the CQ */
-	writeq(val, cq->dpi->dbr);
-}
-
 int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
@@ -2029,7 +1983,6 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 		goto fail;
 
 	cq->id = le32_to_cpu(resp.xid);
-	cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
 	cq->period = BNXT_QPLIB_QUEUE_START_PERIOD;
 	init_waitqueue_head(&cq->waitq);
 	INIT_LIST_HEAD(&cq->sqf_head);
@@ -2037,7 +1990,13 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
 	spin_lock_init(&cq->compl_lock);
 	spin_lock_init(&cq->flush_lock);
 
-	bnxt_qplib_arm_cq_enable(cq);
+	cq->dbinfo.hwq = &cq->hwq;
+	cq->dbinfo.xid = cq->id;
+	cq->dbinfo.db = cq->dpi->dbr;
+	cq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem;
+
+	bnxt_qplib_armen_db(&cq->dbinfo, DBC_DBC_TYPE_CQ_ARMENA);
+
 	return 0;
 
 fail:
@@ -2194,8 +2153,7 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
 		sq->send_phantom = true;
 
 		/* TODO: Only ARM if the previous SQE is ARMALL */
-		bnxt_qplib_arm_cq(cq, DBC_DBC_TYPE_CQ_ARMALL);
-
+		bnxt_qplib_ring_db(&cq->dbinfo, DBC_DBC_TYPE_CQ_ARMALL);
 		rc = -EAGAIN;
 		goto out;
 	}
@@ -2865,7 +2823,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
 	}
 	if (cq->hwq.cons != raw_cons) {
 		cq->hwq.cons = raw_cons;
-		bnxt_qplib_arm_cq(cq, DBC_DBC_TYPE_CQ);
+		bnxt_qplib_ring_db(&cq->dbinfo, DBC_DBC_TYPE_CQ);
 	}
 exit:
 	return num_cqes - budget;
@@ -2874,7 +2832,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
 {
 	if (arm_type)
-		bnxt_qplib_arm_cq(cq, arm_type);
+		bnxt_qplib_ring_db(&cq->dbinfo, arm_type);
 	/* Using cq->arm_state variable to track whether to issue cq handler */
 	atomic_set(&cq->arm_state, 1);
 }
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 765e5d2..9e8d1c5 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -42,7 +42,7 @@
 struct bnxt_qplib_srq {
 	struct bnxt_qplib_pd		*pd;
 	struct bnxt_qplib_dpi		*dpi;
-	void __iomem			*dbr_base;
+	struct bnxt_qplib_db_info	dbinfo;
 	u64				srq_handle;
 	u32				id;
 	u32				max_wqe;
@@ -236,6 +236,7 @@ struct bnxt_qplib_swqe {
 struct bnxt_qplib_q {
 	struct bnxt_qplib_hwq		hwq;
 	struct bnxt_qplib_swq		*swq;
+	struct bnxt_qplib_db_info	dbinfo;
 	struct bnxt_qplib_sg_info	sg_info;
 	u32				max_wqe;
 	u16				q_full_delta;
@@ -370,7 +371,7 @@ struct bnxt_qplib_cqe {
 #define BNXT_QPLIB_QUEUE_START_PERIOD		0x01
 struct bnxt_qplib_cq {
 	struct bnxt_qplib_dpi		*dpi;
-	void __iomem			*dbr_base;
+	struct bnxt_qplib_db_info	dbinfo;
 	u32				max_wqe;
 	u32				id;
 	u16				count;
@@ -433,46 +434,9 @@ struct bnxt_qplib_cq {
 					 NQ_DB_IDX_VALID |	\
 					 NQ_DB_IRQ_DIS)
 
-static inline void bnxt_qplib_ring_nq_db64(void __iomem *db, u32 index,
-					   u32 xid, bool arm)
-{
-	u64 val;
-
-	val = xid & DBC_DBC_XID_MASK;
-	val |= DBC_DBC_PATH_ROCE;
-	val |= arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ;
-	val <<= 32;
-	val |= index & DBC_DBC_INDEX_MASK;
-	writeq(val, db);
-}
-
-static inline void bnxt_qplib_ring_nq_db_rearm(void __iomem *db, u32 raw_cons,
-					       u32 max_elements, u32 xid,
-					       bool gen_p5)
-{
-	u32 index = raw_cons & (max_elements - 1);
-
-	if (gen_p5)
-		bnxt_qplib_ring_nq_db64(db, index, xid, true);
-	else
-		writel(NQ_DB_CP_FLAGS_REARM | (index & DBC_DBC32_XID_MASK), db);
-}
-
-static inline void bnxt_qplib_ring_nq_db(void __iomem *db, u32 raw_cons,
-					 u32 max_elements, u32 xid,
-					 bool gen_p5)
-{
-	u32 index = raw_cons & (max_elements - 1);
-
-	if (gen_p5)
-		bnxt_qplib_ring_nq_db64(db, index, xid, false);
-	else
-		writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db);
-}
-
 struct bnxt_qplib_nq_db {
 	struct bnxt_qplib_reg_desc	reg;
-	void __iomem			*db;
+	struct bnxt_qplib_db_info	dbinfo;
 };
 
 typedef int (*cqn_handler_t)(struct bnxt_qplib_nq *nq,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index 8160404..5359933 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -379,7 +379,6 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
 static void bnxt_qplib_service_creq(unsigned long data)
 {
 	struct bnxt_qplib_rcfw *rcfw = (struct bnxt_qplib_rcfw *)data;
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
 	struct bnxt_qplib_creq_ctx *creq = &rcfw->creq;
 	u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
 	struct bnxt_qplib_hwq *hwq = &creq->hwq;
@@ -429,9 +428,8 @@ static void bnxt_qplib_service_creq(unsigned long data)
 
 	if (hwq->cons != raw_cons) {
 		hwq->cons = raw_cons;
-		bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db,
-					      raw_cons, hwq->max_elements,
-					      creq->ring_id, gen_p5);
+		bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo,
+				      rcfw->res->cctx, true);
 	}
 	spin_unlock_irqrestore(&hwq->lock, flags);
 }
@@ -662,15 +660,12 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 
 void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
 {
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
 	struct bnxt_qplib_creq_ctx *creq;
 
 	creq = &rcfw->creq;
 	tasklet_disable(&creq->creq_tasklet);
 	/* Mask h/w interrupts */
-	bnxt_qplib_ring_creq_db(creq->creq_db.db, creq->hwq.cons,
-				creq->hwq.max_elements, creq->ring_id,
-				gen_p5);
+	bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
 	/* Sync with last running IRQ-handler */
 	synchronize_irq(creq->msix_vec);
 	if (kill)
@@ -710,7 +705,6 @@ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 			      bool need_init)
 {
-	bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx);
 	struct bnxt_qplib_creq_ctx *creq;
 	int rc;
 
@@ -730,9 +724,8 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 	if (rc)
 		return rc;
 	creq->requested = true;
-	bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db,
-				      creq->hwq.cons, creq->hwq.max_elements,
-				      creq->ring_id, gen_p5);
+
+	bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
 
 	return 0;
 }
@@ -801,7 +794,9 @@ static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt)
 		return -ENOMEM;
 	}
 
-	creq_db->db = creq_db->reg.bar_reg;
+	creq_db->dbinfo.db = creq_db->reg.bar_reg;
+	creq_db->dbinfo.hwq = &rcfw->creq.hwq;
+	creq_db->dbinfo.xid = rcfw->creq.ring_id;
 
 	return 0;
 }
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
index 1aff6d4..411fce3 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -247,7 +247,7 @@ struct bnxt_qplib_cmdq_ctx {
 
 struct bnxt_qplib_creq_db {
 	struct bnxt_qplib_reg_desc	reg;
-	void __iomem			*db;
+	struct bnxt_qplib_db_info	dbinfo;
 };
 
 struct bnxt_qplib_creq_stat {
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
index 5fa278e..95b645d 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
@@ -133,6 +133,13 @@ struct bnxt_qplib_hwq {
 	u8				is_user;
 };
 
+struct bnxt_qplib_db_info {
+	void __iomem		*db;
+	void __iomem		*priv_db;
+	struct bnxt_qplib_hwq	*hwq;
+	u32			xid;
+};
+
 /* Tables */
 struct bnxt_qplib_pd_tbl {
 	unsigned long			*tbl;
@@ -290,4 +297,75 @@ void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res,
 int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_ctx *ctx,
 			 bool virt_fn, bool is_p5);
+
+static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info,
+					bool arm)
+{
+	u32 key;
+
+	key = info->hwq->cons & (info->hwq->max_elements - 1);
+	key |= (CMPL_DOORBELL_IDX_VALID |
+		(CMPL_DOORBELL_KEY_CMPL & CMPL_DOORBELL_KEY_MASK));
+	if (!arm)
+		key |= CMPL_DOORBELL_MASK;
+	writel(key, info->db);
+}
+
+static inline void bnxt_qplib_ring_db(struct bnxt_qplib_db_info *info,
+				      u32 type)
+{
+	u64 key = 0;
+
+	key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;
+	key <<= 32;
+	key |= (info->hwq->cons & (info->hwq->max_elements - 1)) &
+		DBC_DBC_INDEX_MASK;
+	writeq(key, info->db);
+}
+
+static inline void bnxt_qplib_ring_prod_db(struct bnxt_qplib_db_info *info,
+					   u32 type)
+{
+	u64 key = 0;
+
+	key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;
+	key <<= 32;
+	key |= (info->hwq->prod & (info->hwq->max_elements - 1)) &
+		DBC_DBC_INDEX_MASK;
+	writeq(key, info->db);
+}
+
+static inline void bnxt_qplib_armen_db(struct bnxt_qplib_db_info *info,
+				       u32 type)
+{
+	u64 key = 0;
+
+	key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;
+	key <<= 32;
+	writeq(key, info->priv_db);
+}
+
+static inline void bnxt_qplib_srq_arm_db(struct bnxt_qplib_db_info *info,
+					 u32 th)
+{
+	u64 key = 0;
+
+	key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | th;
+	key <<= 32;
+	key |=  th & DBC_DBC_INDEX_MASK;
+	writeq(key, info->priv_db);
+}
+
+static inline void bnxt_qplib_ring_nq_db(struct bnxt_qplib_db_info *info,
+					 struct bnxt_qplib_chip_ctx *cctx,
+					 bool arm)
+{
+	u32 type;
+
+	type = arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ;
+	if (bnxt_qplib_is_chip_gen_p5(cctx))
+		bnxt_qplib_ring_db(info, type);
+	else
+		bnxt_qplib_ring_db32(info, arm);
+}
 #endif /* __BNXT_QPLIB_RES_H__ */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
@ 2020-01-24 11:23   ` Leon Romanovsky
  2020-01-25 17:03     ` Devesh Sharma
  2020-01-25 17:46   ` Jason Gunthorpe
  2020-01-30 13:37   ` Parav Pandit
  2 siblings, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-24 11:23 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, jgg, dledford

On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> Restructuring the bnxt_re_create_qp function. Listing below
> the major changes:
>  --Monolithic central part of create_qp where attributes are
>    initialized is now enclosed in one function and this new
>    function has few more sub-functions.
>  --Top level qp limit checking code moved to a function.
>  --GSI QP creation and GSI Shadow qp creation code is handled
>    in a sub function.
>
> Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> ---
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
>  drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
>  3 files changed, 434 insertions(+), 217 deletions(-)
>

Please remove dev_err/dev_dbg/dev_* prints from the driver code.

Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-24 11:23   ` Leon Romanovsky
@ 2020-01-25 17:03     ` Devesh Sharma
  2020-01-25 18:50       ` Leon Romanovsky
  0 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-25 17:03 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Fri, Jan 24, 2020 at 4:53 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > Restructuring the bnxt_re_create_qp function. Listing below
> > the major changes:
> >  --Monolithic central part of create_qp where attributes are
> >    initialized is now enclosed in one function and this new
> >    function has few more sub-functions.
> >  --Top level qp limit checking code moved to a function.
> >  --GSI QP creation and GSI Shadow qp creation code is handled
> >    in a sub function.
> >
> > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > ---
> >  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> >  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
> >  drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
> >  3 files changed, 434 insertions(+), 217 deletions(-)
> >
>
> Please remove dev_err/dev_dbg/dev_* prints from the driver code.
Sure I can do that, are you suggesting to add one more patch in this series?
I guess it should be okay to follow the hw/efa way to  have debug msgs still on.
>
>
> Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
  2020-01-24 11:23   ` Leon Romanovsky
@ 2020-01-25 17:46   ` Jason Gunthorpe
  2020-01-27  8:13     ` Devesh Sharma
  2020-01-30 13:37   ` Parav Pandit
  2 siblings, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-25 17:46 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, dledford

On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> +{
> +	struct bnxt_re_qp *gsi_sqp;
> +	struct bnxt_re_ah *gsi_sah;
> +	struct bnxt_re_dev *rdev;
> +	int rc = 0;
> +
> +	rdev = qp->rdev;
> +	gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> +	gsi_sah = rdev->gsi_ctx.gsi_sah;
> +
> +	/* remove from active qp list */
> +	mutex_lock(&rdev->qp_lock);
> +	list_del(&gsi_sqp->list);
> +	atomic_dec(&rdev->qp_count);
> +	mutex_unlock(&rdev->qp_lock);
> +
> +	dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> +	bnxt_qplib_destroy_ah(&rdev->qplib_res,
> +			      &gsi_sah->qplib_ah,
> +			      true);
> +	bnxt_qplib_clean_qp(&qp->qplib_qp);
> +
> +	dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> +	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> +	if (rc) {
> +		dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> +		goto fail;
> +	}
> +	bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> +
> +	kfree(rdev->gsi_ctx.sqp_tbl);
> +	kfree(gsi_sah);
> +	kfree(gsi_sqp);
> +	rdev->gsi_ctx.gsi_sqp = NULL;
> +	rdev->gsi_ctx.gsi_sah = NULL;
> +	rdev->gsi_ctx.sqp_tbl = NULL;
> +
> +	return 0;
> +fail:
> +	mutex_lock(&rdev->qp_lock);
> +	list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> +	atomic_inc(&rdev->qp_count);
> +	mutex_unlock(&rdev->qp_lock);
> +	return rc;

This error unwind approach looks racy. destroy is not allowed to
fail, so why all this mess?

>  /* Queue Pairs */
>  int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
>  {
> @@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
>  	unsigned int flags;
>  	int rc;
>  
> +	mutex_lock(&rdev->qp_lock);
> +	list_del(&qp->list);
> +	atomic_dec(&rdev->qp_count);
> +	mutex_unlock(&rdev->qp_lock);
>  	bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
>  	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
>  	if (rc) {
>  		dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
> +		mutex_lock(&rdev->qp_lock);
> +		list_add_tail(&qp->list, &rdev->qp_list);
> +		atomic_inc(&rdev->qp_count);
> +		mutex_unlock(&rdev->qp_lock);
>  		return rc;
>  	}

More..

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-24  5:52 ` [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer Devesh Sharma
@ 2020-01-25 18:03   ` Jason Gunthorpe
  2020-01-27  7:39     ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-25 18:03 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, dledford

On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
>  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
>  {
> +	struct bnxt_qplib_chip_ctx *chip_ctx;
> +
> +	if (!rdev->chip_ctx)
> +		return;
> +	chip_ctx = rdev->chip_ctx;
> +	rdev->chip_ctx = NULL;
>  	rdev->rcfw.res = NULL;
>  	rdev->qplib_res.cctx = NULL;
> +	kfree(chip_ctx);
>  }

Are you sure this kfree is late enough? I couldn't deduce if it was
really safe to NULL chip_ctx here.

IMHO you should free it as part of the ib device dealloc.

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 0/7] Refactor control path of bnxt_re driver
  2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
                   ` (6 preceding siblings ...)
  2020-01-24  5:52 ` [PATCH for-next 7/7] RDMA/bnxt_re: Refactor doorbell management functions Devesh Sharma
@ 2020-01-25 18:04 ` Jason Gunthorpe
  2020-01-27  7:39   ` Devesh Sharma
  7 siblings, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-25 18:04 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, dledford

On Fri, Jan 24, 2020 at 12:52:38AM -0500, Devesh Sharma wrote:
> This is the first series out of few more forthcoming series to refactor
> Broadcom's RoCE driver. This series contains patches to refactor control
> path. Since this is first series, there may be few code section which may
> look redundant or overkill but those will be taken care in future patche
> series.
> 
> These patches apply clean on tip of for-next branch.
> Each patch in this series is tested against user and kernel functionality.
> 
> Devesh Sharma (7):
>   RDMA/bnxt_re: Refactor queue pair creation code
>   RDMA/bnxt_re: Replace chip context structure with pointer
>   RDMA/bnxt_re: Refactor hardware queue memory allocation
>   RDMA/bnxt_re: Refactor net ring allocation function
>   RDMA/bnxt_re: Refactor command queue management code
>   RDMA/bnxt_re: Refactor notification queue management code
>   RDMA/bnxt_re: Refactor doorbell management functions
> 
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h    |  24 +-
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c   | 670 +++++++++++++++++++----------
>  drivers/infiniband/hw/bnxt_re/main.c       | 134 +++---
>  drivers/infiniband/hw/bnxt_re/qplib_fp.c   | 423 +++++++++---------
>  drivers/infiniband/hw/bnxt_re/qplib_fp.h   |  94 ++--
>  drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 474 ++++++++++++--------
>  drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |  85 ++--
>  drivers/infiniband/hw/bnxt_re/qplib_res.c  | 475 ++++++++++++--------
>  drivers/infiniband/hw/bnxt_re/qplib_res.h  | 145 ++++++-
>  drivers/infiniband/hw/bnxt_re/qplib_sp.c   |  52 ++-
>  10 files changed, 1579 insertions(+), 997 deletions(-)

Usually when you 'refactor' something the code gets smaller, not
larger. What is going on here?

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-25 17:03     ` Devesh Sharma
@ 2020-01-25 18:50       ` Leon Romanovsky
  2020-01-27  7:39         ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-25 18:50 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Sat, Jan 25, 2020 at 10:33:41PM +0530, Devesh Sharma wrote:
> On Fri, Jan 24, 2020 at 4:53 PM Leon Romanovsky <leon@kernel.org> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > Restructuring the bnxt_re_create_qp function. Listing below
> > > the major changes:
> > >  --Monolithic central part of create_qp where attributes are
> > >    initialized is now enclosed in one function and this new
> > >    function has few more sub-functions.
> > >  --Top level qp limit checking code moved to a function.
> > >  --GSI QP creation and GSI Shadow qp creation code is handled
> > >    in a sub function.
> > >
> > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > ---
> > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> > >  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
> > >  drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
> > >  3 files changed, 434 insertions(+), 217 deletions(-)
> > >
> >
> > Please remove dev_err/dev_dbg/dev_* prints from the driver code.
> Sure I can do that, are you suggesting to add one more patch in this series?
> I guess it should be okay to follow the hw/efa way to  have debug msgs still on.

It is ok to use ibdev_* prints, it is not ok to use dev_* prints.

Thanks

> >
> >
> > Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-24  5:52 ` [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function Devesh Sharma
@ 2020-01-26 14:29   ` Leon Romanovsky
  2020-01-27  7:40     ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-26 14:29 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, jgg, dledford

On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> Introducing a new attribute structure to reduce
> the long list of arguments passed in bnxt_re_net_ring_alloc()
> function.
>
> The caller of bnxt_re_net_ring_alloc should fill in
> the list of attributes in bnxt_re_ring_attr structure
> and then pass the pointer to the function.
>
> Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> ---
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
>  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
>  2 files changed, 45 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> index 86274f4..c736e82 100644
> --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> @@ -89,6 +89,15 @@
>
>  #define BNXT_RE_DEFAULT_ACK_DELAY	16
>
> +struct bnxt_re_ring_attr {
> +	dma_addr_t	*dma_arr;
> +	int		pages;
> +	int		type;
> +	u32		depth;
> +	u32		lrid; /* Logical ring id */
> +	u8		mode;
> +};
> +
>  struct bnxt_re_work {
>  	struct work_struct	work;
>  	unsigned long		event;
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index a966c68..648a5ea 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
>  	return rc;
>  }
>
> -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> -				  int pages, int type, u32 ring_mask,
> -				  u32 map_index, u16 *fw_ring_id)
> +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> +				  struct bnxt_re_ring_attr *ring_attr,
> +				  u16 *fw_ring_id)
>  {
>  	struct bnxt_en_dev *en_dev = rdev->en_dev;
>  	struct hwrm_ring_alloc_input req = {0};
> @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
>  	memset(&fw_msg, 0, sizeof(fw_msg));
>  	bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
>  	req.enables = 0;
> -	req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> -	if (pages > 1) {
> +	req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> +	if (ring_attr->pages > 1) {
>  		/* Page size is in log2 units */
>  		req.page_size = BNXT_PAGE_SHIFT;
>  		req.page_tbl_depth = 1;
>  	}
>  	req.fbo = 0;
>  	/* Association of ring index with doorbell index and MSIX number */
> -	req.logical_id = cpu_to_le16(map_index);
> -	req.length = cpu_to_le32(ring_mask + 1);
> -	req.ring_type = type;
> -	req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> +	req.logical_id = cpu_to_le16(ring_attr->lrid);
> +	req.length = cpu_to_le32(ring_attr->depth + 1);
> +	req.ring_type = ring_attr->type;
> +	req.int_mode = ring_attr->mode;
>  	bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
>  			    sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
>  	rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
>
>  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
>  {
> +	struct bnxt_qplib_ctx *qplib_ctx;
> +	struct bnxt_re_ring_attr rattr;
>  	int num_vec_created = 0;
> -	dma_addr_t *pg_map;
>  	int rc = 0, i;
> -	int pages;
>  	u8 type;
>
> +	memset(&rattr, 0, sizeof(rattr));

Initialize rattr to zero from the beginning and save call to memset.

>  	/* Configure and allocate resources for qplib */
>  	rdev->qplib_res.rcfw = &rdev->rcfw;
>  	rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr,
> @@ -1030,10 +1031,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
>  	if (rc)
>  		goto dealloc_res;
>
> +	qplib_ctx = &rdev->qplib_ctx;
>  	for (i = 0; i < rdev->num_msix - 1; i++) {
> -		rdev->nq[i].res = &rdev->qplib_res;
> -		rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
> -			BNXT_RE_MAX_SRQC_COUNT + 2;
> +		struct bnxt_qplib_nq *nq;
> +
> +		nq = &rdev->nq[i];
> +		nq->hwq.max_elements = (qplib_ctx->cq_count +
> +					qplib_ctx->srqc_count + 2);
>  		rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]);
>  		if (rc) {
>  			dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
> @@ -1041,12 +1045,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
>  			goto free_nq;
>  		}
>  		type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
> -		pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr;
> -		pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count;
> -		rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
> -					    BNXT_QPLIB_NQE_MAX_CNT - 1,
> -					    rdev->msix_entries[i + 1].ring_idx,
> -					    &rdev->nq[i].ring_id);
> +		rattr.dma_arr = nq->hwq.pbl[PBL_LVL_0].pg_map_arr;
> +		rattr.pages = nq->hwq.pbl[rdev->nq[i].hwq.level].pg_count;
> +		rattr.type = type;
> +		rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> +		rattr.depth = BNXT_QPLIB_NQE_MAX_CNT - 1;
> +		rattr.lrid = rdev->msix_entries[i + 1].ring_idx;
> +		rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id);
>  		if (rc) {
>  			dev_err(rdev_to_dev(rdev),
>  				"Failed to allocate NQ fw id with rc = 0x%x",
> @@ -1371,10 +1376,10 @@ static void bnxt_re_worker(struct work_struct *work)
>
>  static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
>  {
> -	dma_addr_t *pg_map;
> -	u32 db_offt, ridx;
> -	int pages, vid;
> +	struct bnxt_re_ring_attr rattr;
> +	u32 db_offt;
>  	bool locked;
> +	int vid;
>  	u8 type;
>  	int rc;
>
> @@ -1383,6 +1388,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
>  	locked = true;
>
>  	/* Registered a new RoCE device instance to netdev */
> +	memset(&rattr, 0, sizeof(rattr));

ditto

>  	rc = bnxt_re_register_netdev(rdev);
>  	if (rc) {
>  		rtnl_unlock();
> @@ -1422,12 +1428,13 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
>  	}
>
>  	type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
> -	pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
> -	pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
> -	ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
> -	rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
> -				    BNXT_QPLIB_CREQE_MAX_CNT - 1,
> -				    ridx, &rdev->rcfw.creq_ring_id);
> +	rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
> +	rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
> +	rattr.type = type;
> +	rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> +	rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1;
> +	rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
> +	rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id);
>  	if (rc) {
>  		pr_err("Failed to allocate CREQ: %#x\n", rc);
>  		goto free_rcfw;
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-25 18:50       ` Leon Romanovsky
@ 2020-01-27  7:39         ` Devesh Sharma
  2020-01-30  6:04           ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  7:39 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Sun, Jan 26, 2020 at 12:20 AM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Sat, Jan 25, 2020 at 10:33:41PM +0530, Devesh Sharma wrote:
> > On Fri, Jan 24, 2020 at 4:53 PM Leon Romanovsky <leon@kernel.org> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > > Restructuring the bnxt_re_create_qp function. Listing below
> > > > the major changes:
> > > >  --Monolithic central part of create_qp where attributes are
> > > >    initialized is now enclosed in one function and this new
> > > >    function has few more sub-functions.
> > > >  --Top level qp limit checking code moved to a function.
> > > >  --GSI QP creation and GSI Shadow qp creation code is handled
> > > >    in a sub function.
> > > >
> > > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > > ---
> > > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> > > >  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
> > > >  drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
> > > >  3 files changed, 434 insertions(+), 217 deletions(-)
> > > >
> > >
> > > Please remove dev_err/dev_dbg/dev_* prints from the driver code.
> > Sure I can do that, are you suggesting to add one more patch in this series?
> > I guess it should be okay to follow the hw/efa way to  have debug msgs still on.
>
> It is ok to use ibdev_* prints, it is not ok to use dev_* prints.
Okay, I will add a new patch to this series
>
> Thanks
>
> > >
> > >
> > > Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-25 18:03   ` Jason Gunthorpe
@ 2020-01-27  7:39     ` Devesh Sharma
  2020-01-27  8:04       ` Leon Romanovsky
  2020-01-28 20:15       ` Jason Gunthorpe
  0 siblings, 2 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  7:39 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Sat, Jan 25, 2020 at 11:33 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
> >  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> >  {
> > +     struct bnxt_qplib_chip_ctx *chip_ctx;
> > +
> > +     if (!rdev->chip_ctx)
> > +             return;
> > +     chip_ctx = rdev->chip_ctx;
> > +     rdev->chip_ctx = NULL;
> >       rdev->rcfw.res = NULL;
> >       rdev->qplib_res.cctx = NULL;
> > +     kfree(chip_ctx);
> >  }
>
> Are you sure this kfree is late enough? I couldn't deduce if it was
> really safe to NULL chip_ctx here.
With the current design its okay to free this here because
bnxt_re_destroy_chip_ctx is indeed the last deallocation performed
before ib_device_dealloc() in any exit path. Further, the call to
bnxt_re_destroy_chip_ctx is protected by rtnl.
following is the exit sequence anyewere in the driver control path
bnxt_re_ib_unreg(rdev); --->> the last deallocation in this func is
destroy_chip_ctx().
bnxt_re_remove_one(rdev); -->> this is a single line function just to
put pci device reference
bnxt_re_dev_unreg(rdev); -->> the first deallocation in this func is
ib_device_dealloc().


>
> IMHO you should free it as part of the ib device dealloc.
>
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 0/7] Refactor control path of bnxt_re driver
  2020-01-25 18:04 ` [PATCH for-next 0/7] Refactor control path of bnxt_re driver Jason Gunthorpe
@ 2020-01-27  7:39   ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  7:39 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Sat, Jan 25, 2020 at 11:34 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Fri, Jan 24, 2020 at 12:52:38AM -0500, Devesh Sharma wrote:
> > This is the first series out of few more forthcoming series to refactor
> > Broadcom's RoCE driver. This series contains patches to refactor control
> > path. Since this is first series, there may be few code section which may
> > look redundant or overkill but those will be taken care in future patche
> > series.
> >
> > These patches apply clean on tip of for-next branch.
> > Each patch in this series is tested against user and kernel functionality.
> >
> > Devesh Sharma (7):
> >   RDMA/bnxt_re: Refactor queue pair creation code
> >   RDMA/bnxt_re: Replace chip context structure with pointer
> >   RDMA/bnxt_re: Refactor hardware queue memory allocation
> >   RDMA/bnxt_re: Refactor net ring allocation function
> >   RDMA/bnxt_re: Refactor command queue management code
> >   RDMA/bnxt_re: Refactor notification queue management code
> >   RDMA/bnxt_re: Refactor doorbell management functions
> >
> >  drivers/infiniband/hw/bnxt_re/bnxt_re.h    |  24 +-
> >  drivers/infiniband/hw/bnxt_re/ib_verbs.c   | 670 +++++++++++++++++++----------
> >  drivers/infiniband/hw/bnxt_re/main.c       | 134 +++---
> >  drivers/infiniband/hw/bnxt_re/qplib_fp.c   | 423 +++++++++---------
> >  drivers/infiniband/hw/bnxt_re/qplib_fp.h   |  94 ++--
> >  drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 474 ++++++++++++--------
> >  drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |  85 ++--
> >  drivers/infiniband/hw/bnxt_re/qplib_res.c  | 475 ++++++++++++--------
> >  drivers/infiniband/hw/bnxt_re/qplib_res.h  | 145 ++++++-
> >  drivers/infiniband/hw/bnxt_re/qplib_sp.c   |  52 ++-
> >  10 files changed, 1579 insertions(+), 997 deletions(-)
>
> Usually when you 'refactor' something the code gets smaller, not
> larger. What is going on here?
I agree with this fact however this series is adding object attribute
structures at various places and the attribute initialization before
object creation is adding up code lines.
>
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-26 14:29   ` Leon Romanovsky
@ 2020-01-27  7:40     ` Devesh Sharma
  2020-01-27  8:02       ` Leon Romanovsky
  2020-01-28  0:35       ` Jason Gunthorpe
  0 siblings, 2 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  7:40 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Sun, Jan 26, 2020 at 7:59 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> > Introducing a new attribute structure to reduce
> > the long list of arguments passed in bnxt_re_net_ring_alloc()
> > function.
> >
> > The caller of bnxt_re_net_ring_alloc should fill in
> > the list of attributes in bnxt_re_ring_attr structure
> > and then pass the pointer to the function.
> >
> > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > ---
> >  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
> >  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
> >  2 files changed, 45 insertions(+), 29 deletions(-)
> >
> > diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > index 86274f4..c736e82 100644
> > --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > @@ -89,6 +89,15 @@
> >
> >  #define BNXT_RE_DEFAULT_ACK_DELAY    16
> >
> > +struct bnxt_re_ring_attr {
> > +     dma_addr_t      *dma_arr;
> > +     int             pages;
> > +     int             type;
> > +     u32             depth;
> > +     u32             lrid; /* Logical ring id */
> > +     u8              mode;
> > +};
> > +
> >  struct bnxt_re_work {
> >       struct work_struct      work;
> >       unsigned long           event;
> > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> > index a966c68..648a5ea 100644
> > --- a/drivers/infiniband/hw/bnxt_re/main.c
> > +++ b/drivers/infiniband/hw/bnxt_re/main.c
> > @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
> >       return rc;
> >  }
> >
> > -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > -                               int pages, int type, u32 ring_mask,
> > -                               u32 map_index, u16 *fw_ring_id)
> > +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> > +                               struct bnxt_re_ring_attr *ring_attr,
> > +                               u16 *fw_ring_id)
> >  {
> >       struct bnxt_en_dev *en_dev = rdev->en_dev;
> >       struct hwrm_ring_alloc_input req = {0};
> > @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> >       memset(&fw_msg, 0, sizeof(fw_msg));
> >       bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
> >       req.enables = 0;
> > -     req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> > -     if (pages > 1) {
> > +     req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> > +     if (ring_attr->pages > 1) {
> >               /* Page size is in log2 units */
> >               req.page_size = BNXT_PAGE_SHIFT;
> >               req.page_tbl_depth = 1;
> >       }
> >       req.fbo = 0;
> >       /* Association of ring index with doorbell index and MSIX number */
> > -     req.logical_id = cpu_to_le16(map_index);
> > -     req.length = cpu_to_le32(ring_mask + 1);
> > -     req.ring_type = type;
> > -     req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > +     req.logical_id = cpu_to_le16(ring_attr->lrid);
> > +     req.length = cpu_to_le32(ring_attr->depth + 1);
> > +     req.ring_type = ring_attr->type;
> > +     req.int_mode = ring_attr->mode;
> >       bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
> >                           sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
> >       rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> > @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
> >
> >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> >  {
> > +     struct bnxt_qplib_ctx *qplib_ctx;
> > +     struct bnxt_re_ring_attr rattr;
> >       int num_vec_created = 0;
> > -     dma_addr_t *pg_map;
> >       int rc = 0, i;
> > -     int pages;
> >       u8 type;
> >
> > +     memset(&rattr, 0, sizeof(rattr));
>
> Initialize rattr to zero from the beginning and save call to memset.
I moved from static initialization to memset due to some sparse/smatch
warnings, rattr has a "pointer member".

>
> >       /* Configure and allocate resources for qplib */
> >       rdev->qplib_res.rcfw = &rdev->rcfw;
> >       rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr,
> > @@ -1030,10 +1031,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> >       if (rc)
> >               goto dealloc_res;
> >
> > +     qplib_ctx = &rdev->qplib_ctx;
> >       for (i = 0; i < rdev->num_msix - 1; i++) {
> > -             rdev->nq[i].res = &rdev->qplib_res;
> > -             rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
> > -                     BNXT_RE_MAX_SRQC_COUNT + 2;
> > +             struct bnxt_qplib_nq *nq;
> > +
> > +             nq = &rdev->nq[i];
> > +             nq->hwq.max_elements = (qplib_ctx->cq_count +
> > +                                     qplib_ctx->srqc_count + 2);
> >               rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]);
> >               if (rc) {
> >                       dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
> > @@ -1041,12 +1045,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> >                       goto free_nq;
> >               }
> >               type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
> > -             pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr;
> > -             pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count;
> > -             rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
> > -                                         BNXT_QPLIB_NQE_MAX_CNT - 1,
> > -                                         rdev->msix_entries[i + 1].ring_idx,
> > -                                         &rdev->nq[i].ring_id);
> > +             rattr.dma_arr = nq->hwq.pbl[PBL_LVL_0].pg_map_arr;
> > +             rattr.pages = nq->hwq.pbl[rdev->nq[i].hwq.level].pg_count;
> > +             rattr.type = type;
> > +             rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > +             rattr.depth = BNXT_QPLIB_NQE_MAX_CNT - 1;
> > +             rattr.lrid = rdev->msix_entries[i + 1].ring_idx;
> > +             rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id);
> >               if (rc) {
> >                       dev_err(rdev_to_dev(rdev),
> >                               "Failed to allocate NQ fw id with rc = 0x%x",
> > @@ -1371,10 +1376,10 @@ static void bnxt_re_worker(struct work_struct *work)
> >
> >  static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
> >  {
> > -     dma_addr_t *pg_map;
> > -     u32 db_offt, ridx;
> > -     int pages, vid;
> > +     struct bnxt_re_ring_attr rattr;
> > +     u32 db_offt;
> >       bool locked;
> > +     int vid;
> >       u8 type;
> >       int rc;
> >
> > @@ -1383,6 +1388,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
> >       locked = true;
> >
> >       /* Registered a new RoCE device instance to netdev */
> > +     memset(&rattr, 0, sizeof(rattr));
>
> ditto
>
> >       rc = bnxt_re_register_netdev(rdev);
> >       if (rc) {
> >               rtnl_unlock();
> > @@ -1422,12 +1428,13 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
> >       }
> >
> >       type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
> > -     pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
> > -     pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
> > -     ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
> > -     rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type,
> > -                                 BNXT_QPLIB_CREQE_MAX_CNT - 1,
> > -                                 ridx, &rdev->rcfw.creq_ring_id);
> > +     rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr;
> > +     rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count;
> > +     rattr.type = type;
> > +     rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > +     rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1;
> > +     rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx;
> > +     rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id);
> >       if (rc) {
> >               pr_err("Failed to allocate CREQ: %#x\n", rc);
> >               goto free_rcfw;
> > --
> > 1.8.3.1
> >

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27  7:40     ` Devesh Sharma
@ 2020-01-27  8:02       ` Leon Romanovsky
  2020-01-27 11:25         ` Devesh Sharma
  2020-01-28  0:35       ` Jason Gunthorpe
  1 sibling, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-27  8:02 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> On Sun, Jan 26, 2020 at 7:59 PM Leon Romanovsky <leon@kernel.org> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> > > Introducing a new attribute structure to reduce
> > > the long list of arguments passed in bnxt_re_net_ring_alloc()
> > > function.
> > >
> > > The caller of bnxt_re_net_ring_alloc should fill in
> > > the list of attributes in bnxt_re_ring_attr structure
> > > and then pass the pointer to the function.
> > >
> > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > ---
> > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
> > >  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
> > >  2 files changed, 45 insertions(+), 29 deletions(-)
> > >
> > > diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > index 86274f4..c736e82 100644
> > > --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > @@ -89,6 +89,15 @@
> > >
> > >  #define BNXT_RE_DEFAULT_ACK_DELAY    16
> > >
> > > +struct bnxt_re_ring_attr {
> > > +     dma_addr_t      *dma_arr;
> > > +     int             pages;
> > > +     int             type;
> > > +     u32             depth;
> > > +     u32             lrid; /* Logical ring id */
> > > +     u8              mode;
> > > +};
> > > +
> > >  struct bnxt_re_work {
> > >       struct work_struct      work;
> > >       unsigned long           event;
> > > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> > > index a966c68..648a5ea 100644
> > > --- a/drivers/infiniband/hw/bnxt_re/main.c
> > > +++ b/drivers/infiniband/hw/bnxt_re/main.c
> > > @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
> > >       return rc;
> > >  }
> > >
> > > -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > -                               int pages, int type, u32 ring_mask,
> > > -                               u32 map_index, u16 *fw_ring_id)
> > > +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> > > +                               struct bnxt_re_ring_attr *ring_attr,
> > > +                               u16 *fw_ring_id)
> > >  {
> > >       struct bnxt_en_dev *en_dev = rdev->en_dev;
> > >       struct hwrm_ring_alloc_input req = {0};
> > > @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > >       memset(&fw_msg, 0, sizeof(fw_msg));
> > >       bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
> > >       req.enables = 0;
> > > -     req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> > > -     if (pages > 1) {
> > > +     req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> > > +     if (ring_attr->pages > 1) {
> > >               /* Page size is in log2 units */
> > >               req.page_size = BNXT_PAGE_SHIFT;
> > >               req.page_tbl_depth = 1;
> > >       }
> > >       req.fbo = 0;
> > >       /* Association of ring index with doorbell index and MSIX number */
> > > -     req.logical_id = cpu_to_le16(map_index);
> > > -     req.length = cpu_to_le32(ring_mask + 1);
> > > -     req.ring_type = type;
> > > -     req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > > +     req.logical_id = cpu_to_le16(ring_attr->lrid);
> > > +     req.length = cpu_to_le32(ring_attr->depth + 1);
> > > +     req.ring_type = ring_attr->type;
> > > +     req.int_mode = ring_attr->mode;
> > >       bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
> > >                           sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
> > >       rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> > > @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
> > >
> > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > >  {
> > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > +     struct bnxt_re_ring_attr rattr;
> > >       int num_vec_created = 0;
> > > -     dma_addr_t *pg_map;
> > >       int rc = 0, i;
> > > -     int pages;
> > >       u8 type;
> > >
> > > +     memset(&rattr, 0, sizeof(rattr));
> >
> > Initialize rattr to zero from the beginning and save call to memset.
> I moved from static initialization to memset due to some sparse/smatch
> warnings, rattr has a "pointer member".

Can you share the error and tool version, because it is pretty common
way to initialize variables? Also "= {0}" would solve your checker
warning.

Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-27  7:39     ` Devesh Sharma
@ 2020-01-27  8:04       ` Leon Romanovsky
  2020-01-27 11:17         ` Devesh Sharma
  2020-01-28 20:15       ` Jason Gunthorpe
  1 sibling, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-27  8:04 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Jason Gunthorpe, linux-rdma, dledford

On Mon, Jan 27, 2020 at 01:09:46PM +0530, Devesh Sharma wrote:
> On Sat, Jan 25, 2020 at 11:33 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
> > >  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> > >  {
> > > +     struct bnxt_qplib_chip_ctx *chip_ctx;
> > > +
> > > +     if (!rdev->chip_ctx)
> > > +             return;
> > > +     chip_ctx = rdev->chip_ctx;
> > > +     rdev->chip_ctx = NULL;
> > >       rdev->rcfw.res = NULL;
> > >       rdev->qplib_res.cctx = NULL;
> > > +     kfree(chip_ctx);
> > >  }
> >
> > Are you sure this kfree is late enough? I couldn't deduce if it was
> > really safe to NULL chip_ctx here.
> With the current design its okay to free this here because
> bnxt_re_destroy_chip_ctx is indeed the last deallocation performed
> before ib_device_dealloc() in any exit path. Further, the call to
> bnxt_re_destroy_chip_ctx is protected by rtnl.

??? Why does device destroy path need global lock to already existing
protection from ib_core?

Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-25 17:46   ` Jason Gunthorpe
@ 2020-01-27  8:13     ` Devesh Sharma
  2020-01-27  8:16       ` Devesh Sharma
                         ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  8:13 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > +{
> > +     struct bnxt_re_qp *gsi_sqp;
> > +     struct bnxt_re_ah *gsi_sah;
> > +     struct bnxt_re_dev *rdev;
> > +     int rc = 0;
> > +
> > +     rdev = qp->rdev;
> > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > +
> > +     /* remove from active qp list */
> > +     mutex_lock(&rdev->qp_lock);
> > +     list_del(&gsi_sqp->list);
> > +     atomic_dec(&rdev->qp_count);
> > +     mutex_unlock(&rdev->qp_lock);
> > +
> > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > +                           &gsi_sah->qplib_ah,
> > +                           true);
> > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > +
> > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > +     if (rc) {
> > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > +             goto fail;
> > +     }
> > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > +
> > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > +     kfree(gsi_sah);
> > +     kfree(gsi_sqp);
> > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > +     rdev->gsi_ctx.gsi_sah = NULL;
> > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > +
> > +     return 0;
> > +fail:
> > +     mutex_lock(&rdev->qp_lock);
> > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > +     atomic_inc(&rdev->qp_count);
> > +     mutex_unlock(&rdev->qp_lock);
> > +     return rc;
>
> This error unwind approach looks racy. destroy is not allowed to
> fail, so why all this mess?
True, the unwind is not required, even if the driver wants to keep it
for debugging purpose, the zombie resource would give rise to
confusion.
>
> >  /* Queue Pairs */
> >  int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> >  {
> > @@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> >       unsigned int flags;
> >       int rc;
> >
> > +     mutex_lock(&rdev->qp_lock);
> > +     list_del(&qp->list);
> > +     atomic_dec(&rdev->qp_count);
> > +     mutex_unlock(&rdev->qp_lock);
> >       bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
> >       rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
> >       if (rc) {
> >               dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
> > +             mutex_lock(&rdev->qp_lock);
> > +             list_add_tail(&qp->list, &rdev->qp_list);
> > +             atomic_inc(&rdev->qp_count);
> > +             mutex_unlock(&rdev->qp_lock);
> >               return rc;
> >       }
>
> More..
Let me see if I can remove it in this series, else future series would
remove it.
>
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  8:13     ` Devesh Sharma
@ 2020-01-27  8:16       ` Devesh Sharma
  2020-01-27  9:27         ` Leon Romanovsky
  2020-01-27  9:26       ` Leon Romanovsky
  2020-01-30  6:04       ` Devesh Sharma
  2 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27  8:16 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Mon, Jan 27, 2020 at 1:43 PM Devesh Sharma
<devesh.sharma@broadcom.com> wrote:
>
> On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > > +{
> > > +     struct bnxt_re_qp *gsi_sqp;
> > > +     struct bnxt_re_ah *gsi_sah;
> > > +     struct bnxt_re_dev *rdev;
> > > +     int rc = 0;
> > > +
> > > +     rdev = qp->rdev;
> > > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > > +
> > > +     /* remove from active qp list */
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_del(&gsi_sqp->list);
> > > +     atomic_dec(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > > +                           &gsi_sah->qplib_ah,
> > > +                           true);
> > > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +     if (rc) {
> > > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > > +             goto fail;
> > > +     }
> > > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +
> > > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > > +     kfree(gsi_sah);
> > > +     kfree(gsi_sqp);
> > > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > > +     rdev->gsi_ctx.gsi_sah = NULL;
> > > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > > +
> > > +     return 0;
> > > +fail:
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > > +     atomic_inc(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +     return rc;
> >
> > This error unwind approach looks racy. destroy is not allowed to
> > fail, so why all this mess?
> True, the unwind is not required, even if the driver wants to keep it
> for debugging purpose, the zombie resource would give rise to
> confusion.
> >
> > >  /* Queue Pairs */
> > >  int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > >  {
> > > @@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > >       unsigned int flags;
> > >       int rc;
> > >
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_del(&qp->list);
> > > +     atomic_dec(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > >       bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
> > >       rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
> > >       if (rc) {
> > >               dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
> > > +             mutex_lock(&rdev->qp_lock);
> > > +             list_add_tail(&qp->list, &rdev->qp_list);
> > > +             atomic_inc(&rdev->qp_count);
> > > +             mutex_unlock(&rdev->qp_lock);
> > >               return rc;
> > >       }
> >
> > More..
> Let me see if I can remove it in this series, else future series would
> remove it.
> >
> > Jason

At the top level, if provider driver is so keen on returning success
in any case, should we change the return type to void of
ib_destroy_xx() hooks?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  8:13     ` Devesh Sharma
  2020-01-27  8:16       ` Devesh Sharma
@ 2020-01-27  9:26       ` Leon Romanovsky
  2020-01-27 11:31         ` Devesh Sharma
  2020-01-30  6:04       ` Devesh Sharma
  2 siblings, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-27  9:26 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Jason Gunthorpe, linux-rdma, dledford

On Mon, Jan 27, 2020 at 01:43:51PM +0530, Devesh Sharma wrote:
> On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > > +{
> > > +     struct bnxt_re_qp *gsi_sqp;
> > > +     struct bnxt_re_ah *gsi_sah;
> > > +     struct bnxt_re_dev *rdev;
> > > +     int rc = 0;
> > > +
> > > +     rdev = qp->rdev;
> > > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > > +
> > > +     /* remove from active qp list */
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_del(&gsi_sqp->list);
> > > +     atomic_dec(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > > +                           &gsi_sah->qplib_ah,
> > > +                           true);
> > > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +     if (rc) {
> > > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > > +             goto fail;
> > > +     }
> > > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +
> > > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > > +     kfree(gsi_sah);
> > > +     kfree(gsi_sqp);
> > > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > > +     rdev->gsi_ctx.gsi_sah = NULL;
> > > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > > +
> > > +     return 0;
> > > +fail:
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > > +     atomic_inc(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +     return rc;
> >
> > This error unwind approach looks racy. destroy is not allowed to
> > fail, so why all this mess?
> True, the unwind is not required, even if the driver wants to keep it
> for debugging purpose, the zombie resource would give rise to
> confusion.

Jason doesn't suggest to leave zombie resources, but to clean everything
without any relation to returned status from bnxt_qplib_destroy_qp().

Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  8:16       ` Devesh Sharma
@ 2020-01-27  9:27         ` Leon Romanovsky
  0 siblings, 0 replies; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-27  9:27 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Jason Gunthorpe, linux-rdma, dledford

On Mon, Jan 27, 2020 at 01:46:13PM +0530, Devesh Sharma wrote:
> On Mon, Jan 27, 2020 at 1:43 PM Devesh Sharma
> <devesh.sharma@broadcom.com> wrote:
> >
> > On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > > > +{
> > > > +     struct bnxt_re_qp *gsi_sqp;
> > > > +     struct bnxt_re_ah *gsi_sah;
> > > > +     struct bnxt_re_dev *rdev;
> > > > +     int rc = 0;
> > > > +
> > > > +     rdev = qp->rdev;
> > > > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > > > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > > > +
> > > > +     /* remove from active qp list */
> > > > +     mutex_lock(&rdev->qp_lock);
> > > > +     list_del(&gsi_sqp->list);
> > > > +     atomic_dec(&rdev->qp_count);
> > > > +     mutex_unlock(&rdev->qp_lock);
> > > > +
> > > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > > > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > > > +                           &gsi_sah->qplib_ah,
> > > > +                           true);
> > > > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > > > +
> > > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > > > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > > +     if (rc) {
> > > > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > > > +             goto fail;
> > > > +     }
> > > > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > > +
> > > > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > > > +     kfree(gsi_sah);
> > > > +     kfree(gsi_sqp);
> > > > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > > > +     rdev->gsi_ctx.gsi_sah = NULL;
> > > > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > > > +
> > > > +     return 0;
> > > > +fail:
> > > > +     mutex_lock(&rdev->qp_lock);
> > > > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > > > +     atomic_inc(&rdev->qp_count);
> > > > +     mutex_unlock(&rdev->qp_lock);
> > > > +     return rc;
> > >
> > > This error unwind approach looks racy. destroy is not allowed to
> > > fail, so why all this mess?
> > True, the unwind is not required, even if the driver wants to keep it
> > for debugging purpose, the zombie resource would give rise to
> > confusion.
> > >
> > > >  /* Queue Pairs */
> > > >  int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > > >  {
> > > > @@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > > >       unsigned int flags;
> > > >       int rc;
> > > >
> > > > +     mutex_lock(&rdev->qp_lock);
> > > > +     list_del(&qp->list);
> > > > +     atomic_dec(&rdev->qp_count);
> > > > +     mutex_unlock(&rdev->qp_lock);
> > > >       bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
> > > >       rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
> > > >       if (rc) {
> > > >               dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
> > > > +             mutex_lock(&rdev->qp_lock);
> > > > +             list_add_tail(&qp->list, &rdev->qp_list);
> > > > +             atomic_inc(&rdev->qp_count);
> > > > +             mutex_unlock(&rdev->qp_lock);
> > > >               return rc;
> > > >       }
> > >
> > > More..
> > Let me see if I can remove it in this series, else future series would
> > remove it.
> > >
> > > Jason
>
> At the top level, if provider driver is so keen on returning success
> in any case, should we change the return type to void of
> ib_destroy_xx() hooks?

We are doing it but in extremely slow way. Patches are welcomed.

Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-27  8:04       ` Leon Romanovsky
@ 2020-01-27 11:17         ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27 11:17 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: Jason Gunthorpe, linux-rdma, dledford

On Mon, Jan 27, 2020 at 1:34 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Mon, Jan 27, 2020 at 01:09:46PM +0530, Devesh Sharma wrote:
> > On Sat, Jan 25, 2020 at 11:33 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
> > > >  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> > > >  {
> > > > +     struct bnxt_qplib_chip_ctx *chip_ctx;
> > > > +
> > > > +     if (!rdev->chip_ctx)
> > > > +             return;
> > > > +     chip_ctx = rdev->chip_ctx;
> > > > +     rdev->chip_ctx = NULL;
> > > >       rdev->rcfw.res = NULL;
> > > >       rdev->qplib_res.cctx = NULL;
> > > > +     kfree(chip_ctx);
> > > >  }
> > >
> > > Are you sure this kfree is late enough? I couldn't deduce if it was
> > > really safe to NULL chip_ctx here.
> > With the current design its okay to free this here because
> > bnxt_re_destroy_chip_ctx is indeed the last deallocation performed
> > before ib_device_dealloc() in any exit path. Further, the call to
> > bnxt_re_destroy_chip_ctx is protected by rtnl.
>
> ??? Why does device destroy path need global lock to already existing
> protection from ib_core?
Oh! probably I confused you, What I meant to say was exit path is
executed under netdev-notifier context which already holds the lock.
RoCE driver is not taking that lock explicitly.
>
> Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27  8:02       ` Leon Romanovsky
@ 2020-01-27 11:25         ` Devesh Sharma
  2020-01-27 12:44           ` Leon Romanovsky
  0 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27 11:25 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Mon, Jan 27, 2020 at 1:32 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > On Sun, Jan 26, 2020 at 7:59 PM Leon Romanovsky <leon@kernel.org> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> > > > Introducing a new attribute structure to reduce
> > > > the long list of arguments passed in bnxt_re_net_ring_alloc()
> > > > function.
> > > >
> > > > The caller of bnxt_re_net_ring_alloc should fill in
> > > > the list of attributes in bnxt_re_ring_attr structure
> > > > and then pass the pointer to the function.
> > > >
> > > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > > ---
> > > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
> > > >  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
> > > >  2 files changed, 45 insertions(+), 29 deletions(-)
> > > >
> > > > diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > index 86274f4..c736e82 100644
> > > > --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > @@ -89,6 +89,15 @@
> > > >
> > > >  #define BNXT_RE_DEFAULT_ACK_DELAY    16
> > > >
> > > > +struct bnxt_re_ring_attr {
> > > > +     dma_addr_t      *dma_arr;
> > > > +     int             pages;
> > > > +     int             type;
> > > > +     u32             depth;
> > > > +     u32             lrid; /* Logical ring id */
> > > > +     u8              mode;
> > > > +};
> > > > +
> > > >  struct bnxt_re_work {
> > > >       struct work_struct      work;
> > > >       unsigned long           event;
> > > > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> > > > index a966c68..648a5ea 100644
> > > > --- a/drivers/infiniband/hw/bnxt_re/main.c
> > > > +++ b/drivers/infiniband/hw/bnxt_re/main.c
> > > > @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
> > > >       return rc;
> > > >  }
> > > >
> > > > -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > > -                               int pages, int type, u32 ring_mask,
> > > > -                               u32 map_index, u16 *fw_ring_id)
> > > > +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> > > > +                               struct bnxt_re_ring_attr *ring_attr,
> > > > +                               u16 *fw_ring_id)
> > > >  {
> > > >       struct bnxt_en_dev *en_dev = rdev->en_dev;
> > > >       struct hwrm_ring_alloc_input req = {0};
> > > > @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > >       memset(&fw_msg, 0, sizeof(fw_msg));
> > > >       bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
> > > >       req.enables = 0;
> > > > -     req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> > > > -     if (pages > 1) {
> > > > +     req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> > > > +     if (ring_attr->pages > 1) {
> > > >               /* Page size is in log2 units */
> > > >               req.page_size = BNXT_PAGE_SHIFT;
> > > >               req.page_tbl_depth = 1;
> > > >       }
> > > >       req.fbo = 0;
> > > >       /* Association of ring index with doorbell index and MSIX number */
> > > > -     req.logical_id = cpu_to_le16(map_index);
> > > > -     req.length = cpu_to_le32(ring_mask + 1);
> > > > -     req.ring_type = type;
> > > > -     req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > > > +     req.logical_id = cpu_to_le16(ring_attr->lrid);
> > > > +     req.length = cpu_to_le32(ring_attr->depth + 1);
> > > > +     req.ring_type = ring_attr->type;
> > > > +     req.int_mode = ring_attr->mode;
> > > >       bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
> > > >                           sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
> > > >       rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> > > > @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
> > > >
> > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > >  {
> > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > +     struct bnxt_re_ring_attr rattr;
> > > >       int num_vec_created = 0;
> > > > -     dma_addr_t *pg_map;
> > > >       int rc = 0, i;
> > > > -     int pages;
> > > >       u8 type;
> > > >
> > > > +     memset(&rattr, 0, sizeof(rattr));
> > >
> > > Initialize rattr to zero from the beginning and save call to memset.
> > I moved from static initialization to memset due to some sparse/smatch
> > warnings, rattr has a "pointer member".
>
> Can you share the error and tool version, because it is pretty common
> way to initialize variables? Also "= {0}" would solve your checker
> warning.
I will have to duplicate it again to report the precise warning but
based on my memory, sparse or smatch was shouting about "pointer
converted to integer without cast"
I guess that was because rattr.dma_arr is a pointer and static
initialization was assigning value 0 while it should had been NULL. If
you insist I would send you exact warning msg and tool-version-number
soon.
>
> Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  9:26       ` Leon Romanovsky
@ 2020-01-27 11:31         ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27 11:31 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: Jason Gunthorpe, linux-rdma, dledford

On Mon, Jan 27, 2020 at 2:56 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Mon, Jan 27, 2020 at 01:43:51PM +0530, Devesh Sharma wrote:
> > On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > > > +{
> > > > +     struct bnxt_re_qp *gsi_sqp;
> > > > +     struct bnxt_re_ah *gsi_sah;
> > > > +     struct bnxt_re_dev *rdev;
> > > > +     int rc = 0;
> > > > +
> > > > +     rdev = qp->rdev;
> > > > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > > > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > > > +
> > > > +     /* remove from active qp list */
> > > > +     mutex_lock(&rdev->qp_lock);
> > > > +     list_del(&gsi_sqp->list);
> > > > +     atomic_dec(&rdev->qp_count);
> > > > +     mutex_unlock(&rdev->qp_lock);
> > > > +
> > > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > > > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > > > +                           &gsi_sah->qplib_ah,
> > > > +                           true);
> > > > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > > > +
> > > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > > > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > > +     if (rc) {
> > > > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > > > +             goto fail;
> > > > +     }
> > > > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > > +
> > > > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > > > +     kfree(gsi_sah);
> > > > +     kfree(gsi_sqp);
> > > > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > > > +     rdev->gsi_ctx.gsi_sah = NULL;
> > > > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > > > +
> > > > +     return 0;
> > > > +fail:
> > > > +     mutex_lock(&rdev->qp_lock);
> > > > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > > > +     atomic_inc(&rdev->qp_count);
> > > > +     mutex_unlock(&rdev->qp_lock);
> > > > +     return rc;
> > >
> > > This error unwind approach looks racy. destroy is not allowed to
> > > fail, so why all this mess?
> > True, the unwind is not required, even if the driver wants to keep it
> > for debugging purpose, the zombie resource would give rise to
> > confusion.
>
> Jason doesn't suggest to leave zombie resources, but to clean everything
> without any relation to returned status from bnxt_qplib_destroy_qp().
Yeah, let me complete my statement, "zombie resources should go, no
need to have them on the list even if destroy-object firmware command
has failed."
>
> Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27 11:25         ` Devesh Sharma
@ 2020-01-27 12:44           ` Leon Romanovsky
  2020-01-27 14:14             ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Leon Romanovsky @ 2020-01-27 12:44 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Mon, Jan 27, 2020 at 04:55:07PM +0530, Devesh Sharma wrote:
> On Mon, Jan 27, 2020 at 1:32 PM Leon Romanovsky <leon@kernel.org> wrote:
> >
> > On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > > On Sun, Jan 26, 2020 at 7:59 PM Leon Romanovsky <leon@kernel.org> wrote:
> > > >
> > > > On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> > > > > Introducing a new attribute structure to reduce
> > > > > the long list of arguments passed in bnxt_re_net_ring_alloc()
> > > > > function.
> > > > >
> > > > > The caller of bnxt_re_net_ring_alloc should fill in
> > > > > the list of attributes in bnxt_re_ring_attr structure
> > > > > and then pass the pointer to the function.
> > > > >
> > > > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > > > ---
> > > > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
> > > > >  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
> > > > >  2 files changed, 45 insertions(+), 29 deletions(-)
> > > > >
> > > > > diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > index 86274f4..c736e82 100644
> > > > > --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > @@ -89,6 +89,15 @@
> > > > >
> > > > >  #define BNXT_RE_DEFAULT_ACK_DELAY    16
> > > > >
> > > > > +struct bnxt_re_ring_attr {
> > > > > +     dma_addr_t      *dma_arr;
> > > > > +     int             pages;
> > > > > +     int             type;
> > > > > +     u32             depth;
> > > > > +     u32             lrid; /* Logical ring id */
> > > > > +     u8              mode;
> > > > > +};
> > > > > +
> > > > >  struct bnxt_re_work {
> > > > >       struct work_struct      work;
> > > > >       unsigned long           event;
> > > > > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> > > > > index a966c68..648a5ea 100644
> > > > > --- a/drivers/infiniband/hw/bnxt_re/main.c
> > > > > +++ b/drivers/infiniband/hw/bnxt_re/main.c
> > > > > @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
> > > > >       return rc;
> > > > >  }
> > > > >
> > > > > -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > > > -                               int pages, int type, u32 ring_mask,
> > > > > -                               u32 map_index, u16 *fw_ring_id)
> > > > > +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> > > > > +                               struct bnxt_re_ring_attr *ring_attr,
> > > > > +                               u16 *fw_ring_id)
> > > > >  {
> > > > >       struct bnxt_en_dev *en_dev = rdev->en_dev;
> > > > >       struct hwrm_ring_alloc_input req = {0};
> > > > > @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > > >       memset(&fw_msg, 0, sizeof(fw_msg));
> > > > >       bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
> > > > >       req.enables = 0;
> > > > > -     req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> > > > > -     if (pages > 1) {
> > > > > +     req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> > > > > +     if (ring_attr->pages > 1) {
> > > > >               /* Page size is in log2 units */
> > > > >               req.page_size = BNXT_PAGE_SHIFT;
> > > > >               req.page_tbl_depth = 1;
> > > > >       }
> > > > >       req.fbo = 0;
> > > > >       /* Association of ring index with doorbell index and MSIX number */
> > > > > -     req.logical_id = cpu_to_le16(map_index);
> > > > > -     req.length = cpu_to_le32(ring_mask + 1);
> > > > > -     req.ring_type = type;
> > > > > -     req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > > > > +     req.logical_id = cpu_to_le16(ring_attr->lrid);
> > > > > +     req.length = cpu_to_le32(ring_attr->depth + 1);
> > > > > +     req.ring_type = ring_attr->type;
> > > > > +     req.int_mode = ring_attr->mode;
> > > > >       bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
> > > > >                           sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
> > > > >       rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> > > > > @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
> > > > >
> > > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > > >  {
> > > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > > +     struct bnxt_re_ring_attr rattr;
> > > > >       int num_vec_created = 0;
> > > > > -     dma_addr_t *pg_map;
> > > > >       int rc = 0, i;
> > > > > -     int pages;
> > > > >       u8 type;
> > > > >
> > > > > +     memset(&rattr, 0, sizeof(rattr));
> > > >
> > > > Initialize rattr to zero from the beginning and save call to memset.
> > > I moved from static initialization to memset due to some sparse/smatch
> > > warnings, rattr has a "pointer member".
> >
> > Can you share the error and tool version, because it is pretty common
> > way to initialize variables? Also "= {0}" would solve your checker
> > warning.
> I will have to duplicate it again to report the precise warning but
> based on my memory, sparse or smatch was shouting about "pointer
> converted to integer without cast"
> I guess that was because rattr.dma_arr is a pointer and static
> initialization was assigning value 0 while it should had been NULL. If
> you insist I would send you exact warning msg and tool-version-number
> soon.

Yes, please, because NULL is 0 and has special meaning in C standard.

> >
> > Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27 12:44           ` Leon Romanovsky
@ 2020-01-27 14:14             ` Devesh Sharma
  2020-01-28 18:09               ` Jason Gunthorpe
  0 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-27 14:14 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Mon, Jan 27, 2020 at 6:14 PM Leon Romanovsky <leon@kernel.org> wrote:
>
> On Mon, Jan 27, 2020 at 04:55:07PM +0530, Devesh Sharma wrote:
> > On Mon, Jan 27, 2020 at 1:32 PM Leon Romanovsky <leon@kernel.org> wrote:
> > >
> > > On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > > > On Sun, Jan 26, 2020 at 7:59 PM Leon Romanovsky <leon@kernel.org> wrote:
> > > > >
> > > > > On Fri, Jan 24, 2020 at 12:52:42AM -0500, Devesh Sharma wrote:
> > > > > > Introducing a new attribute structure to reduce
> > > > > > the long list of arguments passed in bnxt_re_net_ring_alloc()
> > > > > > function.
> > > > > >
> > > > > > The caller of bnxt_re_net_ring_alloc should fill in
> > > > > > the list of attributes in bnxt_re_ring_attr structure
> > > > > > and then pass the pointer to the function.
> > > > > >
> > > > > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > > > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > > > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > > > > ---
> > > > > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  9 +++++
> > > > > >  drivers/infiniband/hw/bnxt_re/main.c    | 65 ++++++++++++++++++---------------
> > > > > >  2 files changed, 45 insertions(+), 29 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > > index 86274f4..c736e82 100644
> > > > > > --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > > +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> > > > > > @@ -89,6 +89,15 @@
> > > > > >
> > > > > >  #define BNXT_RE_DEFAULT_ACK_DELAY    16
> > > > > >
> > > > > > +struct bnxt_re_ring_attr {
> > > > > > +     dma_addr_t      *dma_arr;
> > > > > > +     int             pages;
> > > > > > +     int             type;
> > > > > > +     u32             depth;
> > > > > > +     u32             lrid; /* Logical ring id */
> > > > > > +     u8              mode;
> > > > > > +};
> > > > > > +
> > > > > >  struct bnxt_re_work {
> > > > > >       struct work_struct      work;
> > > > > >       unsigned long           event;
> > > > > > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> > > > > > index a966c68..648a5ea 100644
> > > > > > --- a/drivers/infiniband/hw/bnxt_re/main.c
> > > > > > +++ b/drivers/infiniband/hw/bnxt_re/main.c
> > > > > > @@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev,
> > > > > >       return rc;
> > > > > >  }
> > > > > >
> > > > > > -static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > > > > -                               int pages, int type, u32 ring_mask,
> > > > > > -                               u32 map_index, u16 *fw_ring_id)
> > > > > > +static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev,
> > > > > > +                               struct bnxt_re_ring_attr *ring_attr,
> > > > > > +                               u16 *fw_ring_id)
> > > > > >  {
> > > > > >       struct bnxt_en_dev *en_dev = rdev->en_dev;
> > > > > >       struct hwrm_ring_alloc_input req = {0};
> > > > > > @@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
> > > > > >       memset(&fw_msg, 0, sizeof(fw_msg));
> > > > > >       bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
> > > > > >       req.enables = 0;
> > > > > > -     req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
> > > > > > -     if (pages > 1) {
> > > > > > +     req.page_tbl_addr =  cpu_to_le64(ring_attr->dma_arr[0]);
> > > > > > +     if (ring_attr->pages > 1) {
> > > > > >               /* Page size is in log2 units */
> > > > > >               req.page_size = BNXT_PAGE_SHIFT;
> > > > > >               req.page_tbl_depth = 1;
> > > > > >       }
> > > > > >       req.fbo = 0;
> > > > > >       /* Association of ring index with doorbell index and MSIX number */
> > > > > > -     req.logical_id = cpu_to_le16(map_index);
> > > > > > -     req.length = cpu_to_le32(ring_mask + 1);
> > > > > > -     req.ring_type = type;
> > > > > > -     req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX;
> > > > > > +     req.logical_id = cpu_to_le16(ring_attr->lrid);
> > > > > > +     req.length = cpu_to_le32(ring_attr->depth + 1);
> > > > > > +     req.ring_type = ring_attr->type;
> > > > > > +     req.int_mode = ring_attr->mode;
> > > > > >       bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
> > > > > >                           sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
> > > > > >       rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
> > > > > > @@ -1006,12 +1006,13 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
> > > > > >
> > > > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > > > >  {
> > > > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > > > +     struct bnxt_re_ring_attr rattr;
> > > > > >       int num_vec_created = 0;
> > > > > > -     dma_addr_t *pg_map;
> > > > > >       int rc = 0, i;
> > > > > > -     int pages;
> > > > > >       u8 type;
> > > > > >
> > > > > > +     memset(&rattr, 0, sizeof(rattr));
> > > > >
> > > > > Initialize rattr to zero from the beginning and save call to memset.
> > > > I moved from static initialization to memset due to some sparse/smatch
> > > > warnings, rattr has a "pointer member".
> > >
> > > Can you share the error and tool version, because it is pretty common
> > > way to initialize variables? Also "= {0}" would solve your checker
> > > warning.
> > I will have to duplicate it again to report the precise warning but
> > based on my memory, sparse or smatch was shouting about "pointer
> > converted to integer without cast"
> > I guess that was because rattr.dma_arr is a pointer and static
> > initialization was assigning value 0 while it should had been NULL. If
> > you insist I would send you exact warning msg and tool-version-number
> > soon.
>
> Yes, please, because NULL is 0 and has special meaning in C standard.
This is what sparse warns about:
make C=2 CHECK="/data2/upstream/tools/sparse/sparse"
CF="-D__CHECK_ENDIAN__" drivers/infiniband/hw/bnxt_re/
  CHECK   drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/main.c:1010:43: warning: Using plain
integer as NULL pointer

sparse version used:
v0.6.1-131-g22978b6b
>
> > >
> > > Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27  7:40     ` Devesh Sharma
  2020-01-27  8:02       ` Leon Romanovsky
@ 2020-01-28  0:35       ` Jason Gunthorpe
  2020-01-28  2:43         ` Devesh Sharma
  1 sibling, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-28  0:35 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Leon Romanovsky, linux-rdma, Doug Ledford

On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > >  {
> > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > +     struct bnxt_re_ring_attr rattr;
> > >       int num_vec_created = 0;
> > > -     dma_addr_t *pg_map;
> > >       int rc = 0, i;
> > > -     int pages;
> > >       u8 type;
> > >
> > > +     memset(&rattr, 0, sizeof(rattr));
> >
> > Initialize rattr to zero from the beginning and save call to memset.
> I moved from static initialization to memset due to some sparse/smatch
> warnings, rattr has a "pointer member".

That is why you need to use = {} not the weird '= {0}' version

0 initializes the first member to zero and default initializes the rest
which doesn't work properly if the first member is not an integral
value.

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-28  0:35       ` Jason Gunthorpe
@ 2020-01-28  2:43         ` Devesh Sharma
  2020-01-28 18:09           ` Jason Gunthorpe
  0 siblings, 1 reply; 41+ messages in thread
From: Devesh Sharma @ 2020-01-28  2:43 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: Leon Romanovsky, linux-rdma, Doug Ledford

On Tue, Jan 28, 2020 at 6:05 AM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > >  {
> > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > +     struct bnxt_re_ring_attr rattr;
> > > >       int num_vec_created = 0;
> > > > -     dma_addr_t *pg_map;
> > > >       int rc = 0, i;
> > > > -     int pages;
> > > >       u8 type;
> > > >
> > > > +     memset(&rattr, 0, sizeof(rattr));
> > >
> > > Initialize rattr to zero from the beginning and save call to memset.
> > I moved from static initialization to memset due to some sparse/smatch
> > warnings, rattr has a "pointer member".
>
> That is why you need to use = {} not the weird '= {0}' version
>
> 0 initializes the first member to zero and default initializes the rest
> which doesn't work properly if the first member is not an integral
> value.
>
So should I remove memset(s) in v2?
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-27 14:14             ` Devesh Sharma
@ 2020-01-28 18:09               ` Jason Gunthorpe
  0 siblings, 0 replies; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-28 18:09 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Leon Romanovsky, linux-rdma, Doug Ledford

On Mon, Jan 27, 2020 at 07:44:43PM +0530, Devesh Sharma wrote:
> > > I will have to duplicate it again to report the precise warning but
> > > based on my memory, sparse or smatch was shouting about "pointer
> > > converted to integer without cast"
> > > I guess that was because rattr.dma_arr is a pointer and static
> > > initialization was assigning value 0 while it should had been NULL. If
> > > you insist I would send you exact warning msg and tool-version-number
> > > soon.
> >
> > Yes, please, because NULL is 0 and has special meaning in C standard.
> This is what sparse warns about:
> make C=2 CHECK="/data2/upstream/tools/sparse/sparse"
> CF="-D__CHECK_ENDIAN__" drivers/infiniband/hw/bnxt_re/
>   CHECK   drivers/infiniband/hw/bnxt_re/main.c
> drivers/infiniband/hw/bnxt_re/main.c:1010:43: warning: Using plain
> integer as NULL pointer

Yes, this is entirely expected, you should not use the {0} pattern, it
is not reliable. '= {}' is preferred.

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-28  2:43         ` Devesh Sharma
@ 2020-01-28 18:09           ` Jason Gunthorpe
  2020-01-29  8:29             ` Devesh Sharma
  0 siblings, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-28 18:09 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: Leon Romanovsky, linux-rdma, Doug Ledford

On Tue, Jan 28, 2020 at 08:13:31AM +0530, Devesh Sharma wrote:
> On Tue, Jan 28, 2020 at 6:05 AM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > > >  {
> > > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > > +     struct bnxt_re_ring_attr rattr;
> > > > >       int num_vec_created = 0;
> > > > > -     dma_addr_t *pg_map;
> > > > >       int rc = 0, i;
> > > > > -     int pages;
> > > > >       u8 type;
> > > > >
> > > > > +     memset(&rattr, 0, sizeof(rattr));
> > > >
> > > > Initialize rattr to zero from the beginning and save call to memset.
> > > I moved from static initialization to memset due to some sparse/smatch
> > > warnings, rattr has a "pointer member".
> >
> > That is why you need to use = {} not the weird '= {0}' version
> >
> > 0 initializes the first member to zero and default initializes the rest
> > which doesn't work properly if the first member is not an integral
> > value.

> So should I remove memset(s) in v2?

I would

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-27  7:39     ` Devesh Sharma
  2020-01-27  8:04       ` Leon Romanovsky
@ 2020-01-28 20:15       ` Jason Gunthorpe
  2020-01-30  6:05         ` Devesh Sharma
  1 sibling, 1 reply; 41+ messages in thread
From: Jason Gunthorpe @ 2020-01-28 20:15 UTC (permalink / raw)
  To: Devesh Sharma; +Cc: linux-rdma, dledford

On Mon, Jan 27, 2020 at 01:09:46PM +0530, Devesh Sharma wrote:
> On Sat, Jan 25, 2020 at 11:33 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
> > >  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> > >  {
> > > +     struct bnxt_qplib_chip_ctx *chip_ctx;
> > > +
> > > +     if (!rdev->chip_ctx)
> > > +             return;
> > > +     chip_ctx = rdev->chip_ctx;
> > > +     rdev->chip_ctx = NULL;
> > >       rdev->rcfw.res = NULL;
> > >       rdev->qplib_res.cctx = NULL;
> > > +     kfree(chip_ctx);
> > >  }
> >
> > Are you sure this kfree is late enough? I couldn't deduce if it was
> > really safe to NULL chip_ctx here.
> With the current design its okay to free this here because
> bnxt_re_destroy_chip_ctx is indeed the last deallocation performed
> before ib_device_dealloc() in any exit path. Further, the call to
> bnxt_re_destroy_chip_ctx is protected by rtnl.
> following is the exit sequence anyewere in the driver control path
> bnxt_re_ib_unreg(rdev); --->> the last deallocation in this func is
> destroy_chip_ctx().
> bnxt_re_remove_one(rdev); -->> this is a single line function just to
> put pci device reference
> bnxt_re_dev_unreg(rdev); -->> the first deallocation in this func is
> ib_device_dealloc().

It makes more sense to me to put all the memory deallocation together
in one place, then there is no concern about ordering.

We now have the dealloc_driver callback for this purpose.

It is not 'last deallocation' that matters, but what all the other
stuff is doing between destroy_chip_ctx() and ib_device_dealloc()

Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function
  2020-01-28 18:09           ` Jason Gunthorpe
@ 2020-01-29  8:29             ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-29  8:29 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: Leon Romanovsky, linux-rdma, Doug Ledford

On Tue, Jan 28, 2020 at 11:39 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Tue, Jan 28, 2020 at 08:13:31AM +0530, Devesh Sharma wrote:
> > On Tue, Jan 28, 2020 at 6:05 AM Jason Gunthorpe <jgg@mellanox.com> wrote:
> > >
> > > On Mon, Jan 27, 2020 at 01:10:10PM +0530, Devesh Sharma wrote:
> > > > > >  static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
> > > > > >  {
> > > > > > +     struct bnxt_qplib_ctx *qplib_ctx;
> > > > > > +     struct bnxt_re_ring_attr rattr;
> > > > > >       int num_vec_created = 0;
> > > > > > -     dma_addr_t *pg_map;
> > > > > >       int rc = 0, i;
> > > > > > -     int pages;
> > > > > >       u8 type;
> > > > > >
> > > > > > +     memset(&rattr, 0, sizeof(rattr));
> > > > >
> > > > > Initialize rattr to zero from the beginning and save call to memset.
> > > > I moved from static initialization to memset due to some sparse/smatch
> > > > warnings, rattr has a "pointer member".
> > >
> > > That is why you need to use = {} not the weird '= {0}' version
> > >
> > > 0 initializes the first member to zero and default initializes the rest
> > > which doesn't work properly if the first member is not an integral
> > > value.
>
> > So should I remove memset(s) in v2?
>
> I would
>
Doing it already :-)
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  7:39         ` Devesh Sharma
@ 2020-01-30  6:04           ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-30  6:04 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: linux-rdma, Jason Gunthorpe, Doug Ledford

On Mon, Jan 27, 2020 at 1:09 PM Devesh Sharma
<devesh.sharma@broadcom.com> wrote:
>
> On Sun, Jan 26, 2020 at 12:20 AM Leon Romanovsky <leon@kernel.org> wrote:
> >
> > On Sat, Jan 25, 2020 at 10:33:41PM +0530, Devesh Sharma wrote:
> > > On Fri, Jan 24, 2020 at 4:53 PM Leon Romanovsky <leon@kernel.org> wrote:
> > > >
> > > > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > > > Restructuring the bnxt_re_create_qp function. Listing below
> > > > > the major changes:
> > > > >  --Monolithic central part of create_qp where attributes are
> > > > >    initialized is now enclosed in one function and this new
> > > > >    function has few more sub-functions.
> > > > >  --Top level qp limit checking code moved to a function.
> > > > >  --GSI QP creation and GSI Shadow qp creation code is handled
> > > > >    in a sub function.
> > > > >
> > > > > Signed-off-by: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
> > > > > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > > > Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> > > > > ---
> > > > >  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> > > > >  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++-----------
> > > > >  drivers/infiniband/hw/bnxt_re/main.c     |   3 +-
> > > > >  3 files changed, 434 insertions(+), 217 deletions(-)
> > > > >
> > > >
> > > > Please remove dev_err/dev_dbg/dev_* prints from the driver code.
> > > Sure I can do that, are you suggesting to add one more patch in this series?
> > > I guess it should be okay to follow the hw/efa way to  have debug msgs still on.
> >
> > It is ok to use ibdev_* prints, it is not ok to use dev_* prints.
> Okay, I will add a new patch to this series
> >
> > Thanks
> >
Done added a new patch in V2 of this series.
> > > >
> > > >
> > > > Thanks

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-27  8:13     ` Devesh Sharma
  2020-01-27  8:16       ` Devesh Sharma
  2020-01-27  9:26       ` Leon Romanovsky
@ 2020-01-30  6:04       ` Devesh Sharma
  2 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-30  6:04 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Mon, Jan 27, 2020 at 1:43 PM Devesh Sharma
<devesh.sharma@broadcom.com> wrote:
>
> On Sat, Jan 25, 2020 at 11:16 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> >
> > On Fri, Jan 24, 2020 at 12:52:39AM -0500, Devesh Sharma wrote:
> > > +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
> > > +{
> > > +     struct bnxt_re_qp *gsi_sqp;
> > > +     struct bnxt_re_ah *gsi_sah;
> > > +     struct bnxt_re_dev *rdev;
> > > +     int rc = 0;
> > > +
> > > +     rdev = qp->rdev;
> > > +     gsi_sqp = rdev->gsi_ctx.gsi_sqp;
> > > +     gsi_sah = rdev->gsi_ctx.gsi_sah;
> > > +
> > > +     /* remove from active qp list */
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_del(&gsi_sqp->list);
> > > +     atomic_dec(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
> > > +     bnxt_qplib_destroy_ah(&rdev->qplib_res,
> > > +                           &gsi_sah->qplib_ah,
> > > +                           true);
> > > +     bnxt_qplib_clean_qp(&qp->qplib_qp);
> > > +
> > > +     dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n");
> > > +     rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +     if (rc) {
> > > +             dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed");
> > > +             goto fail;
> > > +     }
> > > +     bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
> > > +
> > > +     kfree(rdev->gsi_ctx.sqp_tbl);
> > > +     kfree(gsi_sah);
> > > +     kfree(gsi_sqp);
> > > +     rdev->gsi_ctx.gsi_sqp = NULL;
> > > +     rdev->gsi_ctx.gsi_sah = NULL;
> > > +     rdev->gsi_ctx.sqp_tbl = NULL;
> > > +
> > > +     return 0;
> > > +fail:
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_add_tail(&gsi_sqp->list, &rdev->qp_list);
> > > +     atomic_inc(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > > +     return rc;
> >
> > This error unwind approach looks racy. destroy is not allowed to
> > fail, so why all this mess?
> True, the unwind is not required, even if the driver wants to keep it
> for debugging purpose, the zombie resource would give rise to
> confusion.
> >
> > >  /* Queue Pairs */
> > >  int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > >  {
> > > @@ -750,10 +797,18 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
> > >       unsigned int flags;
> > >       int rc;
> > >
> > > +     mutex_lock(&rdev->qp_lock);
> > > +     list_del(&qp->list);
> > > +     atomic_dec(&rdev->qp_count);
> > > +     mutex_unlock(&rdev->qp_lock);
> > >       bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
> > >       rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
> > >       if (rc) {
> > >               dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
> > > +             mutex_lock(&rdev->qp_lock);
> > > +             list_add_tail(&qp->list, &rdev->qp_list);
> > > +             atomic_inc(&rdev->qp_count);
> > > +             mutex_unlock(&rdev->qp_lock);
> > >               return rc;
> > >       }
> >
> > More..
> Let me see if I can remove it in this series, else future series would
> remove it.
Done, removing unwind logic in V2.
> >
> > Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer
  2020-01-28 20:15       ` Jason Gunthorpe
@ 2020-01-30  6:05         ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-30  6:05 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma, dledford

On Wed, Jan 29, 2020 at 1:45 AM Jason Gunthorpe <jgg@mellanox.com> wrote:
>
> On Mon, Jan 27, 2020 at 01:09:46PM +0530, Devesh Sharma wrote:
> > On Sat, Jan 25, 2020 at 11:33 PM Jason Gunthorpe <jgg@mellanox.com> wrote:
> > >
> > > On Fri, Jan 24, 2020 at 12:52:40AM -0500, Devesh Sharma wrote:
> > > >  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> > > >  {
> > > > +     struct bnxt_qplib_chip_ctx *chip_ctx;
> > > > +
> > > > +     if (!rdev->chip_ctx)
> > > > +             return;
> > > > +     chip_ctx = rdev->chip_ctx;
> > > > +     rdev->chip_ctx = NULL;
> > > >       rdev->rcfw.res = NULL;
> > > >       rdev->qplib_res.cctx = NULL;
> > > > +     kfree(chip_ctx);
> > > >  }
> > >
> > > Are you sure this kfree is late enough? I couldn't deduce if it was
> > > really safe to NULL chip_ctx here.
> > With the current design its okay to free this here because
> > bnxt_re_destroy_chip_ctx is indeed the last deallocation performed
> > before ib_device_dealloc() in any exit path. Further, the call to
> > bnxt_re_destroy_chip_ctx is protected by rtnl.
> > following is the exit sequence anyewere in the driver control path
> > bnxt_re_ib_unreg(rdev); --->> the last deallocation in this func is
> > destroy_chip_ctx().
> > bnxt_re_remove_one(rdev); -->> this is a single line function just to
> > put pci device reference
> > bnxt_re_dev_unreg(rdev); -->> the first deallocation in this func is
> > ib_device_dealloc().
>
> It makes more sense to me to put all the memory deallocation together
> in one place, then there is no concern about ordering.
>
> We now have the dealloc_driver callback for this purpose.
>
> It is not 'last deallocation' that matters, but what all the other
> stuff is doing between destroy_chip_ctx() and ib_device_dealloc()
As far as this series is concerned, driver is saving crashes however
in a nasty way. I would like to move forward with what I have in this
patch and submit a new patch series which would implement your
suggestion.
>
> Jason

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
  2020-01-24 11:23   ` Leon Romanovsky
  2020-01-25 17:46   ` Jason Gunthorpe
@ 2020-01-30 13:37   ` Parav Pandit
  2020-01-30 16:03     ` Devesh Sharma
  2 siblings, 1 reply; 41+ messages in thread
From: Parav Pandit @ 2020-01-30 13:37 UTC (permalink / raw)
  To: Devesh Sharma, linux-rdma; +Cc: Jason Gunthorpe, dledford



> From: linux-rdma-owner@vger.kernel.org <linux-rdma-
> owner@vger.kernel.org> On Behalf Of Devesh Sharma


>  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++---------

[..]
> +
> +	/* remove from active qp list */
> +	mutex_lock(&rdev->qp_lock);
> +	list_del(&gsi_sqp->list);
> +	atomic_dec(&rdev->qp_count);

Atomic inc/dec/read should not be protected using qp_lock mutex.
Please take it outside the critical section in new refactor code and in old one.

> +	mutex_unlock(&rdev->qp_lock);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code
  2020-01-30 13:37   ` Parav Pandit
@ 2020-01-30 16:03     ` Devesh Sharma
  0 siblings, 0 replies; 41+ messages in thread
From: Devesh Sharma @ 2020-01-30 16:03 UTC (permalink / raw)
  To: Parav Pandit; +Cc: linux-rdma, Jason Gunthorpe, dledford

On Thu, Jan 30, 2020 at 7:08 PM Parav Pandit <parav@mellanox.com> wrote:
>
>
>
> > From: linux-rdma-owner@vger.kernel.org <linux-rdma-
> > owner@vger.kernel.org> On Behalf Of Devesh Sharma
>
>
> >  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  13 +-
> > drivers/infiniband/hw/bnxt_re/ib_verbs.c | 635 ++++++++++++++++++++---------
>
> [..]
> > +
> > +     /* remove from active qp list */
> > +     mutex_lock(&rdev->qp_lock);
> > +     list_del(&gsi_sqp->list);
> > +     atomic_dec(&rdev->qp_count);
>
> Atomic inc/dec/read should not be protected using qp_lock mutex.
> Please take it outside the critical section in new refactor code and in old one.

True, will change.
thnx
>
> > +     mutex_unlock(&rdev->qp_lock);

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2020-01-30 16:04 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-24  5:52 [PATCH for-next 0/7] Refactor control path of bnxt_re driver Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 1/7] RDMA/bnxt_re: Refactor queue pair creation code Devesh Sharma
2020-01-24 11:23   ` Leon Romanovsky
2020-01-25 17:03     ` Devesh Sharma
2020-01-25 18:50       ` Leon Romanovsky
2020-01-27  7:39         ` Devesh Sharma
2020-01-30  6:04           ` Devesh Sharma
2020-01-25 17:46   ` Jason Gunthorpe
2020-01-27  8:13     ` Devesh Sharma
2020-01-27  8:16       ` Devesh Sharma
2020-01-27  9:27         ` Leon Romanovsky
2020-01-27  9:26       ` Leon Romanovsky
2020-01-27 11:31         ` Devesh Sharma
2020-01-30  6:04       ` Devesh Sharma
2020-01-30 13:37   ` Parav Pandit
2020-01-30 16:03     ` Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 2/7] RDMA/bnxt_re: Replace chip context structure with pointer Devesh Sharma
2020-01-25 18:03   ` Jason Gunthorpe
2020-01-27  7:39     ` Devesh Sharma
2020-01-27  8:04       ` Leon Romanovsky
2020-01-27 11:17         ` Devesh Sharma
2020-01-28 20:15       ` Jason Gunthorpe
2020-01-30  6:05         ` Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 3/7] RDMA/bnxt_re: Refactor hardware queue memory allocation Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 4/7] RDMA/bnxt_re: Refactor net ring allocation function Devesh Sharma
2020-01-26 14:29   ` Leon Romanovsky
2020-01-27  7:40     ` Devesh Sharma
2020-01-27  8:02       ` Leon Romanovsky
2020-01-27 11:25         ` Devesh Sharma
2020-01-27 12:44           ` Leon Romanovsky
2020-01-27 14:14             ` Devesh Sharma
2020-01-28 18:09               ` Jason Gunthorpe
2020-01-28  0:35       ` Jason Gunthorpe
2020-01-28  2:43         ` Devesh Sharma
2020-01-28 18:09           ` Jason Gunthorpe
2020-01-29  8:29             ` Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 5/7] RDMA/bnxt_re: Refactor command queue management code Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 6/7] RDMA/bnxt_re: Refactor notification " Devesh Sharma
2020-01-24  5:52 ` [PATCH for-next 7/7] RDMA/bnxt_re: Refactor doorbell management functions Devesh Sharma
2020-01-25 18:04 ` [PATCH for-next 0/7] Refactor control path of bnxt_re driver Jason Gunthorpe
2020-01-27  7:39   ` Devesh Sharma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).