rdma-core/0043-libhns-Refactor-hns-roce-v2-poll-one-and-wc-poll-cqe.patch
zhengfeng luo 910edf6453 Support CQ_EX for hns
Add support for hns CQ_EX and all its dependent patches are also added.

Signed-off-by: zhengfeng luo <luozhengfeng@h-partners.com>
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
2022-08-29 21:05:59 +08:00

324 lines
8.6 KiB
Diff

From 9dd7b55957ccc720a6844613af9d43680d8fbaad Mon Sep 17 00:00:00 2001
From: Xinhao Liu <liuxinhao5@hisilicon.com>
Date: Mon, 7 Mar 2022 18:49:38 +0800
Subject: libhns: Refactor hns roce v2 poll one() and wc poll cqe()
hns_roce_v2_poll_one() and wc_poll_cqe() have a lot of repetitive code.
Aggregating the repetitive parts of these two functions into one function
hns_roce_poll_one() can reduce the repetitive code.
Signed-off-by: Xinhao Liu <liuxinhao5@hisilicon.com>
Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
---
providers/hns/hns_roce_u_hw_v2.c | 228 +++++++++++++++----------------
1 file changed, 107 insertions(+), 121 deletions(-)
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 2804450d..42a77151 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -285,6 +285,7 @@ static void hns_roce_update_rq_db(struct hns_roce_context *ctx,
static void hns_roce_update_sq_db(struct hns_roce_context *ctx,
struct hns_roce_qp *qp)
+
{
struct hns_roce_db sq_db = {};
@@ -548,21 +549,101 @@ static void parse_cqe_for_req(struct hns_roce_v2_cqe *cqe, struct ibv_wc *wc,
wc->opcode = wc_send_op_map[opcode];
}
-static int hns_roce_v2_poll_one(struct hns_roce_cq *cq,
- struct hns_roce_qp **cur_qp, struct ibv_wc *wc)
+static void cqe_proc_sq(struct hns_roce_qp *hr_qp, uint32_t wqe_idx,
+ struct hns_roce_cq *cq)
{
- struct hns_roce_context *ctx = to_hr_ctx(cq->verbs_cq.cq.context);
+ struct hns_roce_wq *wq = &hr_qp->sq;
+
+ if (hr_qp->sq_signal_bits)
+ wq->tail += (wqe_idx - wq->tail) & (wq->wqe_cnt - 1);
+
+ cq->verbs_cq.cq_ex.wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+ ++wq->tail;
+}
+
+static void cqe_proc_srq(struct hns_roce_srq *srq, uint32_t wqe_idx,
+ struct hns_roce_cq *cq)
+{
+ cq->verbs_cq.cq_ex.wr_id = srq->wrid[wqe_idx & (srq->wqe_cnt - 1)];
+ hns_roce_free_srq_wqe(srq, wqe_idx);
+}
+
+static void cqe_proc_rq(struct hns_roce_wq *wq, struct hns_roce_cq *cq)
+{
+ cq->verbs_cq.cq_ex.wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+ ++wq->tail;
+}
+
+static int cqe_proc_wq(struct hns_roce_context *ctx, struct hns_roce_qp *qp,
+ struct hns_roce_cq *cq)
+{
+ struct hns_roce_v2_cqe *cqe = cq->cqe;
+ struct hns_roce_srq *srq = NULL;
+ uint32_t wqe_idx;
+
+ wqe_idx = hr_reg_read(cqe, CQE_WQE_IDX);
+ if (hr_reg_read(cqe, CQE_S_R) == CQE_FOR_SQ) {
+ cqe_proc_sq(qp, wqe_idx, cq);
+ } else {
+ if (get_srq_from_cqe(cqe, ctx, qp, &srq))
+ return V2_CQ_POLL_ERR;
+
+ if (srq)
+ cqe_proc_srq(srq, wqe_idx, cq);
+ else
+ cqe_proc_rq(&qp->rq, cq);
+ }
+
+ return 0;
+}
+
+static int parse_cqe_for_cq(struct hns_roce_context *ctx, struct hns_roce_cq *cq,
+ struct hns_roce_qp *cur_qp, struct ibv_wc *wc)
+{
+ struct hns_roce_v2_cqe *cqe = cq->cqe;
struct hns_roce_srq *srq = NULL;
- struct hns_roce_v2_cqe *cqe;
uint8_t opcode;
- uint8_t status;
+
+ if (!wc) {
+ if (cqe_proc_wq(ctx, cur_qp, cq))
+ return V2_CQ_POLL_ERR;
+
+ return 0;
+ }
+
+ opcode = hr_reg_read(cqe, CQE_OPCODE);
+
+ if (hr_reg_read(cqe, CQE_S_R) == CQE_FOR_SQ) {
+ parse_cqe_for_req(cqe, wc, cur_qp, opcode);
+ } else {
+ wc->byte_len = le32toh(cqe->byte_cnt);
+ get_opcode_for_resp(cqe, wc, opcode);
+
+ if (get_srq_from_cqe(cqe, ctx, cur_qp, &srq))
+ return V2_CQ_POLL_ERR;
+
+ if (srq)
+ parse_cqe_for_srq(cqe, wc, srq);
+ else
+ parse_cqe_for_resp(cqe, wc, cur_qp, opcode);
+ }
+
+ return 0;
+}
+
+static int hns_roce_poll_one(struct hns_roce_context *ctx,
+ struct hns_roce_qp **cur_qp, struct hns_roce_cq *cq,
+ struct ibv_wc *wc)
+{
+ struct hns_roce_v2_cqe *cqe;
+ uint8_t status, wc_status;
uint32_t qpn;
- bool is_send;
cqe = next_cqe_sw_v2(cq);
if (!cqe)
- return V2_CQ_EMPTY;
+ return wc ? V2_CQ_EMPTY : ENOENT;
+ cq->cqe = cqe;
++cq->cons_index;
udma_from_device_barrier();
@@ -576,31 +657,20 @@ static int hns_roce_v2_poll_one(struct hns_roce_cq *cq,
return V2_CQ_POLL_ERR;
}
- opcode = hr_reg_read(cqe, CQE_OPCODE);
- is_send = hr_reg_read(cqe, CQE_S_R) == CQE_FOR_SQ;
- if (is_send) {
- parse_cqe_for_req(cqe, wc, *cur_qp, opcode);
- } else {
- wc->byte_len = le32toh(cqe->byte_cnt);
- get_opcode_for_resp(cqe, wc, opcode);
+ if (parse_cqe_for_cq(ctx, cq, *cur_qp, wc))
+ return V2_CQ_POLL_ERR;
- if (get_srq_from_cqe(cqe, ctx, *cur_qp, &srq))
- return V2_CQ_POLL_ERR;
+ status = hr_reg_read(cqe, CQE_STATUS);
+ wc_status = get_wc_status(status);
- if (srq) {
- parse_cqe_for_srq(cqe, wc, srq);
- } else {
- if (parse_cqe_for_resp(cqe, wc, *cur_qp, opcode))
- return V2_CQ_POLL_ERR;
- }
+ if (wc) {
+ wc->status = wc_status;
+ wc->vendor_err = hr_reg_read(cqe, CQE_SUB_STATUS);
+ wc->qp_num = qpn;
+ } else {
+ cq->verbs_cq.cq_ex.status = wc_status;
}
- wc->qp_num = qpn;
-
- status = hr_reg_read(cqe, CQE_STATUS);
- wc->status = get_wc_status(status);
- wc->vendor_err = hr_reg_read(cqe, CQE_SUB_STATUS);
-
if (status == HNS_ROCE_V2_CQE_SUCCESS)
return V2_CQ_OK;
@@ -614,16 +684,16 @@ static int hns_roce_v2_poll_one(struct hns_roce_cq *cq,
static int hns_roce_u_v2_poll_cq(struct ibv_cq *ibvcq, int ne,
struct ibv_wc *wc)
{
- int npolled;
- int err = V2_CQ_OK;
- struct hns_roce_qp *qp = NULL;
- struct hns_roce_cq *cq = to_hr_cq(ibvcq);
struct hns_roce_context *ctx = to_hr_ctx(ibvcq->context);
+ struct hns_roce_cq *cq = to_hr_cq(ibvcq);
+ struct hns_roce_qp *qp = NULL;
+ int err = V2_CQ_OK;
+ int npolled;
pthread_spin_lock(&cq->lock);
for (npolled = 0; npolled < ne; ++npolled) {
- err = hns_roce_v2_poll_one(cq, &qp, wc + npolled);
+ err = hns_roce_poll_one(ctx, &qp, cq, wc + npolled);
if (err != V2_CQ_OK)
break;
}
@@ -1651,97 +1721,12 @@ static int hns_roce_u_v2_post_srq_recv(struct ibv_srq *ib_srq,
return ret;
}
-static void cqe_proc_sq(struct hns_roce_qp *hr_qp, uint32_t wqe_idx,
- struct hns_roce_cq *cq)
-{
- struct hns_roce_wq *wq = &hr_qp->sq;
-
- if (hr_qp->sq_signal_bits)
- wq->tail += (wqe_idx - wq->tail) & (wq->wqe_cnt - 1);
-
- cq->verbs_cq.cq_ex.wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
- ++wq->tail;
-}
-
-static void cqe_proc_srq(struct hns_roce_srq *srq, uint32_t wqe_idx,
- struct hns_roce_cq *cq)
-{
- cq->verbs_cq.cq_ex.wr_id = srq->wrid[wqe_idx & (srq->wqe_cnt - 1)];
- hns_roce_free_srq_wqe(srq, wqe_idx);
-}
-
-static void cqe_proc_rq(struct hns_roce_qp *hr_qp, struct hns_roce_cq *cq)
-{
- struct hns_roce_wq *wq = &hr_qp->rq;
-
- cq->verbs_cq.cq_ex.wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
- ++wq->tail;
-}
-
-static int cqe_proc_wq(struct hns_roce_context *ctx, struct hns_roce_qp *qp,
- struct hns_roce_cq *cq)
-{
- struct hns_roce_v2_cqe *cqe = cq->cqe;
- struct hns_roce_srq *srq = NULL;
- uint32_t wqe_idx;
-
- wqe_idx = hr_reg_read(cqe, CQE_WQE_IDX);
- if (hr_reg_read(cqe, CQE_S_R) == CQE_FOR_SQ) {
- cqe_proc_sq(qp, wqe_idx, cq);
- } else {
- if (get_srq_from_cqe(cqe, ctx, qp, &srq))
- return V2_CQ_POLL_ERR;
-
- if (srq)
- cqe_proc_srq(srq, wqe_idx, cq);
- else
- cqe_proc_rq(qp, cq);
- }
- return 0;
-}
-
-static int wc_poll_cqe(struct hns_roce_context *ctx, struct hns_roce_cq *cq)
-{
- struct hns_roce_qp *qp = NULL;
- struct hns_roce_v2_cqe *cqe;
- uint8_t status;
- uint32_t qpn;
-
- cqe = next_cqe_sw_v2(cq);
- if (!cqe)
- return ENOENT;
-
- ++cq->cons_index;
- udma_from_device_barrier();
-
- cq->cqe = cqe;
- qpn = hr_reg_read(cqe, CQE_LCL_QPN);
-
- qp = hns_roce_v2_find_qp(ctx, qpn);
- if (!qp)
- return V2_CQ_POLL_ERR;
-
- if (cqe_proc_wq(ctx, qp, cq))
- return V2_CQ_POLL_ERR;
-
- status = hr_reg_read(cqe, CQE_STATUS);
- cq->verbs_cq.cq_ex.status = get_wc_status(status);
-
- if (status == HNS_ROCE_V2_CQE_SUCCESS)
- return V2_CQ_OK;
-
- /*
- * once a cqe in error status, the driver needs to help the HW to
- * generated flushed cqes for all subsequent wqes
- */
- return hns_roce_flush_cqe(qp, status);
-}
-
static int wc_start_poll_cq(struct ibv_cq_ex *current,
struct ibv_poll_cq_attr *attr)
{
struct hns_roce_cq *cq = to_hr_cq(ibv_cq_ex_to_cq(current));
struct hns_roce_context *ctx = to_hr_ctx(current->context);
+ struct hns_roce_qp *qp = NULL;
int err;
if (attr->comp_mask)
@@ -1749,7 +1734,7 @@ static int wc_start_poll_cq(struct ibv_cq_ex *current,
pthread_spin_lock(&cq->lock);
- err = wc_poll_cqe(ctx, cq);
+ err = hns_roce_poll_one(ctx, &qp, cq, NULL);
if (err != V2_CQ_OK)
pthread_spin_unlock(&cq->lock);
@@ -1760,9 +1745,10 @@ static int wc_next_poll_cq(struct ibv_cq_ex *current)
{
struct hns_roce_cq *cq = to_hr_cq(ibv_cq_ex_to_cq(current));
struct hns_roce_context *ctx = to_hr_ctx(current->context);
+ struct hns_roce_qp *qp = NULL;
int err;
- err = wc_poll_cqe(ctx, cq);
+ err = hns_roce_poll_one(ctx, &qp, cq, NULL);
if (err != V2_CQ_OK)
return err;
--
2.30.0