2023-12-12 19:02:37 +08:00
|
|
|
From 99e1e64edab954ce1895d83a3d6f4317bc12c444 Mon Sep 17 00:00:00 2001
|
2023-04-13 15:22:58 +08:00
|
|
|
From: Yixing Liu <liuyixing1@huawei.com>
|
|
|
|
|
Date: Wed, 12 Apr 2023 17:01:09 +0800
|
2023-12-12 19:02:37 +08:00
|
|
|
Subject: [PATCH] libhns: Support congestion control algorithm configuration
|
2023-04-13 15:22:58 +08:00
|
|
|
|
|
|
|
|
driver inclusion
|
|
|
|
|
category: feature
|
|
|
|
|
bugzilla: https://gitee.com/openeuler/kernel/issues/I6N1G4
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Added the use of direct verbs to implement QP-level
|
|
|
|
|
user-configurable congestion control algorithms. Among them,
|
|
|
|
|
the user mode driver mainly provides interfaces for users to
|
|
|
|
|
choose, and the kernel mode driver is responsible for filling
|
|
|
|
|
the resources of different algorithms and providing the
|
|
|
|
|
supported algorithm types for user mode.
|
|
|
|
|
|
|
|
|
|
At the same time, provide a direct verbs interface for users to
|
|
|
|
|
query the type of congestion control algorithm.
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Yixing Liu <liuyixing1@huawei.com>
|
|
|
|
|
Reviewed-by: Yangyang Li <liyangyang20@huawei.com>
|
|
|
|
|
---
|
|
|
|
|
providers/hns/hns_roce_u.c | 1 +
|
|
|
|
|
providers/hns/hns_roce_u.h | 6 ++
|
|
|
|
|
providers/hns/hns_roce_u_verbs.c | 107 +++++++++++++++++++++++++++++--
|
|
|
|
|
providers/hns/hnsdv.h | 22 +++++++
|
|
|
|
|
providers/hns/libhns.map | 1 +
|
|
|
|
|
5 files changed, 131 insertions(+), 6 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
|
|
|
|
|
index 3d29838..87f9ed8 100644
|
|
|
|
|
--- a/providers/hns/hns_roce_u.c
|
|
|
|
|
+++ b/providers/hns/hns_roce_u.c
|
|
|
|
|
@@ -299,6 +299,7 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
|
|
|
|
|
goto err_free;
|
|
|
|
|
|
|
|
|
|
hr_dev->mac_type = resp.mac_type;
|
|
|
|
|
+ hr_dev->congest_type = resp.congest_type;
|
|
|
|
|
|
|
|
|
|
if (!resp.cqe_size)
|
|
|
|
|
context->cqe_size = HNS_ROCE_CQE_SIZE;
|
|
|
|
|
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
|
|
|
|
|
index 76c7adb..41e9599 100644
|
|
|
|
|
--- a/providers/hns/hns_roce_u.h
|
|
|
|
|
+++ b/providers/hns/hns_roce_u.h
|
|
|
|
|
@@ -172,6 +172,7 @@ struct hns_roce_device {
|
|
|
|
|
const struct hns_roce_u_hw *u_hw;
|
|
|
|
|
int hw_version;
|
|
|
|
|
uint8_t mac_type;
|
|
|
|
|
+ uint8_t congest_type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct hns_roce_buf {
|
|
|
|
|
@@ -230,6 +231,11 @@ struct hns_roce_v2_reset_state {
|
|
|
|
|
uint32_t is_reset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
+struct hns_roce_cmd_flag {
|
|
|
|
|
+ uint32_t create_flags;
|
|
|
|
|
+ uint32_t congest_type_flags;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
struct hns_roce_context {
|
|
|
|
|
struct verbs_context ibv_ctx;
|
|
|
|
|
void *uar;
|
|
|
|
|
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
|
2023-12-12 19:02:37 +08:00
|
|
|
index 282ab74..499735c 100644
|
2023-04-13 15:22:58 +08:00
|
|
|
--- a/providers/hns/hns_roce_u_verbs.c
|
|
|
|
|
+++ b/providers/hns/hns_roce_u_verbs.c
|
|
|
|
|
@@ -89,10 +89,10 @@ int hns_roce_u_query_device(struct ibv_context *context,
|
|
|
|
|
struct ibv_device_attr_ex *attr, size_t attr_size)
|
|
|
|
|
{
|
|
|
|
|
struct ib_uverbs_ex_query_device_resp resp;
|
|
|
|
|
+ unsigned int major, minor, sub_minor;
|
|
|
|
|
size_t resp_size = sizeof(resp);
|
|
|
|
|
- int ret;
|
|
|
|
|
uint64_t raw_fw_ver;
|
|
|
|
|
- unsigned int major, minor, sub_minor;
|
|
|
|
|
+ int ret;
|
|
|
|
|
|
|
|
|
|
ret = ibv_cmd_query_device_any(context, input, attr, attr_size, &resp,
|
|
|
|
|
&resp_size);
|
|
|
|
|
@@ -110,6 +110,27 @@ int hns_roce_u_query_device(struct ibv_context *context,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+int hnsdv_query_device(struct ibv_context *context,
|
|
|
|
|
+ struct hnsdv_context *attrs_out)
|
|
|
|
|
+{
|
|
|
|
|
+ struct hns_roce_device *hr_dev = to_hr_dev(context->device);
|
|
|
|
|
+
|
|
|
|
|
+ if (!hr_dev) {
|
|
|
|
|
+ verbs_err(verbs_get_ctx(context), "not a HNS RoCE device!\n");
|
|
|
|
|
+ return EOPNOTSUPP;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!attrs_out)
|
|
|
|
|
+ return EINVAL;
|
|
|
|
|
+
|
|
|
|
|
+ memset(attrs_out, 0, sizeof(*attrs_out));
|
|
|
|
|
+
|
|
|
|
|
+ attrs_out->comp_mask |= HNSDV_CONTEXT_MASK_CONGEST_TYPE;
|
|
|
|
|
+ attrs_out->congest_type = hr_dev->congest_type;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
int hns_roce_u_query_port(struct ibv_context *context, uint8_t port,
|
|
|
|
|
struct ibv_port_attr *attr)
|
|
|
|
|
{
|
|
|
|
|
@@ -956,6 +977,67 @@ int hns_roce_u_destroy_srq(struct ibv_srq *ibv_srq)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+enum {
|
|
|
|
|
+ HNSDV_QP_SUP_COMP_MASK = HNSDV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS |
|
|
|
|
|
+ HNSDV_QP_INIT_ATTR_MASK_QP_CONGEST_TYPE,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static int check_qp_congest_type(struct hns_roce_context *ctx,
|
|
|
|
|
+ struct hnsdv_qp_init_attr *hns_attr,
|
|
|
|
|
+ struct hns_roce_cmd_flag *cmd_flag)
|
|
|
|
|
+{
|
|
|
|
|
+ struct hns_roce_device *hr_dev = to_hr_dev(ctx->ibv_ctx.context.device);
|
|
|
|
|
+
|
|
|
|
|
+ if (!check_comp_mask(hns_attr->congest_type, hr_dev->congest_type)) {
|
|
|
|
|
+ verbs_err(&ctx->ibv_ctx, "unsupported congest type 0x%x.\n",
|
|
|
|
|
+ hns_attr->congest_type);
|
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switch (hns_attr->congest_type) {
|
|
|
|
|
+ case HNSDV_QP_CREATE_ENABLE_DCQCN:
|
|
|
|
|
+ cmd_flag->congest_type_flags |= HNS_ROCE_CREATE_QP_FLAGS_DCQCN;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case HNSDV_QP_CREATE_ENABLE_LDCP:
|
|
|
|
|
+ cmd_flag->congest_type_flags |= HNS_ROCE_CREATE_QP_FLAGS_LDCP;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case HNSDV_QP_CREATE_ENABLE_HC3:
|
2023-12-12 19:02:37 +08:00
|
|
|
+ cmd_flag->congest_type_flags |= HNS_ROCE_CREATE_QP_FLAGS_HC3;
|
2023-04-13 15:22:58 +08:00
|
|
|
+ break;
|
|
|
|
|
+ case HNSDV_QP_CREATE_ENABLE_DIP:
|
|
|
|
|
+ cmd_flag->congest_type_flags |= HNS_ROCE_CREATE_QP_FLAGS_DIP;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ verbs_err(&ctx->ibv_ctx,
|
|
|
|
|
+ "unsupported congestion control algorithm configuration.\n");
|
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int check_hnsdv_qp_attr(struct hns_roce_context *ctx,
|
|
|
|
|
+ struct hnsdv_qp_init_attr *hns_attr,
|
|
|
|
|
+ struct hns_roce_cmd_flag *cmd_flag)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+
|
|
|
|
|
+ if (!hns_attr)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (!check_comp_mask(hns_attr->comp_mask, HNSDV_QP_SUP_COMP_MASK)) {
|
|
|
|
|
+ verbs_err(&ctx->ibv_ctx, "invalid hnsdv comp_mask 0x%x.\n",
|
|
|
|
|
+ hns_attr->comp_mask);
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret = check_qp_congest_type(ctx, hns_attr, cmd_flag);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ return ret;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
enum {
|
|
|
|
|
CREATE_QP_SUP_COMP_MASK = IBV_QP_INIT_ATTR_PD | IBV_QP_INIT_ATTR_XRCD |
|
|
|
|
|
IBV_QP_INIT_ATTR_SEND_OPS_FLAGS,
|
|
|
|
|
@@ -1050,7 +1132,9 @@ static int verify_qp_create_cap(struct hns_roce_context *ctx,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int verify_qp_create_attr(struct hns_roce_context *ctx,
|
|
|
|
|
- struct ibv_qp_init_attr_ex *attr)
|
|
|
|
|
+ struct ibv_qp_init_attr_ex *attr,
|
|
|
|
|
+ struct hnsdv_qp_init_attr *hns_attr,
|
|
|
|
|
+ struct hns_roce_cmd_flag *cmd_flag)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
@@ -1058,6 +1142,10 @@ static int verify_qp_create_attr(struct hns_roce_context *ctx,
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
+ ret = check_hnsdv_qp_attr(ctx, hns_attr, cmd_flag);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ return ret;
|
|
|
|
|
+
|
|
|
|
|
return verify_qp_create_cap(ctx, attr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1452,7 +1540,8 @@ static int hns_roce_store_qp(struct hns_roce_context *ctx,
|
|
|
|
|
static int qp_exec_create_cmd(struct ibv_qp_init_attr_ex *attr,
|
|
|
|
|
struct hns_roce_qp *qp,
|
|
|
|
|
struct hns_roce_context *ctx,
|
|
|
|
|
- uint64_t *dwqe_mmap_key)
|
|
|
|
|
+ uint64_t *dwqe_mmap_key,
|
|
|
|
|
+ struct hns_roce_cmd_flag *cmd_flag)
|
|
|
|
|
{
|
|
|
|
|
struct hns_roce_create_qp_ex_resp resp_ex = {};
|
|
|
|
|
struct hns_roce_create_qp_ex cmd_ex = {};
|
|
|
|
|
@@ -1464,6 +1553,11 @@ static int qp_exec_create_cmd(struct ibv_qp_init_attr_ex *attr,
|
|
|
|
|
cmd_ex.log_sq_stride = qp->sq.wqe_shift;
|
|
|
|
|
cmd_ex.log_sq_bb_count = hr_ilog32(qp->sq.wqe_cnt);
|
|
|
|
|
|
|
|
|
|
+ if (cmd_flag->congest_type_flags) {
|
|
|
|
|
+ cmd_ex.comp_mask |= HNS_ROCE_CREATE_QP_MASK_CONGEST_TYPE;
|
|
|
|
|
+ cmd_ex.congest_type_flags = cmd_flag->congest_type_flags;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
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));
|
|
|
|
|
@@ -1543,11 +1637,12 @@ 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_cmd_flag cmd_flag = {};
|
|
|
|
|
struct hns_roce_qp *qp;
|
|
|
|
|
uint64_t dwqe_mmap_key;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
- ret = verify_qp_create_attr(context, attr);
|
|
|
|
|
+ ret = verify_qp_create_attr(context, attr, hns_attr, &cmd_flag);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
|
|
@@ -1567,7 +1662,7 @@ static struct ibv_qp *create_qp(struct ibv_context *ibv_ctx,
|
|
|
|
|
if (ret)
|
|
|
|
|
goto err_buf;
|
|
|
|
|
|
|
|
|
|
- ret = qp_exec_create_cmd(attr, qp, context, &dwqe_mmap_key);
|
|
|
|
|
+ ret = qp_exec_create_cmd(attr, qp, context, &dwqe_mmap_key, &cmd_flag);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto err_cmd;
|
|
|
|
|
|
|
|
|
|
diff --git a/providers/hns/hnsdv.h b/providers/hns/hnsdv.h
|
|
|
|
|
index cfe1611..e15b428 100644
|
|
|
|
|
--- a/providers/hns/hnsdv.h
|
|
|
|
|
+++ b/providers/hns/hnsdv.h
|
|
|
|
|
@@ -45,19 +45,41 @@ enum hnsdv_qp_create_flags {
|
|
|
|
|
HNSDV_QP_CREATE_ENABLE_DCA_MODE = 1 << 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
+enum hnsdv_qp_congest_ctrl_type {
|
|
|
|
|
+ HNSDV_QP_CREATE_ENABLE_DCQCN = 1 << 0,
|
|
|
|
|
+ HNSDV_QP_CREATE_ENABLE_LDCP = 1 << 1,
|
|
|
|
|
+ HNSDV_QP_CREATE_ENABLE_HC3 = 1 << 2,
|
|
|
|
|
+ HNSDV_QP_CREATE_ENABLE_DIP = 1 << 3,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
enum hnsdv_qp_init_attr_mask {
|
|
|
|
|
HNSDV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS = 1 << 0,
|
|
|
|
|
+ HNSDV_QP_INIT_ATTR_MASK_QP_CONGEST_TYPE = 1 << 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct hnsdv_qp_init_attr {
|
|
|
|
|
uint64_t comp_mask; /* Use enum hnsdv_qp_init_attr_mask */
|
|
|
|
|
uint32_t create_flags; /* Use enum hnsdv_qp_create_flags */
|
|
|
|
|
+ uint8_t congest_type; /* Use enum hnsdv_qp_congest_ctrl_type */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ibv_qp *hnsdv_create_qp(struct ibv_context *context,
|
|
|
|
|
struct ibv_qp_init_attr_ex *qp_attr,
|
|
|
|
|
struct hnsdv_qp_init_attr *hns_qp_attr);
|
|
|
|
|
|
|
|
|
|
+enum hnsdv_query_context_comp_mask {
|
|
|
|
|
+ HNSDV_CONTEXT_MASK_CONGEST_TYPE = 1 << 0,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+struct hnsdv_context {
|
|
|
|
|
+ uint64_t comp_mask; /* use enum hnsdv_query_context_comp_mask */
|
|
|
|
|
+ uint64_t flags;
|
|
|
|
|
+ uint8_t congest_type; /* Use enum hnsdv_qp_congest_ctrl_type */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+int hnsdv_query_device(struct ibv_context *ctx_in,
|
|
|
|
|
+ struct hnsdv_context *attrs_out);
|
|
|
|
|
+
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
diff --git a/providers/hns/libhns.map b/providers/hns/libhns.map
|
|
|
|
|
index aed491c..ebf28eb 100644
|
|
|
|
|
--- a/providers/hns/libhns.map
|
|
|
|
|
+++ b/providers/hns/libhns.map
|
|
|
|
|
@@ -5,5 +5,6 @@ HNS_1.0 {
|
|
|
|
|
hnsdv_is_supported;
|
|
|
|
|
hnsdv_open_device;
|
|
|
|
|
hnsdv_create_qp;
|
|
|
|
|
+ hnsdv_query_device;
|
|
|
|
|
local: *;
|
|
|
|
|
};
|
|
|
|
|
--
|
|
|
|
|
2.25.1
|
|
|
|
|
|