代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/rdma-core 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From c104e33f0c4466f0c4b163984736eac18e9c8357 Mon Sep 17 00:00:00 2001
From: Chengchang Tang <tangchengchang@huawei.com>
Date: Mon, 10 May 2021 17:13:13 +0800
Subject: [PATCH 21/25] libhns: Add support for shrinking DCA memory pool
driver inclusion
category: feature
bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I9C2AQ
------------------------------------------------------------------
The QP's WQE buffer may be detached after QP is modified or CQE is polled,
and the state of DCA mem object may be changed as clean for no QP is using
it. So shrink the clean DCA mem from the memory pool and destroy the DCA
mem's buffer to reduce the memory consumption.
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Reviewed-by: Yangyang Li <liyangyang20@huawei.com>
---
providers/hns/hns_roce_u.h | 2 +
providers/hns/hns_roce_u_buf.c | 103 +++++++++++++++++++++++++++++++
providers/hns/hns_roce_u_hw_v2.c | 7 +++
3 files changed, 112 insertions(+)
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index 90b2205..e3fa24d 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -214,6 +214,7 @@ struct hns_roce_dca_ctx {
int mem_cnt;
unsigned int unit_size;
uint64_t max_size;
+ uint64_t min_size;
uint64_t curr_size;
};
@@ -602,6 +603,7 @@ void hns_roce_qp_spinlock_destroy(struct hns_roce_qp *qp);
void hns_roce_free_qp_buf(struct hns_roce_qp *qp, struct hns_roce_context *ctx);
+void hns_roce_shrink_dca_mem(struct hns_roce_context *ctx);
void hns_roce_cleanup_dca_mem(struct hns_roce_context *ctx);
int hns_roce_add_dca_mem(struct hns_roce_context *ctx, uint32_t size);
diff --git a/providers/hns/hns_roce_u_buf.c b/providers/hns/hns_roce_u_buf.c
index 02c43ae..c0f86e9 100644
--- a/providers/hns/hns_roce_u_buf.c
+++ b/providers/hns/hns_roce_u_buf.c
@@ -101,6 +101,20 @@ static inline uint64_t dca_mem_to_key(struct hns_roce_dca_mem *dca_mem)
return (uintptr_t)dca_mem;
}
+static struct hns_roce_dca_mem *key_to_dca_mem(struct hns_roce_dca_ctx *ctx,
+ uint64_t key)
+{
+ struct hns_roce_dca_mem *mem;
+ struct hns_roce_dca_mem *tmp;
+
+ list_for_each_safe(&ctx->mem_list, mem, tmp, entry) {
+ if (dca_mem_to_key(mem) == key)
+ return mem;
+ }
+
+ return NULL;
+}
+
static inline void *dca_mem_addr(struct hns_roce_dca_mem *dca_mem, int offset)
{
return dca_mem->buf.buf + offset;
@@ -156,6 +170,32 @@ void hns_roce_cleanup_dca_mem(struct hns_roce_context *ctx)
deregister_dca_mem(ctx, mem->handle);
}
+struct hns_dca_mem_shrink_resp {
+ uint32_t free_mems;
+ uint64_t free_key;
+};
+
+static int shrink_dca_mem(struct hns_roce_context *ctx, uint32_t handle,
+ uint64_t size, struct hns_dca_mem_shrink_resp *resp)
+{
+ int ret;
+
+ DECLARE_COMMAND_BUFFER(cmd, HNS_IB_OBJECT_DCA_MEM,
+ HNS_IB_METHOD_DCA_MEM_SHRINK, 4);
+ fill_attr_in_obj(cmd, HNS_IB_ATTR_DCA_MEM_SHRINK_HANDLE, handle);
+ fill_attr_in_uint64(cmd, HNS_IB_ATTR_DCA_MEM_SHRINK_RESERVED_SIZE, size);
+ fill_attr_out(cmd, HNS_IB_ATTR_DCA_MEM_SHRINK_OUT_FREE_KEY,
+ &resp->free_key, sizeof(resp->free_key));
+ fill_attr_out(cmd, HNS_IB_ATTR_DCA_MEM_SHRINK_OUT_FREE_MEMS,
+ &resp->free_mems, sizeof(resp->free_mems));
+
+ ret = execute_ioctl(&ctx->ibv_ctx.context, cmd);
+ if (ret)
+ verbs_err(&ctx->ibv_ctx, "failed to shrink DCA mem, ret = %d.\n",
+ ret);
+
+ return ret;
+}
static bool add_dca_mem_enabled(struct hns_roce_dca_ctx *ctx,
uint32_t alloc_size)
{
@@ -175,6 +215,17 @@ static bool add_dca_mem_enabled(struct hns_roce_dca_ctx *ctx,
return enable;
}
+static bool shrink_dca_mem_enabled(struct hns_roce_dca_ctx *ctx)
+{
+ bool enable;
+
+ pthread_spin_lock(&ctx->lock);
+ enable = ctx->mem_cnt > 0 && ctx->min_size < ctx->max_size;
+ pthread_spin_unlock(&ctx->lock);
+
+ return enable;
+}
+
int hns_roce_add_dca_mem(struct hns_roce_context *ctx, uint32_t size)
{
struct hns_roce_dca_ctx *dca_ctx = &ctx->dca_ctx;
@@ -207,3 +258,55 @@ int hns_roce_add_dca_mem(struct hns_roce_context *ctx, uint32_t size)
return 0;
}
+
+void hns_roce_shrink_dca_mem(struct hns_roce_context *ctx)
+{
+ struct hns_roce_dca_ctx *dca_ctx = &ctx->dca_ctx;
+ struct hns_dca_mem_shrink_resp resp = {};
+ struct hns_roce_dca_mem *mem;
+ int dca_mem_cnt;
+ uint32_t handle;
+ int ret;
+
+ pthread_spin_lock(&dca_ctx->lock);
+ dca_mem_cnt = ctx->dca_ctx.mem_cnt;
+ pthread_spin_unlock(&dca_ctx->lock);
+ while (dca_mem_cnt > 0 && shrink_dca_mem_enabled(dca_ctx)) {
+ resp.free_mems = 0;
+ /* Step 1: Use any DCA mem uobject to shrink pool */
+ pthread_spin_lock(&dca_ctx->lock);
+ mem = list_tail(&dca_ctx->mem_list,
+ struct hns_roce_dca_mem, entry);
+ handle = mem ? mem->handle : 0;
+ pthread_spin_unlock(&dca_ctx->lock);
+ if (!mem)
+ break;
+
+ ret = shrink_dca_mem(ctx, handle, dca_ctx->min_size, &resp);
+ if (ret || likely(resp.free_mems < 1))
+ break;
+
+ /* Step 2: Remove shrunk DCA mem node from pool */
+ pthread_spin_lock(&dca_ctx->lock);
+ mem = key_to_dca_mem(dca_ctx, resp.free_key);
+ if (mem) {
+ list_del(&mem->entry);
+ dca_ctx->mem_cnt--;
+ dca_ctx->curr_size -= mem->buf.length;
+ }
+
+ handle = mem ? mem->handle : 0;
+ pthread_spin_unlock(&dca_ctx->lock);
+ if (!mem)
+ break;
+
+ /* Step 3: Destroy DCA mem uobject */
+ deregister_dca_mem(ctx, handle);
+ free_dca_mem(ctx, mem);
+ /* No any free memory after deregister 1 DCA mem */
+ if (resp.free_mems <= 1)
+ break;
+
+ dca_mem_cnt--;
+ }
+}
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 9016978..0a100b8 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -932,6 +932,10 @@ static int hns_roce_u_v2_poll_cq(struct ibv_cq *ibvcq, int ne,
hns_roce_spin_unlock(&cq->hr_lock);
+ /* Try to shrink the DCA mem */
+ if (ctx->dca_ctx.mem_cnt > 0)
+ hns_roce_shrink_dca_mem(ctx);
+
return err == V2_CQ_POLL_ERR ? err : npolled;
}
@@ -1883,6 +1887,9 @@ static int hns_roce_u_v2_destroy_qp(struct ibv_qp *ibqp)
free(qp);
+ if (ctx->dca_ctx.mem_cnt > 0)
+ hns_roce_shrink_dca_mem(ctx);
+
return ret;
}
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。