rdma-core/0039-libhns-Clear-remaining-unused-sges-when-post-recv.patch
zhengfeng luo 123f94ea3f Backport batch of bugfix and refactor patches for hns from rdma-core v39
These patches are mainly related to IO operations.

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

172 lines
5.0 KiB
Diff

From 85a5aa79327f45e4bea8d7ad0e55842225ca676a Mon Sep 17 00:00:00 2001
From: Wenpeng Liang <liangwenpeng@huawei.com>
Date: Tue, 18 Jan 2022 19:58:51 +0800
Subject: libhns: Clear remaining unused sges when post recv
The HIP09 requires the driver to clear the unused data segments in wqe
buffer to make the hns ROCEE stop reading the remaining invalid sges for
RQ.
Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
---
providers/hns/hns_roce_u_hw_v2.c | 88 ++++++++++++++------------------
1 file changed, 39 insertions(+), 49 deletions(-)
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 20745dc..6b0d7f1 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -85,14 +85,6 @@ static inline void set_data_seg_v2(struct hns_roce_v2_wqe_data_seg *dseg,
dseg->len = htole32(sg->length);
}
-/* Fill an ending sge to make hw stop reading the remaining sges in wqe */
-static inline void set_ending_data_seg(struct hns_roce_v2_wqe_data_seg *dseg)
-{
- dseg->lkey = htole32(0x0);
- dseg->addr = 0;
- dseg->len = htole32(INVALID_SGE_LENGTH);
-}
-
static void set_extend_atomic_seg(struct hns_roce_qp *qp, unsigned int sge_cnt,
struct hns_roce_sge_info *sge_info, void *buf)
{
@@ -1247,23 +1239,43 @@ static int check_qp_recv(struct ibv_qp *qp, struct hns_roce_context *ctx)
return 0;
}
-static void fill_rq_wqe(struct hns_roce_qp *qp, struct ibv_recv_wr *wr,
- unsigned int wqe_idx)
+static void fill_recv_sge_to_wqe(struct ibv_recv_wr *wr, void *wqe,
+ unsigned int max_sge, bool rsv)
{
- struct hns_roce_v2_wqe_data_seg *dseg;
- struct hns_roce_rinl_sge *sge_list;
- int i;
+ struct hns_roce_v2_wqe_data_seg *dseg = wqe;
+ unsigned int i, cnt;
- dseg = get_recv_wqe_v2(qp, wqe_idx);
- for (i = 0; i < wr->num_sge; i++) {
+ for (i = 0, cnt = 0; i < wr->num_sge; i++) {
+ /* Skip zero-length sge */
if (!wr->sg_list[i].length)
continue;
- set_data_seg_v2(dseg, wr->sg_list + i);
- dseg++;
+
+ set_data_seg_v2(dseg + cnt, wr->sg_list + i);
+ cnt++;
}
- if (qp->rq.rsv_sge)
- set_ending_data_seg(dseg);
+ /* Fill a reserved sge to make ROCEE stop reading remaining segments */
+ if (rsv) {
+ dseg[cnt].lkey = 0;
+ dseg[cnt].addr = 0;
+ dseg[cnt].len = htole32(INVALID_SGE_LENGTH);
+ } else {
+ /* Clear remaining segments to make ROCEE ignore sges */
+ if (cnt < max_sge)
+ memset(dseg + cnt, 0,
+ (max_sge - cnt) * HNS_ROCE_SGE_SIZE);
+ }
+}
+
+static void fill_rq_wqe(struct hns_roce_qp *qp, struct ibv_recv_wr *wr,
+ unsigned int wqe_idx, unsigned int max_sge)
+{
+ struct hns_roce_rinl_sge *sge_list;
+ unsigned int i;
+ void *wqe;
+
+ wqe = get_recv_wqe_v2(qp, wqe_idx);
+ fill_recv_sge_to_wqe(wr, wqe, max_sge, qp->rq.rsv_sge);
if (!qp->rq_rinl_buf.wqe_cnt)
return;
@@ -1310,7 +1322,7 @@ static int hns_roce_u_v2_post_recv(struct ibv_qp *ibvqp, struct ibv_recv_wr *wr,
}
wqe_idx = (qp->rq.head + nreq) & (qp->rq.wqe_cnt - 1);
- fill_rq_wqe(qp, wr, wqe_idx);
+ fill_rq_wqe(qp, wr, wqe_idx, max_sge);
qp->rq.wrid[wqe_idx] = wr->wr_id;
}
@@ -1536,10 +1548,8 @@ static int hns_roce_v2_srqwq_overflow(struct hns_roce_srq *srq)
}
static int check_post_srq_valid(struct hns_roce_srq *srq,
- struct ibv_recv_wr *wr)
+ struct ibv_recv_wr *wr, unsigned int max_sge)
{
- unsigned int max_sge = srq->max_gs - srq->rsv_sge;
-
if (hns_roce_v2_srqwq_overflow(srq))
return -ENOMEM;
@@ -1575,28 +1585,6 @@ static int get_wqe_idx(struct hns_roce_srq *srq, unsigned int *wqe_idx)
return 0;
}
-static void fill_srq_wqe(struct hns_roce_srq *srq, unsigned int wqe_idx,
- struct ibv_recv_wr *wr)
-{
- struct hns_roce_v2_wqe_data_seg *dseg;
- int i;
-
- dseg = get_srq_wqe(srq, wqe_idx);
-
- for (i = 0; i < wr->num_sge; ++i) {
- dseg[i].len = htole32(wr->sg_list[i].length);
- dseg[i].lkey = htole32(wr->sg_list[i].lkey);
- dseg[i].addr = htole64(wr->sg_list[i].addr);
- }
-
- /* hw stop reading when identify the last one */
- if (srq->rsv_sge) {
- dseg[i].len = htole32(INVALID_SGE_LENGTH);
- dseg[i].lkey = htole32(0x0);
- dseg[i].addr = 0;
- }
-}
-
static void fill_wqe_idx(struct hns_roce_srq *srq, unsigned int wqe_idx)
{
struct hns_roce_idx_que *idx_que = &srq->idx_que;
@@ -1624,15 +1612,16 @@ static int hns_roce_u_v2_post_srq_recv(struct ibv_srq *ib_srq,
{
struct hns_roce_context *ctx = to_hr_ctx(ib_srq->context);
struct hns_roce_srq *srq = to_hr_srq(ib_srq);
+ unsigned int wqe_idx, max_sge, nreq;
struct hns_roce_db srq_db;
- unsigned int wqe_idx;
int ret = 0;
- int nreq;
+ void *wqe;
pthread_spin_lock(&srq->lock);
+ max_sge = srq->max_gs - srq->rsv_sge;
for (nreq = 0; wr; ++nreq, wr = wr->next) {
- ret = check_post_srq_valid(srq, wr);
+ ret = check_post_srq_valid(srq, wr, max_sge);
if (ret) {
*bad_wr = wr;
break;
@@ -1644,7 +1633,8 @@ static int hns_roce_u_v2_post_srq_recv(struct ibv_srq *ib_srq,
break;
}
- fill_srq_wqe(srq, wqe_idx, wr);
+ wqe = get_srq_wqe(srq, wqe_idx);
+ fill_recv_sge_to_wqe(wr, wqe, max_sge, srq->rsv_sge);
fill_wqe_idx(srq, wqe_idx);
srq->wrid[wqe_idx] = wr->wr_id;
--
2.27.0