From 2e6a4819b2851687124f547d5ba7bc0808f3d9be Mon Sep 17 00:00:00 2001 From: Junxian Huang Date: Thu, 18 Apr 2024 13:49:30 +0800 Subject: [PATCH] libhns: Fix several context locks issue [ Upstream commit 6772962084dd1ee0ec277d79c63673f8736aa94f ] Fix several context lock issue: 1. db_list_mutex is used without init currently. Add its init to hns_roce_alloc_context(). 2. pthread_mutex_init()/pthread_spin_init() may return error value. Check the return value in hns_roce_alloc_context(). 3. Add destruction for these context locks. 4. Encapsulate init and destruction functions for these context locks. Fixes: 13eae8889690 ("libhns: Support rq record doorbell") Fixes: 887b78c80224 ("libhns: Add initial main frame") Signed-off-by: Junxian Huang Signed-off-by: Nicolas Morey --- providers/hns/hns_roce_u.c | 58 +++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c index 6eac4ff0a..29d3ce2a6 100644 --- a/providers/hns/hns_roce_u.c +++ b/providers/hns/hns_roce_u.c @@ -99,6 +99,47 @@ static uint32_t calc_table_shift(uint32_t entry_count, uint32_t size_shift) return count_shift > size_shift ? count_shift - size_shift : 0; } +static int hns_roce_init_context_lock(struct hns_roce_context *context) +{ + int ret; + + ret = pthread_spin_init(&context->uar_lock, PTHREAD_PROCESS_PRIVATE); + if (ret) + return ret; + + ret = pthread_mutex_init(&context->qp_table_mutex, NULL); + if (ret) + goto destroy_uar_lock; + + ret = pthread_mutex_init(&context->srq_table_mutex, NULL); + if (ret) + goto destroy_qp_mutex; + + ret = pthread_mutex_init(&context->db_list_mutex, NULL); + if (ret) + goto destroy_srq_mutex; + + return 0; + +destroy_srq_mutex: + pthread_mutex_destroy(&context->srq_table_mutex); + +destroy_qp_mutex: + pthread_mutex_destroy(&context->qp_table_mutex); + +destroy_uar_lock: + pthread_spin_destroy(&context->uar_lock); + return ret; +} + +static void hns_roce_destroy_context_lock(struct hns_roce_context *context) +{ + pthread_spin_destroy(&context->uar_lock); + pthread_mutex_destroy(&context->qp_table_mutex); + pthread_mutex_destroy(&context->srq_table_mutex); + pthread_mutex_destroy(&context->db_list_mutex); +} + static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, int cmd_fd, void *private_data) @@ -118,7 +159,10 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, if (ibv_cmd_get_context(&context->ibv_ctx, &cmd, sizeof(cmd), &resp.ibv_resp, sizeof(resp))) - goto err_free; + goto err_ibv_cmd; + + if (hns_roce_init_context_lock(context)) + goto err_ibv_cmd; if (!resp.cqe_size) context->cqe_size = HNS_ROCE_CQE_SIZE; @@ -130,14 +174,12 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, 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 = 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) context->srq_table[i].refcnt = 0; @@ -146,7 +188,7 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, struct ibv_device_attr_ex, orig_attr), sizeof(dev_attrs))) - goto err_free; + goto err_set_attr; hr_dev->hw_version = dev_attrs.hw_ver; context->max_qp_wr = dev_attrs.max_qp_wr; @@ -158,7 +200,7 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, context->uar = mmap(NULL, hr_dev->page_size, PROT_READ | PROT_WRITE, MAP_SHARED, cmd_fd, offset); if (context->uar == MAP_FAILED) - goto err_free; + goto err_set_attr; offset += hr_dev->page_size; @@ -174,7 +216,6 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, goto db_free; } - pthread_spin_init(&context->uar_lock, PTHREAD_PROCESS_PRIVATE); verbs_set_ops(&context->ibv_ctx, &hns_common_ops); verbs_set_ops(&context->ibv_ctx, &hr_dev->u_hw->hw_ops); @@ -185,7 +226,9 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev, munmap(context->uar, hr_dev->page_size); context->uar = NULL; -err_free: +err_set_attr: + hns_roce_destroy_context_lock(context); +err_ibv_cmd: verbs_uninit_context(&context->ibv_ctx); free(context); return NULL; @@ -200,6 +243,7 @@ static void hns_roce_free_context(struct ibv_context *ibctx) if (hr_dev->hw_version == HNS_ROCE_HW_VER1) munmap(context->cq_tptr_base, HNS_ROCE_CQ_DB_BUF_SIZE); + hns_roce_destroy_context_lock(context); verbs_uninit_context(&context->ibv_ctx); free(context); }