355 lines
10 KiB
Diff
355 lines
10 KiB
Diff
|
|
From 80a8e63d5e764868cbaf2af3e522a320b5781508 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Chengchang Tang <tangchengchang@huawei.com>
|
||
|
|
Date: Mon, 30 Oct 2023 16:59:18 +0800
|
||
|
|
Subject: [PATCH 4/8] libhns: Add support for POE CQs
|
||
|
|
|
||
|
|
driver inclusion
|
||
|
|
category: feature
|
||
|
|
bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I8C6X4
|
||
|
|
|
||
|
|
---------------------------------------------------------------
|
||
|
|
|
||
|
|
Added support for POE CQs. POE CQs will forward CQE directly to
|
||
|
|
the corresponding POE channel.
|
||
|
|
|
||
|
|
In this case, the driver cannot update the QP CI, so
|
||
|
|
hnsdv_update_sq_ci() is added to allow users to change the QP CI.
|
||
|
|
|
||
|
|
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
|
||
|
|
---
|
||
|
|
providers/hns/hns_roce_u.c | 11 ++--
|
||
|
|
providers/hns/hns_roce_u_hw_v2.c | 19 ++++++
|
||
|
|
providers/hns/hns_roce_u_verbs.c | 110 ++++++++++++++++++++++++++++---
|
||
|
|
providers/hns/hnsdv.h | 22 +++++++
|
||
|
|
providers/hns/libhns.map | 2 +
|
||
|
|
5 files changed, 150 insertions(+), 14 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
|
||
|
|
index 1085b85..084385b 100644
|
||
|
|
--- a/providers/hns/hns_roce_u.c
|
||
|
|
+++ b/providers/hns/hns_roce_u.c
|
||
|
|
@@ -321,7 +321,8 @@ static void set_default_hw_id(struct hns_roce_context *context)
|
||
|
|
}
|
||
|
|
|
||
|
|
static int query_dev_attr(struct hns_roce_context *context,
|
||
|
|
- struct hns_roce_device *hr_dev)
|
||
|
|
+ struct hns_roce_device *hr_dev,
|
||
|
|
+ struct hns_roce_alloc_ucontext_resp *resp)
|
||
|
|
{
|
||
|
|
struct ibv_device_attr_ex attrx = {};
|
||
|
|
struct ibv_device_attr *dev_attrs = &attrx.orig_attr;
|
||
|
|
@@ -339,6 +340,9 @@ static int query_dev_attr(struct hns_roce_context *context,
|
||
|
|
context->max_srq_wr = dev_attrs->max_srq_wr;
|
||
|
|
context->max_srq_sge = dev_attrs->max_srq_sge;
|
||
|
|
|
||
|
|
+ if (get_link_type(dev_attrs->vendor_part_id, &hr_dev->link_type))
|
||
|
|
+ hr_dev->link_type = resp->mac_type;
|
||
|
|
+
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -390,12 +394,9 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
|
||
|
|
for (i = 0; i < HNS_ROCE_SRQ_TABLE_SIZE; ++i)
|
||
|
|
context->srq_table[i].refcnt = 0;
|
||
|
|
|
||
|
|
- if (query_dev_attr(context, hr_dev))
|
||
|
|
+ if (query_dev_attr(context, hr_dev, &resp))
|
||
|
|
goto err_free;
|
||
|
|
|
||
|
|
- if (get_link_type(dev_attrs.vendor_part_id, &hr_dev->link_type))
|
||
|
|
- hr_dev->link_type = resp.mac_type;
|
||
|
|
-
|
||
|
|
if (init_dca_context(context, cmd_fd,
|
||
|
|
&resp, ctx_attr, hr_dev->page_size))
|
||
|
|
goto err_free;
|
||
|
|
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
|
||
|
|
index fbd02dc..688b760 100644
|
||
|
|
--- a/providers/hns/hns_roce_u_hw_v2.c
|
||
|
|
+++ b/providers/hns/hns_roce_u_hw_v2.c
|
||
|
|
@@ -1029,6 +1029,9 @@ static int hns_roce_u_v2_poll_cq(struct ibv_cq *ibvcq, int ne,
|
||
|
|
int err = V2_CQ_OK;
|
||
|
|
int npolled;
|
||
|
|
|
||
|
|
+ if (cq->flags & HNS_ROCE_CQ_FLAG_POE_EN)
|
||
|
|
+ return V2_CQ_POLL_ERR;
|
||
|
|
+
|
||
|
|
hns_roce_spin_lock(&cq->hr_lock);
|
||
|
|
|
||
|
|
if (unlikely(hns_roce_reseted(ctx))) {
|
||
|
|
@@ -2202,6 +2205,9 @@ static int wc_start_poll_cq(struct ibv_cq_ex *current,
|
||
|
|
if (attr->comp_mask)
|
||
|
|
return EINVAL;
|
||
|
|
|
||
|
|
+ if (cq->flags & HNS_ROCE_CQ_FLAG_POE_EN)
|
||
|
|
+ return EOPNOTSUPP;
|
||
|
|
+
|
||
|
|
hns_roce_spin_lock(&cq->hr_lock);
|
||
|
|
|
||
|
|
if (unlikely(hns_roce_reseted(ctx))) {
|
||
|
|
@@ -3119,6 +3125,19 @@ int hns_roce_attach_qp_ex_ops(struct ibv_qp_init_attr_ex *attr,
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+void hnsdv_update_sq_ci(struct ibv_qp *ibv_qp, uint32_t inc_cnt)
|
||
|
|
+{
|
||
|
|
+ struct hns_roce_qp *qp;
|
||
|
|
+ struct hns_roce_wq *wq;
|
||
|
|
+
|
||
|
|
+ if (!ibv_qp)
|
||
|
|
+ return;
|
||
|
|
+
|
||
|
|
+ qp = to_hr_qp(ibv_qp);
|
||
|
|
+ wq = &qp->sq;
|
||
|
|
+ wq->tail += inc_cnt & (wq->wqe_cnt - 1);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
const struct hns_roce_u_hw hns_roce_u_hw_v2 = {
|
||
|
|
.hw_version = HNS_ROCE_HW_VER2,
|
||
|
|
.hw_ops = {
|
||
|
|
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
|
||
|
|
index 5b86077..c7863d7 100644
|
||
|
|
--- a/providers/hns/hns_roce_u_verbs.c
|
||
|
|
+++ b/providers/hns/hns_roce_u_verbs.c
|
||
|
|
@@ -36,6 +36,7 @@
|
||
|
|
#include <math.h>
|
||
|
|
#include <errno.h>
|
||
|
|
#include <pthread.h>
|
||
|
|
+#include <inttypes.h>
|
||
|
|
#include <sys/mman.h>
|
||
|
|
#include <ccan/ilog.h>
|
||
|
|
#include <ccan/minmax.h>
|
||
|
|
@@ -470,8 +471,40 @@ enum {
|
||
|
|
IBV_WC_EX_WITH_CVLAN,
|
||
|
|
};
|
||
|
|
|
||
|
|
+enum {
|
||
|
|
+ HNSDV_CQ_SUP_COMP_MASK = HNSDV_CQ_INIT_ATTR_MASK_CREATE_FLAGS,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+enum {
|
||
|
|
+ HNSDV_CQ_SUP_CREATE_FLAGS = HNSDV_CQ_CREATE_ENABLE_POE_MODE,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static int verify_hnsdv_cq_create_attr(struct hns_roce_context *ctx,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
+{
|
||
|
|
+ if (!hns_cq_attr)
|
||
|
|
+ return 0;
|
||
|
|
+
|
||
|
|
+ if (!check_comp_mask(hns_cq_attr->comp_mask, HNSDV_CQ_SUP_COMP_MASK)) {
|
||
|
|
+ verbs_err(&ctx->ibv_ctx, "Unsupported cq comps 0x%"PRIu64"\n",
|
||
|
|
+ hns_cq_attr->comp_mask);
|
||
|
|
+ return EOPNOTSUPP;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if ((hns_cq_attr->comp_mask & HNSDV_CQ_INIT_ATTR_MASK_CREATE_FLAGS) &&
|
||
|
|
+ !check_comp_mask(hns_cq_attr->create_flags,
|
||
|
|
+ HNSDV_CQ_SUP_CREATE_FLAGS)) {
|
||
|
|
+ verbs_err(&ctx->ibv_ctx, "Unsupported cq flags 0x%"PRIu64"\n",
|
||
|
|
+ hns_cq_attr->create_flags);
|
||
|
|
+ return EOPNOTSUPP;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
|
||
|
|
- struct hns_roce_context *context)
|
||
|
|
+ struct hns_roce_context *context,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
{
|
||
|
|
if (!attr->cqe || attr->cqe > context->max_cqe)
|
||
|
|
return -EINVAL;
|
||
|
|
@@ -495,7 +528,7 @@ static int verify_cq_create_attr(struct ibv_cq_init_attr_ex *attr,
|
||
|
|
attr->cqe = max_t(uint32_t, HNS_ROCE_MIN_CQE_NUM,
|
||
|
|
roundup_pow_of_two(attr->cqe));
|
||
|
|
|
||
|
|
- return 0;
|
||
|
|
+ return verify_hnsdv_cq_create_attr(context, hns_cq_attr);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int hns_roce_alloc_cq_buf(struct hns_roce_cq *cq)
|
||
|
|
@@ -508,9 +541,34 @@ static int hns_roce_alloc_cq_buf(struct hns_roce_cq *cq)
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static void set_hnsdv_cq_attr(struct hns_roce_ib_create_cq *cmd_drv,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
+{
|
||
|
|
+ if (!hns_cq_attr)
|
||
|
|
+ return;
|
||
|
|
+
|
||
|
|
+ if (hns_cq_attr->create_flags & HNSDV_CQ_CREATE_ENABLE_POE_MODE) {
|
||
|
|
+ cmd_drv->create_flags |= HNS_ROCE_CREATE_CQ_FLAGS_POE_MODE;
|
||
|
|
+ cmd_drv->poe_channel = hns_cq_attr->poe_channel;
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int check_hnsdv_cq_flags(struct hnsdv_cq_init_attr *hns_cq_attr,
|
||
|
|
+ struct hns_roce_cq *cq)
|
||
|
|
+{
|
||
|
|
+ if (!hns_cq_attr)
|
||
|
|
+ return 0;
|
||
|
|
+
|
||
|
|
+ if ((hns_cq_attr->create_flags & HNSDV_CQ_CREATE_ENABLE_POE_MODE) &&
|
||
|
|
+ !(cq->flags & HNS_ROCE_CQ_FLAG_POE_EN))
|
||
|
|
+ return EOPNOTSUPP;
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int exec_cq_create_cmd(struct ibv_context *context,
|
||
|
|
struct hns_roce_cq *cq,
|
||
|
|
- struct ibv_cq_init_attr_ex *attr)
|
||
|
|
+ struct ibv_cq_init_attr_ex *attr,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
{
|
||
|
|
struct hns_roce_create_cq_ex_resp resp_ex = {};
|
||
|
|
struct hns_roce_ib_create_cq_resp *resp_drv;
|
||
|
|
@@ -525,6 +583,8 @@ static int exec_cq_create_cmd(struct ibv_context *context,
|
||
|
|
cmd_drv->db_addr = (uintptr_t)cq->db;
|
||
|
|
cmd_drv->cqe_size = (uintptr_t)cq->cqe_size;
|
||
|
|
|
||
|
|
+ set_hnsdv_cq_attr(cmd_drv, hns_cq_attr);
|
||
|
|
+
|
||
|
|
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);
|
||
|
|
@@ -534,7 +594,14 @@ static int exec_cq_create_cmd(struct ibv_context *context,
|
||
|
|
cq->cqn = resp_drv->cqn;
|
||
|
|
cq->flags = resp_drv->cap_flags;
|
||
|
|
|
||
|
|
- return 0;
|
||
|
|
+ ret = check_hnsdv_cq_flags(hns_cq_attr, cq);
|
||
|
|
+ if (ret)
|
||
|
|
+ goto flags_err;
|
||
|
|
+ return ret;
|
||
|
|
+
|
||
|
|
+flags_err:
|
||
|
|
+ ibv_cmd_destroy_cq(&cq->verbs_cq.cq);
|
||
|
|
+ return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int hns_roce_init_cq_swc(struct hns_roce_cq *cq,
|
||
|
|
@@ -581,13 +648,14 @@ static int hns_roce_cq_spinlock_init(struct ibv_context *context,
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct ibv_cq_ex *create_cq(struct ibv_context *context,
|
||
|
|
- struct ibv_cq_init_attr_ex *attr)
|
||
|
|
+ struct ibv_cq_init_attr_ex *attr,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
{
|
||
|
|
struct hns_roce_context *hr_ctx = to_hr_ctx(context);
|
||
|
|
struct hns_roce_cq *cq;
|
||
|
|
int ret;
|
||
|
|
|
||
|
|
- ret = verify_cq_create_attr(attr, hr_ctx);
|
||
|
|
+ ret = verify_cq_create_attr(attr, hr_ctx, hns_cq_attr);
|
||
|
|
if (ret)
|
||
|
|
goto err;
|
||
|
|
|
||
|
|
@@ -618,7 +686,7 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
|
||
|
|
if (ret)
|
||
|
|
goto err_swc;
|
||
|
|
|
||
|
|
- ret = exec_cq_create_cmd(context, cq, attr);
|
||
|
|
+ ret = exec_cq_create_cmd(context, cq, attr, hns_cq_attr);
|
||
|
|
if (ret)
|
||
|
|
goto err_cmd;
|
||
|
|
|
||
|
|
@@ -652,7 +720,7 @@ struct ibv_cq *hns_roce_u_create_cq(struct ibv_context *context, int cqe,
|
||
|
|
.comp_vector = comp_vector,
|
||
|
|
};
|
||
|
|
|
||
|
|
- cq = create_cq(context, &attr);
|
||
|
|
+ cq = create_cq(context, &attr, NULL);
|
||
|
|
return cq ? ibv_cq_ex_to_cq(cq) : NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -661,13 +729,37 @@ struct ibv_cq_ex *hns_roce_u_create_cq_ex(struct ibv_context *context,
|
||
|
|
{
|
||
|
|
struct ibv_cq_ex *cq;
|
||
|
|
|
||
|
|
- cq = create_cq(context, attr);
|
||
|
|
+ cq = create_cq(context, attr, NULL);
|
||
|
|
if (cq)
|
||
|
|
hns_roce_attach_cq_ex_ops(cq, attr->wc_flags);
|
||
|
|
|
||
|
|
return cq;
|
||
|
|
}
|
||
|
|
|
||
|
|
+struct ibv_cq_ex *hnsdv_create_cq_ex(struct ibv_context *context,
|
||
|
|
+ struct ibv_cq_init_attr_ex *cq_attr,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr)
|
||
|
|
+{
|
||
|
|
+ struct hns_roce_context *ctx = context ? to_hr_ctx(context) : NULL;
|
||
|
|
+ struct ibv_cq_ex *cq;
|
||
|
|
+
|
||
|
|
+ if (!ctx || !cq_attr) {
|
||
|
|
+ errno = EINVAL;
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (!is_hns_dev(context->device)) {
|
||
|
|
+ errno = EOPNOTSUPP;
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ cq = create_cq(context, cq_attr, hns_cq_attr);
|
||
|
|
+ if (cq)
|
||
|
|
+ hns_roce_attach_cq_ex_ops(cq, cq_attr->wc_flags);
|
||
|
|
+
|
||
|
|
+ return cq;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void hns_roce_u_cq_event(struct ibv_cq *cq)
|
||
|
|
{
|
||
|
|
to_hr_cq(cq)->arm_sn++;
|
||
|
|
diff --git a/providers/hns/hnsdv.h b/providers/hns/hnsdv.h
|
||
|
|
index 159edb8..c5c7c11 100644
|
||
|
|
--- a/providers/hns/hnsdv.h
|
||
|
|
+++ b/providers/hns/hnsdv.h
|
||
|
|
@@ -92,6 +92,28 @@ struct hnsdv_context {
|
||
|
|
int hnsdv_query_device(struct ibv_context *ctx_in,
|
||
|
|
struct hnsdv_context *attrs_out);
|
||
|
|
|
||
|
|
+enum hnsdv_cq_init_attr_mask {
|
||
|
|
+ HNSDV_CQ_INIT_ATTR_MASK_CREATE_FLAGS = 1 << 0,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+enum hnsdv_cq_create_flags {
|
||
|
|
+ HNSDV_CQ_CREATE_ENABLE_POE_MODE = 1 << 0,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+struct hnsdv_cq_init_attr {
|
||
|
|
+ uint64_t comp_mask; /* Use enum hnsdv_cq_init_attr_mask */
|
||
|
|
+ uint64_t create_flags; /* Use enum hnsdv_cq_create_flags */
|
||
|
|
+ uint8_t poe_channel; /* poe channel to use */
|
||
|
|
+ uint8_t reserved[7];
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+struct ibv_cq_ex *hnsdv_create_cq_ex(struct ibv_context *context,
|
||
|
|
+ struct ibv_cq_init_attr_ex *cq_attr,
|
||
|
|
+ struct hnsdv_cq_init_attr *hns_cq_attr);
|
||
|
|
+
|
||
|
|
+/* used in stars mode */
|
||
|
|
+void hnsdv_update_sq_ci(struct ibv_qp *qp, uint32_t inc_idx);
|
||
|
|
+
|
||
|
|
#ifdef __cplusplus
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
diff --git a/providers/hns/libhns.map b/providers/hns/libhns.map
|
||
|
|
index ebf28eb..27efc83 100644
|
||
|
|
--- a/providers/hns/libhns.map
|
||
|
|
+++ b/providers/hns/libhns.map
|
||
|
|
@@ -6,5 +6,7 @@ HNS_1.0 {
|
||
|
|
hnsdv_open_device;
|
||
|
|
hnsdv_create_qp;
|
||
|
|
hnsdv_query_device;
|
||
|
|
+ hnsdv_create_cq_ex;
|
||
|
|
+ hnsdv_update_sq_ci;
|
||
|
|
local: *;
|
||
|
|
};
|
||
|
|
--
|
||
|
|
2.25.1
|
||
|
|
|