代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/rdma-core 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 13d4b60fcd0880fae54b1af627eeb7297d7b086d Mon Sep 17 00:00:00 2001
From: Chengchang Tang <tangchengchang@huawei.com>
Date: Tue, 29 Jun 2021 21:01:27 +0800
Subject: libhns: Sync DCA status by shared memory
driver inclusion
category: feature
bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I63L1M
----------------------------------------------------------
Use DCA num from the resp of modify_qp() and indicate the DCA status bit in
the shared memory, if the num is valid, the user DCA can get the DCA status
by testing the bit in the shared memory for each QP, othewise invoke the
verbs 'HNS_IB_METHOD_DCA_MEM_ATTACH' to check the DCA status.
Each QP has 2 bits in shared memory, 1 bit is used to lock the DCA status
changing by kernel driver or user driver, another bit is used to indicate
the DCA attaching status.
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Reviewed-by: Yangyang Li <liyangyang20@huawei.com>
---
providers/hns/hns_roce_u.h | 31 +++++++++++++++++++++++
providers/hns/hns_roce_u_buf.c | 42 ++++++++++++++++++++++++++++++++
providers/hns/hns_roce_u_hw_v2.c | 20 ++++++++++++++-
3 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index a8f811e..91b0c8f 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -362,6 +362,7 @@ struct hns_roce_dca_buf {
void **bufs;
unsigned int max_cnt;
unsigned int shift;
+ unsigned int dcan;
};
struct hns_roce_qp {
@@ -422,6 +423,7 @@ struct hns_roce_dca_attach_attr {
uint32_t sq_offset;
uint32_t sge_offset;
uint32_t rq_offset;
+ bool force;
};
struct hns_roce_dca_detach_attr {
@@ -534,6 +536,32 @@ static inline int hns_roce_spin_unlock(struct hns_roce_spinlock *hr_lock)
return 0;
}
+#define HNS_ROCE_BIT_MASK(nr) (1UL << ((nr) % 64))
+#define HNS_ROCE_BIT_WORD(nr) ((nr) / 64)
+
+static inline bool atomic_test_bit(atomic_bitmap_t *p, uint32_t nr)
+{
+ p += HNS_ROCE_BIT_WORD(nr);
+ return !!(atomic_load(p) & HNS_ROCE_BIT_MASK(nr));
+}
+
+static inline bool test_and_set_bit_lock(atomic_bitmap_t *p, uint32_t nr)
+{
+ uint64_t mask = HNS_ROCE_BIT_MASK(nr);
+
+ p += HNS_ROCE_BIT_WORD(nr);
+ if (atomic_load(p) & mask)
+ return true;
+
+ return (atomic_fetch_or(p, mask) & mask) != 0;
+}
+
+static inline void clear_bit_unlock(atomic_bitmap_t *p, uint32_t nr)
+{
+ p += HNS_ROCE_BIT_WORD(nr);
+ atomic_fetch_and(p, ~HNS_ROCE_BIT_MASK(nr));
+}
+
int hns_roce_u_query_device(struct ibv_context *context,
const struct ibv_query_device_ex_input *input,
struct ibv_device_attr_ex *attr, size_t attr_size);
@@ -614,6 +642,9 @@ int hns_roce_attach_dca_mem(struct hns_roce_context *ctx, uint32_t handle,
uint32_t size, struct hns_roce_dca_buf *buf);
void hns_roce_detach_dca_mem(struct hns_roce_context *ctx, uint32_t handle,
struct hns_roce_dca_detach_attr *attr);
+bool hns_roce_dca_start_post(struct hns_roce_dca_ctx *ctx, uint32_t dcan);
+void hns_roce_dca_stop_post(struct hns_roce_dca_ctx *ctx, uint32_t dcan);
+
void hns_roce_shrink_dca_mem(struct hns_roce_context *ctx);
void hns_roce_cleanup_dca_mem(struct hns_roce_context *ctx);
diff --git a/providers/hns/hns_roce_u_buf.c b/providers/hns/hns_roce_u_buf.c
index 3d41b89..08c0fbc 100644
--- a/providers/hns/hns_roce_u_buf.c
+++ b/providers/hns/hns_roce_u_buf.c
@@ -440,6 +440,45 @@ static int setup_dca_buf(struct hns_roce_context *ctx, uint32_t handle,
return (idx >= page_count) ? 0 : -ENOMEM;
}
+#define DCAN_TO_SYNC_BIT(n) ((n) * HNS_DCA_BITS_PER_STATUS)
+#define DCAN_TO_STAT_BIT(n) DCAN_TO_SYNC_BIT(n)
+
+#define MAX_DCA_TRY_LOCK_TIMES 10
+bool hns_roce_dca_start_post(struct hns_roce_dca_ctx *ctx, uint32_t dcan)
+{
+ atomic_bitmap_t *st = ctx->sync_status;
+ int try_times = 0;
+
+ if (!st || dcan >= ctx->max_qps)
+ return true;
+
+ while (test_and_set_bit_lock(st, DCAN_TO_SYNC_BIT(dcan)))
+ if (try_times++ > MAX_DCA_TRY_LOCK_TIMES)
+ return false;
+
+ return true;
+}
+
+void hns_roce_dca_stop_post(struct hns_roce_dca_ctx *ctx, uint32_t dcan)
+{
+ atomic_bitmap_t *st = ctx->sync_status;
+
+ if (!st || dcan >= ctx->max_qps)
+ return;
+
+ clear_bit_unlock(st, DCAN_TO_SYNC_BIT(dcan));
+}
+
+static bool check_dca_is_attached(struct hns_roce_dca_ctx *ctx, uint32_t dcan)
+{
+ atomic_bitmap_t *st = ctx->buf_status;
+
+ if (!st || dcan >= ctx->max_qps)
+ return false;
+
+ return atomic_test_bit(st, DCAN_TO_STAT_BIT(dcan));
+}
+
#define DCA_EXPAND_MEM_TRY_TIMES 3
int hns_roce_attach_dca_mem(struct hns_roce_context *ctx, uint32_t handle,
struct hns_roce_dca_attach_attr *attr,
@@ -451,6 +490,9 @@ int hns_roce_attach_dca_mem(struct hns_roce_context *ctx, uint32_t handle,
int try_times = 0;
int ret = 0;
+ if (!attr->force && check_dca_is_attached(&ctx->dca_ctx, buf->dcan))
+ return 0;
+
do {
resp.alloc_pages = 0;
ret = attach_dca_mem(ctx, handle, attr, &resp);
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 7e3ad92..028d20c 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -601,6 +601,7 @@ static int dca_attach_qp_buf(struct hns_roce_context *ctx,
struct hns_roce_qp *qp)
{
struct hns_roce_dca_attach_attr attr = {};
+ bool enable_detach;
uint32_t idx;
int ret;
@@ -622,9 +623,16 @@ static int dca_attach_qp_buf(struct hns_roce_context *ctx,
attr.rq_offset = idx << qp->rq.wqe_shift;
}
+ enable_detach = check_dca_detach_enable(qp);
+ if (enable_detach &&
+ !hns_roce_dca_start_post(&ctx->dca_ctx, qp->dca_wqe.dcan))
+ /* Force attach if failed to sync dca status */
+ attr.force = true;
ret = hns_roce_attach_dca_mem(ctx, qp->verbs_qp.qp.handle, &attr,
- qp->buf_size, &qp->dca_wqe);
+ qp->buf_size, &qp->dca_wqe);
+ if (ret && enable_detach)
+ hns_roce_dca_stop_post(&ctx->dca_ctx, qp->dca_wqe.dcan);
hns_roce_spin_unlock(&qp->rq.hr_lock);
hns_roce_spin_unlock(&qp->sq.hr_lock);
@@ -1450,6 +1458,9 @@ out:
hns_roce_spin_unlock(&qp->sq.hr_lock);
+ if (check_dca_detach_enable(qp))
+ hns_roce_dca_stop_post(&ctx->dca_ctx, qp->dca_wqe.dcan);
+
if (ibvqp->state == IBV_QPS_ERR) {
attr.qp_state = IBV_QPS_ERR;
@@ -1582,6 +1593,9 @@ out:
hns_roce_spin_unlock(&qp->rq.hr_lock);
+ if (check_dca_detach_enable(qp))
+ hns_roce_dca_stop_post(&ctx->dca_ctx, qp->dca_wqe.dcan);
+
if (ibvqp->state == IBV_QPS_ERR) {
attr.qp_state = IBV_QPS_ERR;
hns_roce_u_v2_modify_qp(ibvqp, &attr, IBV_QP_STATE);
@@ -1693,6 +1707,7 @@ static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
if (attr->qp_state == IBV_QPS_RTR) {
hr_qp->tc_mode = resp_ex.drv_payload.tc_mode;
hr_qp->priority = resp_ex.drv_payload.priority;
+ hr_qp->dca_wqe.dcan = resp_ex.drv_payload.dcan;
}
}
@@ -2721,6 +2736,9 @@ static int wr_complete(struct ibv_qp_ex *ibv_qp)
out:
hns_roce_spin_unlock(&qp->sq.hr_lock);
+ if (check_dca_detach_enable(qp))
+ hns_roce_dca_stop_post(&ctx->dca_ctx, qp->dca_wqe.dcan);
+
if (ibv_qp->qp_base.state == IBV_QPS_ERR) {
attr.qp_state = IBV_QPS_ERR;
hns_roce_u_v2_modify_qp(&ibv_qp->qp_base, &attr, IBV_QP_STATE);
--
2.30.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。