From 23460b4c6a7ab68e2b6d217460684a554f7e78eb Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Mon, 16 Apr 2018 18:11:25 -0700 Subject: [PATCH] net/bnxt: avoid freeing memzone multiple times Since we are storing the mem_zone address for each ring created, we are freeing the same address multiple times. For example the memory zone created for Rx is being freed during Rx ring cleanup, AGG ring cleanup and CQ cleanup. Avoid this by storing the memory zone address in RXQ instead and free it as a part of queue_release dev_op. In the same way do the same for TX queues as well. Fixes: 51c87ebafc7d ("net/bnxt: add Tx queue create/destroy") Cc: stable@dpdk.org Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt_ring.c | 10 +++++++--- drivers/net/bnxt/bnxt_ring.h | 4 ++-- drivers/net/bnxt/bnxt_rxq.c | 4 +++- drivers/net/bnxt/bnxt_rxq.h | 1 + drivers/net/bnxt/bnxt_txq.c | 4 +++- drivers/net/bnxt/bnxt_txq.h | 1 + 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c index 4998c610a0..478eab4f32 100644 --- a/drivers/net/bnxt/bnxt_ring.c +++ b/drivers/net/bnxt/bnxt_ring.c @@ -28,7 +28,7 @@ void bnxt_free_ring(struct bnxt_ring *ring) memset((char *)*ring->vmem, 0, ring->vmem_size); *ring->vmem = NULL; } - rte_memzone_free((const struct rte_memzone *)ring->mem_zone); + ring->mem_zone = NULL; } /* @@ -61,12 +61,14 @@ int bnxt_init_ring_grps(struct bnxt *bp) * rx bd ring - Only non-zero length if rx_ring_info is not NULL */ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, - struct bnxt_tx_ring_info *tx_ring_info, - struct bnxt_rx_ring_info *rx_ring_info, + struct bnxt_tx_queue *txq, + struct bnxt_rx_queue *rxq, struct bnxt_cp_ring_info *cp_ring_info, const char *suffix) { struct bnxt_ring *cp_ring = cp_ring_info->cp_ring_struct; + struct bnxt_rx_ring_info *rx_ring_info = rxq ? rxq->rx_ring : NULL; + struct bnxt_tx_ring_info *tx_ring_info = txq ? txq->tx_ring : NULL; struct bnxt_ring *tx_ring; struct bnxt_ring *rx_ring; struct rte_pci_device *pdev = bp->pdev; @@ -165,6 +167,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, } if (tx_ring_info) { + txq->mz = mz; tx_ring = tx_ring_info->tx_ring_struct; tx_ring->bd = ((char *)mz->addr + tx_ring_start); @@ -184,6 +187,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, } if (rx_ring_info) { + rxq->mz = mz; rx_ring = rx_ring_info->rx_ring_struct; rx_ring->bd = ((char *)mz->addr + rx_ring_start); diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h index d70eb64dee..6c86259e84 100644 --- a/drivers/net/bnxt/bnxt_ring.h +++ b/drivers/net/bnxt/bnxt_ring.h @@ -65,8 +65,8 @@ struct bnxt_cp_ring_info; void bnxt_free_ring(struct bnxt_ring *ring); int bnxt_init_ring_grps(struct bnxt *bp); int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, - struct bnxt_tx_ring_info *tx_ring_info, - struct bnxt_rx_ring_info *rx_ring_info, + struct bnxt_tx_queue *txq, + struct bnxt_rx_queue *rxq, struct bnxt_cp_ring_info *cp_ring_info, const char *suffix); int bnxt_alloc_hwrm_rings(struct bnxt *bp); diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c index d797a47e99..e939c9ac0a 100644 --- a/drivers/net/bnxt/bnxt_rxq.c +++ b/drivers/net/bnxt/bnxt_rxq.c @@ -267,6 +267,8 @@ void bnxt_rx_queue_release_op(void *rx_queue) bnxt_free_ring(rxq->cp_ring->cp_ring_struct); bnxt_free_rxq_stats(rxq); + rte_memzone_free(rxq->mz); + rxq->mz = NULL; rte_free(rxq); } @@ -328,7 +330,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, eth_dev->data->rx_queues[queue_idx] = rxq; /* Allocate RX ring hardware descriptors */ - if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring, + if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq, rxq->cp_ring, "rxr")) { PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for rx_ring failed!\n"); diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h index 3350d77199..8307f603cb 100644 --- a/drivers/net/bnxt/bnxt_rxq.h +++ b/drivers/net/bnxt/bnxt_rxq.h @@ -33,6 +33,7 @@ struct bnxt_rx_queue { struct bnxt_rx_ring_info *rx_ring; struct bnxt_cp_ring_info *cp_ring; rte_atomic64_t rx_mbuf_alloc_fail; + const struct rte_memzone *mz; }; void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq); diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c index 37531ea49e..07e25d77b8 100644 --- a/drivers/net/bnxt/bnxt_txq.c +++ b/drivers/net/bnxt/bnxt_txq.c @@ -65,6 +65,8 @@ void bnxt_tx_queue_release_op(void *tx_queue) bnxt_free_ring(txq->cp_ring->cp_ring_struct); bnxt_free_txq_stats(txq); + rte_memzone_free(txq->mz); + txq->mz = NULL; rte_free(txq); } @@ -119,7 +121,7 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, txq->port_id = eth_dev->data->port_id; /* Allocate TX ring hardware descriptors */ - if (bnxt_alloc_rings(bp, queue_idx, txq->tx_ring, NULL, txq->cp_ring, + if (bnxt_alloc_rings(bp, queue_idx, txq, NULL, txq->cp_ring, "txr")) { PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for tx_ring failed!"); bnxt_tx_queue_release_op(txq); diff --git a/drivers/net/bnxt/bnxt_txq.h b/drivers/net/bnxt/bnxt_txq.h index 47bbef1e74..8df87148fb 100644 --- a/drivers/net/bnxt/bnxt_txq.h +++ b/drivers/net/bnxt/bnxt_txq.h @@ -33,6 +33,7 @@ struct bnxt_tx_queue { unsigned int cp_nr_rings; struct bnxt_cp_ring_info *cp_ring; + const struct rte_memzone *mz; }; void bnxt_free_txq_stats(struct bnxt_tx_queue *txq); -- 2.20.1