High-performance-network
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- 2 participants
- 98 discussions
您好!
sig-high-performance-network 邀请您参加 2025-07-10 11:00 召开的Zoom会议(自动录制)
会议主题:High-performance-network SIG例会
会议链接:https://us06web.zoom.us/j/84375148100?pwd=bJ4jQahZXEwaqIDDNYbdTibpgOiHp0.1
会议纪要:https://etherpad.openeuler.org/p/sig-high-performance-network-meetings
更多资讯尽在:https://www.openeuler.org/zh/
Hello!
sig-high-performance-network invites you to attend the Zoom conference(auto recording) will be held at 2025-07-10 11:00,
The subject of the conference is High-performance-network SIG例会
You can join the meeting at https://us06web.zoom.us/j/84375148100?pwd=bJ4jQahZXEwaqIDDNYbdTibpgOiHp0.1
Add topics at https://etherpad.openeuler.org/p/sig-high-performance-network-meetings
More information: https://www.openeuler.org/en/
1
0
From: Guofeng Yue <yueguofeng(a)h-partners.com>
1. Fix the double-free of rinl_buf->wqe_list
2. Fix ret not assigned in create_srq
3. Sync the TD lock-free code of the community
Signed-off-by: Guofeng Yue <yueguofeng(a)h-partners.com>
---
...Fix-double-free-of-rinl-buf-wqe-list.patch | 48 ++
...s-Fix-ret-not-assigned-in-create-srq.patch | 46 ++
...hns-Add-error-logs-to-help-diagnosis.patch | 240 ++++++++
...lock-free-codes-from-mainline-driver.patch | 519 ++++++++++++++++++
...-Assign-ibv-srq-pd-when-creating-SRQ.patch | 31 ++
0104-libhns-Clean-up-data-type-issues.patch | 113 ++++
...hns-Add-debug-log-for-lock-free-mode.patch | 46 ++
rdma-core.spec | 15 +-
8 files changed, 1057 insertions(+), 1 deletion(-)
create mode 100644 0099-libhns-Fix-double-free-of-rinl-buf-wqe-list.patch
create mode 100644 0100-libhns-Fix-ret-not-assigned-in-create-srq.patch
create mode 100644 0101-libhns-Add-error-logs-to-help-diagnosis.patch
create mode 100644 0102-libhns-Sync-lock-free-codes-from-mainline-driver.patch
create mode 100644 0103-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
create mode 100644 0104-libhns-Clean-up-data-type-issues.patch
create mode 100644 0105-libhns-Add-debug-log-for-lock-free-mode.patch
diff --git a/0099-libhns-Fix-double-free-of-rinl-buf-wqe-list.patch b/0099-libhns-Fix-double-free-of-rinl-buf-wqe-list.patch
new file mode 100644
index 0000000..042c03d
--- /dev/null
+++ b/0099-libhns-Fix-double-free-of-rinl-buf-wqe-list.patch
@@ -0,0 +1,48 @@
+From 0a14854f63540a745fcda95872d4ae0298bbc5f0 Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Mon, 26 May 2025 21:20:29 +0800
+Subject: [PATCH 099/105] libhns: Fix double-free of rinl buf->wqe list
+
+rinl_buf->wqe_list will be double-freed in error flow, first in
+alloc_recv_rinl_buf() and then in free_recv_rinl_buf(). Actually
+free_recv_rinl_buf() shouldn't be called when alloc_recv_rinl_buf()
+failed.
+
+Fixes: 83b0baff3ccf ("libhns: Refactor rq inline")
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 7418d2c..7d83a33 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -1658,18 +1658,20 @@ static int qp_alloc_wqe(struct ibv_qp_init_attr_ex *attr,
+ qp->dca_wqe.shift = qp->pageshift;
+ qp->dca_wqe.bufs = calloc(qp->dca_wqe.max_cnt, sizeof(void *));
+ if (!qp->dca_wqe.bufs)
+- goto err_alloc;
++ goto err_alloc_recv_rinl_buf;
+ verbs_debug(&ctx->ibv_ctx, "alloc DCA buf.\n");
+ } else {
+ if (hns_roce_alloc_buf(&qp->buf, qp->buf_size,
+ 1 << qp->pageshift))
+- goto err_alloc;
++ goto err_alloc_recv_rinl_buf;
+ }
+
+ return 0;
+
+-err_alloc:
++err_alloc_recv_rinl_buf:
+ free_recv_rinl_buf(&qp->rq_rinl_buf);
++
++err_alloc:
+ if (qp->rq.wrid)
+ free(qp->rq.wrid);
+
+--
+2.33.0
+
diff --git a/0100-libhns-Fix-ret-not-assigned-in-create-srq.patch b/0100-libhns-Fix-ret-not-assigned-in-create-srq.patch
new file mode 100644
index 0000000..fa05de9
--- /dev/null
+++ b/0100-libhns-Fix-ret-not-assigned-in-create-srq.patch
@@ -0,0 +1,46 @@
+From 138d2d80aea27adea77fee042ba6107adaee8687 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:14 +0800
+Subject: [PATCH 100/105] libhns: Fix ret not assigned in create srq()
+
+Fix the problem that ret may not be assigned in the error flow
+of create_srq().
+
+Fixes: b38bae4b5b9e ("libhns: Add support for lock-free SRQ")
+Fixes: b914c76318f5 ("libhns: Refactor the process of create_srq")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 7d83a33..3a1c40e 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -1070,16 +1070,20 @@ static struct ibv_srq *create_srq(struct ibv_context *context,
+ goto err;
+ }
+
+- if (hns_roce_srq_spinlock_init(context, srq, init_attr))
++ ret = hns_roce_srq_spinlock_init(context, srq, init_attr);
++ if (ret)
+ goto err_free_srq;
+
+ set_srq_param(context, srq, init_attr);
+- if (alloc_srq_buf(srq))
++ ret = alloc_srq_buf(srq);
++ if (ret)
+ goto err_destroy_lock;
+
+ srq->rdb = hns_roce_alloc_db(hr_ctx, HNS_ROCE_SRQ_TYPE_DB);
+- if (!srq->rdb)
++ if (!srq->rdb) {
++ ret = ENOMEM;
+ goto err_srq_buf;
++ }
+
+ ret = exec_srq_create_cmd(context, srq, init_attr);
+ if (ret)
+--
+2.33.0
+
diff --git a/0101-libhns-Add-error-logs-to-help-diagnosis.patch b/0101-libhns-Add-error-logs-to-help-diagnosis.patch
new file mode 100644
index 0000000..1edde09
--- /dev/null
+++ b/0101-libhns-Add-error-logs-to-help-diagnosis.patch
@@ -0,0 +1,240 @@
+From b9513a369315c7d5c56b19b468369f1a6025d45f Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Fri, 27 Dec 2024 14:02:29 +0800
+Subject: [PATCH 101/105] libhns: Add error logs to help diagnosis
+
+Add error logs to help diagnosis.
+
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u.c | 4 +-
+ providers/hns/hns_roce_u_hw_v2.c | 3 ++
+ providers/hns/hns_roce_u_verbs.c | 87 +++++++++++++++++++++++++-------
+ 3 files changed, 74 insertions(+), 20 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
+index dfcd798..32a73c7 100644
+--- a/providers/hns/hns_roce_u.c
++++ b/providers/hns/hns_roce_u.c
+@@ -268,8 +268,10 @@ static int hns_roce_mmap(struct hns_roce_device *hr_dev,
+
+ context->uar = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, cmd_fd, 0);
+- if (context->uar == MAP_FAILED)
++ if (context->uar == MAP_FAILED) {
++ verbs_err(&context->ibv_ctx, "error: failed to mmap uar page.\n");
+ return -ENOMEM;
++ }
+
+ return 0;
+ }
+diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
+index 70fe2f7..56a42e7 100644
+--- a/providers/hns/hns_roce_u_hw_v2.c
++++ b/providers/hns/hns_roce_u_hw_v2.c
+@@ -3131,6 +3131,9 @@ static int fill_send_wr_ops(const struct ibv_qp_init_attr_ex *attr,
+ fill_send_wr_ops_ud(qp_ex);
+ break;
+ default:
++ verbs_err(verbs_get_ctx(qp_ex->qp_base.context),
++ "QP type %d not supported for qp_ex send ops.\n",
++ attr->qp_type);
+ return -EOPNOTSUPP;
+ }
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 3a1c40e..271525a 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -524,8 +524,11 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ struct hns_roce_context *context,
+ struct hnsdv_cq_init_attr *hns_cq_attr)
+ {
+- if (!attr->cqe || attr->cqe > context->max_cqe)
+- return -EINVAL;
++ if (!attr->cqe || attr->cqe > context->max_cqe) {
++ verbs_err(&context->ibv_ctx, "unsupported cq depth %u.\n",
++ attr->cqe);
++ return EINVAL;
++ }
+
+ if (!check_comp_mask(attr->comp_mask, CREATE_CQ_SUPPORTED_COMP_MASK)) {
+ verbs_err(&context->ibv_ctx, "unsupported cq comps 0x%x\n",
+@@ -533,8 +536,11 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ return EOPNOTSUPP;
+ }
+
+- if (!check_comp_mask(attr->wc_flags, CREATE_CQ_SUPPORTED_WC_FLAGS))
+- return -EOPNOTSUPP;
++ if (!check_comp_mask(attr->wc_flags, CREATE_CQ_SUPPORTED_WC_FLAGS)) {
++ verbs_err(&context->ibv_ctx, "unsupported wc flags 0x%llx.\n",
++ attr->wc_flags);
++ return EOPNOTSUPP;
++ }
+
+ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
+ if (!to_hr_pad(attr->parent_domain)) {
+@@ -617,8 +623,11 @@ static int exec_cq_create_cmd(struct ibv_context *context,
+ ret = ibv_cmd_create_cq_ex(context, attr, &cq->verbs_cq,
+ &cmd_ex.ibv_cmd, sizeof(cmd_ex),
+ &resp_ex.ibv_resp, sizeof(resp_ex), 0);
+- if (ret)
++ if (ret) {
++ verbs_err(verbs_get_ctx(context),
++ "failed to exec create cq cmd, ret = %d.\n", ret);
+ return ret;
++ }
+
+ cq->cqn = resp_drv->cqn;
+ cq->flags = resp_drv->cap_flags;
+@@ -877,13 +886,20 @@ static int verify_srq_create_attr(struct hns_roce_context *context,
+ struct ibv_srq_init_attr_ex *attr)
+ {
+ if (attr->srq_type != IBV_SRQT_BASIC &&
+- attr->srq_type != IBV_SRQT_XRC)
++ attr->srq_type != IBV_SRQT_XRC) {
++ verbs_err(&context->ibv_ctx,
++ "unsupported srq type, type = %d.\n", attr->srq_type);
+ return -EINVAL;
++ }
+
+ if (!attr->attr.max_sge ||
+ attr->attr.max_wr > context->max_srq_wr ||
+- attr->attr.max_sge > context->max_srq_sge)
++ attr->attr.max_sge > context->max_srq_sge) {
++ verbs_err(&context->ibv_ctx,
++ "invalid srq attr size, max_wr = %u, max_sge = %u.\n",
++ attr->attr.max_wr, attr->attr.max_sge);
+ return -EINVAL;
++ }
+
+ attr->attr.max_wr = max_t(uint32_t, attr->attr.max_wr,
+ HNS_ROCE_MIN_SRQ_WQE_NUM);
+@@ -1015,8 +1031,12 @@ static int exec_srq_create_cmd(struct ibv_context *context,
+ ret = ibv_cmd_create_srq_ex(context, &srq->verbs_srq, init_attr,
+ &cmd_ex.ibv_cmd, sizeof(cmd_ex),
+ &resp_ex.ibv_resp, sizeof(resp_ex));
+- if (ret)
++ if (ret) {
++ verbs_err(verbs_get_ctx(context),
++ "failed to exec create srq cmd, ret = %d.\n",
++ ret);
+ return ret;
++ }
+
+ srq->srqn = resp_ex.srqn;
+ srq->cap_flags = resp_ex.cap_flags;
+@@ -1340,9 +1360,12 @@ static int check_qp_create_mask(struct hns_roce_context *ctx,
+ struct ibv_qp_init_attr_ex *attr)
+ {
+ struct hns_roce_device *hr_dev = to_hr_dev(ctx->ibv_ctx.context.device);
++ int ret = 0;
+
+- if (!check_comp_mask(attr->comp_mask, CREATE_QP_SUP_COMP_MASK))
+- return -EOPNOTSUPP;
++ if (!check_comp_mask(attr->comp_mask, CREATE_QP_SUP_COMP_MASK)) {
++ ret = EOPNOTSUPP;
++ goto out;
++ }
+
+ if (attr->comp_mask & IBV_QP_INIT_ATTR_SEND_OPS_FLAGS &&
+ !check_comp_mask(attr->send_ops_flags, SEND_OPS_FLAG_MASK))
+@@ -1351,22 +1374,26 @@ static int check_qp_create_mask(struct hns_roce_context *ctx,
+ switch (attr->qp_type) {
+ case IBV_QPT_UD:
+ if (hr_dev->hw_version == HNS_ROCE_HW_VER2)
+- return -EINVAL;
++ return EINVAL;
+ SWITCH_FALLTHROUGH;
+ case IBV_QPT_RC:
+ case IBV_QPT_XRC_SEND:
+ if (!(attr->comp_mask & IBV_QP_INIT_ATTR_PD))
+- return -EINVAL;
++ ret = EINVAL;
+ break;
+ case IBV_QPT_XRC_RECV:
+ if (!(attr->comp_mask & IBV_QP_INIT_ATTR_XRCD))
+- return -EINVAL;
++ ret = EINVAL;
+ break;
+ default:
+- return -EINVAL;
++ return EOPNOTSUPP;
+ }
+
+- return 0;
++out:
++ if (ret)
++ verbs_err(&ctx->ibv_ctx, "invalid comp_mask 0x%x.\n",
++ attr->comp_mask);
++ return ret;
+ }
+
+ static int hns_roce_qp_has_rq(struct ibv_qp_init_attr_ex *attr)
+@@ -1391,8 +1418,13 @@ static int verify_qp_create_cap(struct hns_roce_context *ctx,
+ if (cap->max_send_wr > ctx->max_qp_wr ||
+ cap->max_recv_wr > ctx->max_qp_wr ||
+ cap->max_send_sge > ctx->max_sge ||
+- cap->max_recv_sge > ctx->max_sge)
++ cap->max_recv_sge > ctx->max_sge) {
++ verbs_err(&ctx->ibv_ctx,
++ "invalid qp cap size, max_send/recv_wr = {%u, %u}, max_send/recv_sge = {%u, %u}.\n",
++ cap->max_send_wr, cap->max_recv_wr,
++ cap->max_send_sge, cap->max_recv_sge);
+ return -EINVAL;
++ }
+
+ has_rq = hns_roce_qp_has_rq(attr);
+ if (!has_rq) {
+@@ -1401,12 +1433,20 @@ static int verify_qp_create_cap(struct hns_roce_context *ctx,
+ }
+
+ min_wqe_num = HNS_ROCE_V2_MIN_WQE_NUM;
+- if (cap->max_send_wr < min_wqe_num)
++ if (cap->max_send_wr < min_wqe_num) {
++ verbs_debug(&ctx->ibv_ctx,
++ "change sq depth from %u to minimum %u.\n",
++ cap->max_send_wr, min_wqe_num);
+ cap->max_send_wr = min_wqe_num;
++ }
+
+ if (cap->max_recv_wr) {
+- if (cap->max_recv_wr < min_wqe_num)
++ if (cap->max_recv_wr < min_wqe_num) {
++ verbs_debug(&ctx->ibv_ctx,
++ "change rq depth from %u to minimum %u.\n",
++ cap->max_recv_wr, min_wqe_num);
+ cap->max_recv_wr = min_wqe_num;
++ }
+
+ if (!cap->max_recv_sge)
+ return -EINVAL;
+@@ -1916,6 +1956,11 @@ static int qp_exec_create_cmd(struct ibv_qp_init_attr_ex *attr,
+ ret = ibv_cmd_create_qp_ex2(&ctx->ibv_ctx.context, &qp->verbs_qp, attr,
+ &cmd_ex.ibv_cmd, sizeof(cmd_ex),
+ &resp_ex.ibv_resp, sizeof(resp_ex));
++ if (ret) {
++ verbs_err(&ctx->ibv_ctx,
++ "failed to exec create qp cmd, ret = %d.\n", ret);
++ return ret;
++ }
+
+ qp->flags = resp_ex.drv_payload.cap_flags;
+ *dwqe_mmap_key = resp_ex.drv_payload.dwqe_mmap_key;
+@@ -1977,8 +2022,12 @@ static int mmap_dwqe(struct ibv_context *ibv_ctx, struct hns_roce_qp *qp,
+ {
+ qp->dwqe_page = mmap(NULL, HNS_ROCE_DWQE_PAGE_SIZE, PROT_WRITE,
+ MAP_SHARED, ibv_ctx->cmd_fd, dwqe_mmap_key);
+- if (qp->dwqe_page == MAP_FAILED)
++ if (qp->dwqe_page == MAP_FAILED) {
++ verbs_err(verbs_get_ctx(ibv_ctx),
++ "failed to mmap direct wqe page, QPN = %u.\n",
++ qp->verbs_qp.qp.qp_num);
+ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.33.0
+
diff --git a/0102-libhns-Sync-lock-free-codes-from-mainline-driver.patch b/0102-libhns-Sync-lock-free-codes-from-mainline-driver.patch
new file mode 100644
index 0000000..62509e3
--- /dev/null
+++ b/0102-libhns-Sync-lock-free-codes-from-mainline-driver.patch
@@ -0,0 +1,519 @@
+From 8cd132d5f4aa489b9eeaa3f43865c41e4ac28101 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 19 Mar 2025 18:13:52 +0800
+Subject: [PATCH 102/105] libhns: Sync lock-free codes from mainline driver
+
+Sync lock-free codes from mainline driver. There is only one functional
+change that add pad refcnt when creating qp/cq/srq, and other changes
+are mostly coding cleanup.
+
+The mainline PR was:
+https://github.com/linux-rdma/rdma-core/pull/1482
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/f877d6e610e438515e1535c9ec7a3a3ef37c58e0
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/234d135276ea8ef83633113e224e0cd735ebeca8
+
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u.h | 1 +
+ providers/hns/hns_roce_u_hw_v2.c | 18 +++-
+ providers/hns/hns_roce_u_hw_v2.h | 4 +-
+ providers/hns/hns_roce_u_verbs.c | 163 ++++++++++++++-----------------
+ 4 files changed, 88 insertions(+), 98 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
+index 863d4b5..7f5872c 100644
+--- a/providers/hns/hns_roce_u.h
++++ b/providers/hns/hns_roce_u.h
+@@ -318,6 +318,7 @@ struct hns_roce_cq {
+ unsigned long flags;
+ unsigned int cqe_size;
+ struct hns_roce_v2_cqe *cqe;
++ struct ibv_pd *parent_domain;
+ struct list_head list_sq;
+ struct list_head list_rq;
+ struct list_head list_srq;
+diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
+index 56a42e7..acb373c 100644
+--- a/providers/hns/hns_roce_u_hw_v2.c
++++ b/providers/hns/hns_roce_u_hw_v2.c
+@@ -1976,8 +1976,11 @@ static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
+ return ret;
+ }
+
+-void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
++void hns_roce_lock_cqs(struct ibv_qp *qp)
+ {
++ struct hns_roce_cq *send_cq = to_hr_cq(qp->send_cq);
++ struct hns_roce_cq *recv_cq = to_hr_cq(qp->recv_cq);
++
+ if (send_cq && recv_cq) {
+ if (send_cq == recv_cq) {
+ hns_roce_spin_lock(&send_cq->hr_lock);
+@@ -1995,8 +1998,11 @@ void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
+ }
+ }
+
+-void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
++void hns_roce_unlock_cqs(struct ibv_qp *qp)
+ {
++ struct hns_roce_cq *send_cq = to_hr_cq(qp->send_cq);
++ struct hns_roce_cq *recv_cq = to_hr_cq(qp->recv_cq);
++
+ if (send_cq && recv_cq) {
+ if (send_cq == recv_cq) {
+ hns_roce_spin_unlock(&send_cq->hr_lock);
+@@ -2017,6 +2023,7 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_c
+ static int hns_roce_u_v2_destroy_qp(struct ibv_qp *ibqp)
+ {
+ struct hns_roce_context *ctx = to_hr_ctx(ibqp->context);
++ struct hns_roce_pad *pad = to_hr_pad(ibqp->pd);
+ struct hns_roce_qp *qp = to_hr_qp(ibqp);
+ int ret;
+
+@@ -2029,7 +2036,7 @@ static int hns_roce_u_v2_destroy_qp(struct ibv_qp *ibqp)
+
+ hns_roce_v2_clear_qp(ctx, qp);
+
+- hns_roce_lock_cqs(to_hr_cq(ibqp->send_cq), to_hr_cq(ibqp->recv_cq));
++ hns_roce_lock_cqs(ibqp);
+
+ if (ibqp->recv_cq) {
+ __hns_roce_v2_cq_clean(to_hr_cq(ibqp->recv_cq), ibqp->qp_num,
+@@ -2045,11 +2052,14 @@ static int hns_roce_u_v2_destroy_qp(struct ibv_qp *ibqp)
+ list_del(&qp->scq_node);
+ }
+
+- hns_roce_unlock_cqs(to_hr_cq(ibqp->send_cq), to_hr_cq(ibqp->recv_cq));
++ hns_roce_unlock_cqs(ibqp);
+
+ hns_roce_free_qp_buf(qp, ctx);
+ hns_roce_qp_spinlock_destroy(qp);
+
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
++
+ free(qp);
+
+ if (ctx->dca_ctx.mem_cnt > 0)
+diff --git a/providers/hns/hns_roce_u_hw_v2.h b/providers/hns/hns_roce_u_hw_v2.h
+index fa83bbe..01d16ac 100644
+--- a/providers/hns/hns_roce_u_hw_v2.h
++++ b/providers/hns/hns_roce_u_hw_v2.h
+@@ -347,7 +347,7 @@ void hns_roce_v2_clear_qp(struct hns_roce_context *ctx, struct hns_roce_qp *qp);
+ void hns_roce_attach_cq_ex_ops(struct ibv_cq_ex *cq_ex, uint64_t wc_flags);
+ int hns_roce_attach_qp_ex_ops(struct ibv_qp_init_attr_ex *attr,
+ struct hns_roce_qp *qp);
+-void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq);
+-void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq);
++void hns_roce_lock_cqs(struct ibv_qp *qp);
++void hns_roce_unlock_cqs(struct ibv_qp *qp);
+
+ #endif /* _HNS_ROCE_U_HW_V2_H */
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 271525a..0708b95 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -44,16 +44,11 @@
+ #include "hns_roce_u_db.h"
+ #include "hns_roce_u_hw_v2.h"
+
+-static int hns_roce_whether_need_lock(struct ibv_pd *pd)
++static bool hns_roce_whether_need_lock(struct ibv_pd *pd)
+ {
+- struct hns_roce_pad *pad;
+- bool need_lock = true;
+-
+- pad = to_hr_pad(pd);
+- if (pad && pad->td)
+- need_lock = false;
++ struct hns_roce_pad *pad = to_hr_pad(pd);
+
+- return need_lock;
++ return !(pad && pad->td);
+ }
+
+ static int hns_roce_spinlock_init(struct hns_roce_spinlock *hr_lock,
+@@ -165,7 +160,7 @@ struct ibv_td *hns_roce_u_alloc_td(struct ibv_context *context,
+ struct hns_roce_td *td;
+
+ if (attr->comp_mask) {
+- errno = EINVAL;
++ errno = EOPNOTSUPP;
+ return NULL;
+ }
+
+@@ -184,19 +179,14 @@ struct ibv_td *hns_roce_u_alloc_td(struct ibv_context *context,
+ int hns_roce_u_dealloc_td(struct ibv_td *ibv_td)
+ {
+ struct hns_roce_td *td;
+- int ret = 0;
+
+ td = to_hr_td(ibv_td);
+- if (atomic_load(&td->refcount) > 1) {
+- ret = -EBUSY;
+- goto err;
+- }
++ if (atomic_load(&td->refcount) > 1)
++ return EBUSY;
+
+ free(td);
+
+-err:
+- errno = abs(ret);
+- return ret;
++ return 0;
+ }
+
+ struct ibv_pd *hns_roce_u_alloc_pd(struct ibv_context *context)
+@@ -204,7 +194,6 @@ struct ibv_pd *hns_roce_u_alloc_pd(struct ibv_context *context)
+ struct hns_roce_alloc_pd_resp resp = {};
+ struct ibv_alloc_pd cmd;
+ struct hns_roce_pd *pd;
+- int ret;
+
+ pd = calloc(1, sizeof(*pd));
+ if (!pd) {
+@@ -212,10 +201,9 @@ struct ibv_pd *hns_roce_u_alloc_pd(struct ibv_context *context)
+ return NULL;
+ }
+
+- ret = ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd, sizeof(cmd),
+- &resp.ibv_resp, sizeof(resp));
+-
+- if (ret)
++ errno = ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd, sizeof(cmd),
++ &resp.ibv_resp, sizeof(resp));
++ if (errno)
+ goto err;
+
+ atomic_init(&pd->refcount, 1);
+@@ -225,7 +213,6 @@ struct ibv_pd *hns_roce_u_alloc_pd(struct ibv_context *context)
+
+ err:
+ free(pd);
+- errno = abs(ret);
+ return NULL;
+ }
+
+@@ -256,41 +243,40 @@ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ pad->pd.protection_domain = to_hr_pd(attr->pd);
+ atomic_fetch_add(&pad->pd.protection_domain->refcount, 1);
+
++ atomic_init(&pad->pd.refcount, 1);
+ ibv_initialize_parent_domain(&pad->pd.ibv_pd,
+ &pad->pd.protection_domain->ibv_pd);
+
+ return &pad->pd.ibv_pd;
+ }
+
+-static void hns_roce_free_pad(struct hns_roce_pad *pad)
++static int hns_roce_free_pad(struct hns_roce_pad *pad)
+ {
++ if (atomic_load(&pad->pd.refcount) > 1)
++ return EBUSY;
++
+ atomic_fetch_sub(&pad->pd.protection_domain->refcount, 1);
+
+ if (pad->td)
+ atomic_fetch_sub(&pad->td->refcount, 1);
+
+ free(pad);
++ return 0;
+ }
+
+ static int hns_roce_free_pd(struct hns_roce_pd *pd)
+ {
+ int ret;
+
+- if (atomic_load(&pd->refcount) > 1) {
+- ret = -EBUSY;
+- goto err;
+- }
++ if (atomic_load(&pd->refcount) > 1)
++ return EBUSY;
+
+ ret = ibv_cmd_dealloc_pd(&pd->ibv_pd);
+ if (ret)
+- goto err;
++ return ret;
+
+ free(pd);
+-
+-err:
+- errno = abs(ret);
+-
+- return ret;
++ return 0;
+ }
+
+ int hns_roce_u_dealloc_pd(struct ibv_pd *ibv_pd)
+@@ -298,10 +284,8 @@ int hns_roce_u_dealloc_pd(struct ibv_pd *ibv_pd)
+ struct hns_roce_pad *pad = to_hr_pad(ibv_pd);
+ struct hns_roce_pd *pd = to_hr_pd(ibv_pd);
+
+- if (pad) {
+- hns_roce_free_pad(pad);
+- return 0;
+- }
++ if (pad)
++ return hns_roce_free_pad(pad);
+
+ return hns_roce_free_pd(pd);
+ }
+@@ -524,6 +508,8 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ struct hns_roce_context *context,
+ struct hnsdv_cq_init_attr *hns_cq_attr)
+ {
++ struct hns_roce_pad *pad = to_hr_pad(attr->parent_domain);
++
+ if (!attr->cqe || attr->cqe > context->max_cqe) {
+ verbs_err(&context->ibv_ctx, "unsupported cq depth %u.\n",
+ attr->cqe);
+@@ -542,11 +528,9 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ return EOPNOTSUPP;
+ }
+
+- if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
+- if (!to_hr_pad(attr->parent_domain)) {
+- verbs_err(&context->ibv_ctx, "failed to check the pad of cq.\n");
+- return EINVAL;
+- }
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD && !pad) {
++ verbs_err(&context->ibv_ctx, "failed to check the pad of cq.\n");
++ return EINVAL;
+ }
+
+ attr->cqe = max_t(uint32_t, HNS_ROCE_MIN_CQE_NUM,
+@@ -668,19 +652,10 @@ static void hns_roce_uninit_cq_swc(struct hns_roce_cq *cq)
+ }
+ }
+
+-static int hns_roce_cq_spinlock_init(struct ibv_context *context,
+- struct hns_roce_cq *cq,
++static int hns_roce_cq_spinlock_init(struct hns_roce_cq *cq,
+ struct ibv_cq_init_attr_ex *attr)
+ {
+- struct hns_roce_pad *pad = NULL;
+- int need_lock;
+-
+- if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD)
+- pad = to_hr_pad(attr->parent_domain);
+-
+- need_lock = hns_roce_whether_need_lock(pad ? &pad->pd.ibv_pd : NULL);
+- if (!need_lock)
+- verbs_info(verbs_get_ctx(context), "configure cq as no lock.\n");
++ bool need_lock = hns_roce_whether_need_lock(attr->parent_domain);
+
+ return hns_roce_spinlock_init(&cq->hr_lock, need_lock);
+ }
+@@ -689,6 +664,7 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *attr,
+ struct hnsdv_cq_init_attr *hns_cq_attr)
+ {
++ struct hns_roce_pad *pad = to_hr_pad(attr->parent_domain);
+ struct hns_roce_context *hr_ctx = to_hr_ctx(context);
+ struct hns_roce_cq *cq;
+ int ret;
+@@ -703,7 +679,12 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
+ goto err;
+ }
+
+- ret = hns_roce_cq_spinlock_init(context, cq, attr);
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
++ cq->parent_domain = attr->parent_domain;
++ atomic_fetch_add(&pad->pd.refcount, 1);
++ }
++
++ ret = hns_roce_cq_spinlock_init(cq, attr);
+ if (ret)
+ goto err_lock;
+
+@@ -741,6 +722,8 @@ err_db:
+ err_buf:
+ hns_roce_spinlock_destroy(&cq->hr_lock);
+ err_lock:
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(cq);
+ err:
+ errno = abs(ret);
+@@ -813,6 +796,7 @@ int hns_roce_u_modify_cq(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr)
+ int hns_roce_u_destroy_cq(struct ibv_cq *cq)
+ {
+ struct hns_roce_cq *hr_cq = to_hr_cq(cq);
++ struct hns_roce_pad *pad = to_hr_pad(hr_cq->parent_domain);
+ int ret;
+
+ ret = ibv_cmd_destroy_cq(cq);
+@@ -827,6 +811,9 @@ int hns_roce_u_destroy_cq(struct ibv_cq *cq)
+
+ hns_roce_spinlock_destroy(&hr_cq->hr_lock);
+
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
++
+ free(hr_cq);
+
+ return ret;
+@@ -1060,15 +1047,10 @@ static void init_srq_cq_list(struct hns_roce_srq *srq,
+ hns_roce_spin_unlock(&srq_cq->hr_lock);
+ }
+
+-static int hns_roce_srq_spinlock_init(struct ibv_context *context,
+- struct hns_roce_srq *srq,
++static int hns_roce_srq_spinlock_init(struct hns_roce_srq *srq,
+ struct ibv_srq_init_attr_ex *attr)
+ {
+- int need_lock;
+-
+- need_lock = hns_roce_whether_need_lock(attr->pd);
+- if (!need_lock)
+- verbs_info(verbs_get_ctx(context), "configure srq as no lock.\n");
++ bool need_lock = hns_roce_whether_need_lock(attr->pd);
+
+ return hns_roce_spinlock_init(&srq->hr_lock, need_lock);
+ }
+@@ -1077,6 +1059,7 @@ static struct ibv_srq *create_srq(struct ibv_context *context,
+ struct ibv_srq_init_attr_ex *init_attr)
+ {
+ struct hns_roce_context *hr_ctx = to_hr_ctx(context);
++ struct hns_roce_pad *pad = to_hr_pad(init_attr->pd);
+ struct hns_roce_srq *srq;
+ int ret;
+
+@@ -1089,8 +1072,10 @@ static struct ibv_srq *create_srq(struct ibv_context *context,
+ ret = -ENOMEM;
+ goto err;
+ }
++ if (pad)
++ atomic_fetch_add(&pad->pd.refcount, 1);
+
+- ret = hns_roce_srq_spinlock_init(context, srq, init_attr);
++ ret = hns_roce_srq_spinlock_init(srq, init_attr);
+ if (ret)
+ goto err_free_srq;
+
+@@ -1134,6 +1119,8 @@ err_destroy_lock:
+ hns_roce_spinlock_destroy(&srq->hr_lock);
+
+ err_free_srq:
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(srq);
+
+ err:
+@@ -1209,6 +1196,7 @@ static void del_srq_from_cq_list(struct hns_roce_srq *srq)
+ int hns_roce_u_destroy_srq(struct ibv_srq *ibv_srq)
+ {
+ struct hns_roce_context *ctx = to_hr_ctx(ibv_srq->context);
++ struct hns_roce_pad *pad = to_hr_pad(ibv_srq->pd);
+ struct hns_roce_srq *srq = to_hr_srq(ibv_srq);
+ int ret;
+
+@@ -1224,6 +1212,10 @@ int hns_roce_u_destroy_srq(struct ibv_srq *ibv_srq)
+ free_srq_buf(srq);
+
+ hns_roce_spinlock_destroy(&srq->hr_lock);
++
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
++
+ free(srq);
+
+ return 0;
+@@ -1478,38 +1470,19 @@ static int verify_qp_create_attr(struct hns_roce_context *ctx,
+ return verify_qp_create_cap(ctx, attr);
+ }
+
+-static int hns_roce_qp_spinlock_init(struct hns_roce_context *ctx,
+- struct ibv_qp_init_attr_ex *attr,
++static int hns_roce_qp_spinlock_init(struct ibv_qp_init_attr_ex *attr,
+ struct hns_roce_qp *qp)
+ {
+- int sq_need_lock;
+- int rq_need_lock;
++ bool need_lock = hns_roce_whether_need_lock(attr->pd);
+ int ret;
+
+- sq_need_lock = hns_roce_whether_need_lock(attr->pd);
+- if (!sq_need_lock)
+- verbs_warn(&ctx->ibv_ctx, "configure sq as no lock.\n");
+-
+- rq_need_lock = hns_roce_whether_need_lock(attr->pd);
+- if (!rq_need_lock)
+- verbs_warn(&ctx->ibv_ctx, "configure rq as no lock.\n");
+-
+- ret = hns_roce_spinlock_init(&qp->sq.hr_lock, sq_need_lock);
+- if (ret) {
+- verbs_err(&ctx->ibv_ctx, "failed to init sq spinlock.\n");
++ ret = hns_roce_spinlock_init(&qp->sq.hr_lock, need_lock);
++ if (ret)
+ return ret;
+- }
+-
+- ret = hns_roce_spinlock_init(&qp->rq.hr_lock, rq_need_lock);
+- if (ret) {
+- verbs_err(&ctx->ibv_ctx, "failed to init rq spinlock.\n");
+- goto err_rq_lock;
+- }
+-
+- return 0;
+
+-err_rq_lock:
+- hns_roce_spinlock_destroy(&qp->sq.hr_lock);
++ ret = hns_roce_spinlock_init(&qp->rq.hr_lock, need_lock);
++ if (ret)
++ hns_roce_spinlock_destroy(&qp->sq.hr_lock);
+
+ return ret;
+ }
+@@ -2044,7 +2017,7 @@ static void add_qp_to_cq_list(struct ibv_qp_init_attr_ex *attr,
+ list_node_init(&qp->rcq_node);
+ list_node_init(&qp->srcq_node);
+
+- hns_roce_lock_cqs(send_cq, recv_cq);
++ hns_roce_lock_cqs(&qp->verbs_qp.qp);
+ if (send_cq)
+ list_add_tail(&send_cq->list_sq, &qp->scq_node);
+ if (recv_cq) {
+@@ -2053,7 +2026,7 @@ static void add_qp_to_cq_list(struct ibv_qp_init_attr_ex *attr,
+ else
+ list_add_tail(&recv_cq->list_rq, &qp->rcq_node);
+ }
+- hns_roce_unlock_cqs(send_cq, recv_cq);
++ hns_roce_unlock_cqs(&qp->verbs_qp.qp);
+ }
+
+ static struct ibv_qp *create_qp(struct ibv_context *ibv_ctx,
+@@ -2061,6 +2034,7 @@ static struct ibv_qp *create_qp(struct ibv_context *ibv_ctx,
+ struct hnsdv_qp_init_attr *hns_attr)
+ {
+ struct hns_roce_context *context = to_hr_ctx(ibv_ctx);
++ struct hns_roce_pad *pad = to_hr_pad(attr->pd);
+ struct hns_roce_cmd_flag cmd_flag = {};
+ struct hns_roce_qp *qp;
+ uint64_t dwqe_mmap_key;
+@@ -2078,7 +2052,10 @@ static struct ibv_qp *create_qp(struct ibv_context *ibv_ctx,
+
+ hns_roce_set_qp_params(attr, qp, context);
+
+- ret = hns_roce_qp_spinlock_init(context, attr, qp);
++ if (pad)
++ atomic_fetch_add(&pad->pd.refcount, 1);
++
++ ret = hns_roce_qp_spinlock_init(attr, qp);
+ if (ret)
+ goto err_spinlock;
+
+@@ -2121,6 +2098,8 @@ err_cmd:
+ err_buf:
+ hns_roce_qp_spinlock_destroy(qp);
+ err_spinlock:
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(qp);
+ err:
+ if (ret < 0)
+--
+2.33.0
+
diff --git a/0103-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch b/0103-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
new file mode 100644
index 0000000..c4d3f96
--- /dev/null
+++ b/0103-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
@@ -0,0 +1,31 @@
+From 93ddf71e89c8a8a4c0e2d7bf2d1f1d2c1bc3d903 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:17 +0800
+Subject: [PATCH 103/105] verbs: Assign ibv srq->pd when creating SRQ
+
+Some providers need to access ibv_srq->pd during SRQ destruction, but
+it may not be assigned currently when using ibv_create_srq_ex(). This
+may lead to some SRQ-related resource leaks. Assign ibv_srq->pd when
+creating SRQ to ensure pd can be obtained correctly.
+
+Fixes: 40c1365b2198 ("Add support for XRC SRQs")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ libibverbs/cmd_srq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libibverbs/cmd_srq.c b/libibverbs/cmd_srq.c
+index dfaaa6a..259ea0d 100644
+--- a/libibverbs/cmd_srq.c
++++ b/libibverbs/cmd_srq.c
+@@ -63,6 +63,7 @@ static int ibv_icmd_create_srq(struct ibv_pd *pd, struct verbs_srq *vsrq,
+ struct verbs_xrcd *vxrcd = NULL;
+ enum ibv_srq_type srq_type;
+
++ srq->pd = pd;
+ srq->context = pd->context;
+ pthread_mutex_init(&srq->mutex, NULL);
+ pthread_cond_init(&srq->cond, NULL);
+--
+2.33.0
+
diff --git a/0104-libhns-Clean-up-data-type-issues.patch b/0104-libhns-Clean-up-data-type-issues.patch
new file mode 100644
index 0000000..1f69533
--- /dev/null
+++ b/0104-libhns-Clean-up-data-type-issues.patch
@@ -0,0 +1,113 @@
+From a20bcd29a5c2194f947f1ce24970b4be9d1cf32a Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Thu, 13 Mar 2025 17:26:50 +0800
+Subject: [PATCH 104/105] libhns: Clean up data type issues
+
+Clean up mixed signed/unsigned type issues. Fix a wrong format
+character as well.
+
+Fixes: cf6d9149f8f5 ("libhns: Introduce hns direct verbs")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u.h | 2 +-
+ providers/hns/hns_roce_u_hw_v2.c | 13 +++++++------
+ providers/hns/hns_roce_u_verbs.c | 4 ++--
+ 3 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
+index 7f5872c..3e9b487 100644
+--- a/providers/hns/hns_roce_u.h
++++ b/providers/hns/hns_roce_u.h
+@@ -367,7 +367,7 @@ struct hns_roce_wq {
+ unsigned long *wrid;
+ struct hns_roce_spinlock hr_lock;
+ unsigned int wqe_cnt;
+- int max_post;
++ unsigned int max_post;
+ unsigned int head;
+ unsigned int tail;
+ unsigned int max_gs;
+diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
+index acb373c..70e5b1f 100644
+--- a/providers/hns/hns_roce_u_hw_v2.c
++++ b/providers/hns/hns_roce_u_hw_v2.c
+@@ -173,7 +173,7 @@ static enum ibv_wc_status get_wc_status(uint8_t status)
+ { HNS_ROCE_V2_CQE_XRC_VIOLATION_ERR, IBV_WC_REM_INV_RD_REQ_ERR },
+ };
+
+- for (int i = 0; i < ARRAY_SIZE(map); i++) {
++ for (unsigned int i = 0; i < ARRAY_SIZE(map); i++) {
+ if (status == map[i].cqe_status)
+ return map[i].wc_status;
+ }
+@@ -1216,7 +1216,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ unsigned int sge_mask = qp->ex_sge.sge_cnt - 1;
+ void *dst_addr, *src_addr, *tail_bound_addr;
+ uint32_t src_len, tail_len;
+- int i;
++ uint32_t i;
+
+ if (sge_info->total_len > qp->sq.ext_sge_cnt * HNS_ROCE_SGE_SIZE)
+ return EINVAL;
+@@ -1286,7 +1286,7 @@ static void fill_ud_inn_inl_data(const struct ibv_send_wr *wr,
+
+ static bool check_inl_data_len(struct hns_roce_qp *qp, unsigned int len)
+ {
+- int mtu = mtu_enum_to_int(qp->path_mtu);
++ unsigned int mtu = mtu_enum_to_int(qp->path_mtu);
+
+ return (len <= qp->max_inline_data && len <= mtu);
+ }
+@@ -1727,7 +1727,8 @@ 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 = wqe;
+- unsigned int i, cnt;
++ unsigned int cnt;
++ int i;
+
+ for (i = 0, cnt = 0; i < wr->num_sge; i++) {
+ /* Skip zero-length sge */
+@@ -2090,7 +2091,7 @@ static int check_post_srq_valid(struct hns_roce_srq *srq,
+ static int get_wqe_idx(struct hns_roce_srq *srq, unsigned int *wqe_idx)
+ {
+ struct hns_roce_idx_que *idx_que = &srq->idx_que;
+- int bit_num;
++ unsigned int bit_num;
+ int i;
+
+ /* bitmap[i] is set zero if all bits are allocated */
+@@ -2499,7 +2500,7 @@ static void set_sgl_rc(struct hns_roce_v2_wqe_data_seg *dseg,
+ unsigned int mask = qp->ex_sge.sge_cnt - 1;
+ unsigned int msg_len = 0;
+ unsigned int cnt = 0;
+- int i;
++ unsigned int i;
+
+ for (i = 0; i < num_sge; i++) {
+ if (!sge[i].length)
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 0708b95..1ea7501 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -510,7 +510,7 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ {
+ struct hns_roce_pad *pad = to_hr_pad(attr->parent_domain);
+
+- if (!attr->cqe || attr->cqe > context->max_cqe) {
++ if (!attr->cqe || attr->cqe > (uint32_t)context->max_cqe) {
+ verbs_err(&context->ibv_ctx, "unsupported cq depth %u.\n",
+ attr->cqe);
+ return EINVAL;
+@@ -1497,7 +1497,7 @@ static int alloc_recv_rinl_buf(uint32_t max_sge,
+ struct hns_roce_rinl_buf *rinl_buf)
+ {
+ unsigned int cnt;
+- int i;
++ unsigned int i;
+
+ cnt = rinl_buf->wqe_cnt;
+ rinl_buf->wqe_list = calloc(cnt,
+--
+2.33.0
+
diff --git a/0105-libhns-Add-debug-log-for-lock-free-mode.patch b/0105-libhns-Add-debug-log-for-lock-free-mode.patch
new file mode 100644
index 0000000..28b0762
--- /dev/null
+++ b/0105-libhns-Add-debug-log-for-lock-free-mode.patch
@@ -0,0 +1,46 @@
+From 8954a581ff8b82d6cb3cca93f8558c86091ea155 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Thu, 24 Apr 2025 20:32:12 +0800
+Subject: [PATCH 105/105] libhns: Add debug log for lock-free mode
+
+Currently there is no way to observe whether the lock-free mode is
+configured from the driver's perspective. Add debug log for this.
+
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 1ea7501..8491431 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -219,6 +219,7 @@ err:
+ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ struct ibv_parent_domain_init_attr *attr)
+ {
++ struct hns_roce_pd *protection_domain;
+ struct hns_roce_pad *pad;
+
+ if (ibv_check_alloc_parent_domain(attr))
+@@ -235,12 +236,16 @@ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ return NULL;
+ }
+
++ protection_domain = to_hr_pd(attr->pd);
+ if (attr->td) {
+ pad->td = to_hr_td(attr->td);
+ atomic_fetch_add(&pad->td->refcount, 1);
++ verbs_debug(verbs_get_ctx(context),
++ "set PAD(0x%x) to lock-free mode.\n",
++ protection_domain->pdn);
+ }
+
+- pad->pd.protection_domain = to_hr_pd(attr->pd);
++ pad->pd.protection_domain = protection_domain;
+ atomic_fetch_add(&pad->pd.protection_domain->refcount, 1);
+
+ atomic_init(&pad->pd.refcount, 1);
+--
+2.33.0
+
diff --git a/rdma-core.spec b/rdma-core.spec
index 131cbd6..098ddcc 100644
--- a/rdma-core.spec
+++ b/rdma-core.spec
@@ -1,6 +1,6 @@
Name: rdma-core
Version: 41.0
-Release: 35
+Release: 36
Summary: RDMA core userspace libraries and daemons
License: GPLv2 or BSD
Url: https://github.com/linux-rdma/rdma-core
@@ -104,6 +104,13 @@ patch95: 0095-libhns-Adapt-UD-inline-data-size-for-UCX.patch
patch96: 0096-libhns-Fix-wrong-order-of-spin_unlock-in-modify_qp.patch
patch97: 0097-libxscale-Match-dev-by-vid-and-did.patch
patch98: 0098-libxscale-update-to-version-2412GA.patch
+patch99: 0099-libhns-Fix-double-free-of-rinl-buf-wqe-list.patch
+patch100: 0100-libhns-Fix-ret-not-assigned-in-create-srq.patch
+patch101: 0101-libhns-Add-error-logs-to-help-diagnosis.patch
+patch102: 0102-libhns-Sync-lock-free-codes-from-mainline-driver.patch
+patch103: 0103-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
+patch104: 0104-libhns-Clean-up-data-type-issues.patch
+patch105: 0105-libhns-Add-debug-log-for-lock-free-mode.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
@@ -354,6 +361,12 @@ fi
%{_mandir}/*
%changelog
+* Fir Jul 4 2025 Guofeng Yue <yueguofeng(a)h-partners.com> - 41.0-36
+- Type: bugfix
+- ID: NA
+- SUG: NA
+- DESC: sync some patches for libhns
+
* Wed May 14 2025 Xin Tian <tianx(a)yunsilicon.com> - 41.0-35
- Type: feature
- ID: NA
--
2.33.0
1
0
From: wenglianfa <wenglianfa(a)huawei.com>
Currently static compilation with lttng tracing enabled fails with
the following errors:
In file included from /home/rdma-core/providers/rxe/rxe_trace.c:9:
/rdma-core/providers/rxe/rxe_trace.h:12:38: fatal error: rxe_trace.h: No such file or directory
12 | #define LTTNG_UST_TRACEPOINT_INCLUDE "rxe_trace.h"
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [providers/rxe/CMakeFiles/rxe.dir/build.make:76: providers/rxe/CMakeFiles/rxe.dir/rxe_trace.c.o] Error 1
make[2]: *** Waiting for unfinished jobs....
In file included from /home/rdma-core/providers/efa/efa_trace.c:9:
/home/rdma-core/providers/efa/efa_trace.h:12:38: fatal error: efa_trace.h: No such file or directory
12 | #define LTTNG_UST_TRACEPOINT_INCLUDE "efa_trace.h"
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [providers/efa/CMakeFiles/efa-static.dir/build.make:76: providers/efa/CMakeFiles/efa-static.dir/efa_trace.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:3085: providers/efa/CMakeFiles/efa-static.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
In file included from /home/rdma-core/providers/mlx5/mlx5_trace.c:9:
/home/rdma-core/providers/mlx5/mlx5_trace.h:12:38: fatal error: mlx5_trace.h: No such file or directory
12 | #define LTTNG_UST_TRACEPOINT_INCLUDE "mlx5_trace.h"
| ^~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [providers/mlx5/CMakeFiles/mlx5-static.dir/build.make:76: providers/mlx5/CMakeFiles/mlx5-static.dir/mlx5_trace.c.o] Error 1
make[2]: *** Waiting for unfinished jobs....
In file included from /home/rdma-core/providers/hns/hns_roce_u_trace.c:9:
/home/rdma-core/providers/hns/hns_roce_u_trace.h:12:38: fatal error: hns_roce_u_trace.h: No such file or directory
12 | #define LTTNG_UST_TRACEPOINT_INCLUDE "hns_roce_u_trace.h"
| ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
Fix it by linking the library and including drivers' directories for
static compilation.
Fixes: 382b359d990c ("efa: Add support for LTTng tracing")
Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
providers/efa/CMakeLists.txt | 4 ++++
providers/hns/CMakeLists.txt | 4 ++++
providers/mlx5/CMakeLists.txt | 4 ++++
providers/rxe/CMakeLists.txt | 4 ++++
4 files changed, 16 insertions(+)
diff --git a/providers/efa/CMakeLists.txt b/providers/efa/CMakeLists.txt
index e999f3b77..865317446 100644
--- a/providers/efa/CMakeLists.txt
+++ b/providers/efa/CMakeLists.txt
@@ -18,4 +18,8 @@ rdma_pkg_config("efa" "libibverbs" "${CMAKE_THREAD_LIBS_INIT}")
if (ENABLE_LTTNG AND LTTNGUST_FOUND)
target_include_directories(efa PUBLIC ".")
target_link_libraries(efa LINK_PRIVATE LTTng::UST)
+ if (ENABLE_STATIC)
+ target_include_directories(efa-static PUBLIC ".")
+ target_link_libraries(efa-static LINK_PRIVATE LTTng::UST)
+ endif()
endif()
diff --git a/providers/hns/CMakeLists.txt b/providers/hns/CMakeLists.txt
index 36ebfacfb..7277cd65f 100644
--- a/providers/hns/CMakeLists.txt
+++ b/providers/hns/CMakeLists.txt
@@ -21,4 +21,8 @@ rdma_pkg_config("hns" "libibverbs" "${CMAKE_THREAD_LIBS_INIT}")
if (ENABLE_LTTNG AND LTTNGUST_FOUND)
target_include_directories(hns PUBLIC ".")
target_link_libraries(hns LINK_PRIVATE LTTng::UST)
+ if (ENABLE_STATIC)
+ target_include_directories(hns-static PUBLIC ".")
+ target_link_libraries(hns-static LINK_PRIVATE LTTng::UST)
+ endif()
endif()
diff --git a/providers/mlx5/CMakeLists.txt b/providers/mlx5/CMakeLists.txt
index 4a438d911..92f4e1b18 100644
--- a/providers/mlx5/CMakeLists.txt
+++ b/providers/mlx5/CMakeLists.txt
@@ -57,4 +57,8 @@ rdma_pkg_config("mlx5" "libibverbs" "${CMAKE_THREAD_LIBS_INIT}")
if (ENABLE_LTTNG AND LTTNGUST_FOUND)
target_include_directories(mlx5 PUBLIC ".")
target_link_libraries(mlx5 LINK_PRIVATE LTTng::UST)
+ if (ENABLE_STATIC)
+ target_include_directories(mlx5-static PUBLIC ".")
+ target_link_libraries(mlx5-static LINK_PRIVATE LTTng::UST)
+ endif()
endif()
diff --git a/providers/rxe/CMakeLists.txt b/providers/rxe/CMakeLists.txt
index 0fdc1cb3e..8a0a16842 100644
--- a/providers/rxe/CMakeLists.txt
+++ b/providers/rxe/CMakeLists.txt
@@ -10,4 +10,8 @@ rdma_provider(rxe
if (ENABLE_LTTNG AND LTTNGUST_FOUND)
target_include_directories("rxe-rdmav${IBVERBS_PABI_VERSION}" PUBLIC ".")
target_link_libraries("rxe-rdmav${IBVERBS_PABI_VERSION}" LINK_PRIVATE LTTng::UST)
+ if (ENABLE_STATIC)
+ target_include_directories(rxe PUBLIC ".")
+ target_link_libraries(rxe LINK_PRIVATE LTTng::UST)
+ endif()
endif()
--
2.33.0
1
3

13 Jun '25
From: Guofeng Yue <yueguofeng(a)h-partners.com>
Sync some patches from mainline
Signed-off-by: Guofeng Yue <yueguofeng(a)h-partners.com>
---
...replace-rand-with-getrandom-during-M.patch | 91 +++++++++++++++
...m-buffer-initialization-optimization.patch | 82 ++++++++++++++
...st-Fix-perform-warm-up-process-stuck.patch | 64 +++++++++++
...lock-free-mode-not-working-for-SRQ-X.patch | 105 ++++++++++++++++++
0020-Perftest-Fix-recv-cq-leak.patch | 54 +++++++++
perftest.spec | 13 ++-
6 files changed, 408 insertions(+), 1 deletion(-)
create mode 100644 0016-Revert-Perftest-replace-rand-with-getrandom-during-M.patch
create mode 100644 0017-Perftest-random-buffer-initialization-optimization.patch
create mode 100644 0018-Perftest-Fix-perform-warm-up-process-stuck.patch
create mode 100644 0019-Perftest-Fix-TD-lock-free-mode-not-working-for-SRQ-X.patch
create mode 100644 0020-Perftest-Fix-recv-cq-leak.patch
diff --git a/0016-Revert-Perftest-replace-rand-with-getrandom-during-M.patch b/0016-Revert-Perftest-replace-rand-with-getrandom-during-M.patch
new file mode 100644
index 0000000..0551e6d
--- /dev/null
+++ b/0016-Revert-Perftest-replace-rand-with-getrandom-during-M.patch
@@ -0,0 +1,91 @@
+From 454a41de4caa020a900eb9511fc49069ef10c53d Mon Sep 17 00:00:00 2001
+From: Guofeng Yue <yueguofeng(a)h-partners.com>
+Date: Mon, 9 Jun 2025 14:51:20 +0800
+Subject: [PATCH 16/20] Revert "Perftest: replace rand() with getrandom()
+ during MR buffer initialization"
+
+This reverts commit 189406b72d9d94c3c95298ba65ad9ce4ae90405b.
+---
+ configure.ac | 1 -
+ src/perftest_resources.c | 31 +++++--------------------------
+ 2 files changed, 5 insertions(+), 27 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index d976663..a756488 100755
+--- a/configure.ac
++++ b/configure.ac
+@@ -60,7 +60,6 @@ AC_PROG_LIBTOOL
+ AC_PROG_RANLIB
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS([infiniband/verbs.h],,[AC_MSG_ERROR([ibverbs header files not found])])
+-AC_CHECK_HEADERS([sys/random.h],,)
+ AC_CHECK_LIB([ibverbs], [ibv_get_device_list], [], [AC_MSG_ERROR([libibverbs not found])])
+ AC_CHECK_LIB([rdmacm], [rdma_create_event_channel], [], AC_MSG_ERROR([librdmacm-devel not found]))
+ AC_CHECK_LIB([ibumad], [umad_init], [LIBUMAD=-libumad], AC_MSG_ERROR([libibumad not found]))
+diff --git a/src/perftest_resources.c b/src/perftest_resources.c
+index 843c45f..6609afc 100755
+--- a/src/perftest_resources.c
++++ b/src/perftest_resources.c
+@@ -22,9 +22,6 @@
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+-#ifdef HAVE_SYS_RANDOM_H
+-#include <sys/random.h>
+-#endif
+ #ifdef HAVE_SRD
+ #include <infiniband/efadv.h>
+ #endif
+@@ -1604,33 +1601,12 @@ int create_cqs(struct pingpong_context *ctx, struct perftest_parameters *user_pa
+ return ret;
+ }
+
+-static void random_data(char *buf, int buff_size)
+-{
+- int i;
+-#ifdef HAVE_SYS_RANDOM_H
+- char *tmp = buf;
+- int ret;
+-
+- for(i = buff_size; i > 0;) {
+- ret = getrandom(tmp, i, 0);
+- if(ret < 0)
+- goto fall_back;
+- tmp += ret;
+- i -= ret;
+- }
+- return;
+-fall_back:
+-#endif
+- srand(time(NULL));
+- for (i = 0; i < buff_size; i++)
+- buf[i] = (char)rand();
+-}
+-
+ /******************************************************************************
+ *
+ ******************************************************************************/
+ int create_single_mr(struct pingpong_context *ctx, struct perftest_parameters *user_param, int qp_index)
+ {
++ int i;
+ int flags = IBV_ACCESS_LOCAL_WRITE;
+
+
+@@ -1769,10 +1745,13 @@ int create_single_mr(struct pingpong_context *ctx, struct perftest_parameters *u
+ #ifdef HAVE_CUDA
+ if (!user_param->use_cuda) {
+ #endif
++ srand(time(NULL));
+ if (user_param->verb == WRITE && user_param->tst == LAT) {
+ memset(ctx->buf[qp_index], 0, ctx->buff_size);
+ } else {
+- random_data(ctx->buf[qp_index], ctx->buff_size);
++ for (i = 0; i < ctx->buff_size; i++) {
++ ((char*)ctx->buf[qp_index])[i] = (char)rand();
++ }
+ }
+ #ifdef HAVE_CUDA
+ }
+--
+2.33.0
+
diff --git a/0017-Perftest-random-buffer-initialization-optimization.patch b/0017-Perftest-random-buffer-initialization-optimization.patch
new file mode 100644
index 0000000..fd48325
--- /dev/null
+++ b/0017-Perftest-random-buffer-initialization-optimization.patch
@@ -0,0 +1,82 @@
+From eef2e242bf7db2879b7b87fb53312030513754b6 Mon Sep 17 00:00:00 2001
+From: Shmuel Shaul <sshaul(a)nvidia.com>
+Date: Mon, 21 Apr 2025 14:58:47 +0300
+Subject: [PATCH 17/20] Perftest: random buffer initialization optimization
+
+Replace the standard rand() function with PCG32 algorithm in buffer
+initialization
+to improve performance. The PCG32 implementation:
+- Generates 32-bit random numbers (0 to 4,294,967,295)
+- Uses /dev/urandom for initial seeding with fallback to time+pid+clock
+- Provides better performance than standard rand()
+- Maintains good randomness properties
+
+Signed-off-by: Shmuel Shaul <sshaul(a)nvidia.com>
+---
+ src/perftest_resources.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/src/perftest_resources.c b/src/perftest_resources.c
+index 6609afc..7c01da7 100755
+--- a/src/perftest_resources.c
++++ b/src/perftest_resources.c
+@@ -38,6 +38,7 @@ static enum ibv_wr_opcode opcode_atomic_array[] = {IBV_WR_ATOMIC_CMP_AND_SWP,IBV
+ struct perftest_parameters* duration_param;
+ struct check_alive_data check_alive_data;
+
++
+ /******************************************************************************
+ * Beginning
+ ******************************************************************************/
+@@ -320,6 +321,33 @@ static int pp_free_mmap(struct pingpong_context *ctx)
+ return 0;
+ }
+
++static uint32_t perftest_rand(uint32_t *state) {
++ uint32_t x = *state;
++ *state = x * 747796405 + 2891336453;
++ uint32_t word = ((x >> ((x >> 28) + 4)) ^ x) * 277803737;
++ return (word >> 22) ^ word;
++ }
++
++ // Proper initialization the rand algorithm
++ static uint32_t init_perftest_rand_state() {
++ uint32_t seed;
++
++ FILE* f = fopen("/dev/urandom", "rb");
++ if (f) {
++ if (fread(&seed, sizeof(seed), 1, f) == 1) {
++ fclose(f);
++ return seed;
++ }
++ fclose(f);
++ }
++
++ seed = (uint32_t)time(NULL);
++ seed ^= (uint32_t)getpid();
++ seed ^= (uint32_t)clock();
++
++ return seed;
++ }
++
+ static int next_word_string(char* input, char* output, int from_index)
+ {
+ int i = from_index;
+@@ -1745,12 +1773,12 @@ int create_single_mr(struct pingpong_context *ctx, struct perftest_parameters *u
+ #ifdef HAVE_CUDA
+ if (!user_param->use_cuda) {
+ #endif
+- srand(time(NULL));
++ uint32_t rng_state = init_perftest_rand_state();
+ if (user_param->verb == WRITE && user_param->tst == LAT) {
+ memset(ctx->buf[qp_index], 0, ctx->buff_size);
+ } else {
+ for (i = 0; i < ctx->buff_size; i++) {
+- ((char*)ctx->buf[qp_index])[i] = (char)rand();
++ ((char*)ctx->buf[qp_index])[i] = (char)perftest_rand(&rng_state);
+ }
+ }
+ #ifdef HAVE_CUDA
+--
+2.33.0
+
diff --git a/0018-Perftest-Fix-perform-warm-up-process-stuck.patch b/0018-Perftest-Fix-perform-warm-up-process-stuck.patch
new file mode 100644
index 0000000..8054456
--- /dev/null
+++ b/0018-Perftest-Fix-perform-warm-up-process-stuck.patch
@@ -0,0 +1,64 @@
+From eeb0572c2500ade41860dc9b2bb89619aa13b07a Mon Sep 17 00:00:00 2001
+From: Guofeng Yue <yueguofeng(a)h-partners.com>
+Date: Tue, 15 Apr 2025 17:09:47 +0800
+Subject: [PATCH 18/20] Perftest: Fix perform warm up process stuck
+
+In perform_warm_up mode, if the length of post_list is 1 and the
+message size is less than or equal to 8192, all send_flags in WRs
+are 0 and CQEs will not be generated since IBV_SEND_SIGNALED is
+not set. As a result, the perform_warm_up process will stuck in
+an infinite poll-CQ loop.
+
+Set IBV_SEND_SIGNALED in this case to requiring CQE, and clear the
+flag after post_send_method to avoid affecting subsequent tests.
+
+Fixes: 56d025e4f19a ("Allow overriding CQ moderation on post list mode (#58)")
+Signed-off-by: Guofeng Yue <yueguofeng(a)h-partners.com>
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ src/perftest_resources.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/perftest_resources.c b/src/perftest_resources.c
+index 7c01da7..d123e79 100755
+--- a/src/perftest_resources.c
++++ b/src/perftest_resources.c
+@@ -3301,6 +3301,7 @@ int perform_warm_up(struct pingpong_context *ctx,struct perftest_parameters *use
+ struct ibv_wc *wc_for_cleaning = NULL;
+ int num_of_qps = user_param->num_of_qps;
+ int return_value = 0;
++ int set_signaled = 0;
+
+ if(user_param->duplex && (user_param->use_xrc || user_param->connection_type == DC))
+ num_of_qps /= 2;
+@@ -3317,9 +3318,13 @@ int perform_warm_up(struct pingpong_context *ctx,struct perftest_parameters *use
+ ne = ibv_poll_cq(ctx->send_cq,user_param->tx_depth,wc_for_cleaning);
+
+ for (index=0 ; index < num_of_qps ; index++) {
++ /* ask for completion on this wr */
++ if (user_param->post_list == 1 && !(ctx->wr[index].send_flags & IBV_SEND_SIGNALED)) {
++ ctx->wr[index].send_flags |= IBV_SEND_SIGNALED;
++ set_signaled = 1;
++ }
+
+ for (warmindex = 0 ;warmindex < warmupsession ;warmindex += user_param->post_list) {
+-
+ err = post_send_method(ctx, index, user_param);
+ if (err) {
+ fprintf(stderr,"Couldn't post send during warm up: qp %d scnt=%d \n",index,warmindex);
+@@ -3328,6 +3333,12 @@ int perform_warm_up(struct pingpong_context *ctx,struct perftest_parameters *use
+ }
+ }
+
++ /* Clear the flag to avoid affecting subsequent tests. */
++ if (set_signaled) {
++ ctx->wr[index].send_flags &= ~IBV_SEND_SIGNALED;
++ set_signaled = 0;
++ }
++
+ do {
+
+ ne = ibv_poll_cq(ctx->send_cq,1,&wc);
+--
+2.33.0
+
diff --git a/0019-Perftest-Fix-TD-lock-free-mode-not-working-for-SRQ-X.patch b/0019-Perftest-Fix-TD-lock-free-mode-not-working-for-SRQ-X.patch
new file mode 100644
index 0000000..5f7957f
--- /dev/null
+++ b/0019-Perftest-Fix-TD-lock-free-mode-not-working-for-SRQ-X.patch
@@ -0,0 +1,105 @@
+From 68fd12d94e24a6cd250e682f8242d9f2be2d4ba5 Mon Sep 17 00:00:00 2001
+From: Guofeng Yue <yueguofeng(a)h-partners.com>
+Date: Tue, 15 Apr 2025 17:09:46 +0800
+Subject: [PATCH 19/20] Perftest: Fix TD lock-free mode not working for SRQ/XRC
+ QP
+
+When creating SRQ/XRC QP in TD lock-free mode, pass in ctx->pad
+instead of ctx->pd, otherwise the lock-free won't work.
+
+Besides, use ctx->pad directly when creating QP/SRQ since pad
+is designed to be interchangeable with the usual pd. When
+lock-free mode is disabled, pad is the exactly the usual pd.
+
+Fixes: b6f957f6bc6c ("Perftest: Add support for TD lock-free mode")
+Signed-off-by: Guofeng Yue <yueguofeng(a)h-partners.com>
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ src/perftest_resources.c | 21 ++++++++++++---------
+ src/perftest_resources.h | 2 +-
+ 2 files changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/src/perftest_resources.c b/src/perftest_resources.c
+index d123e79..b388a45 100755
+--- a/src/perftest_resources.c
++++ b/src/perftest_resources.c
+@@ -913,7 +913,8 @@ static int ctx_xrc_srq_create(struct pingpong_context *ctx,
+ else
+ srq_init_attr.cq = ctx->send_cq;
+
+- srq_init_attr.pd = ctx->pd;
++ srq_init_attr.pd = ctx->pad;
++
+ ctx->srq = ibv_create_srq_ex(ctx->context, &srq_init_attr);
+ if (ctx->srq == NULL) {
+ fprintf(stderr, "Couldn't open XRC SRQ\n");
+@@ -956,7 +957,8 @@ static struct ibv_qp *ctx_xrc_qp_create(struct pingpong_context *ctx,
+ qp_init_attr.cap.max_send_wr = user_param->tx_depth;
+ qp_init_attr.cap.max_send_sge = 1;
+ qp_init_attr.comp_mask = IBV_QP_INIT_ATTR_PD;
+- qp_init_attr.pd = ctx->pd;
++ qp_init_attr.pd = ctx->pad;
++
+ #ifdef HAVE_IBV_WR_API
+ if (!user_param->use_old_post_send)
+ qp_init_attr.comp_mask |= IBV_QP_INIT_ATTR_SEND_OPS_FLAGS;
+@@ -1994,6 +1996,10 @@ int ctx_init(struct pingpong_context *ctx, struct perftest_parameters *user_para
+ fprintf(stderr, "Couldn't allocate PAD\n");
+ return FAILURE;
+ }
++ } else {
++ #endif
++ ctx->pad = ctx->pd;
++ #ifdef HAVE_TD_API
+ }
+ #endif
+
+@@ -2111,7 +2117,7 @@ int ctx_init(struct pingpong_context *ctx, struct perftest_parameters *user_para
+ attr.comp_mask = IBV_SRQ_INIT_ATTR_TYPE | IBV_SRQ_INIT_ATTR_PD;
+ attr.attr.max_wr = user_param->rx_depth;
+ attr.attr.max_sge = 1;
+- attr.pd = ctx->pd;
++ attr.pd = ctx->pad;
+
+ attr.srq_type = IBV_SRQT_BASIC;
+ ctx->srq = ibv_create_srq_ex(ctx->context, &attr);
+@@ -2132,7 +2138,7 @@ int ctx_init(struct pingpong_context *ctx, struct perftest_parameters *user_para
+ .max_sge = 1
+ }
+ };
+- ctx->srq = ibv_create_srq(ctx->pd, &attr);
++ ctx->srq = ibv_create_srq(ctx->pad, &attr);
+ if (!ctx->srq) {
+ fprintf(stderr, "Couldn't create SRQ\n");
+ return FAILURE;
+@@ -2319,11 +2325,8 @@ struct ibv_qp* ctx_qp_create(struct pingpong_context *ctx,
+ else if (opcode == IBV_WR_RDMA_READ)
+ attr_ex.send_ops_flags |= IBV_QP_EX_WITH_RDMA_READ;
+ }
+- #ifdef HAVE_TD_API
+- attr_ex.pd = user_param->no_lock ? ctx->pad : ctx->pd;
+- #else
+- attr_ex.pd = ctx->pd;
+- #endif
++
++ attr_ex.pd = ctx->pad;
+ attr_ex.comp_mask |= IBV_QP_INIT_ATTR_SEND_OPS_FLAGS | IBV_QP_INIT_ATTR_PD;
+ attr_ex.send_cq = attr.send_cq;
+ attr_ex.recv_cq = attr.recv_cq;
+diff --git a/src/perftest_resources.h b/src/perftest_resources.h
+index ba8630b..fb11d44 100755
+--- a/src/perftest_resources.h
++++ b/src/perftest_resources.h
+@@ -172,8 +172,8 @@ struct pingpong_context {
+ struct ibv_pd *pd;
+ #ifdef HAVE_TD_API
+ struct ibv_td *td;
+- struct ibv_pd *pad;
+ #endif
++ struct ibv_pd *pad;
+ struct ibv_mr **mr;
+ struct ibv_cq *send_cq;
+ struct ibv_cq *recv_cq;
+--
+2.33.0
+
diff --git a/0020-Perftest-Fix-recv-cq-leak.patch b/0020-Perftest-Fix-recv-cq-leak.patch
new file mode 100644
index 0000000..9a06f3c
--- /dev/null
+++ b/0020-Perftest-Fix-recv-cq-leak.patch
@@ -0,0 +1,54 @@
+From 7dc37bf199b64d9deb7ae041bc5c66819fdd6c32 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Thu, 21 Jul 2022 16:14:09 +0300
+Subject: [PATCH 20/20] Perftest: Fix recv-cq leak
+
+Perftest creates both send-cq and recv-cq but only destroy send-cq
+on SEND client. This further leads to failure in deallocating parent
+domain due to the pad refcount design in driver:
+
+Failed to deallocate PAD - No data available
+Failed to deallocate TD - No data available
+Failed to deallocate PD - No data available
+
+The original mainline PR was:
+https://github.com/linux-rdma/perftest/commit/869f96161be03850c9ace80bbac488ac6010a561
+
+Signed-off-by: Shmuel Shaul <sshaul(a)nvidia.com>
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ src/perftest_resources.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/perftest_resources.c b/src/perftest_resources.c
+index b388a45..b6a0da6 100755
+--- a/src/perftest_resources.c
++++ b/src/perftest_resources.c
+@@ -1253,6 +1253,7 @@ int destroy_ctx(struct pingpong_context *ctx,
+ int i, first, dereg_counter, rc;
+ int test_result = 0;
+ int num_of_qps = user_param->num_of_qps;
++ int dct_only = (user_param->machine == SERVER && !(user_param->duplex || user_param->tst == LAT));
+
+ if (user_param->wait_destroy) {
+ printf(" Waiting %u seconds before releasing resources...\n",
+@@ -1347,12 +1348,10 @@ int destroy_ctx(struct pingpong_context *ctx,
+ test_result = 1;
+ }
+
+- if (user_param->verb == SEND && (user_param->tst == LAT || user_param->machine == SERVER || user_param->duplex || (ctx->channel)) ) {
+- if (!(user_param->connection_type == DC && user_param->machine == SERVER)) {
+- if (ibv_destroy_cq(ctx->recv_cq)) {
+- fprintf(stderr, "Failed to destroy CQ - %s\n", strerror(errno));
+- test_result = 1;
+- }
++ if ((user_param->verb == SEND) || (user_param->connection_type == DC && !dct_only)){
++ if (ibv_destroy_cq(ctx->recv_cq)) {
++ fprintf(stderr, "Failed to destroy CQ - %s\n", strerror(errno));
++ test_result = 1;
+ }
+ }
+
+--
+2.33.0
+
diff --git a/perftest.spec b/perftest.spec
index 9aa4b46..cf405e8 100644
--- a/perftest.spec
+++ b/perftest.spec
@@ -1,6 +1,6 @@
Name: perftest
Version: 4.5
-Release: 13
+Release: 14
License: GPL-2.0-only OR BSD-2-Clause
Summary: RDMA Performance Testing Tools
Url: https://github.com/linux-rdma/perftest
@@ -21,6 +21,11 @@ Patch12: 0012-Perftest-Add-support-for-TD-lock-free-mode.patch
Patch13: 0013-Perftest-Fix-TD-lock-free-mode-not-working-for-QP.patch
Patch14: 0014-Perftest-Fix-failure-in-creating-cq-when-create-cq-e.patch
Patch15: 0015-Perftest-modify-source_ip-to-bind_sounce_ip-to-fix-i.patch
+Patch16: 0016-Revert-Perftest-replace-rand-with-getrandom-during-M.patch
+Patch17: 0017-Perftest-random-buffer-initialization-optimization.patch
+Patch18: 0018-Perftest-Fix-perform-warm-up-process-stuck.patch
+Patch19: 0019-Perftest-Fix-TD-lock-free-mode-not-working-for-SRQ-X.patch
+Patch20: 0020-Perftest-Fix-recv-cq-leak.patch
BuildRequires: automake gcc libibverbs-devel >= 1.2.0 librdmacm-devel >= 1.0.21 libibumad-devel >= 1.3.10.2
BuildRequires: pciutils-devel libibverbs librdmacm libibumad
@@ -47,6 +52,12 @@ done
%_bindir/*
%changelog
+* Tue Jun 10 2025 Guofeng Yue <yueguofeng(a)h-partners.com> - 4.5-14
+- Type: bugfix
+- ID: NA
+- SUG: NA
+- DESC: Sync some patches from mainline
+
* Wed Mar 12 2025 Funda Wang <fundawang(a)yeah.net> - 4.5-13
- Type: bugfix
- ID: NA
--
2.33.0
1
0

12 Jun '25
From: huangdonghua <huangdonghua3(a)h-partners.com>
Signed-off-by: huangdonghua <huangdonghua3(a)h-partners.com>
---
...-for-input-param-of-hnsdv_query_devi.patch | 54 +++++++++++++
...ns-Adapt-UD-inline-data-size-for-UCX.patch | 75 +++++++++++++++++++
rdma-core.spec | 10 ++-
3 files changed, 138 insertions(+), 1 deletion(-)
create mode 100644 0066-libhns-Add-check-for-input-param-of-hnsdv_query_devi.patch
create mode 100644 0067-libhns-Adapt-UD-inline-data-size-for-UCX.patch
diff --git a/0066-libhns-Add-check-for-input-param-of-hnsdv_query_devi.patch b/0066-libhns-Add-check-for-input-param-of-hnsdv_query_devi.patch
new file mode 100644
index 0000000..6980843
--- /dev/null
+++ b/0066-libhns-Add-check-for-input-param-of-hnsdv_query_devi.patch
@@ -0,0 +1,54 @@
+From 57985b930eab7e5cf4dc53efa6d303ede9b414c6 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Mon, 20 May 2024 14:05:33 +0800
+Subject: [PATCH 66/67] libhns: Add check for input param of
+ hnsdv_query_device()
+
+mainline inclusion
+from mainline-master
+commit 19e66a6b75fd1f441e787d1791fe8a416b2d56cb
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/#ICEES4
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1462/commits/5f9e08f62feb67d0841f6fff2bd119a3df63bde9
+
+------------------------------------------------------------------
+
+Add check for input param of hnsdv_query_device() to avoid null ptr.
+
+Fixes: cf6d9149f8f5 ("libhns: Introduce hns direct verbs")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Donghua Huang <huangdonghua3(a)h-partners.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 8bf7bc1..8594666 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -1933,9 +1933,9 @@ struct ibv_qp *hnsdv_create_qp(struct ibv_context *context,
+ int hnsdv_query_device(struct ibv_context *context,
+ struct hnsdv_context *attrs_out)
+ {
+- struct hns_roce_device *hr_dev = to_hr_dev(context->device);
++ struct hns_roce_device *hr_dev;
+
+- if (!hr_dev || !attrs_out)
++ if (!context || !context->device || !attrs_out)
+ return EINVAL;
+
+ if (!is_hns_dev(context->device)) {
+@@ -1944,6 +1944,7 @@ int hnsdv_query_device(struct ibv_context *context,
+ }
+ memset(attrs_out, 0, sizeof(*attrs_out));
+
++ hr_dev = to_hr_dev(context->device);
+ attrs_out->comp_mask |= HNSDV_CONTEXT_MASK_CONGEST_TYPE;
+ attrs_out->congest_type = hr_dev->congest_cap;
+
+--
+2.33.0
+
diff --git a/0067-libhns-Adapt-UD-inline-data-size-for-UCX.patch b/0067-libhns-Adapt-UD-inline-data-size-for-UCX.patch
new file mode 100644
index 0000000..e951fc6
--- /dev/null
+++ b/0067-libhns-Adapt-UD-inline-data-size-for-UCX.patch
@@ -0,0 +1,75 @@
+From 04af69fd5f136852024989d47076898be5982722 Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Tue, 25 Feb 2025 20:29:53 +0800
+Subject: [PATCH 67/67] libhns: Adapt UD inline data size for UCX
+
+driver inclusion
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/ICEEPO
+
+------------------------------------------------------------------
+
+Adapt UD inline data size for UCX. The value
+must be at least 128 to avoid the ucx bug.
+
+The issue url:
+https://gitee.com/src-openeuler/rdma-core/issues/ICEEPO?from=project-issue
+
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+Signed-off-by: Donghua Huang <huangdonghua3(a)h-partners.com>
+---
+ providers/hns/hns_roce_u.h | 2 ++
+ providers/hns/hns_roce_u_verbs.c | 16 ++++++++++++----
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
+index e7e3f01..3d34495 100644
+--- a/providers/hns/hns_roce_u.h
++++ b/providers/hns/hns_roce_u.h
+@@ -83,6 +83,8 @@ typedef _Atomic(uint64_t) atomic_bitmap_t;
+ #define HNS_ROCE_ADDRESS_MASK 0xFFFFFFFF
+ #define HNS_ROCE_ADDRESS_SHIFT 32
+
++#define HNS_ROCE_MIN_UD_INLINE 128
++
+ #define roce_get_field(origin, mask, shift) \
+ (((le32toh(origin)) & (mask)) >> (shift))
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 8594666..7a0fcab 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -1511,10 +1511,18 @@ static unsigned int get_sge_num_from_max_inl_data(bool is_ud,
+ }
+
+ static uint32_t get_max_inline_data(struct hns_roce_context *ctx,
+- struct ibv_qp_cap *cap)
++ struct ibv_qp_cap *cap,
++ bool is_ud)
+ {
+- if (cap->max_inline_data)
+- return min_t(uint32_t, roundup_pow_of_two(cap->max_inline_data),
++ uint32_t max_inline_data = cap->max_inline_data;
++
++ if (max_inline_data) {
++ max_inline_data = roundup_pow_of_two(max_inline_data);
++
++ if (is_ud && max_inline_data < HNS_ROCE_MIN_UD_INLINE)
++ max_inline_data = HNS_ROCE_MIN_UD_INLINE;
++
++ return min_t(uint32_t, max_inline_data,
+ ctx->max_inline_data);
+
+ return 0;
+@@ -1536,7 +1544,7 @@ static void set_ext_sge_param(struct hns_roce_context *ctx,
+ attr->cap.max_send_sge);
+
+ if (ctx->config & HNS_ROCE_RSP_EXSGE_FLAGS) {
+- attr->cap.max_inline_data = get_max_inline_data(ctx, &attr->cap);
++ attr->cap.max_inline_data = get_max_inline_data(ctx, &attr->cap, is_ud);
+
+ inline_ext_sge = max(ext_wqe_sge_cnt,
+ get_sge_num_from_max_inl_data(is_ud,
+--
+2.33.0
+
diff --git a/rdma-core.spec b/rdma-core.spec
index ed09fe8..046cf98 100644
--- a/rdma-core.spec
+++ b/rdma-core.spec
@@ -1,6 +1,6 @@
Name: rdma-core
Version: 50.0
-Release: 31
+Release: 32
Summary: RDMA core userspace libraries and daemons
License: GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
Url: https://github.com/linux-rdma/rdma-core
@@ -71,6 +71,8 @@ patch62: 0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
patch63: 0063-libxscale-update-to-version-2412GA.patch
patch64: 0064-libxscale-automatically-load-xsc_ib.ko.patch
patch65: 0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch
+patch66: 0066-libhns-Add-check-for-input-param-of-hnsdv_query_devi.patch
+patch67: 0067-libhns-Adapt-UD-inline-data-size-for-UCX.patch
BuildRequires: binutils cmake >= 2.8.11 gcc libudev-devel pkgconfig pkgconfig(libnl-3.0)
BuildRequires: pkgconfig(libnl-route-3.0) systemd systemd-devel
@@ -650,6 +652,12 @@ fi
%doc %{_docdir}/%{name}-%{version}/70-persistent-ipoib.rules
%changelog
+* Thu Jun 12 2025 Donghua Huang <huangdonghua3(a)h-partners.com> - 50.0-32
+- Type: bugfix
+- ID: NA
+- SUG: NA
+- DESC: libhns: Increase input parameter checks and adjust inline data size.
+
* Tue May 27 2025 Junxian Huang <huangjunxian6(a)hisilicon.com> - 50.0-31
- Type: bugfix
- ID: NA
--
2.33.0
1
0
MW is no longer supported in hns. Delete relevant codes.
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
providers/hns/hns_roce_u.c | 3 --
providers/hns/hns_roce_u.h | 5 ---
providers/hns/hns_roce_u_hw_v2.c | 32 ----------------
providers/hns/hns_roce_u_hw_v2.h | 7 ----
providers/hns/hns_roce_u_verbs.c | 63 --------------------------------
5 files changed, 110 deletions(-)
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index 63a1ac551..21c5f51e7 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -58,15 +58,12 @@ static const struct verbs_match_ent hca_table[] = {
};
static const struct verbs_context_ops hns_common_ops = {
- .alloc_mw = hns_roce_u_alloc_mw,
.alloc_pd = hns_roce_u_alloc_pd,
- .bind_mw = hns_roce_u_bind_mw,
.cq_event = hns_roce_u_cq_event,
.create_cq = hns_roce_u_create_cq,
.create_cq_ex = hns_roce_u_create_cq_ex,
.create_qp = hns_roce_u_create_qp,
.create_qp_ex = hns_roce_u_create_qp_ex,
- .dealloc_mw = hns_roce_u_dealloc_mw,
.dealloc_pd = hns_roce_u_dealloc_pd,
.dereg_mr = hns_roce_u_dereg_mr,
.destroy_cq = hns_roce_u_destroy_cq,
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index 614fed992..1cf3c7cb5 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -508,11 +508,6 @@ int hns_roce_u_rereg_mr(struct verbs_mr *vmr, int flags, struct ibv_pd *pd,
void *addr, size_t length, int access);
int hns_roce_u_dereg_mr(struct verbs_mr *vmr);
-struct ibv_mw *hns_roce_u_alloc_mw(struct ibv_pd *pd, enum ibv_mw_type type);
-int hns_roce_u_dealloc_mw(struct ibv_mw *mw);
-int hns_roce_u_bind_mw(struct ibv_qp *qp, struct ibv_mw *mw,
- struct ibv_mw_bind *mw_bind);
-
struct ibv_cq *hns_roce_u_create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector);
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index d24cad5bf..784841f43 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -51,7 +51,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(BIND_MW, BIND_MW_TYPE),
HR_IBV_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV),
};
@@ -386,7 +385,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_BIND_MW] = IBV_WC_BIND_MW,
};
static const unsigned int wc_rcv_op_map[] = {
@@ -568,7 +566,6 @@ static void parse_cqe_for_req(struct hns_roce_v2_cqe *cqe, struct ibv_wc *wc,
case HNS_ROCE_SQ_OP_SEND:
case HNS_ROCE_SQ_OP_SEND_WITH_INV:
case HNS_ROCE_SQ_OP_RDMA_WRITE:
- case HNS_ROCE_SQ_OP_BIND_MW:
wc->wc_flags = 0;
break;
case HNS_ROCE_SQ_OP_SEND_WITH_IMM:
@@ -1251,28 +1248,6 @@ static int set_rc_inl(struct hns_roce_qp *qp, const struct ibv_send_wr *wr,
return 0;
}
-static void set_bind_mw_seg(struct hns_roce_rc_sq_wqe *wqe,
- const struct ibv_send_wr *wr)
-{
- unsigned int access = wr->bind_mw.bind_info.mw_access_flags;
-
- hr_reg_write_bool(wqe, RCWQE_MW_TYPE, wr->bind_mw.mw->type - 1);
- hr_reg_write_bool(wqe, RCWQE_MW_RA_EN,
- !!(access & IBV_ACCESS_REMOTE_ATOMIC));
- hr_reg_write_bool(wqe, RCWQE_MW_RR_EN,
- !!(access & IBV_ACCESS_REMOTE_READ));
- hr_reg_write_bool(wqe, RCWQE_MW_RW_EN,
- !!(access & IBV_ACCESS_REMOTE_WRITE));
-
- wqe->new_rkey = htole32(wr->bind_mw.rkey);
- wqe->byte_16 = htole32(wr->bind_mw.bind_info.length &
- HNS_ROCE_ADDRESS_MASK);
- wqe->byte_20 = htole32(wr->bind_mw.bind_info.length >>
- HNS_ROCE_ADDRESS_SHIFT);
- wqe->rkey = htole32(wr->bind_mw.bind_info.mr->rkey);
- wqe->va = htole64(wr->bind_mw.bind_info.addr);
-}
-
static int check_rc_opcode(struct hns_roce_rc_sq_wqe *wqe,
const struct ibv_send_wr *wr)
{
@@ -1298,9 +1273,6 @@ static int check_rc_opcode(struct hns_roce_rc_sq_wqe *wqe,
case IBV_WR_SEND_WITH_INV:
wqe->inv_key = htole32(wr->invalidate_rkey);
break;
- case IBV_WR_BIND_MW:
- set_bind_mw_seg(wqe, wr);
- break;
default:
ret = EINVAL;
break;
@@ -1334,9 +1306,6 @@ static int set_rc_wqe(void *wqe, struct hns_roce_qp *qp, struct ibv_send_wr *wr,
hr_reg_write(rc_sq_wqe, RCWQE_MSG_START_SGE_IDX,
sge_info->start_idx & (qp->ex_sge.sge_cnt - 1));
- if (wr->opcode == IBV_WR_BIND_MW)
- goto wqe_valid;
-
wqe += sizeof(struct hns_roce_rc_sq_wqe);
dseg = wqe;
@@ -1357,7 +1326,6 @@ static int set_rc_wqe(void *wqe, struct hns_roce_qp *qp, struct ibv_send_wr *wr,
if (ret)
return ret;
-wqe_valid:
enable_wqe(qp, rc_sq_wqe, qp->sq.head + nreq);
return 0;
diff --git a/providers/hns/hns_roce_u_hw_v2.h b/providers/hns/hns_roce_u_hw_v2.h
index abf94673e..af061399c 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_BIND_MW_TYPE = 0xc,
HNS_ROCE_WQE_OP_MASK = 0x1f
};
@@ -84,7 +83,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_BIND_MW = 0xc,
};
enum {
@@ -232,11 +230,6 @@ struct hns_roce_rc_sq_wqe {
#define RCWQE_VA1_L RCWQE_FIELD_LOC(479, 448)
#define RCWQE_VA1_H RCWQE_FIELD_LOC(511, 480)
-#define RCWQE_MW_TYPE RCWQE_FIELD_LOC(256, 256)
-#define RCWQE_MW_RA_EN RCWQE_FIELD_LOC(258, 258)
-#define RCWQE_MW_RR_EN RCWQE_FIELD_LOC(259, 259)
-#define RCWQE_MW_RW_EN RCWQE_FIELD_LOC(260, 260)
-
struct hns_roce_v2_wqe_data_seg {
__le32 len;
__le32 lkey;
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
index a906e8d58..10fb474af 100644
--- a/providers/hns/hns_roce_u_verbs.c
+++ b/providers/hns/hns_roce_u_verbs.c
@@ -346,69 +346,6 @@ int hns_roce_u_dereg_mr(struct verbs_mr *vmr)
return ret;
}
-int hns_roce_u_bind_mw(struct ibv_qp *qp, struct ibv_mw *mw,
- struct ibv_mw_bind *mw_bind)
-{
- struct ibv_mw_bind_info *bind_info = &mw_bind->bind_info;
- struct ibv_send_wr *bad_wr = NULL;
- struct ibv_send_wr wr = {};
- int ret;
-
- if (bind_info->mw_access_flags & ~(IBV_ACCESS_REMOTE_WRITE |
- IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_ATOMIC))
- return EINVAL;
-
- wr.opcode = IBV_WR_BIND_MW;
- wr.next = NULL;
-
- wr.wr_id = mw_bind->wr_id;
- wr.send_flags = mw_bind->send_flags;
-
- wr.bind_mw.mw = mw;
- wr.bind_mw.rkey = ibv_inc_rkey(mw->rkey);
- wr.bind_mw.bind_info = mw_bind->bind_info;
-
- ret = hns_roce_u_v2_post_send(qp, &wr, &bad_wr);
- if (ret)
- return ret;
-
- mw->rkey = wr.bind_mw.rkey;
-
- return 0;
-}
-
-struct ibv_mw *hns_roce_u_alloc_mw(struct ibv_pd *pd, enum ibv_mw_type type)
-{
- struct ibv_mw *mw;
- struct ibv_alloc_mw cmd = {};
- struct ib_uverbs_alloc_mw_resp resp = {};
-
- mw = malloc(sizeof(*mw));
- if (!mw)
- return NULL;
-
- if (ibv_cmd_alloc_mw(pd, type, mw, &cmd, sizeof(cmd),
- &resp, sizeof(resp))) {
- free(mw);
- return NULL;
- }
-
- return mw;
-}
-
-int hns_roce_u_dealloc_mw(struct ibv_mw *mw)
-{
- int ret;
-
- ret = ibv_cmd_dealloc_mw(mw);
- if (ret)
- return ret;
-
- free(mw);
-
- return 0;
-}
-
enum {
CREATE_CQ_SUPPORTED_COMP_MASK = IBV_CQ_INIT_ATTR_MASK_FLAGS |
IBV_CQ_INIT_ATTR_MASK_PD,
--
2.33.0
1
0
rinl_buf->wqe_list will be double-freed in error flow, first in
alloc_recv_rinl_buf() and then in free_recv_rinl_buf(). Actually
free_recv_rinl_buf() shouldn't be called when alloc_recv_rinl_buf()
failed.
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
...Fix-double-free-of-rinl_buf-wqe_list.patch | 53 +++++++++++++++++++
rdma-core.spec | 9 +++-
2 files changed, 61 insertions(+), 1 deletion(-)
create mode 100644 0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch
diff --git a/0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch b/0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch
new file mode 100644
index 0000000..e568c7a
--- /dev/null
+++ b/0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch
@@ -0,0 +1,53 @@
+From 583d8210da89563fcef0c6e508f58cc7adf72a3b Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Mon, 12 May 2025 10:51:32 +0800
+Subject: [PATCH 65/65] libhns: Fix double-free of rinl_buf->wqe_list
+
+driver inclusion
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/ICAQ55
+
+------------------------------------------------------------------
+
+rinl_buf->wqe_list will be double-freed in error flow, first in
+alloc_recv_rinl_buf() and then in free_recv_rinl_buf(). Actually
+free_recv_rinl_buf() shouldn't be called when alloc_recv_rinl_buf()
+failed.
+
+Fixes: 83b0baff3ccf ("libhns: Refactor rq inline")
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index edd8e3d..8bf7bc1 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -1453,18 +1453,19 @@ static int qp_alloc_wqe(struct ibv_qp_init_attr_ex *attr,
+ qp->dca_wqe.shift = qp->pageshift;
+ qp->dca_wqe.bufs = calloc(qp->dca_wqe.max_cnt, sizeof(void *));
+ if (!qp->dca_wqe.bufs)
+- goto err_alloc;
++ goto err_alloc_recv_rinl_buf;
+ verbs_debug(&ctx->ibv_ctx, "alloc DCA buf.\n");
+ } else {
+ if (hns_roce_alloc_buf(&qp->buf, qp->buf_size,
+ 1 << qp->pageshift))
+- goto err_alloc;
++ goto err_alloc_recv_rinl_buf;
+ }
+
+ return 0;
+
+-err_alloc:
++err_alloc_recv_rinl_buf:
+ free_recv_rinl_buf(&qp->rq_rinl_buf);
++err_alloc:
+ if (qp->rq.wrid)
+ free(qp->rq.wrid);
+
+--
+2.33.0
+
diff --git a/rdma-core.spec b/rdma-core.spec
index b252761..ed09fe8 100644
--- a/rdma-core.spec
+++ b/rdma-core.spec
@@ -1,6 +1,6 @@
Name: rdma-core
Version: 50.0
-Release: 30
+Release: 31
Summary: RDMA core userspace libraries and daemons
License: GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
Url: https://github.com/linux-rdma/rdma-core
@@ -70,6 +70,7 @@ patch61: 0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch
patch62: 0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
patch63: 0063-libxscale-update-to-version-2412GA.patch
patch64: 0064-libxscale-automatically-load-xsc_ib.ko.patch
+patch65: 0065-libhns-Fix-double-free-of-rinl_buf-wqe_list.patch
BuildRequires: binutils cmake >= 2.8.11 gcc libudev-devel pkgconfig pkgconfig(libnl-3.0)
BuildRequires: pkgconfig(libnl-route-3.0) systemd systemd-devel
@@ -649,6 +650,12 @@ fi
%doc %{_docdir}/%{name}-%{version}/70-persistent-ipoib.rules
%changelog
+* Tue May 27 2025 Junxian Huang <huangjunxian6(a)hisilicon.com> - 50.0-31
+- Type: bugfix
+- ID: NA
+- SUG: NA
+- DESC: libhns: Fix double-free of rinl_buf->wqe_list
+
* Fri May 16 2025 Xin Tian <tianx(a)yunsilicon.com> - 50.0-30
- Type: feature
- ID: NA
--
2.33.0
1
0

26 May '25
From: wenglianfa <wenglianfa(a)huawei.com>
rinl_buf->wqe_list will be double-freed in error flow, first in
alloc_recv_rinl_buf() and then in free_recv_rinl_buf(). Actually
free_recv_rinl_buf() shouldn't be called when alloc_recv_rinl_buf()
failed.
Fixes: 83b0baff3ccf ("libhns: Refactor rq inline")
Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
providers/hns/hns_roce_u_verbs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
index 132fcaeba..a906e8d58 100644
--- a/providers/hns/hns_roce_u_verbs.c
+++ b/providers/hns/hns_roce_u_verbs.c
@@ -1256,12 +1256,13 @@ static int qp_alloc_wqe(struct ibv_qp_cap *cap, struct hns_roce_qp *qp,
}
if (hns_roce_alloc_buf(&qp->buf, qp->buf_size, HNS_HW_PAGE_SIZE))
- goto err_alloc;
+ goto err_alloc_recv_rinl_buf;
return 0;
-err_alloc:
+err_alloc_recv_rinl_buf:
free_recv_rinl_buf(&qp->rq_rinl_buf);
+err_alloc:
if (qp->rq.wrid)
free(qp->rq.wrid);
--
2.33.0
1
0
From: Xinghai Cen <cenxinghai(a)h-partners.com>
The last commit was found when I created a XRC SRQ in
lock-free mode but failed to destroy it because of the
refcnt check added in the previous commit.
The failure was because the PAD was acquired through
ibv_srq->pd in destroy_srq(), while ibv_srq->pd wasn't
assigned when the SRQ was created by ibv_create_srq_ex().
So let's assign ibv_srq->pd in the common ibv_icmd_create_srq() ,
so that drivers can get the correct pd no matter
which api the SRQ is created by.
Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
---
...hns-Add-debug-log-for-lock-free-mode.patch | 59 +++++++++++
...s-Fix-ret-not-assigned-in-create-srq.patch | 58 +++++++++++
...efcnt-leaking-in-error-flow-of-creat.patch | 99 +++++++++++++++++++
...-freeing-pad-without-checking-refcnt.patch | 69 +++++++++++++
...-Assign-ibv-srq-pd-when-creating-SRQ.patch | 43 ++++++++
rdma-core.spec | 13 ++-
6 files changed, 340 insertions(+), 1 deletion(-)
create mode 100644 0058-libhns-Add-debug-log-for-lock-free-mode.patch
create mode 100644 0059-libhns-Fix-ret-not-assigned-in-create-srq.patch
create mode 100644 0060-libhns-Fix-pad-refcnt-leaking-in-error-flow-of-creat.patch
create mode 100644 0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch
create mode 100644 0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
diff --git a/0058-libhns-Add-debug-log-for-lock-free-mode.patch b/0058-libhns-Add-debug-log-for-lock-free-mode.patch
new file mode 100644
index 0000000..86bc0a5
--- /dev/null
+++ b/0058-libhns-Add-debug-log-for-lock-free-mode.patch
@@ -0,0 +1,59 @@
+From 20dc7f183603b936ba7a865fc8a6d115073b1e29 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Thu, 24 Apr 2025 20:32:12 +0800
+Subject: [PATCH 58/62] libhns: Add debug log for lock-free mode
+
+mainline inclusion
+from mainline-v56.0-65
+commit fb96940fcf6f96185d407d57bcaf775ccf8f1762
+category: cheanup
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/IC3X57
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/fb96940fcf6f96185d407d57bcaf775ccf8f1762
+
+---------------------------------------------------------------------
+
+Currently there is no way to observe whether the lock-free mode is
+configured from the driver's perspective. Add debug log for this.
+
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 5fe169e..3efc2f4 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -182,6 +182,7 @@ err:
+ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ struct ibv_parent_domain_init_attr *attr)
+ {
++ struct hns_roce_pd *protection_domain;
+ struct hns_roce_pad *pad;
+
+ if (ibv_check_alloc_parent_domain(attr))
+@@ -198,12 +199,16 @@ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ return NULL;
+ }
+
++ protection_domain = to_hr_pd(attr->pd);
+ if (attr->td) {
+ pad->td = to_hr_td(attr->td);
+ atomic_fetch_add(&pad->td->refcount, 1);
++ verbs_debug(verbs_get_ctx(context),
++ "set PAD(0x%x) to lock-free mode.\n",
++ protection_domain->pdn);
+ }
+
+- pad->pd.protection_domain = to_hr_pd(attr->pd);
++ pad->pd.protection_domain = protection_domain;
+ atomic_fetch_add(&pad->pd.protection_domain->refcount, 1);
+
+ atomic_init(&pad->pd.refcount, 1);
+--
+2.33.0
+
diff --git a/0059-libhns-Fix-ret-not-assigned-in-create-srq.patch b/0059-libhns-Fix-ret-not-assigned-in-create-srq.patch
new file mode 100644
index 0000000..10443d6
--- /dev/null
+++ b/0059-libhns-Fix-ret-not-assigned-in-create-srq.patch
@@ -0,0 +1,58 @@
+From cf284feddf6bb98c600061a3fd1f0095e46b540e Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:14 +0800
+Subject: [PATCH 59/62] libhns: Fix ret not assigned in create srq()
+
+mainline inclusion
+from mainline-v56.0-65
+commit 2034b1860c5a8b0cc3879315259462c04e53a98d
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/IC3X57
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/2034b1860c5a8b0cc3879315259462c04e53a98d
+
+---------------------------------------------------------------------
+
+Fix the problem that ret may not be assigned in the error flow
+of create_srq().
+
+Fixes: aa7bcf7f7e44 ("libhns: Add support for lock-free SRQ")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 3efc2f4..b26ac29 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -933,16 +933,20 @@ static struct ibv_srq *create_srq(struct ibv_context *context,
+ if (pad)
+ atomic_fetch_add(&pad->pd.refcount, 1);
+
+- if (hns_roce_srq_spinlock_init(context, srq, init_attr))
++ ret = hns_roce_srq_spinlock_init(context, srq, init_attr)
++ if (ret)
+ goto err_free_srq;
+
+ set_srq_param(context, srq, init_attr);
+- if (alloc_srq_buf(srq))
++ ret = alloc_srq_buf(srq)
++ if (ret)
+ goto err_destroy_lock;
+
+ srq->rdb = hns_roce_alloc_db(hr_ctx, HNS_ROCE_SRQ_TYPE_DB);
+- if (!srq->rdb)
++ if (!srq->rdb) {
++ ret = ENOMEM;
+ goto err_srq_buf;
++ }
+
+ ret = exec_srq_create_cmd(context, srq, init_attr);
+ if (ret)
+--
+2.33.0
+
diff --git a/0060-libhns-Fix-pad-refcnt-leaking-in-error-flow-of-creat.patch b/0060-libhns-Fix-pad-refcnt-leaking-in-error-flow-of-creat.patch
new file mode 100644
index 0000000..95a1e69
--- /dev/null
+++ b/0060-libhns-Fix-pad-refcnt-leaking-in-error-flow-of-creat.patch
@@ -0,0 +1,99 @@
+From 2bc3cafa227528e2893dadfff7cf54cfee427e1a Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:15 +0800
+Subject: [PATCH 60/62] libhns: Fix pad refcnt leaking in error flow of create
+ qp/cq/srq
+
+mainline inclusion
+from mainline-v56.0-65
+commit f877d6e610e438515e1535c9ec7a3a3ef37c58e0
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/IC3X57
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/f877d6e610e438515e1535c9ec7a3a3ef37c58e0
+
+---------------------------------------------------------------------
+
+Decrease pad refcnt by 1 in error flow of create qp/cq/srq.
+
+Fixes: f8b4f622b1c5 ("libhns: Add support for lock-free QP")
+Fixes: 95225025e24c ("libhns: Add support for lock-free CQ")
+Fixes: aa7bcf7f7e44 ("libhns: Add support for lock-free SRQ")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index b26ac29..5a62bb2 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -445,12 +445,9 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
+ return EOPNOTSUPP;
+ }
+
+- if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
+- if (!pad) {
+- verbs_err(&context->ibv_ctx, "failed to check the pad of cq.\n");
+- return EINVAL;
+- }
+- atomic_fetch_add(&pad->pd.refcount, 1);
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD && !pad) {
++ verbs_err(&context->ibv_ctx, "failed to check the pad of cq.\n");
++ return EINVAL;
+ }
+
+ attr->cqe = max_t(uint32_t, HNS_ROCE_MIN_CQE_NUM,
+@@ -556,6 +553,7 @@ static void hns_roce_uninit_cq_swc(struct hns_roce_cq *cq)
+ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *attr)
+ {
++ struct hns_roce_pad *pad = to_hr_pad(attr->parent_domain);
+ struct hns_roce_context *hr_ctx = to_hr_ctx(context);
+ struct hns_roce_cq *cq;
+ int ret;
+@@ -570,8 +568,10 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
+ goto err;
+ }
+
+- if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD)
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
+ cq->parent_domain = attr->parent_domain;
++ atomic_fetch_add(&pad->pd.refcount, 1);
++ }
+
+ ret = hns_roce_cq_spinlock_init(context, cq, attr);
+ if (ret)
+@@ -611,6 +611,8 @@ err_db:
+ err_buf:
+ hns_roce_spinlock_destroy(&cq->hr_lock);
+ err_lock:
++ if (attr->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(cq);
+ err:
+ if (ret < 0)
+@@ -977,6 +979,8 @@ err_destroy_lock:
+ hns_roce_spinlock_destroy(&srq->hr_lock);
+
+ err_free_srq:
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(srq);
+
+ err:
+@@ -1872,6 +1876,8 @@ err_cmd:
+ err_buf:
+ hns_roce_qp_spinlock_destroy(qp);
+ err_spinlock:
++ if (pad)
++ atomic_fetch_sub(&pad->pd.refcount, 1);
+ free(qp);
+ err:
+ if (ret < 0)
+--
+2.33.0
+
diff --git a/0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch b/0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch
new file mode 100644
index 0000000..d37dee6
--- /dev/null
+++ b/0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch
@@ -0,0 +1,69 @@
+From 0db7ff07caa483da0fb2cfd7944d549a38b4c720 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:16 +0800
+Subject: [PATCH 61/62] libhns: Fix freeing pad without checking refcnt
+
+mainline inclusion
+from mainline-v56.0-65
+commit 234d135276ea8ef83633113e224e0cd735ebeca8
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/IC3X57
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/234d135276ea8ef83633113e224e0cd735ebeca8
+
+---------------------------------------------------------------------
+
+Currently pad refcnt will be added when creating qp/cq/srq, but it is
+not checked when freeing pad. Add a check to prevent freeing pad when
+it is still used by any qp/cq/srq.
+
+Fixes: 7b6b3dae328f ("libhns: Add support for thread domain and parent
+domain")
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
+---
+ providers/hns/hns_roce_u_verbs.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
+index 5a62bb2..8c37496 100644
+--- a/providers/hns/hns_roce_u_verbs.c
++++ b/providers/hns/hns_roce_u_verbs.c
+@@ -218,14 +218,18 @@ struct ibv_pd *hns_roce_u_alloc_pad(struct ibv_context *context,
+ return &pad->pd.ibv_pd;
+ }
+
+-static void hns_roce_free_pad(struct hns_roce_pad *pad)
++static int hns_roce_free_pad(struct hns_roce_pad *pad)
+ {
++ if (atomic_load(&pad->pd.refcount) > 1)
++ return EBUSY;
++
+ atomic_fetch_sub(&pad->pd.protection_domain->refcount, 1);
+
+ if (pad->td)
+ atomic_fetch_sub(&pad->td->refcount, 1);
+
+ free(pad);
++ return 0;
+ }
+
+ static int hns_roce_free_pd(struct hns_roce_pd *pd)
+@@ -248,10 +252,8 @@ int hns_roce_u_dealloc_pd(struct ibv_pd *ibv_pd)
+ struct hns_roce_pad *pad = to_hr_pad(ibv_pd);
+ struct hns_roce_pd *pd = to_hr_pd(ibv_pd);
+
+- if (pad) {
+- hns_roce_free_pad(pad);
+- return 0;
+- }
++ if (pad)
++ return hns_roce_free_pad(pad);
+
+ return hns_roce_free_pd(pd);
+ }
+--
+2.33.0
+
diff --git a/0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch b/0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
new file mode 100644
index 0000000..e7d0395
--- /dev/null
+++ b/0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
@@ -0,0 +1,43 @@
+From f8f9295695921fa796bb93c5ee7066e50221bbc3 Mon Sep 17 00:00:00 2001
+From: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Date: Wed, 23 Apr 2025 16:55:17 +0800
+Subject: [PATCH 62/62] verbs: Assign ibv srq->pd when creating SRQ
+
+mainline inclusion
+from mainline-v56.0-65
+commit bf1e427141fde2651bab4860e77a432bb7e26094
+category: bugfix
+bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/IC3X57
+CVE: NA
+
+Reference:
+https://github.com/linux-rdma/rdma-core/pull/1599/commits/bf1e427141fde2651bab4860e77a432bb7e26094
+
+---------------------------------------------------------------------
+
+Some providers need to access ibv_srq->pd during SRQ destruction, but
+it may not be assigned currently when using ibv_create_srq_ex(). This
+may lead to some SRQ-related resource leaks. Assign ibv_srq->pd when
+creating SRQ to ensure pd can be obtained correctly.
+
+Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
+Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com>
+---
+ libibverbs/cmd_srq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libibverbs/cmd_srq.c b/libibverbs/cmd_srq.c
+index dfaaa6a..259ea0d 100644
+--- a/libibverbs/cmd_srq.c
++++ b/libibverbs/cmd_srq.c
+@@ -63,6 +63,7 @@ static int ibv_icmd_create_srq(struct ibv_pd *pd, struct verbs_srq *vsrq,
+ struct verbs_xrcd *vxrcd = NULL;
+ enum ibv_srq_type srq_type;
+
++ srq->pd = pd;
+ srq->context = pd->context;
+ pthread_mutex_init(&srq->mutex, NULL);
+ pthread_cond_init(&srq->cond, NULL);
+--
+2.33.0
+
diff --git a/rdma-core.spec b/rdma-core.spec
index e760f40..928fc75 100644
--- a/rdma-core.spec
+++ b/rdma-core.spec
@@ -1,6 +1,6 @@
Name: rdma-core
Version: 50.0
-Release: 27
+Release: 28
Summary: RDMA core userspace libraries and daemons
License: GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
Url: https://github.com/linux-rdma/rdma-core
@@ -63,6 +63,11 @@ patch54: 0054-libhns-Fix-wrong-max-inline-data-value.patch
patch55: 0055-libhns-Fix-wrong-order-of-spin-unlock-in-modify-qp.patch
patch56: 0056-libhns-Add-initial-support-for-HNS-LTTng-tracing.patch
patch57: 0057-libhns-Add-tracepoint-for-HNS-RoCE-I-O.patch
+patch58: 0058-libhns-Add-debug-log-for-lock-free-mode.patch
+patch59: 0059-libhns-Fix-ret-not-assigned-in-create-srq.patch
+patch60: 0060-libhns-Fix-pad-refcnt-leaking-in-error-flow-of-creat.patch
+patch61: 0061-libhns-Fix-freeing-pad-without-checking-refcnt.patch
+patch62: 0062-verbs-Assign-ibv-srq-pd-when-creating-SRQ.patch
BuildRequires: binutils cmake >= 2.8.11 gcc libudev-devel pkgconfig pkgconfig(libnl-3.0)
BuildRequires: pkgconfig(libnl-route-3.0) systemd systemd-devel
@@ -642,6 +647,12 @@ fi
%doc %{_docdir}/%{name}-%{version}/70-persistent-ipoib.rules
%changelog
+* Fri Apr 25 2025 Xinghai Cen <cenxinghai(a)h-partners.com> - 50.0-28
+- Type: bugfix
+- ID: NA
+- SUG: NA
+- DESC: Bugfixes and one debug improvement
+
* Wed Apr 23 2025 Xinghai Cen <cenxinghai(a)h-partners.com> - 50.0-27
- Type: feature
- ID: NA
--
2.33.0
1
0
From: Chengchang Tang <tangchengchang(a)huawei.com>
HNS RoCE will check whether the length of the recv sge exceeds
the range of the corresponding MR, which can cause hns RoCE to
report a CQE error.
Signed-off-by: Chengchang Tang <tangchengchang(a)huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
src/perftest_resources.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/perftest_resources.c b/src/perftest_resources.c
index 9e9f41f..f8c0de2 100755
--- a/src/perftest_resources.c
+++ b/src/perftest_resources.c
@@ -3261,6 +3261,19 @@ void ctx_set_send_reg_wqes(struct pingpong_context *ctx,
}
}
+static uint64_t set_recv_length(struct pingpong_context *ctx,
+ struct perftest_parameters *user_param)
+{
+ enum ctx_device current_dev = ib_dev_name(ctx->context);
+ int mtu = MTU_SIZE(user_param->curr_mtu);
+ uint64_t length = SIZE(user_param->connection_type, user_param->size, 1);
+
+ if (current_dev != HNS && user_param->use_srq == ON)
+ length = ((length + mtu - 1 )/ mtu) * mtu;
+
+ return length;
+}
+
/******************************************************************************
*
******************************************************************************/
@@ -3270,8 +3283,7 @@ int ctx_set_recv_wqes(struct pingpong_context *ctx,struct perftest_parameters *u
int num_of_qps = user_param->num_of_qps;
struct ibv_recv_wr *bad_wr_recv;
int size_per_qp = user_param->rx_depth / user_param->recv_post_list;
- int mtu = MTU_SIZE(user_param->curr_mtu);
- uint64_t length = user_param->use_srq == ON ? (((SIZE(user_param->connection_type ,user_param->size, 1) + mtu - 1 )/ mtu) * mtu) : SIZE(user_param->connection_type, user_param->size, 1);
+ uint64_t length = set_recv_length(ctx, user_param);
/* Write w/imm completions have zero recieve buffer length */
if (user_param->verb == WRITE_IMM)
--
2.33.0
1
0