rdma-core/0036-libhns-Fix-the-calculation-of-QP-SRQ-table-size.patch
zhengfeng luo 123f94ea3f Backport batch of bugfix and refactor patches for hns from rdma-core v39
These patches are mainly related to IO operations.

Signed-off-by: zhengfeng luo <luozhengfeng@h-partners.com>
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
2022-08-29 21:05:49 +08:00

203 lines
7.6 KiB
Diff

From 48e8ca01b1e5d033fca6e988d2d280846c95d7e1 Mon Sep 17 00:00:00 2001
From: Wenpeng Liang <liangwenpeng@huawei.com>
Date: Fri, 31 Dec 2021 18:01:06 +0800
Subject: libhns: Fix the calculation of QP/SRQ table size
The table_size means the maximum number of QP/SRQ. This value may not be
a power of two. The old algorithm will lead to a result that allocates a
mismatched table.
Fixes: 887b78c80224 ("libhns: Add initial main frame")
Fixes: 9e3df7578153 ("libhns: Support ibv_create_srq_ex")
Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
providers/hns/hns_roce_u.c | 18 +++++++++++-------
providers/hns/hns_roce_u.h | 20 ++++++++++++++------
providers/hns/hns_roce_u_hw_v1.c | 4 ++--
providers/hns/hns_roce_u_hw_v2.c | 4 ++--
providers/hns/hns_roce_u_verbs.c | 9 ++++-----
5 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index 9dc4905..6eac4ff 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -92,6 +92,13 @@ static const struct verbs_context_ops hns_common_ops = {
.get_srq_num = hns_roce_u_get_srq_num,
};
+static uint32_t calc_table_shift(uint32_t entry_count, uint32_t size_shift)
+{
+ uint32_t count_shift = hr_ilog32(entry_count);
+
+ return count_shift > size_shift ? count_shift - size_shift : 0;
+}
+
static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
int cmd_fd,
void *private_data)
@@ -120,18 +127,15 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
else
context->cqe_size = HNS_ROCE_V3_CQE_SIZE;
- context->num_qps = resp.qp_tab_size;
- context->num_srqs = resp.srq_tab_size;
-
- context->qp_table_shift = ffs(context->num_qps) - 1 -
- HNS_ROCE_QP_TABLE_BITS;
+ context->qp_table_shift = calc_table_shift(resp.qp_tab_size,
+ HNS_ROCE_QP_TABLE_BITS);
context->qp_table_mask = (1 << context->qp_table_shift) - 1;
pthread_mutex_init(&context->qp_table_mutex, NULL);
for (i = 0; i < HNS_ROCE_QP_TABLE_SIZE; ++i)
context->qp_table[i].refcnt = 0;
- context->srq_table_shift = ffs(context->num_srqs) - 1 -
- HNS_ROCE_SRQ_TABLE_BITS;
+ context->srq_table_shift = calc_table_shift(resp.srq_tab_size,
+ HNS_ROCE_SRQ_TABLE_BITS);
context->srq_table_mask = (1 << context->srq_table_shift) - 1;
pthread_mutex_init(&context->srq_table_mutex, NULL);
for (i = 0; i < HNS_ROCE_SRQ_TABLE_SIZE; ++i)
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index df7f485..9366923 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -154,10 +154,8 @@
#define hr_reg_read(ptr, field) _hr_reg_read(ptr, field)
-enum {
- HNS_ROCE_QP_TABLE_BITS = 8,
- HNS_ROCE_QP_TABLE_SIZE = 1 << HNS_ROCE_QP_TABLE_BITS,
-};
+#define HNS_ROCE_QP_TABLE_BITS 8
+#define HNS_ROCE_QP_TABLE_SIZE BIT(HNS_ROCE_QP_TABLE_BITS)
#define HNS_ROCE_SRQ_TABLE_BITS 8
#define HNS_ROCE_SRQ_TABLE_SIZE BIT(HNS_ROCE_SRQ_TABLE_BITS)
@@ -211,7 +209,6 @@ struct hns_roce_context {
int refcnt;
} qp_table[HNS_ROCE_QP_TABLE_SIZE];
pthread_mutex_t qp_table_mutex;
- uint32_t num_qps;
uint32_t qp_table_shift;
uint32_t qp_table_mask;
@@ -220,7 +217,6 @@ struct hns_roce_context {
int refcnt;
} srq_table[HNS_ROCE_SRQ_TABLE_SIZE];
pthread_mutex_t srq_table_mutex;
- uint32_t num_srqs;
uint32_t srq_table_shift;
uint32_t srq_table_mask;
@@ -382,6 +378,18 @@ static inline unsigned int hr_ilog32(unsigned int count)
return ilog32(count - 1);
}
+static inline uint32_t to_hr_qp_table_index(uint32_t qpn,
+ struct hns_roce_context *ctx)
+{
+ return (qpn >> ctx->qp_table_shift) & (HNS_ROCE_QP_TABLE_SIZE - 1);
+}
+
+static inline uint32_t to_hr_srq_table_index(uint32_t srqn,
+ struct hns_roce_context *ctx)
+{
+ return (srqn >> ctx->srq_table_shift) & (HNS_ROCE_SRQ_TABLE_SIZE - 1);
+}
+
static inline struct hns_roce_device *to_hr_dev(struct ibv_device *ibv_dev)
{
return container_of(ibv_dev, struct hns_roce_device, ibv_dev.device);
diff --git a/providers/hns/hns_roce_u_hw_v1.c b/providers/hns/hns_roce_u_hw_v1.c
index 838e004..28ad482 100644
--- a/providers/hns/hns_roce_u_hw_v1.c
+++ b/providers/hns/hns_roce_u_hw_v1.c
@@ -220,7 +220,7 @@ static int hns_roce_wq_overflow(struct hns_roce_wq *wq, int nreq,
static struct hns_roce_qp *hns_roce_find_qp(struct hns_roce_context *ctx,
uint32_t qpn)
{
- uint32_t tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
+ uint32_t tind = to_hr_qp_table_index(qpn, ctx);
if (ctx->qp_table[tind].refcnt) {
return ctx->qp_table[tind].table[qpn & ctx->qp_table_mask];
@@ -232,7 +232,7 @@ static struct hns_roce_qp *hns_roce_find_qp(struct hns_roce_context *ctx,
static void hns_roce_clear_qp(struct hns_roce_context *ctx, uint32_t qpn)
{
- uint32_t tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
+ uint32_t tind = to_hr_qp_table_index(qpn, ctx);
if (!--ctx->qp_table[tind].refcnt)
free(ctx->qp_table[tind].table);
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 558457a..e39ee7f 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -343,7 +343,7 @@ static void update_cq_db(struct hns_roce_context *ctx,
static struct hns_roce_qp *hns_roce_v2_find_qp(struct hns_roce_context *ctx,
uint32_t qpn)
{
- uint32_t tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
+ uint32_t tind = to_hr_qp_table_index(qpn, ctx);
if (ctx->qp_table[tind].refcnt)
return ctx->qp_table[tind].table[qpn & ctx->qp_table_mask];
@@ -354,7 +354,7 @@ static struct hns_roce_qp *hns_roce_v2_find_qp(struct hns_roce_context *ctx,
void hns_roce_v2_clear_qp(struct hns_roce_context *ctx, struct hns_roce_qp *qp)
{
uint32_t qpn = qp->verbs_qp.qp.qp_num;
- uint32_t tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
+ uint32_t tind = to_hr_qp_table_index(qpn, ctx);
pthread_mutex_lock(&ctx->qp_table_mutex);
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
index 557d075..5ccb701 100644
--- a/providers/hns/hns_roce_u_verbs.c
+++ b/providers/hns/hns_roce_u_verbs.c
@@ -431,8 +431,7 @@ int hns_roce_u_destroy_cq(struct ibv_cq *cq)
static int hns_roce_store_srq(struct hns_roce_context *ctx,
struct hns_roce_srq *srq)
{
- uint32_t tind = (srq->srqn & (ctx->num_srqs - 1)) >>
- ctx->srq_table_shift;
+ uint32_t tind = to_hr_srq_table_index(srq->srqn, ctx);
pthread_mutex_lock(&ctx->srq_table_mutex);
@@ -457,7 +456,7 @@ static int hns_roce_store_srq(struct hns_roce_context *ctx,
struct hns_roce_srq *hns_roce_find_srq(struct hns_roce_context *ctx,
uint32_t srqn)
{
- uint32_t tind = (srqn & (ctx->num_srqs - 1)) >> ctx->srq_table_shift;
+ uint32_t tind = to_hr_srq_table_index(srqn, ctx);
if (ctx->srq_table[tind].refcnt)
return ctx->srq_table[tind].table[srqn & ctx->srq_table_mask];
@@ -467,7 +466,7 @@ struct hns_roce_srq *hns_roce_find_srq(struct hns_roce_context *ctx,
static void hns_roce_clear_srq(struct hns_roce_context *ctx, uint32_t srqn)
{
- uint32_t tind = (srqn & (ctx->num_srqs - 1)) >> ctx->srq_table_shift;
+ uint32_t tind = to_hr_srq_table_index(srqn, ctx);
pthread_mutex_lock(&ctx->srq_table_mutex);
@@ -1108,7 +1107,7 @@ static int hns_roce_store_qp(struct hns_roce_context *ctx,
struct hns_roce_qp *qp)
{
uint32_t qpn = qp->verbs_qp.qp.qp_num;
- uint32_t tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
+ uint32_t tind = to_hr_qp_table_index(qpn, ctx);
pthread_mutex_lock(&ctx->qp_table_mutex);
if (!ctx->qp_table[tind].refcnt) {
--
2.27.0