From cdfb3b7b65cc1334ec52c259cfcc4cdfa830ed96 Mon Sep 17 00:00:00 2001 From: Zhou Juan Date: Thu, 11 May 2023 20:11:44 +0800 Subject: [PATCH] Fix the sge number related errors and remove local invalidate operation 1. 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. 2. In the sq inline scenario, when num_sge in post_send is not 1, sge array appears in the for loop without rotation and directly copy out of bounds. 3. Currently local invalidate operation don't work properly. Disable it for the time being. HIP08 and HIP09 hardware does not support this feature, so delete the associated code. Signed-off-by: Juan Zhou (cherry picked from commit 43c14b73409cf6e63278d5ff68e2694e592e9015) --- ...Fix-the-sge-num-problem-of-atomic-op.patch | 91 +++++++++++ 0045-libhns-Fix-sge-tail_len-overflow.patch | 55 +++++++ ...s-Disable-local-invalidate-operation.patch | 153 ++++++++++++++++++ rdma-core.spec | 11 +- 4 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 0044-libhns-Fix-the-sge-num-problem-of-atomic-op.patch create mode 100644 0045-libhns-Fix-sge-tail_len-overflow.patch create mode 100644 0046-libhns-Disable-local-invalidate-operation.patch diff --git a/0044-libhns-Fix-the-sge-num-problem-of-atomic-op.patch b/0044-libhns-Fix-the-sge-num-problem-of-atomic-op.patch new file mode 100644 index 0000000..a28b2b7 --- /dev/null +++ b/0044-libhns-Fix-the-sge-num-problem-of-atomic-op.patch @@ -0,0 +1,91 @@ +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 + diff --git a/0045-libhns-Fix-sge-tail_len-overflow.patch b/0045-libhns-Fix-sge-tail_len-overflow.patch new file mode 100644 index 0000000..de3d9da --- /dev/null +++ b/0045-libhns-Fix-sge-tail_len-overflow.patch @@ -0,0 +1,55 @@ +From 2653621c332c79ba591d76a442061bd13ad23030 Mon Sep 17 00:00:00 2001 +From: Luoyouming +Date: Sat, 6 May 2023 18:06:39 +0800 +Subject: [PATCH 2/3] libhns: Fix sge tail_len overflow + +mainline inclusion +commit cd9c9ea5 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I72F0C +CVE: NA + +---------------------------------------------------------------------- + +In the sq inline scenario, when num_sge in post_send is not 1, sge +array appears in the for loop without rotation and directly copy +out of bounds. + +The fill_ext_sge_inl_data() calculates the remaining length of the +array by subtracting the current address from the tail address. If +the length is not sufficient, redundant data will be copied after +rotating the array. However, in the code, sge_cnt & sge_mask always +equals to 0, which causes the tail address of the array to be +mistakenly taken as the first address. Additionally, tail_len will +be either 0 or may overflow when calculating this value. After +overflowing to a very large number, the driver makes an incorrect +judgment and copies all the data directly. When the data length +exceeds the remaining length, an out-of-bounds problem with the +array will occur. + +This patch modifies tail_bound_addr(tail pointer) to the actual sge +array tail address. + +Fixes: 2ced2bc4d1d4 ("libhns: Fix out-of-bounds write when filling inline data into extended sge space") +Signed-off-by: Luoyouming +Signed-off-by: Zhou Juan +--- + providers/hns/hns_roce_u_hw_v2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c +index 5533cdb..3d46f35 100644 +--- a/providers/hns/hns_roce_u_hw_v2.c ++++ b/providers/hns/hns_roce_u_hw_v2.c +@@ -1028,7 +1028,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp, + return EINVAL; + + dst_addr = get_send_sge_ex(qp, sge_info->start_idx & sge_mask); +- tail_bound_addr = get_send_sge_ex(qp, qp->ex_sge.sge_cnt & sge_mask); ++ tail_bound_addr = get_send_sge_ex(qp, qp->ex_sge.sge_cnt); + + for (i = 0; i < num_buf; i++) { + tail_len = (uintptr_t)tail_bound_addr - (uintptr_t)dst_addr; +-- +2.25.1 + diff --git a/0046-libhns-Disable-local-invalidate-operation.patch b/0046-libhns-Disable-local-invalidate-operation.patch new file mode 100644 index 0000000..b8a6668 --- /dev/null +++ b/0046-libhns-Disable-local-invalidate-operation.patch @@ -0,0 +1,153 @@ +From b3cea3522d575fdb60b6f426e43d45cec3deb847 Mon Sep 17 00:00:00 2001 +From: Yangyang Li +Date: Sat, 6 May 2023 18:06:40 +0800 +Subject: [PATCH 3/3] libhns: Disable local invalidate operation + +mainline inclusion +commit d8eec872 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I72F0U +CVE: NA + +---------------------------------------------------------------------- + +Currently local invalidate operation don't work properly. +Disable it for the time being. +HIP08 and HIP09 hardware does not support this feature, so +delete the associated code. + +Fixes: a9ae7e9bfb5d ("libhns: Add local invalidate MR support for hip08") +Signed-off-by: Yangyang Li +Signed-off-by: Zhou Juan +--- + providers/hns/hns_roce_u_hw_v2.c | 30 +----------------------------- + providers/hns/hns_roce_u_hw_v2.h | 2 -- + 2 files changed, 1 insertion(+), 31 deletions(-) + +diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c +index 3d46f35..b929bbf 100644 +--- a/providers/hns/hns_roce_u_hw_v2.c ++++ b/providers/hns/hns_roce_u_hw_v2.c +@@ -50,7 +50,6 @@ static const uint32_t hns_roce_opcode[] = { + HR_IBV_OPC_MAP(RDMA_READ, RDMA_READ), + HR_IBV_OPC_MAP(ATOMIC_CMP_AND_SWP, ATOMIC_COM_AND_SWAP), + HR_IBV_OPC_MAP(ATOMIC_FETCH_AND_ADD, ATOMIC_FETCH_AND_ADD), +- HR_IBV_OPC_MAP(LOCAL_INV, LOCAL_INV), + HR_IBV_OPC_MAP(BIND_MW, BIND_MW_TYPE), + HR_IBV_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV), + }; +@@ -429,7 +428,6 @@ static const unsigned int wc_send_op_map[] = { + [HNS_ROCE_SQ_OP_RDMA_READ] = IBV_WC_RDMA_READ, + [HNS_ROCE_SQ_OP_ATOMIC_COMP_AND_SWAP] = IBV_WC_COMP_SWAP, + [HNS_ROCE_SQ_OP_ATOMIC_FETCH_AND_ADD] = IBV_WC_FETCH_ADD, +- [HNS_ROCE_SQ_OP_LOCAL_INV] = IBV_WC_LOCAL_INV, + [HNS_ROCE_SQ_OP_BIND_MW] = IBV_WC_BIND_MW, + }; + +@@ -597,9 +595,6 @@ static void parse_cqe_for_req(struct hns_roce_v2_cqe *cqe, struct ibv_wc *wc, + case HNS_ROCE_SQ_OP_RDMA_WRITE_WITH_IMM: + wc->wc_flags = IBV_WC_WITH_IMM; + break; +- case HNS_ROCE_SQ_OP_LOCAL_INV: +- wc->wc_flags = IBV_WC_WITH_INV; +- break; + case HNS_ROCE_SQ_OP_RDMA_READ: + case HNS_ROCE_SQ_OP_ATOMIC_COMP_AND_SWAP: + case HNS_ROCE_SQ_OP_ATOMIC_FETCH_AND_ADD: +@@ -1338,9 +1333,6 @@ static int check_rc_opcode(struct hns_roce_rc_sq_wqe *wqe, + wqe->rkey = htole32(wr->wr.atomic.rkey); + wqe->va = htole64(wr->wr.atomic.remote_addr); + break; +- case IBV_WR_LOCAL_INV: +- hr_reg_enable(wqe, RCWQE_SO); +- /* fallthrough */ + case IBV_WR_SEND_WITH_INV: + wqe->inv_key = htole32(wr->invalidate_rkey); + break; +@@ -1372,7 +1364,6 @@ static int set_rc_wqe(void *wqe, struct hns_roce_qp *qp, struct ibv_send_wr *wr, + !!(wr->send_flags & IBV_SEND_SOLICITED)); + hr_reg_write_bool(wqe, RCWQE_INLINE, + !!(wr->send_flags & IBV_SEND_INLINE)); +- hr_reg_clear(wqe, RCWQE_SO); + + ret = check_rc_opcode(rc_sq_wqe, wr); + if (ret) +@@ -2092,8 +2083,6 @@ static unsigned int get_wc_flags_for_sq(uint8_t opcode) + case HNS_ROCE_SQ_OP_SEND_WITH_IMM: + case HNS_ROCE_SQ_OP_RDMA_WRITE_WITH_IMM: + return IBV_WC_WITH_IMM; +- case HNS_ROCE_SQ_OP_LOCAL_INV: +- return IBV_WC_WITH_INV; + default: + return 0; + } +@@ -2202,7 +2191,6 @@ init_rc_wqe(struct hns_roce_qp *qp, uint64_t wr_id, unsigned int opcode) + hr_reg_write_bool(wqe, RCWQE_FENCE, send_flags & IBV_SEND_FENCE); + hr_reg_write_bool(wqe, RCWQE_SE, send_flags & IBV_SEND_SOLICITED); + hr_reg_clear(wqe, RCWQE_INLINE); +- hr_reg_clear(wqe, RCWQE_SO); + + if (check_qp_dca_enable(qp)) + fill_rc_dca_fields(qp->verbs_qp.qp.qp_num, wqe); +@@ -2332,20 +2320,6 @@ static void wr_send_inv_rc(struct ibv_qp_ex *ibv_qp, uint32_t invalidate_rkey) + wqe->inv_key = htole32(invalidate_rkey); + } + +-static void wr_local_inv_rc(struct ibv_qp_ex *ibv_qp, uint32_t invalidate_rkey) +-{ +- struct hns_roce_qp *qp = to_hr_qp(&ibv_qp->qp_base); +- struct hns_roce_rc_sq_wqe *wqe; +- +- wqe = init_rc_wqe(qp, ibv_qp->wr_id, HNS_ROCE_WQE_OP_LOCAL_INV); +- if (!wqe) +- return; +- +- hr_reg_enable(wqe, RCWQE_SO); +- wqe->inv_key = htole32(invalidate_rkey); +- enable_wqe(qp, wqe, qp->sq.head); +-} +- + static void wr_set_xrc_srqn(struct ibv_qp_ex *ibv_qp, uint32_t remote_srqn) + { + struct hns_roce_qp *qp = to_hr_qp(&ibv_qp->qp_base); +@@ -2833,8 +2807,7 @@ enum { + IBV_QP_EX_WITH_RDMA_WRITE_WITH_IMM | + IBV_QP_EX_WITH_RDMA_READ | + IBV_QP_EX_WITH_ATOMIC_CMP_AND_SWP | +- IBV_QP_EX_WITH_ATOMIC_FETCH_AND_ADD | +- IBV_QP_EX_WITH_LOCAL_INV, ++ IBV_QP_EX_WITH_ATOMIC_FETCH_AND_ADD, + HNS_SUPPORTED_SEND_OPS_FLAGS_UD = + IBV_QP_EX_WITH_SEND | + IBV_QP_EX_WITH_SEND_WITH_IMM, +@@ -2850,7 +2823,6 @@ static void fill_send_wr_ops_rc_xrc(struct ibv_qp_ex *qp_ex) + qp_ex->wr_rdma_write_imm = wr_rdma_write_imm; + qp_ex->wr_set_inline_data = wr_set_inline_data_rc; + qp_ex->wr_set_inline_data_list = wr_set_inline_data_list_rc; +- qp_ex->wr_local_inv = wr_local_inv_rc; + qp_ex->wr_atomic_cmp_swp = wr_atomic_cmp_swp; + qp_ex->wr_atomic_fetch_add = wr_atomic_fetch_add; + qp_ex->wr_set_sge = wr_set_sge_rc; +diff --git a/providers/hns/hns_roce_u_hw_v2.h b/providers/hns/hns_roce_u_hw_v2.h +index a22995d..d628d76 100644 +--- a/providers/hns/hns_roce_u_hw_v2.h ++++ b/providers/hns/hns_roce_u_hw_v2.h +@@ -60,7 +60,6 @@ enum { + HNS_ROCE_WQE_OP_ATOMIC_MASK_COMP_AND_SWAP = 0x8, + HNS_ROCE_WQE_OP_ATOMIC_MASK_FETCH_AND_ADD = 0x9, + HNS_ROCE_WQE_OP_FAST_REG_PMR = 0xa, +- HNS_ROCE_WQE_OP_LOCAL_INV = 0xb, + HNS_ROCE_WQE_OP_BIND_MW_TYPE = 0xc, + HNS_ROCE_WQE_OP_MASK = 0x1f + }; +@@ -85,7 +84,6 @@ enum { + HNS_ROCE_SQ_OP_ATOMIC_MASK_COMP_AND_SWAP = 0x8, + HNS_ROCE_SQ_OP_ATOMIC_MASK_FETCH_AND_ADD = 0x9, + HNS_ROCE_SQ_OP_FAST_REG_PMR = 0xa, +- HNS_ROCE_SQ_OP_LOCAL_INV = 0xb, + HNS_ROCE_SQ_OP_BIND_MW = 0xc, + }; + +-- +2.25.1 + diff --git a/rdma-core.spec b/rdma-core.spec index 348ea1a..942228f 100644 --- a/rdma-core.spec +++ b/rdma-core.spec @@ -1,6 +1,6 @@ Name: rdma-core Version: 41.0 -Release: 10 +Release: 11 Summary: RDMA core userspace libraries and daemons License: GPLv2 or BSD Url: https://github.com/linux-rdma/rdma-core @@ -49,6 +49,9 @@ Patch39: 0040-Update-kernel-headers.patch Patch40: 0041-libhns-Support-congestion-control-algorithm-configur.patch Patch41: 0042-Update-kernel-headers.patch Patch42: 0043-libhns-Add-support-for-SVE-Direct-WQE.patch +Patch43: 0044-libhns-Fix-the-sge-num-problem-of-atomic-op.patch +Patch44: 0045-libhns-Fix-sge-tail_len-overflow.patch +Patch45: 0046-libhns-Disable-local-invalidate-operation.patch BuildRequires: binutils cmake >= 2.8.11 gcc libudev-devel pkgconfig pkgconfig(libnl-3.0) BuildRequires: pkgconfig(libnl-route-3.0) valgrind-devel systemd systemd-devel @@ -296,6 +299,12 @@ fi %{_mandir}/* %changelog +* Thu May 11 2023 Juan Zhou - 41.0-11 +- Type: bugfix +- ID: NA +- SUG: NA +- DESC: Fix the sge number related errors and remove local invalidate operation + * Mon Apr 17 2023 Juan Zhou - 41.0-10 - Type: bugfix - ID: NA -- Gitee