From 5526c8025d4d16e68b412e378b0ceab42dbcd9d4 Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Fri, 11 Oct 2019 10:14:16 +0530 Subject: [PATCH] net/bnxt: fix race between interrupt handler and dev config Fix a possible that while interrupt handler is in the middle of processing, dev_configure_op() might come in and try to destroy/realloc the default completion ring on which interrupt completions arrive. Synchronize the two so they don't race each other Fixes: 7bc8e9a227cc ("net/bnxt: support async link notification") Cc: stable@dpdk.org Signed-off-by: Somnath Kotur Signed-off-by: Kalesh AP Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 1 + drivers/net/bnxt/bnxt_ethdev.c | 19 +++++++++++++++++-- drivers/net/bnxt/bnxt_irq.c | 7 ++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 189f693b06..e5bdf63602 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -574,6 +574,7 @@ struct bnxt { void *hwrm_short_cmd_req_addr; rte_iova_t hwrm_short_cmd_req_dma_addr; rte_spinlock_t hwrm_lock; + pthread_mutex_t def_cp_lock; uint16_t max_req_len; uint16_t max_resp_len; uint16_t hwrm_max_ext_req_len; diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index b58a875c7d..e7ec99e15d 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -627,6 +627,9 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) * resource reservation. This will ensure the resource counts * are calculated correctly. */ + + pthread_mutex_lock(&bp->def_cp_lock); + if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { bnxt_disable_int(bp); bnxt_free_cp_ring(bp, bp->async_cp_ring); @@ -635,15 +638,20 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) rc = bnxt_hwrm_func_reserve_vf_resc(bp, false); if (rc) { PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc); + pthread_mutex_unlock(&bp->def_cp_lock); return -ENOSPC; } if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { rc = bnxt_alloc_async_cp_ring(bp); - if (rc) + if (rc) { + pthread_mutex_unlock(&bp->def_cp_lock); return rc; + } bnxt_enable_int(bp); } + + pthread_mutex_unlock(&bp->def_cp_lock); } else { /* legacy driver needs to get updated values */ rc = bnxt_hwrm_func_qcaps(bp); @@ -4585,8 +4593,14 @@ bnxt_init_locks(struct bnxt *bp) int err; err = pthread_mutex_init(&bp->flow_lock, NULL); - if (err) + if (err) { PMD_DRV_LOG(ERR, "Unable to initialize flow_lock\n"); + return err; + } + + err = pthread_mutex_init(&bp->def_cp_lock, NULL); + if (err) + PMD_DRV_LOG(ERR, "Unable to initialize def_cp_lock\n"); return err; } @@ -4735,6 +4749,7 @@ static void bnxt_uninit_locks(struct bnxt *bp) { pthread_mutex_destroy(&bp->flow_lock); + pthread_mutex_destroy(&bp->def_cp_lock); } static int diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c index 6c5bcfb623..4feb637e22 100644 --- a/drivers/net/bnxt/bnxt_irq.c +++ b/drivers/net/bnxt/bnxt_irq.c @@ -30,9 +30,12 @@ void bnxt_int_handler(void *param) return; raw_cons = cpr->cp_raw_cons; + pthread_mutex_lock(&bp->def_cp_lock); while (1) { - if (!cpr || !cpr->cp_ring_struct || !cpr->cp_db.doorbell) + if (!cpr || !cpr->cp_ring_struct || !cpr->cp_db.doorbell) { + pthread_mutex_unlock(&bp->def_cp_lock); return; + } cons = RING_CMP(cpr->cp_ring_struct, raw_cons); cmp = &cpr->cp_desc_ring[cons]; @@ -49,6 +52,8 @@ void bnxt_int_handler(void *param) bnxt_db_nq_arm(cpr); else B_CP_DB_REARM(cpr, cpr->cp_raw_cons); + + pthread_mutex_unlock(&bp->def_cp_lock); } int bnxt_free_int(struct bnxt *bp) -- 2.20.1