* [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters
@ 2024-08-10 19:19 Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 1/4] RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters Selvin Xavier
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Selvin Xavier @ 2024-08-10 19:19 UTC (permalink / raw)
To: leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Selvin Xavier
Enable the Variable size Work Queue entry support for Gen P7 adapters. This would
help in the better utilization of the queue memory and pci bandwidth due to the
smaller send queue Work entries.
Please review and apply.
Thanks,
Selvin Xavier
Selvin Xavier (4):
RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
RDMA/bnxt_re: Get the WQE index from slot index while completing the
WQEs
RDMA/bnxt_re: Handle variable WQE support for user applications
RDMA/bnxt_re: Enable variable size WQEs for user space applications
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 119 +++++++++++++++++++------------
drivers/infiniband/hw/bnxt_re/ib_verbs.h | 16 ++++-
drivers/infiniband/hw/bnxt_re/main.c | 21 +++---
drivers/infiniband/hw/bnxt_re/qplib_fp.c | 58 ++++++++++++---
drivers/infiniband/hw/bnxt_re/qplib_fp.h | 24 ++++++-
drivers/infiniband/hw/bnxt_re/qplib_sp.c | 7 +-
drivers/infiniband/hw/bnxt_re/qplib_sp.h | 6 ++
include/uapi/rdma/bnxt_re-abi.h | 7 ++
8 files changed, 186 insertions(+), 72 deletions(-)
--
2.5.5
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH for-next 1/4] RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
2024-08-10 19:19 [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters Selvin Xavier
@ 2024-08-10 19:19 ` Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs Selvin Xavier
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Selvin Xavier @ 2024-08-10 19:19 UTC (permalink / raw)
To: leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Selvin Xavier, Hongguang Gao
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.
Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 +++++---
drivers/infiniband/hw/bnxt_re/main.c | 21 +++++++++++----------
drivers/infiniband/hw/bnxt_re/qplib_fp.c | 18 +++++++++---------
drivers/infiniband/hw/bnxt_re/qplib_fp.h | 14 +++++++++++---
drivers/infiniband/hw/bnxt_re/qplib_sp.c | 7 +++++--
drivers/infiniband/hw/bnxt_re/qplib_sp.h | 6 ++++++
6 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 7c75735..5073ab1 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -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;
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 9714b9a..31ba89c 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -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 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
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;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 49e4a4a..0af09e7 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -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,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 56538b9..f54d7a0 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -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)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index 9328db9..ca2aa35 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -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;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index 16a67d7..a633e2a 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -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__*/
--
2.5.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs
2024-08-10 19:19 [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 1/4] RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters Selvin Xavier
@ 2024-08-10 19:19 ` Selvin Xavier
2024-08-12 8:48 ` Zhu Yanjun
2024-08-10 19:19 ` [PATCH for-next 3/4] RDMA/bnxt_re: Handle variable WQE support for user applications Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 4/4] RDMA/bnxt_re: Enable variable size WQEs for user space applications Selvin Xavier
3 siblings, 1 reply; 8+ messages in thread
From: Selvin Xavier @ 2024-08-10 19:19 UTC (permalink / raw)
To: leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Selvin Xavier, Hongguang Gao
While reporting the completions, SQ Work Queue index is required to
identify the WQE that generated the completions. In variable WQE mode,
FW returns the slot index for Error completions. Driver need to walk
through the shadow queue between the consumer index and producer index
and matches the slot index returned by FW. If a match is found, the next
index of the shadow queue is the WQE index to be considered for remaining
poll_cq loop.
Signed-off-by: Hongguang Gao <hong``guang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 ++++++++++++++++++++++++++++++++
drivers/infiniband/hw/bnxt_re/qplib_fp.h | 10 ++++++++
2 files changed, 50 insertions(+)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 0af09e7..b49f49c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -2471,6 +2471,32 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
return rc;
}
+static int bnxt_qplib_get_cqe_sq_cons(struct bnxt_qplib_q *sq, u32 cqe_slot)
+{
+ struct bnxt_qplib_hwq *sq_hwq;
+ struct bnxt_qplib_swq *swq;
+ int cqe_sq_cons = -1;
+ u32 start, last;
+
+ sq_hwq = &sq->hwq;
+
+ start = sq->swq_start;
+ last = sq->swq_last;
+
+ while (last != start) {
+ swq = &sq->swq[last];
+ if (swq->slot_idx == cqe_slot) {
+ cqe_sq_cons = swq->next_idx;
+ dev_err(&sq_hwq->pdev->dev, "%s: Found cons wqe = %d slot = %d\n",
+ __func__, cqe_sq_cons, cqe_slot);
+ break;
+ }
+
+ last = swq->next_idx;
+ }
+ return cqe_sq_cons;
+}
+
static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
struct cq_req *hwcqe,
struct bnxt_qplib_cqe **pcqe, int *budget,
@@ -2481,6 +2507,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
struct bnxt_qplib_qp *qp;
struct bnxt_qplib_q *sq;
u32 cqe_sq_cons;
+ int cqe_cons;
int rc = 0;
qp = (struct bnxt_qplib_qp *)((unsigned long)
@@ -2498,6 +2525,19 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
"%s: QP in Flush QP = %p\n", __func__, qp);
goto done;
}
+
+ if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
+ cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
+ if (cqe_cons < 0) {
+ dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
+ __func__, hwcqe->sq_cons_idx);
+ goto done;
+ }
+ cqe_sq_cons = cqe_cons;
+ dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
+ __func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
+ }
+
/* Require to walk the sq's swq to fabricate CQEs for all previously
* signaled SWQEs due to CQE aggregation from the current sq cons
* to the cqe_sq_cons
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index f54d7a0..2e7a4fd 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -649,4 +649,14 @@ static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn)
(((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) &
SQ_MSN_SEARCH_START_PSN_MASK));
}
+
+static inline bool __is_var_wqe(struct bnxt_qplib_qp *qp)
+{
+ return (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE);
+}
+
+static inline bool __is_err_cqe_for_var_wqe(struct bnxt_qplib_qp *qp, u8 status)
+{
+ return (status != CQ_REQ_STATUS_OK) && __is_var_wqe(qp);
+}
#endif /* __BNXT_QPLIB_FP_H__ */
--
2.5.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH for-next 3/4] RDMA/bnxt_re: Handle variable WQE support for user applications
2024-08-10 19:19 [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 1/4] RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs Selvin Xavier
@ 2024-08-10 19:19 ` Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 4/4] RDMA/bnxt_re: Enable variable size WQEs for user space applications Selvin Xavier
3 siblings, 0 replies; 8+ messages in thread
From: Selvin Xavier @ 2024-08-10 19:19 UTC (permalink / raw)
To: leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Selvin Xavier, Hongguang Gao
User library calculates the number of slots required for user
applications and it can pass that information to the driver.
Driver can use this value and update the HW directly. This
mechanism is currently used only for the newly introduced variable
size WQEs.
Extend the bnxt_re_qp_req structure to pass the Send Queue slot count.
Reorganize the code to get the sq_slots before initializing the Send Queue
attributes.
Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 108 ++++++++++++++++++-------------
drivers/infiniband/hw/bnxt_re/ib_verbs.h | 16 ++++-
include/uapi/rdma/bnxt_re-abi.h | 6 ++
3 files changed, 84 insertions(+), 46 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 5073ab1..2932db1 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1017,20 +1017,15 @@ static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp,
}
static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
- struct bnxt_re_qp *qp, struct ib_udata *udata)
+ struct bnxt_re_qp *qp, struct bnxt_re_ucontext *cntx,
+ struct bnxt_re_qp_req *ureq)
{
struct bnxt_qplib_qp *qplib_qp;
- struct bnxt_re_ucontext *cntx;
- struct bnxt_re_qp_req ureq;
int bytes = 0, psn_sz;
struct ib_umem *umem;
int psn_nume;
qplib_qp = &qp->qplib_qp;
- cntx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext,
- ib_uctx);
- if (ib_copy_from_udata(&ureq, udata, sizeof(ureq)))
- return -EFAULT;
bytes = (qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size);
/* Consider mapping PSN search memory only for RC QPs. */
@@ -1038,15 +1033,20 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
sizeof(struct sq_psn_search_ext) :
sizeof(struct sq_psn_search);
- psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
- qplib_qp->sq.max_wqe :
- ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
- sizeof(struct bnxt_qplib_sge));
+ if (cntx && bnxt_re_is_var_size_supported(rdev, cntx)) {
+ psn_nume = ureq->sq_slots;
+ } else {
+ psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
+ qplib_qp->sq.max_wqe : ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
+ sizeof(struct bnxt_qplib_sge));
+ }
+ if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
+ psn_nume = roundup_pow_of_two(psn_nume);
bytes += (psn_nume * psn_sz);
}
bytes = PAGE_ALIGN(bytes);
- umem = ib_umem_get(&rdev->ibdev, ureq.qpsva, bytes,
+ umem = ib_umem_get(&rdev->ibdev, ureq->qpsva, bytes,
IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem))
return PTR_ERR(umem);
@@ -1055,12 +1055,12 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
qplib_qp->sq.sg_info.umem = umem;
qplib_qp->sq.sg_info.pgsize = PAGE_SIZE;
qplib_qp->sq.sg_info.pgshft = PAGE_SHIFT;
- qplib_qp->qp_handle = ureq.qp_handle;
+ qplib_qp->qp_handle = ureq->qp_handle;
if (!qp->qplib_qp.srq) {
bytes = (qplib_qp->rq.max_wqe * qplib_qp->rq.wqe_size);
bytes = PAGE_ALIGN(bytes);
- umem = ib_umem_get(&rdev->ibdev, ureq.qprva, bytes,
+ umem = ib_umem_get(&rdev->ibdev, ureq->qprva, bytes,
IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem))
goto rqfail;
@@ -1259,14 +1259,15 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
struct ib_qp_init_attr *init_attr,
- struct bnxt_re_ucontext *uctx)
+ struct bnxt_re_ucontext *uctx,
+ struct bnxt_re_qp_req *ureq)
{
struct bnxt_qplib_dev_attr *dev_attr;
struct bnxt_qplib_qp *qplqp;
struct bnxt_re_dev *rdev;
struct bnxt_qplib_q *sq;
+ int diff = 0;
int entries;
- int diff;
int rc;
rdev = qp->rdev;
@@ -1275,22 +1276,28 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
dev_attr = &rdev->dev_attr;
sq->max_sge = init_attr->cap.max_send_sge;
- if (sq->max_sge > dev_attr->max_qp_sges) {
- sq->max_sge = dev_attr->max_qp_sges;
- init_attr->cap.max_send_sge = sq->max_sge;
- }
+ entries = init_attr->cap.max_send_wr;
+ if (uctx && qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) {
+ sq->max_wqe = ureq->sq_slots;
+ sq->max_sw_wqe = ureq->sq_slots;
+ sq->wqe_size = sizeof(struct sq_sge);
+ } else {
+ if (sq->max_sge > dev_attr->max_qp_sges) {
+ sq->max_sge = dev_attr->max_qp_sges;
+ init_attr->cap.max_send_sge = sq->max_sge;
+ }
- rc = bnxt_re_setup_swqe_size(qp, init_attr);
- if (rc)
- return rc;
+ rc = bnxt_re_setup_swqe_size(qp, init_attr);
+ if (rc)
+ return rc;
- entries = init_attr->cap.max_send_wr;
- /* Allocate 128 + 1 more than what's provided */
- diff = (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ?
- 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);
+ /* Allocate 128 + 1 more than what's provided */
+ diff = (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ?
+ 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
@@ -1353,10 +1360,10 @@ static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,
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_re_ucontext *uctx,
+ struct bnxt_re_qp_req *ureq)
{
struct bnxt_qplib_dev_attr *dev_attr;
- struct bnxt_re_ucontext *uctx;
struct bnxt_qplib_qp *qplqp;
struct bnxt_re_dev *rdev;
struct bnxt_re_cq *cq;
@@ -1366,7 +1373,6 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
qplqp = &qp->qplib_qp;
dev_attr = &rdev->dev_attr;
- uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
/* Setup misc params */
ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr);
qplqp->pd = &pd->qplib_pd;
@@ -1379,8 +1385,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
goto out;
}
qplqp->type = (u8)qptype;
- qplqp->wqe_mode = rdev->chip_ctx->modes.wqe_mode;
-
+ qplqp->wqe_mode = bnxt_re_is_var_size_supported(rdev, uctx);
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;
@@ -1415,14 +1420,14 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
bnxt_re_adjust_gsi_rq_attr(qp);
/* Setup SQ */
- rc = bnxt_re_init_sq_attr(qp, init_attr, uctx);
+ rc = bnxt_re_init_sq_attr(qp, init_attr, uctx, ureq);
if (rc)
goto out;
if (init_attr->qp_type == IB_QPT_GSI)
bnxt_re_adjust_gsi_sq_attr(qp, init_attr, uctx);
- if (udata) /* This will update DPI and qp_handle */
- rc = bnxt_re_init_user_qp(rdev, pd, qp, udata);
+ if (uctx) /* This will update DPI and qp_handle */
+ rc = bnxt_re_init_user_qp(rdev, pd, qp, uctx, ureq);
out:
return rc;
}
@@ -1523,14 +1528,27 @@ static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev,
int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
struct ib_udata *udata)
{
- struct ib_pd *ib_pd = ib_qp->pd;
- 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 = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
+ struct bnxt_qplib_dev_attr *dev_attr;
+ struct bnxt_re_ucontext *uctx;
+ struct bnxt_re_qp_req ureq;
+ struct bnxt_re_dev *rdev;
+ struct bnxt_re_pd *pd;
+ struct bnxt_re_qp *qp;
+ struct ib_pd *ib_pd;
u32 active_qps;
int rc;
+ ib_pd = ib_qp->pd;
+ pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
+ rdev = pd->rdev;
+ dev_attr = &rdev->dev_attr;
+ qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
+
+ uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
+ if (udata)
+ if (ib_copy_from_udata(&ureq, udata, min(udata->inlen, sizeof(ureq))))
+ return -EFAULT;
+
rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr);
if (!rc) {
rc = -EINVAL;
@@ -1538,7 +1556,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
}
qp->rdev = rdev;
- rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata);
+ rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, uctx, &ureq);
if (rc)
goto fail;
@@ -4213,7 +4231,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
goto cfail;
if (ureq.comp_mask & BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT) {
resp.comp_mask |= BNXT_RE_UCNTX_CMASK_POW2_DISABLED;
- uctx->cmask |= BNXT_RE_UCNTX_CMASK_POW2_DISABLED;
+ uctx->cmask |= BNXT_RE_UCNTX_CAP_POW2_DISABLED;
}
}
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index e98cb17..7c8350f 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -171,12 +171,26 @@ static inline u16 bnxt_re_get_rwqe_size(int nsge)
return sizeof(struct rq_wqe_hdr) + (nsge * sizeof(struct sq_sge));
}
+enum {
+ BNXT_RE_UCNTX_CAP_POW2_DISABLED = 0x1ULL,
+ BNXT_RE_UCNTX_CAP_VAR_WQE_ENABLED = 0x2ULL,
+};
+
static inline u32 bnxt_re_init_depth(u32 ent, struct bnxt_re_ucontext *uctx)
{
- return uctx ? (uctx->cmask & BNXT_RE_UCNTX_CMASK_POW2_DISABLED) ?
+ return uctx ? (uctx->cmask & BNXT_RE_UCNTX_CAP_POW2_DISABLED) ?
ent : roundup_pow_of_two(ent) : ent;
}
+static inline bool bnxt_re_is_var_size_supported(struct bnxt_re_dev *rdev,
+ struct bnxt_re_ucontext *uctx)
+{
+ if (uctx)
+ return uctx->cmask & BNXT_RE_UCNTX_CAP_VAR_WQE_ENABLED;
+ else
+ return rdev->chip_ctx->modes.wqe_mode;
+}
+
int bnxt_re_query_device(struct ib_device *ibdev,
struct ib_device_attr *ib_attr,
struct ib_udata *udata);
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index e61104f..7114061 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -118,10 +118,16 @@ struct bnxt_re_resize_cq_req {
__aligned_u64 cq_va;
};
+enum bnxt_re_qp_mask {
+ BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS = 0x1,
+};
+
struct bnxt_re_qp_req {
__aligned_u64 qpsva;
__aligned_u64 qprva;
__aligned_u64 qp_handle;
+ __aligned_u64 comp_mask;
+ __u32 sq_slots;
};
struct bnxt_re_qp_resp {
--
2.5.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH for-next 4/4] RDMA/bnxt_re: Enable variable size WQEs for user space applications
2024-08-10 19:19 [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters Selvin Xavier
` (2 preceding siblings ...)
2024-08-10 19:19 ` [PATCH for-next 3/4] RDMA/bnxt_re: Handle variable WQE support for user applications Selvin Xavier
@ 2024-08-10 19:19 ` Selvin Xavier
3 siblings, 0 replies; 8+ messages in thread
From: Selvin Xavier @ 2024-08-10 19:19 UTC (permalink / raw)
To: leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Selvin Xavier, Hongguang Gao
Add backward compatibility code to enable variable size WQEs
only if the user lib supports it.
Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 +++++
include/uapi/rdma/bnxt_re-abi.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 2932db1..82444fd 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4233,6 +4233,11 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
resp.comp_mask |= BNXT_RE_UCNTX_CMASK_POW2_DISABLED;
uctx->cmask |= BNXT_RE_UCNTX_CAP_POW2_DISABLED;
}
+ if (ureq.comp_mask & BNXT_RE_COMP_MASK_REQ_UCNTX_VAR_WQE_SUPPORT) {
+ resp.comp_mask |= BNXT_RE_UCNTX_CMASK_HAVE_MODE;
+ resp.mode = rdev->chip_ctx->modes.wqe_mode;
+ uctx->cmask |= BNXT_RE_UCNTX_CAP_VAR_WQE_ENABLED;
+ }
}
rc = ib_copy_to_udata(udata, &resp, min(udata->outlen, sizeof(resp)));
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index 7114061..6821002 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -66,6 +66,7 @@ enum bnxt_re_wqe_mode {
enum {
BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT = 0x01,
+ BNXT_RE_COMP_MASK_REQ_UCNTX_VAR_WQE_SUPPORT = 0x02,
};
struct bnxt_re_uctx_req {
--
2.5.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs
2024-08-10 19:19 ` [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs Selvin Xavier
@ 2024-08-12 8:48 ` Zhu Yanjun
2024-08-12 10:08 ` Leon Romanovsky
0 siblings, 1 reply; 8+ messages in thread
From: Zhu Yanjun @ 2024-08-12 8:48 UTC (permalink / raw)
To: Selvin Xavier, leon, jgg; +Cc: linux-rdma, andrew.gospodarek, Hongguang Gao
在 2024/8/11 3:19, Selvin Xavier 写道:
> While reporting the completions, SQ Work Queue index is required to
> identify the WQE that generated the completions. In variable WQE mode,
> FW returns the slot index for Error completions. Driver need to walk
> through the shadow queue between the consumer index and producer index
> and matches the slot index returned by FW. If a match is found, the next
> index of the shadow queue is the WQE index to be considered for remaining
> poll_cq loop.
>
> Signed-off-by: Hongguang Gao <hong``guang.gao@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
> drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 ++++++++++++++++++++++++++++++++
> drivers/infiniband/hw/bnxt_re/qplib_fp.h | 10 ++++++++
> 2 files changed, 50 insertions(+)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> index 0af09e7..b49f49c 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> @@ -2471,6 +2471,32 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
> return rc;
> }
>
> +static int bnxt_qplib_get_cqe_sq_cons(struct bnxt_qplib_q *sq, u32 cqe_slot)
> +{
> + struct bnxt_qplib_hwq *sq_hwq;
> + struct bnxt_qplib_swq *swq;
> + int cqe_sq_cons = -1;
> + u32 start, last;
> +
> + sq_hwq = &sq->hwq;
> +
> + start = sq->swq_start;
> + last = sq->swq_last;
> +
> + while (last != start) {
> + swq = &sq->swq[last];
> + if (swq->slot_idx == cqe_slot) {
> + cqe_sq_cons = swq->next_idx;
> + dev_err(&sq_hwq->pdev->dev, "%s: Found cons wqe = %d slot = %d\n",
> + __func__, cqe_sq_cons, cqe_slot);
> + break;
> + }
> +
> + last = swq->next_idx;
> + }
> + return cqe_sq_cons;
> +}
> +
> static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> struct cq_req *hwcqe,
> struct bnxt_qplib_cqe **pcqe, int *budget,
> @@ -2481,6 +2507,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> struct bnxt_qplib_qp *qp;
> struct bnxt_qplib_q *sq;
> u32 cqe_sq_cons;
> + int cqe_cons;
> int rc = 0;
>
> qp = (struct bnxt_qplib_qp *)((unsigned long)
> @@ -2498,6 +2525,19 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> "%s: QP in Flush QP = %p\n", __func__, qp);
> goto done;
> }
> +
> + if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
> + cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
> + if (cqe_cons < 0) {
> + dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
> + __func__, hwcqe->sq_cons_idx);
> + goto done;
> + }
> + cqe_sq_cons = cqe_cons;
> + dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
> + __func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
> + }
> +
> /* Require to walk the sq's swq to fabricate CQEs for all previously
> * signaled SWQEs due to CQE aggregation from the current sq cons
> * to the cqe_sq_cons
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> index f54d7a0..2e7a4fd 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> @@ -649,4 +649,14 @@ static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn)
> (((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) &
> SQ_MSN_SEARCH_START_PSN_MASK));
> }
> +
> +static inline bool __is_var_wqe(struct bnxt_qplib_qp *qp)
IIRC, inline is not needed here. The compiler will determine if the
function inline is needed or not.
It is a trivial problem.
Zhu Yanjun
> +{
> + return (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE);
> +}
> +
> +static inline bool __is_err_cqe_for_var_wqe(struct bnxt_qplib_qp *qp, u8 status)
ditto.
> +{
> + return (status != CQ_REQ_STATUS_OK) && __is_var_wqe(qp);
> +}
> #endif /* __BNXT_QPLIB_FP_H__ */
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs
2024-08-12 8:48 ` Zhu Yanjun
@ 2024-08-12 10:08 ` Leon Romanovsky
2024-08-12 10:45 ` Zhu Yanjun
0 siblings, 1 reply; 8+ messages in thread
From: Leon Romanovsky @ 2024-08-12 10:08 UTC (permalink / raw)
To: Zhu Yanjun
Cc: Selvin Xavier, jgg, linux-rdma, andrew.gospodarek, Hongguang Gao
On Mon, Aug 12, 2024 at 04:48:44PM +0800, Zhu Yanjun wrote:
> 在 2024/8/11 3:19, Selvin Xavier 写道:
> > While reporting the completions, SQ Work Queue index is required to
> > identify the WQE that generated the completions. In variable WQE mode,
> > FW returns the slot index for Error completions. Driver need to walk
> > through the shadow queue between the consumer index and producer index
> > and matches the slot index returned by FW. If a match is found, the next
> > index of the shadow queue is the WQE index to be considered for remaining
> > poll_cq loop.
> >
> > Signed-off-by: Hongguang Gao <hong``guang.gao@broadcom.com>
> > Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > ---
> > drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 ++++++++++++++++++++++++++++++++
> > drivers/infiniband/hw/bnxt_re/qplib_fp.h | 10 ++++++++
> > 2 files changed, 50 insertions(+)
> >
> > diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> > index 0af09e7..b49f49c 100644
> > --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> > +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> > @@ -2471,6 +2471,32 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
> > return rc;
> > }
> > +static int bnxt_qplib_get_cqe_sq_cons(struct bnxt_qplib_q *sq, u32 cqe_slot)
> > +{
> > + struct bnxt_qplib_hwq *sq_hwq;
> > + struct bnxt_qplib_swq *swq;
> > + int cqe_sq_cons = -1;
> > + u32 start, last;
> > +
> > + sq_hwq = &sq->hwq;
> > +
> > + start = sq->swq_start;
> > + last = sq->swq_last;
> > +
> > + while (last != start) {
> > + swq = &sq->swq[last];
> > + if (swq->slot_idx == cqe_slot) {
> > + cqe_sq_cons = swq->next_idx;
> > + dev_err(&sq_hwq->pdev->dev, "%s: Found cons wqe = %d slot = %d\n",
> > + __func__, cqe_sq_cons, cqe_slot);
> > + break;
> > + }
> > +
> > + last = swq->next_idx;
> > + }
> > + return cqe_sq_cons;
> > +}
> > +
> > static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> > struct cq_req *hwcqe,
> > struct bnxt_qplib_cqe **pcqe, int *budget,
> > @@ -2481,6 +2507,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> > struct bnxt_qplib_qp *qp;
> > struct bnxt_qplib_q *sq;
> > u32 cqe_sq_cons;
> > + int cqe_cons;
> > int rc = 0;
> > qp = (struct bnxt_qplib_qp *)((unsigned long)
> > @@ -2498,6 +2525,19 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
> > "%s: QP in Flush QP = %p\n", __func__, qp);
> > goto done;
> > }
> > +
> > + if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
> > + cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
> > + if (cqe_cons < 0) {
> > + dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
> > + __func__, hwcqe->sq_cons_idx);
> > + goto done;
> > + }
> > + cqe_sq_cons = cqe_cons;
> > + dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
> > + __func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
> > + }
> > +
> > /* Require to walk the sq's swq to fabricate CQEs for all previously
> > * signaled SWQEs due to CQE aggregation from the current sq cons
> > * to the cqe_sq_cons
> > diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> > index f54d7a0..2e7a4fd 100644
> > --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> > +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> > @@ -649,4 +649,14 @@ static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn)
> > (((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) &
> > SQ_MSN_SEARCH_START_PSN_MASK));
> > }
> > +
> > +static inline bool __is_var_wqe(struct bnxt_qplib_qp *qp)
>
> IIRC, inline is not needed here. The compiler will determine if the function
> inline is needed or not.
Selvin added inline functions to *.h file and not to *.c file.
Thanks
>
> It is a trivial problem.
>
> Zhu Yanjun
>
> > +{
> > + return (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE);
> > +}
> > +
> > +static inline bool __is_err_cqe_for_var_wqe(struct bnxt_qplib_qp *qp, u8 status)
>
> ditto.
>
> > +{
> > + return (status != CQ_REQ_STATUS_OK) && __is_var_wqe(qp);
> > +}
> > #endif /* __BNXT_QPLIB_FP_H__ */
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs
2024-08-12 10:08 ` Leon Romanovsky
@ 2024-08-12 10:45 ` Zhu Yanjun
0 siblings, 0 replies; 8+ messages in thread
From: Zhu Yanjun @ 2024-08-12 10:45 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Selvin Xavier, jgg, linux-rdma, andrew.gospodarek, Hongguang Gao
在 2024/8/12 18:08, Leon Romanovsky 写道:
> On Mon, Aug 12, 2024 at 04:48:44PM +0800, Zhu Yanjun wrote:
>> 在 2024/8/11 3:19, Selvin Xavier 写道:
>>> While reporting the completions, SQ Work Queue index is required to
>>> identify the WQE that generated the completions. In variable WQE mode,
>>> FW returns the slot index for Error completions. Driver need to walk
>>> through the shadow queue between the consumer index and producer index
>>> and matches the slot index returned by FW. If a match is found, the next
>>> index of the shadow queue is the WQE index to be considered for remaining
>>> poll_cq loop.
>>>
>>> Signed-off-by: Hongguang Gao <hong``guang.gao@broadcom.com>
>>> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
>>> ---
>>> drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 ++++++++++++++++++++++++++++++++
>>> drivers/infiniband/hw/bnxt_re/qplib_fp.h | 10 ++++++++
>>> 2 files changed, 50 insertions(+)
>>>
>>> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
>>> index 0af09e7..b49f49c 100644
>>> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
>>> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
>>> @@ -2471,6 +2471,32 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
>>> return rc;
>>> }
>>> +static int bnxt_qplib_get_cqe_sq_cons(struct bnxt_qplib_q *sq, u32 cqe_slot)
>>> +{
>>> + struct bnxt_qplib_hwq *sq_hwq;
>>> + struct bnxt_qplib_swq *swq;
>>> + int cqe_sq_cons = -1;
>>> + u32 start, last;
>>> +
>>> + sq_hwq = &sq->hwq;
>>> +
>>> + start = sq->swq_start;
>>> + last = sq->swq_last;
>>> +
>>> + while (last != start) {
>>> + swq = &sq->swq[last];
>>> + if (swq->slot_idx == cqe_slot) {
>>> + cqe_sq_cons = swq->next_idx;
>>> + dev_err(&sq_hwq->pdev->dev, "%s: Found cons wqe = %d slot = %d\n",
>>> + __func__, cqe_sq_cons, cqe_slot);
>>> + break;
>>> + }
>>> +
>>> + last = swq->next_idx;
>>> + }
>>> + return cqe_sq_cons;
>>> +}
>>> +
>>> static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
>>> struct cq_req *hwcqe,
>>> struct bnxt_qplib_cqe **pcqe, int *budget,
>>> @@ -2481,6 +2507,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
>>> struct bnxt_qplib_qp *qp;
>>> struct bnxt_qplib_q *sq;
>>> u32 cqe_sq_cons;
>>> + int cqe_cons;
>>> int rc = 0;
>>> qp = (struct bnxt_qplib_qp *)((unsigned long)
>>> @@ -2498,6 +2525,19 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
>>> "%s: QP in Flush QP = %p\n", __func__, qp);
>>> goto done;
>>> }
>>> +
>>> + if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
>>> + cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
>>> + if (cqe_cons < 0) {
>>> + dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
>>> + __func__, hwcqe->sq_cons_idx);
>>> + goto done;
>>> + }
>>> + cqe_sq_cons = cqe_cons;
>>> + dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
>>> + __func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
>>> + }
>>> +
>>> /* Require to walk the sq's swq to fabricate CQEs for all previously
>>> * signaled SWQEs due to CQE aggregation from the current sq cons
>>> * to the cqe_sq_cons
>>> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
>>> index f54d7a0..2e7a4fd 100644
>>> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
>>> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
>>> @@ -649,4 +649,14 @@ static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn)
>>> (((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) &
>>> SQ_MSN_SEARCH_START_PSN_MASK));
>>> }
>>> +
>>> +static inline bool __is_var_wqe(struct bnxt_qplib_qp *qp)
>> IIRC, inline is not needed here. The compiler will determine if the function
>> inline is needed or not.
> Selvin added inline functions to *.h file and not to *.c file.
Yeah. I mistook that these 2 functions were in *.c file.
Thanks.
Zhu Yanjun
>
> Thanks
>
>> It is a trivial problem.
>>
>> Zhu Yanjun
>>
>>> +{
>>> + return (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE);
>>> +}
>>> +
>>> +static inline bool __is_err_cqe_for_var_wqe(struct bnxt_qplib_qp *qp, u8 status)
>> ditto.
>>
>>> +{
>>> + return (status != CQ_REQ_STATUS_OK) && __is_var_wqe(qp);
>>> +}
>>> #endif /* __BNXT_QPLIB_FP_H__ */
--
Best Regards,
Yanjun.Zhu
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-08-12 10:45 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-10 19:19 [PATCH for-next 0/4] RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 1/4] RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs Selvin Xavier
2024-08-12 8:48 ` Zhu Yanjun
2024-08-12 10:08 ` Leon Romanovsky
2024-08-12 10:45 ` Zhu Yanjun
2024-08-10 19:19 ` [PATCH for-next 3/4] RDMA/bnxt_re: Handle variable WQE support for user applications Selvin Xavier
2024-08-10 19:19 ` [PATCH for-next 4/4] RDMA/bnxt_re: Enable variable size WQEs for user space applications Selvin Xavier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.