From 48e8ca01b1e5d033fca6e988d2d280846c95d7e1 Mon Sep 17 00:00:00 2001 From: Wenpeng Liang 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 Signed-off-by: Leon Romanovsky --- 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