High-performance-network
Threads by month
- ----- 2025 -----
- August
- 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
July 2025
- 2 participants
- 4 discussions

25 Jul '25
Support roce_dfx_sta query
Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com>
---
...-roce-Fix-array-out-of-bounds-access.patch | 110 ++++++++
...l-roce-Support-to-print-u64-reg_data.patch | 198 ++++++++++++++
...d-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch | 248 ++++++++++++++++++
hikptool.spec | 8 +-
4 files changed, 563 insertions(+), 1 deletion(-)
create mode 100644 0100-hikptool-roce-Fix-array-out-of-bounds-access.patch
create mode 100644 0101-hikptool-roce-Support-to-print-u64-reg_data.patch
create mode 100644 0102-hikptool-roce-Add-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch
diff --git a/0100-hikptool-roce-Fix-array-out-of-bounds-access.patch b/0100-hikptool-roce-Fix-array-out-of-bounds-access.patch
new file mode 100644
index 0000000..9b02414
--- /dev/null
+++ b/0100-hikptool-roce-Fix-array-out-of-bounds-access.patch
@@ -0,0 +1,110 @@
+From e4888f49e7d72d23e72537849141901fa2227440 Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Tue, 20 May 2025 20:37:22 +0800
+Subject: [PATCH 100/102] hikptool/roce: Fix array out-of-bounds access
+
+cur_block_num may be greater than reg data num. As
+a result, out-of-bounds access to the reg_data.offset or
+reg_data.data array may occur during memcpy().
+
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+---
+ net/roce/roce_ext_common/hikp_roce_ext_common.c | 10 ++++++++++
+ net/roce/roce_scc/hikp_roce_scc.c | 10 ++++++----
+ net/roce/roce_trp/hikp_roce_trp.c | 12 +++++++-----
+ 3 files changed, 23 insertions(+), 9 deletions(-)
+
+diff --git a/net/roce/roce_ext_common/hikp_roce_ext_common.c b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+index 9c844f4..fda2cf8 100644
+--- a/net/roce/roce_ext_common/hikp_roce_ext_common.c
++++ b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+@@ -96,6 +96,7 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+ struct reg_data *reg = &output->reg;
+ struct hikp_cmd_ret *cmd_ret;
+ uint32_t remain_block;
++ size_t reg_data_size;
+ size_t cur_size;
+ int ret;
+
+@@ -144,6 +145,15 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+ }
+
+ cur_size = res_head->cur_block_num * sizeof(uint32_t);
++ /*calculates the size of reg_data in the roce_ext_res_param structure.*/
++ reg_data_size = cmd_ret->rsp_data_num * sizeof(uint32_t) - sizeof(struct roce_ext_head);
++ if (cur_size + reg_array_length * sizeof(uint32_t) > reg_data_size) {
++ printf("hikptool roce_%s cur size error, cur_size: %zu, reg_data_size: %zu.\n",
++ cmd_name, cur_size, reg_data_size);
++ ret = -EINVAL;
++ hikp_roce_ext_reg_data_free(reg);
++ goto get_data_error;
++ }
+ memcpy(reg->offset + block_id,
+ (uint32_t *)&roce_ext_res->reg_data, cur_size);
+ memcpy(reg->data + block_id,
+diff --git a/net/roce/roce_scc/hikp_roce_scc.c b/net/roce/roce_scc/hikp_roce_scc.c
+index 67a2a1e..d8aee47 100644
+--- a/net/roce/roce_scc/hikp_roce_scc.c
++++ b/net/roce/roce_scc/hikp_roce_scc.c
+@@ -169,9 +169,10 @@ static int hikp_roce_scc_get_total_data_num(struct roce_scc_head *res_head,
+ }
+
+ cur_size = roce_scc_res->head.cur_block_num * sizeof(uint32_t);
+- if (cur_size > max_size) {
++ if (cur_size > max_size || roce_scc_res->head.cur_block_num > ROCE_HIKP_SCC_REG_NUM) {
+ printf("hikptool roce_scc log data copy size error, "
+- "data size: 0x%zx, max size: 0x%zx\n", cur_size, max_size);
++ "data size: 0x%zx, max size: 0x%zx, block_num: 0x%x\n",
++ cur_size, max_size, roce_scc_res->head.cur_block_num);
+ ret = -EINVAL;
+ goto get_data_error;
+ }
+@@ -204,10 +205,11 @@ static int hikp_roce_scc_get_next_data(struct roce_scc_head *res_head,
+
+ roce_scc_res = (struct roce_scc_res_param *)cmd_ret->rsp_data;
+ cur_size = roce_scc_res->head.cur_block_num * sizeof(uint32_t);
+- if (cur_size > data_size) {
++ if (cur_size > data_size || roce_scc_res->head.cur_block_num > ROCE_HIKP_SCC_REG_NUM) {
+ hikp_cmd_free(&cmd_ret);
+ printf("hikptool roce_scc next log data copy size error, "
+- "data size: 0x%zx, max size: 0x%zx\n", cur_size, data_size);
++ "data size: 0x%zx, max size: 0x%zx, block_num: 0x%x\n",
++ cur_size, data_size, roce_scc_res->head.cur_block_num);
+ return -EINVAL;
+ }
+ memcpy(*offset, roce_scc_res->reg_data.offset, cur_size);
+diff --git a/net/roce/roce_trp/hikp_roce_trp.c b/net/roce/roce_trp/hikp_roce_trp.c
+index 67dfb8e..8b34409 100644
+--- a/net/roce/roce_trp/hikp_roce_trp.c
++++ b/net/roce/roce_trp/hikp_roce_trp.c
+@@ -192,9 +192,10 @@ static int hikp_roce_trp_get_total_data_num(struct roce_trp_head *res_head,
+ }
+
+ cur_size = roce_trp_res->head.cur_block_num * sizeof(uint32_t);
+- if (cur_size > max_size) {
++ if (cur_size > max_size || roce_trp_res->head.cur_block_num > ROCE_HIKP_TRP_REG_NUM) {
+ printf("hikptool roce_trp log data copy size error, "
+- "data size: 0x%zx, max size: 0x%zx\n", cur_size, max_size);
++ "data size: 0x%zx, max size: 0x%zx, block_num: 0x%x\n",
++ cur_size, max_size, roce_trp_res->head.cur_block_num);
+ hikp_roce_trp_reg_data_free(offset, data);
+ ret = -EINVAL;
+ goto get_data_error;
+@@ -229,10 +230,11 @@ static int hikp_roce_trp_get_next_data(struct roce_trp_head *res_head,
+ roce_trp_res = (struct roce_trp_res_param *)cmd_ret->rsp_data;
+ cur_size = roce_trp_res->head.cur_block_num * sizeof(uint32_t);
+
+- if (cur_size > data_size) {
+- hikp_cmd_free(&cmd_ret);
++ if (cur_size > data_size || roce_trp_res->head.cur_block_num > ROCE_HIKP_TRP_REG_NUM) {
+ printf("hikptool roce_trp next log data copy size error, "
+- "data size: 0x%zx, max size: 0x%zx\n", cur_size, data_size);
++ "data size: 0x%zx, max size: 0x%zx, block_num: 0x%x\n",
++ cur_size, data_size, roce_trp_res->head.cur_block_num);
++ hikp_cmd_free(&cmd_ret);
+ return -EINVAL;
+ }
+ memcpy(*offset, roce_trp_res->reg_data.offset, cur_size);
+--
+2.33.0
+
diff --git a/0101-hikptool-roce-Support-to-print-u64-reg_data.patch b/0101-hikptool-roce-Support-to-print-u64-reg_data.patch
new file mode 100644
index 0000000..1e09945
--- /dev/null
+++ b/0101-hikptool-roce-Support-to-print-u64-reg_data.patch
@@ -0,0 +1,198 @@
+From e680dee0da5cc54d3a71076ecb49f7de88feb62a Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Thu, 3 Jul 2025 17:25:08 +0800
+Subject: [PATCH 101/102] hikptool/roce: Support to print u64 reg_data
+
+Support to print u64 reg_data.
+
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+---
+ .../roce_ext_common/hikp_roce_ext_common.c | 61 +++++++++++++------
+ .../roce_ext_common/hikp_roce_ext_common.h | 26 +++++++-
+ 2 files changed, 66 insertions(+), 21 deletions(-)
+
+diff --git a/net/roce/roce_ext_common/hikp_roce_ext_common.c b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+index fda2cf8..c225ec8 100644
+--- a/net/roce/roce_ext_common/hikp_roce_ext_common.c
++++ b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+@@ -12,6 +12,7 @@
+ */
+
+ #include "hikp_roce_ext_common.h"
++#include <stddef.h>
+
+ static void hikp_roce_ext_reg_data_free(struct reg_data *reg)
+ {
+@@ -95,9 +96,11 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+ struct roce_ext_res_param *roce_ext_res;
+ struct reg_data *reg = &output->reg;
+ struct hikp_cmd_ret *cmd_ret;
++ size_t reg_data_offset;
+ uint32_t remain_block;
+- size_t reg_data_size;
+- size_t cur_size;
++ size_t offset_size;
++ size_t data_size;
++ void *dst_data;
+ int ret;
+
+ /* reg_array_length greater than or equal to 0 ensures that cmd_name
+@@ -117,6 +120,7 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+
+ if (block_id == 0) {
+ res_head->total_block_num = roce_ext_res->head.total_block_num;
++ res_head->flags = roce_ext_res->head.flags;
+ if (!res_head->total_block_num) {
+ printf("hikptool roce_%s total_block_num error!\n",
+ cmd_name);
+@@ -124,10 +128,12 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+ goto get_data_error;
+ }
+ reg->offset = (uint32_t *)calloc(res_head->total_block_num, sizeof(uint32_t));
+- reg->data = (uint32_t *)calloc(res_head->total_block_num, sizeof(uint32_t));
++ output->per_val_size = res_head->flags & ROCE_HIKP_DATA_U64_FLAG ?
++ sizeof(uint64_t) : sizeof(uint32_t);
++ reg->data = calloc(res_head->total_block_num, output->per_val_size);
+ if ((reg->offset == NULL) || (reg->data == NULL)) {
+- printf("hikptool roce_%s alloc log memmory 0x%zx failed!\n",
+- cmd_name, res_head->total_block_num * sizeof(uint32_t));
++ printf("hikptool roce_%s alloc log memmory failed!\n",
++ cmd_name);
+ ret = -ENOMEM;
+ hikp_roce_ext_reg_data_free(reg);
+ goto get_data_error;
+@@ -144,20 +150,32 @@ static int hikp_roce_ext_get_res(enum roce_cmd_type cmd_type,
+ goto get_data_error;
+ }
+
+- cur_size = res_head->cur_block_num * sizeof(uint32_t);
+- /*calculates the size of reg_data in the roce_ext_res_param structure.*/
+- reg_data_size = cmd_ret->rsp_data_num * sizeof(uint32_t) - sizeof(struct roce_ext_head);
+- if (cur_size + reg_array_length * sizeof(uint32_t) > reg_data_size) {
+- printf("hikptool roce_%s cur size error, cur_size: %zu, reg_data_size: %zu.\n",
+- cmd_name, cur_size, reg_data_size);
++ /*
++ * The data structure `roce_ext_res_param_u64` returned by the
++ * firmware is 8-byte aligned, so the offset of the `reg_data`
++ * member needs to be adjusted accordingly.
++ */
++ if (res_head->flags & ROCE_HIKP_DATA_U64_FLAG)
++ reg_data_offset = offsetof(struct roce_ext_res_param_u64, reg_data);
++ else
++ reg_data_offset = offsetof(struct roce_ext_res_param, reg_data);
++
++ offset_size = res_head->cur_block_num * sizeof(uint32_t);
++ data_size = res_head->cur_block_num * output->per_val_size;
++ dst_data = reg->data_u32 + block_id * output->per_val_size / sizeof(uint32_t);
++ /* Avoid memcpy out-of-bounds. */
++ if ((reg_data_offset + data_size) / sizeof(uint32_t) + reg_array_length > cmd_ret->rsp_data_num) {
++ printf("hikptool roce_%s cur size error, data_size: %zu, rsp_data_num: %u.\n",
++ cmd_name, data_size, cmd_ret->rsp_data_num);
+ ret = -EINVAL;
+ hikp_roce_ext_reg_data_free(reg);
+ goto get_data_error;
+ }
+ memcpy(reg->offset + block_id,
+- (uint32_t *)&roce_ext_res->reg_data, cur_size);
+- memcpy(reg->data + block_id,
+- (uint32_t *)&roce_ext_res->reg_data + reg_array_length, cur_size);
++ (uint32_t *)&roce_ext_res->head + reg_data_offset / sizeof(uint32_t),
++ offset_size);
++ memcpy(dst_data, (uint32_t *)&roce_ext_res->head + reg_data_offset
++ / sizeof(uint32_t) + reg_array_length, data_size);
+
+ get_data_error:
+ hikp_cmd_free(&cmd_ret);
+@@ -172,15 +190,20 @@ static void hikp_roce_ext_print(enum roce_cmd_type cmd_type,
+ const char *cmd_name = get_cmd_name(cmd_type);
+ uint8_t arr_len = output->reg_name.arr_len;
+ uint32_t *offset = output->reg.offset;
+- uint32_t *data = output->reg.data;
++ struct reg_data *reg = &output->reg;
++ const char *name;
+ uint32_t i;
+
+ printf("**************%s INFO*************\n", cmd_name);
+ printf("%-40s[addr_offset] : reg_data\n", "reg_name");
+- for (i = 0; i < total_block_num; i++)
+- printf("%-40s[0x%08X] : 0x%08X\n",
+- i < arr_len ? reg_name[i] : "",
+- offset[i], data[i]);
++ for (i = 0; i < total_block_num; i++) {
++ name = i < arr_len ? reg_name[i] : "";
++ printf("%-40s[0x%08X] : ", name, offset[i]);
++ if (output->res_head.flags & ROCE_HIKP_DATA_U64_FLAG)
++ printf("0x%016lX\n", reg->data_u64[i]);
++ else
++ printf("0x%08X\n", reg->data_u32[i]);
++ }
+ printf("************************************\n");
+ }
+
+diff --git a/net/roce/roce_ext_common/hikp_roce_ext_common.h b/net/roce/roce_ext_common/hikp_roce_ext_common.h
+index 8568556..6f04024 100644
+--- a/net/roce/roce_ext_common/hikp_roce_ext_common.h
++++ b/net/roce/roce_ext_common/hikp_roce_ext_common.h
+@@ -17,6 +17,7 @@
+ #include "hikp_net_lib.h"
+
+ #define ROCE_MAX_REG_NUM (NET_MAX_REQ_DATA_NUM - 1)
++#define ROCE_MAX_U64_REG_NUM 18
+
+ #define ROCE_HIKP_CAEP_REG_NUM_EXT ROCE_MAX_REG_NUM
+ #define ROCE_HIKP_GMV_REG_NUM_EXT ROCE_MAX_REG_NUM
+@@ -30,11 +31,15 @@
+ #define ROCE_HIKP_RST_REG_NUM ROCE_MAX_REG_NUM
+ #define ROCE_HIKP_GLOBAL_CFG_REG_NUM ROCE_MAX_REG_NUM
+ #define ROCE_HIKP_BOND_REG_NUM ROCE_MAX_REG_NUM
++#define ROCE_HIKP_DFX_STA_NUM_EXT ROCE_MAX_U64_REG_NUM
++
++#define ROCE_HIKP_DATA_U64_FLAG 1 << 0
+
+ struct roce_ext_head {
+ uint8_t total_block_num;
+ uint8_t cur_block_num;
+- uint16_t reserved;
++ uint8_t flags;
++ uint8_t reserved;
+ };
+
+ struct roce_ext_res_param {
+@@ -42,9 +47,25 @@ struct roce_ext_res_param {
+ uint32_t reg_data[0];
+ };
+
++struct roce_ext_res_data_u64 {
++ uint32_t offset[ROCE_MAX_U64_REG_NUM];
++ uint64_t data[ROCE_MAX_U64_REG_NUM];
++ uint32_t rsv[4];
++};
++
++struct roce_ext_res_param_u64 {
++ struct roce_ext_head head;
++ uint32_t rsv;
++ struct roce_ext_res_data_u64 reg_data;
++};
++
+ struct reg_data {
+ uint32_t *offset;
+- uint32_t *data;
++ union {
++ void *data;
++ uint32_t *data_u32;
++ uint64_t *data_u64;
++ };
+ };
+
+ struct roce_ext_reg_name {
+@@ -55,6 +76,7 @@ struct roce_ext_reg_name {
+ struct roce_ext_res_output {
+ struct roce_ext_head res_head;
+ struct reg_data reg;
++ uint32_t per_val_size;
+ struct roce_ext_reg_name reg_name;
+ };
+
+--
+2.33.0
+
diff --git a/0102-hikptool-roce-Add-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch b/0102-hikptool-roce-Add-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch
new file mode 100644
index 0000000..1c2d9eb
--- /dev/null
+++ b/0102-hikptool-roce-Add-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch
@@ -0,0 +1,248 @@
+From f704e9fc2d5d878e669b303ec8571e54c734e811 Mon Sep 17 00:00:00 2001
+From: wenglianfa <wenglianfa(a)huawei.com>
+Date: Wed, 2 Jul 2025 11:46:15 +0800
+Subject: [PATCH 102/102] hikptool/roce: Add roce_dfx_sta cmd for RoCE DFX
+ statistics
+
+Add roce_dfx_sta cmd for RoCE DFX statistics.
+
+Example:
+hikptool roce_dfx_sta -i eth1
+
+Signed-off-by: wenglianfa <wenglianfa(a)huawei.com>
+---
+ info_collect/hikp_collect_roce.c | 22 ++++
+ net/hikp_net_lib.h | 1 +
+ net/roce/roce_dfx_sta/hikp_roce_dfx_sta.c | 107 ++++++++++++++++++
+ net/roce/roce_dfx_sta/hikp_roce_dfx_sta.h | 33 ++++++
+ .../roce_ext_common/hikp_roce_ext_common.c | 1 +
+ 5 files changed, 164 insertions(+)
+ create mode 100644 net/roce/roce_dfx_sta/hikp_roce_dfx_sta.c
+ create mode 100644 net/roce/roce_dfx_sta/hikp_roce_dfx_sta.h
+
+diff --git a/info_collect/hikp_collect_roce.c b/info_collect/hikp_collect_roce.c
+index baf2899..01d773b 100644
+--- a/info_collect/hikp_collect_roce.c
++++ b/info_collect/hikp_collect_roce.c
+@@ -26,6 +26,7 @@
+ #include "hikp_roce_tsp.h"
+ #include "hikp_roce_scc.h"
+ #include "hikp_roce_gmv.h"
++#include "hikp_roce_dfx_sta.h"
+
+ static void collect_roce_devinfo_log(void)
+ {
+@@ -125,6 +126,26 @@ static int collect_hikp_roce_gmv_log(void *nic_name)
+ return 0;
+ }
+
++static int collect_hikp_roce_dfx_sta_log(void *nic_name)
++{
++ struct major_cmd_ctrl self = {0};
++ struct hikp_cmd_type type = {0};
++ int ret;
++
++ self.cmd_ptr = &type;
++ ret = hikp_roce_set_dfx_sta_bdf((char *)nic_name);
++ if (ret) {
++ HIKP_ERROR_PRINT("failed to set roce_dfx_sta bdf for %s.\n",
++ (char *)nic_name);
++ return ret;
++ }
++
++ printf("hikptool roce_dfx_sta -i %s\n", (char *)nic_name);
++ hikp_roce_dfx_sta_execute(&self);
++
++ return 0;
++}
++
+ static int collect_hikp_roce_scc_log(void *nic_name)
+ {
+ struct major_cmd_ctrl self = {0};
+@@ -466,6 +487,7 @@ static int collect_one_roce_hikp_log(void *net_name)
+ { "roce_tsp", collect_hikp_roce_tsp_log },
+ { "roce_scc", collect_hikp_roce_scc_log },
+ { "roce_gmv", collect_hikp_roce_gmv_log },
++ { "roce_dfx_sta", collect_hikp_roce_dfx_sta_log },
+ };
+ size_t i;
+
+diff --git a/net/hikp_net_lib.h b/net/hikp_net_lib.h
+index 7ebabfa..aa700ab 100644
+--- a/net/hikp_net_lib.h
++++ b/net/hikp_net_lib.h
+@@ -103,6 +103,7 @@ enum roce_cmd_type {
+ GET_ROCEE_RST_CMD,
+ GET_ROCEE_GLOBAL_CFG_CMD,
+ GET_ROCEE_BOND_CMD,
++ GET_ROCEE_DFX_STA_CMD,
+ };
+
+ enum ub_cmd_type {
+diff --git a/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.c b/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.c
+new file mode 100644
+index 0000000..b74507c
+--- /dev/null
++++ b/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.c
+@@ -0,0 +1,107 @@
++/*
++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd.
++ * Hikptool is licensed under Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
++ *
++ * See the Mulan PSL v2 for more details.
++ */
++
++#include "hikp_roce_dfx_sta.h"
++
++static struct cmd_roce_dfx_sta_param_t g_roce_dfx_sta_param_t = { 0 };
++
++int hikp_roce_set_dfx_sta_bdf(char *nic_name)
++{
++ return tool_check_and_get_valid_bdf_id(nic_name,
++ &g_roce_dfx_sta_param_t.target);
++}
++
++static int hikp_roce_dfx_sta_help(struct major_cmd_ctrl *self, const char *argv)
++{
++ HIKP_SET_USED(argv);
++
++ printf("\n Usage: %s %s\n", self->cmd_ptr->name, "-i <interface>\n");
++ printf("\n %s\n", self->cmd_ptr->help_info);
++ printf(" Options:\n\n");
++ printf(" %s, %-25s %s\n", "-h", "--help", "display this help and exit");
++ printf(" %s, %-25s %s\n", "-i", "--interface=<interface>", "device target, e.g. eth0");
++ printf(" %s, %-25s %s\n", "-c", "--clear=<clear>", "clear param count registers");
++ printf("\n");
++
++ return 0;
++}
++
++static int hikp_roce_dfx_sta_target(struct major_cmd_ctrl *self, const char *argv)
++{
++ self->err_no = tool_check_and_get_valid_bdf_id(argv, &(g_roce_dfx_sta_param_t.target));
++ if (self->err_no != 0)
++ snprintf(self->err_str, sizeof(self->err_str), "Unknown device %s.", argv);
++
++ return self->err_no;
++}
++
++static int hikp_roce_dfx_sta_clear_set(struct major_cmd_ctrl *self, const char *argv)
++{
++ HIKP_SET_USED(self);
++ HIKP_SET_USED(argv);
++
++ g_roce_dfx_sta_param_t.reset_flag = 1;
++ return 0;
++}
++
++/* DON'T change the order of this array or add entries between! */
++static const char *g_dfx_sta_reg_name[] = {
++ "PKT_RNR_STA",
++ "PKT_RTY_STA",
++ "MSN_RTY_STA",
++};
++
++static int hikp_roce_dfx_sta_get_data(struct hikp_cmd_ret **cmd_ret,
++ uint32_t block_id,
++ struct roce_ext_reg_name *reg_name)
++{
++ struct hikp_cmd_header req_header = { 0 };
++ struct roce_dfx_sta_req_param req_data;
++ uint32_t req_size;
++ int ret;
++
++ reg_name->reg_name = g_dfx_sta_reg_name;
++ reg_name->arr_len = HIKP_ARRAY_SIZE(g_dfx_sta_reg_name);
++
++ req_data.reset_flag = g_roce_dfx_sta_param_t.reset_flag;
++ req_data.bdf = g_roce_dfx_sta_param_t.target.bdf;
++ req_data.block_id = block_id;
++
++ req_size = sizeof(struct roce_dfx_sta_req_param);
++ hikp_cmd_init(&req_header, ROCE_MOD, GET_ROCEE_DFX_STA_CMD, 0);
++ *cmd_ret = hikp_cmd_alloc(&req_header, &req_data, req_size);
++ ret = hikp_rsp_normal_check(*cmd_ret);
++ if (ret)
++ printf("hikptool roce_dfx_sta get cmd data failed, ret: %d\n", ret);
++
++ return ret;
++}
++
++void hikp_roce_dfx_sta_execute(struct major_cmd_ctrl *self)
++{
++ hikp_roce_ext_execute(self, GET_ROCEE_DFX_STA_CMD, hikp_roce_dfx_sta_get_data);
++}
++
++static void cmd_roce_dfx_sta_init(void)
++{
++ struct major_cmd_ctrl *major_cmd = get_major_cmd();
++
++ major_cmd->option_count = 0;
++ major_cmd->execute = hikp_roce_dfx_sta_execute;
++
++ cmd_option_register("-h", "--help", false, hikp_roce_dfx_sta_help);
++ cmd_option_register("-i", "--interface", true, hikp_roce_dfx_sta_target);
++ cmd_option_register("-c", "--clear", false, hikp_roce_dfx_sta_clear_set);
++}
++
++HIKP_CMD_DECLARE("roce_dfx_sta", "get or clear RoCE dfx statistics", cmd_roce_dfx_sta_init);
+diff --git a/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.h b/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.h
+new file mode 100644
+index 0000000..b515356
+--- /dev/null
++++ b/net/roce/roce_dfx_sta/hikp_roce_dfx_sta.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd.
++ * Hikptool is licensed under Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
++ *
++ * See the Mulan PSL v2 for more details.
++ */
++
++#ifndef HIKP_ROCE_DFX_STA_H
++#define HIKP_ROCE_DFX_STA_H
++
++#include "hikp_roce_ext_common.h"
++
++struct cmd_roce_dfx_sta_param_t {
++ uint8_t reset_flag;
++ struct tool_target target;
++};
++
++struct roce_dfx_sta_req_param {
++ struct bdf_t bdf;
++ uint32_t block_id;
++ uint8_t reset_flag;
++};
++
++int hikp_roce_set_dfx_sta_bdf(char *nic_name);
++void hikp_roce_dfx_sta_execute(struct major_cmd_ctrl *self);
++
++#endif /* HIKP_ROCE_DFX_STA_H */
+diff --git a/net/roce/roce_ext_common/hikp_roce_ext_common.c b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+index c225ec8..ac6c8fb 100644
+--- a/net/roce/roce_ext_common/hikp_roce_ext_common.c
++++ b/net/roce/roce_ext_common/hikp_roce_ext_common.c
+@@ -44,6 +44,7 @@ static const struct cmd_type_info {
+ {GET_ROCEE_RST_CMD, "RST", ROCE_HIKP_RST_REG_NUM},
+ {GET_ROCEE_GLOBAL_CFG_CMD, "GLOBAL_CFG", ROCE_HIKP_GLOBAL_CFG_REG_NUM},
+ {GET_ROCEE_BOND_CMD, "BOND", ROCE_HIKP_BOND_REG_NUM},
++ {GET_ROCEE_DFX_STA_CMD, "DFX_STA", ROCE_HIKP_DFX_STA_NUM_EXT},
+ };
+
+ static int get_cmd_info_table_idx(enum roce_cmd_type cmd_type)
+--
+2.33.0
+
diff --git a/hikptool.spec b/hikptool.spec
index c19df02..c6ea91f 100644
--- a/hikptool.spec
+++ b/hikptool.spec
@@ -3,7 +3,7 @@
Name: hikptool
Summary: A userspace tool for Linux providing problem location on Kunpeng chips
Version: 1.0.0
-Release: 18
+Release: 19
License: MulanPSL2
Source: %{name}-%{version}.tar.gz
ExclusiveOS: linux
@@ -115,6 +115,9 @@ Patch0096: 0096-Hikptool-add-support-dump-SDMA-register-information-.patch
Patch0097: 0097-Add-support-collect-sdma-hikptool-dump-reg-info.patch
Patch0098: 0098-hikptool-Update-the-tool-version-number-to-1.1.4.patch
Patch0099: 0099-hikptool-The-cpu_ring-command-is-added.patch
+Patch0100: 0100-hikptool-roce-Fix-array-out-of-bounds-access.patch
+Patch0101: 0101-hikptool-roce-Support-to-print-u64-reg_data.patch
+Patch0102: 0102-hikptool-roce-Add-roce_dfx_sta-cmd-for-RoCE-DFX-stat.patch
%description
This package contains the hikptool
@@ -167,6 +170,9 @@ fi
/sbin/ldconfig
%changelog
+* Fri Jul 25 2025 Junxian Huang <huangjunxian6(a)hisilicon.com> 1.0.0-19
+- Support roce_dfx_sta query
+
* Fri Jun 6 2025 veega2022 <zhuweijia(a)huawei.com> 1.0.0-18
- The cpu_ring command is added.
--
2.33.0
1
0
您好!
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