From b5127a009336e0e6947433148c6c7422c277bce7 Mon Sep 17 00:00:00 2001 From: Luoyouming Date: Sat, 6 May 2023 18:06:38 +0800 Subject: [PATCH 1/3] libhns: Fix the sge num problem of atomic op mainline inclusion commit b4793235 category: bugfix bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I72EWP CVE: NA ---------------------------------------------------------------------- The hns hardware logic requires wr->num_sge to be 1 when performing atomic operations. The code does not judge this condition, and the current patch adds this constraint. Fixes: 3507f87f7760 ("libhns: Optimize set_sge process") Fixes: 36446a56eea5 ("libhns: Extended QP supports the new post send mechanism") Signed-off-by: Luoyouming Signed-off-by: Zhou Juan --- providers/hns/hns_roce_u_hw_v2.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c index a49b50d..5533cdb 100644 --- a/providers/hns/hns_roce_u_hw_v2.c +++ b/providers/hns/hns_roce_u_hw_v2.c @@ -106,6 +106,9 @@ static int set_atomic_seg(struct hns_roce_qp *qp, struct ibv_send_wr *wr, void *buf[ATOMIC_BUF_NUM_MAX]; unsigned int buf_sge_num; + /* There is only one sge in atomic wr, and data_len is the data length + * in the first sge + */ if (is_std_atomic(data_len)) { if (wr->opcode == IBV_WR_ATOMIC_CMP_AND_SWP) { aseg->fetchadd_swap_data = htole64(wr->wr.atomic.swap); @@ -923,16 +926,19 @@ static void set_rc_sge(struct hns_roce_v2_wqe_data_seg *dseg, uint32_t mask = qp->ex_sge.sge_cnt - 1; uint32_t index = sge_info->start_idx; struct ibv_sge *sge = wr->sg_list; + int total_sge = wr->num_sge; + bool flag = false; uint32_t len = 0; uint32_t cnt = 0; - int flag; int i; - flag = (wr->send_flags & IBV_SEND_INLINE && - wr->opcode != IBV_WR_ATOMIC_FETCH_AND_ADD && - wr->opcode != IBV_WR_ATOMIC_CMP_AND_SWP); + if (wr->opcode == IBV_WR_ATOMIC_FETCH_AND_ADD || + wr->opcode == IBV_WR_ATOMIC_CMP_AND_SWP) + total_sge = 1; + else + flag = !!(wr->send_flags & IBV_SEND_INLINE); - for (i = 0; i < wr->num_sge; i++, sge++) { + for (i = 0; i < total_sge; i++, sge++) { if (unlikely(!sge->length)) continue; @@ -2267,6 +2273,7 @@ static void wr_set_sge_list_rc(struct ibv_qp_ex *ibv_qp, size_t num_sge, struct hns_roce_qp *qp = to_hr_qp(&ibv_qp->qp_base); struct hns_roce_rc_sq_wqe *wqe = qp->cur_wqe; struct hns_roce_v2_wqe_data_seg *dseg; + uint32_t opcode; if (!wqe) return; @@ -2276,9 +2283,15 @@ static void wr_set_sge_list_rc(struct ibv_qp_ex *ibv_qp, size_t num_sge, return; } + hr_reg_write(wqe, RCWQE_MSG_START_SGE_IDX, qp->sge_info.start_idx & (qp->ex_sge.sge_cnt - 1)); + opcode = hr_reg_read(wqe, RCWQE_OPCODE); + if (opcode == HNS_ROCE_WQE_OP_ATOMIC_COM_AND_SWAP || + opcode == HNS_ROCE_WQE_OP_ATOMIC_FETCH_AND_ADD) + num_sge = 1; + dseg = (void *)(wqe + 1); set_sgl_rc(dseg, qp, sg_list, num_sge); -- 2.25.1