RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
authorSelvin Xavier <selvin.xavier@broadcom.com>
Mon, 19 Aug 2024 04:47:23 +0000 (21:47 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 27 Aug 2024 13:15:57 +0000 (10:15 -0300)
Variable size WQE means that each send Work Queue Entry to HW can use
different WQE sizes as opposed to the static WQE size on the current
devices. Set variable WQE mode for Gen P7 devices. Depth of the Queue will
be a multiple of slot which is 16 bytes. The number of slots should be a
multiple of 256 as per the HW requirement.

Initialize the Software shadow queue to hold requests equal to the number
of slots. Also, do not expose the variable size WQE capability until the
last patch in the series.

Link: https://patch.msgid.link/r/1724042847-1481-2-git-send-email-selvin.xavier@broadcom.com
Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h

index 7c757351a0166fc176d597555347463442d646fd..5073ab18dc19f73866607a127b8bbab2a59beeca 100644 (file)
@@ -1156,6 +1156,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
        /* Shadow QP SQ depth should be same as QP1 RQ depth */
        qp->qplib_qp.sq.wqe_size = bnxt_re_get_wqe_size(0, 6);
        qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe;
+       qp->qplib_qp.sq.max_sw_wqe = qp1_qp->rq.max_wqe;
        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;
@@ -1167,6 +1168,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
 
        qp->qplib_qp.rq.wqe_size = bnxt_re_get_rwqe_size(6);
        qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe;
+       qp->qplib_qp.rq.max_sw_wqe = qp1_qp->rq.max_wqe;
        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;
@@ -1228,6 +1230,7 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
                 */
                entries = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1, uctx);
                rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+               rq->max_sw_wqe = rq->max_wqe;
                rq->q_full_delta = 0;
                rq->sg_info.pgsize = PAGE_SIZE;
                rq->sg_info.pgshft = PAGE_SHIFT;
@@ -1287,6 +1290,7 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
                0 : BNXT_QPLIB_RESERVED_QP_WRS;
        entries = bnxt_re_init_depth(entries + diff + 1, uctx);
        sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1);
+       sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true);
        sq->q_full_delta = diff + 1;
        /*
         * Reserving one slot for Phantom WQE. Application can
@@ -2155,6 +2159,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
                        entries = bnxt_re_init_depth(qp_attr->cap.max_recv_wr, uctx);
                        qp->qplib_qp.rq.max_wqe =
                                min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+                       qp->qplib_qp.rq.max_sw_wqe = qp->qplib_qp.rq.max_wqe;
                        qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe -
                                                       qp_attr->cap.max_recv_wr;
                        qp->qplib_qp.rq.max_sge = qp_attr->cap.max_recv_sge;
@@ -4187,9 +4192,6 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
        resp.cqe_sz = sizeof(struct cq_base);
        resp.max_cqd = dev_attr->max_cq_wqes;
 
-       resp.comp_mask |= BNXT_RE_UCNTX_CMASK_HAVE_MODE;
-       resp.mode = rdev->chip_ctx->modes.wqe_mode;
-
        if (rdev->chip_ctx->modes.db_push)
                resp.comp_mask |= BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED;
 
index 9714b9ab75240bc3019e05bbc1235b2a97678277..31ba89cffe9d862734c9649965c290fae973c4cc 100644 (file)
@@ -129,13 +129,13 @@ static void bnxt_re_set_db_offset(struct bnxt_re_dev *rdev)
        }
 }
 
-static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode)
+static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev)
 {
        struct bnxt_qplib_chip_ctx *cctx;
 
        cctx = rdev->chip_ctx;
-       cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
-                              mode : BNXT_QPLIB_WQE_MODE_STATIC;
+       cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx) ?
+                              BNXT_QPLIB_WQE_MODE_VARIABLE : BNXT_QPLIB_WQE_MODE_STATIC;
        if (bnxt_re_hwrm_qcaps(rdev))
                dev_err(rdev_to_dev(rdev),
                        "Failed to query hwrm qcaps\n");
@@ -158,7 +158,7 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
        kfree(chip_ctx);
 }
 
-static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode)
+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;
@@ -180,7 +180,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode)
        rdev->qplib_res.dattr = &rdev->dev_attr;
        rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev);
 
-       bnxt_re_set_drv_mode(rdev, wqe_mode);
+       bnxt_re_set_drv_mode(rdev);
 
        bnxt_re_set_db_offset(rdev);
        rc = bnxt_qplib_map_db_bar(&rdev->qplib_res);
@@ -1620,7 +1620,7 @@ static void bnxt_re_worker(struct work_struct *work)
        schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));
 }
 
-static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
+static int bnxt_re_dev_init(struct bnxt_re_dev *rdev)
 {
        struct bnxt_re_ring_attr rattr = {};
        struct bnxt_qplib_creq_ctx *creq;
@@ -1638,7 +1638,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
        }
        set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
 
-       rc = bnxt_re_setup_chip_ctx(rdev, wqe_mode);
+       rc = bnxt_re_setup_chip_ctx(rdev);
        if (rc) {
                bnxt_unregister_dev(rdev->en_dev);
                clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
@@ -1790,7 +1790,7 @@ fail:
        return rc;
 }
 
-static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode)
+static int bnxt_re_add_device(struct auxiliary_device *adev)
 {
        struct bnxt_aux_priv *aux_priv =
                container_of(adev, struct bnxt_aux_priv, aux_dev);
@@ -1807,7 +1807,7 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode)
                goto exit;
        }
 
-       rc = bnxt_re_dev_init(rdev, wqe_mode);
+       rc = bnxt_re_dev_init(rdev);
        if (rc)
                goto re_dev_dealloc;
 
@@ -1937,7 +1937,8 @@ static int bnxt_re_probe(struct auxiliary_device *adev,
        int rc;
 
        mutex_lock(&bnxt_re_mutex);
-       rc = bnxt_re_add_device(adev, BNXT_QPLIB_WQE_MODE_STATIC);
+
+       rc = bnxt_re_add_device(adev);
        if (rc) {
                mutex_unlock(&bnxt_re_mutex);
                return rc;
index 49e4a4a50bfaeb2784330eec016be435f21aef0e..0af09e77e94b79abc5ece8d197f4edf883d7652e 100644 (file)
@@ -809,13 +809,13 @@ static int bnxt_qplib_alloc_init_swq(struct bnxt_qplib_q *que)
 {
        int indx;
 
-       que->swq = kcalloc(que->max_wqe, sizeof(*que->swq), GFP_KERNEL);
+       que->swq = kcalloc(que->max_sw_wqe, sizeof(*que->swq), GFP_KERNEL);
        if (!que->swq)
                return -ENOMEM;
 
        que->swq_start = 0;
-       que->swq_last = que->max_wqe - 1;
-       for (indx = 0; indx < que->max_wqe; indx++)
+       que->swq_last = que->max_sw_wqe - 1;
+       for (indx = 0; indx < que->max_sw_wqe; indx++)
                que->swq[indx].next_idx = indx + 1;
        que->swq[que->swq_last].next_idx = 0; /* Make it circular */
        que->swq_last = 0;
@@ -851,7 +851,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        hwq_attr.res = res;
        hwq_attr.sginfo = &sq->sg_info;
        hwq_attr.stride = sizeof(struct sq_sge);
-       hwq_attr.depth = bnxt_qplib_get_depth(sq);
+       hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, false);
        hwq_attr.type = HWQ_TYPE_QUEUE;
        rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
        if (rc)
@@ -879,7 +879,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
                hwq_attr.res = res;
                hwq_attr.sginfo = &rq->sg_info;
                hwq_attr.stride = sizeof(struct sq_sge);
-               hwq_attr.depth = bnxt_qplib_get_depth(rq);
+               hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false);
                hwq_attr.type = HWQ_TYPE_QUEUE;
                rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
                if (rc)
@@ -1011,7 +1011,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        hwq_attr.res = res;
        hwq_attr.sginfo = &sq->sg_info;
        hwq_attr.stride = sizeof(struct sq_sge);
-       hwq_attr.depth = bnxt_qplib_get_depth(sq);
+       hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, true);
        hwq_attr.aux_stride = psn_sz;
        hwq_attr.aux_depth = psn_sz ? bnxt_qplib_set_sq_size(sq, qp->wqe_mode)
                                    : 0;
@@ -1052,7 +1052,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
                hwq_attr.res = res;
                hwq_attr.sginfo = &rq->sg_info;
                hwq_attr.stride = sizeof(struct sq_sge);
-               hwq_attr.depth = bnxt_qplib_get_depth(rq);
+               hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false);
                hwq_attr.aux_stride = 0;
                hwq_attr.aux_depth = 0;
                hwq_attr.type = HWQ_TYPE_QUEUE;
@@ -2492,7 +2492,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
        }
        sq = &qp->sq;
 
-       cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_wqe;
+       cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_sw_wqe;
        if (qp->sq.flushed) {
                dev_dbg(&cq->hwq.pdev->dev,
                        "%s: QP in Flush QP = %p\n", __func__, qp);
@@ -2882,7 +2882,7 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
        cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx);
        if (cqe_cons == 0xFFFF)
                goto do_rq;
-       cqe_cons %= sq->max_wqe;
+       cqe_cons %= sq->max_sw_wqe;
 
        if (qp->sq.flushed) {
                dev_dbg(&cq->hwq.pdev->dev,
index 56538b90d6c56fabd700924654d5ae629f887124..f54d7a0c7dad3d599704d375fe6142e498f7e9db 100644 (file)
@@ -251,6 +251,7 @@ struct bnxt_qplib_q {
        struct bnxt_qplib_db_info       dbinfo;
        struct bnxt_qplib_sg_info       sg_info;
        u32                             max_wqe;
+       u32                             max_sw_wqe;
        u16                             wqe_size;
        u16                             q_full_delta;
        u16                             max_sge;
@@ -586,15 +587,22 @@ static inline void bnxt_qplib_swq_mod_start(struct bnxt_qplib_q *que, u32 idx)
        que->swq_start = que->swq[idx].next_idx;
 }
 
-static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que)
+static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que, u8 wqe_mode, bool is_sq)
 {
-       return (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge);
+       u32 slots;
+
+       /* Queue depth is the number of slots. */
+       slots = (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge);
+       /* For variable WQE mode, need to align the slots to 256 */
+       if (wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE && is_sq)
+               slots = ALIGN(slots, BNXT_VAR_MAX_SLOT_ALIGN);
+       return slots;
 }
 
 static inline u32 bnxt_qplib_set_sq_size(struct bnxt_qplib_q *que, u8 wqe_mode)
 {
        return (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
-               que->max_wqe : bnxt_qplib_get_depth(que);
+               que->max_wqe : bnxt_qplib_get_depth(que, wqe_mode, true);
 }
 
 static inline u32 bnxt_qplib_set_sq_max_slot(u8 wqe_mode)
index 9328db92fa6db3ab02ce6bcddecd11c7fc4cefbe..ca2aa35e6eec8c0a46d2e086fd3153086c7f9bf4 100644 (file)
@@ -95,11 +95,13 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
        struct bnxt_qplib_cmdqmsg msg = {};
        struct creq_query_func_resp_sb *sb;
        struct bnxt_qplib_rcfw_sbuf sbuf;
+       struct bnxt_qplib_chip_ctx *cctx;
        struct cmdq_query_func req = {};
        u8 *tqm_alloc;
        int i, rc;
        u32 temp;
 
+       cctx = rcfw->res->cctx;
        bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
                                 CMDQ_BASE_OPCODE_QUERY_FUNC,
                                 sizeof(req));
@@ -133,8 +135,9 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
         * reporting the max number
         */
        attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1;
-       attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx) ?
-                           6 : sb->max_sge;
+
+       attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ?
+                           min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6;
        attr->max_cq = le32_to_cpu(sb->max_cq);
        attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
        attr->max_cq_sges = attr->max_qp_sges;
index 16a67d70a6fc4bcdf5a4df70b0ae1fc5f9fac13a..a633e2a9aa94c1943032dbba6ece7fc2dfa5d7a8 100644 (file)
@@ -40,6 +40,7 @@
 #ifndef __BNXT_QPLIB_SP_H__
 #define __BNXT_QPLIB_SP_H__
 
+#include <rdma/bnxt_re-abi.h>
 #define BNXT_QPLIB_RESERVED_QP_WRS     128
 
 struct bnxt_qplib_dev_attr {
@@ -351,4 +352,9 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
 int bnxt_qplib_modify_cc(struct bnxt_qplib_res *res,
                         struct bnxt_qplib_cc_param *cc_param);
 
+#define BNXT_VAR_MAX_WQE       4352
+#define BNXT_VAR_MAX_SLOT_ALIGN 256
+#define BNXT_VAR_MAX_SGE        13
+#define BNXT_RE_MAX_RQ_WQES     65536
+
 #endif /* __BNXT_QPLIB_SP_H__*/