[v3,1/4] net/e1000: fix memzone leak when re-configure the RX/TX queues

Message ID abf062dd370f31df38d196a4f5ddc60c8ff50601.1632315160.git.wangyunjian@huawei.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series fixes for intel drivers |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Yunjian Wang Sept. 22, 2021, 1:28 p.m. UTC
  Normally when closing the device the queue memzone should be
freed. But the memzone will be not freed, when device setup
ops like:

rte_eth_bond_slave_remove
-->__eth_bond_slave_remove_lock_free
---->slave_remove
------>rte_eth_dev_internal_reset
-------->rte_eth_dev_rx_queue_config
---------->eth_dev_rx_queue_config
------------>em_rx_queue_release
rte_eth_dev_close
-->eth_em_close
---->em_dev_free_queues
------>em_rx_queue_release
      (not been called due to nb_rx_queues and nb_tx_queues are 0)

And when queue number is changed to small size, the BIG memzone
queue index will be lost. This will lead to a memory leak. So we
should release the memzone when releasing queues.

Fixes: 460d1679586e ("drivers/net: delete HW rings while freeing queues")
Cc: stable@dpdk.org

Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
---
 drivers/net/e1000/em_rxtx.c  | 8 ++++++--
 drivers/net/e1000/igb_rxtx.c | 9 +++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)
  

Comments

Wang, Haiyue Sept. 22, 2021, 1:51 p.m. UTC | #1
> -----Original Message-----
> From: Yunjian Wang <wangyunjian@huawei.com>
> Sent: Wednesday, September 22, 2021 21:28
> To: dev@dpdk.org
> Cc: Wang, Haiyue <haiyue.wang@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; dingxiaoxiong@huawei.com; Yunjian Wang
> <wangyunjian@huawei.com>; stable@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 1/4] net/e1000: fix memzone leak when re-configure the RX/TX queues
> 
> Normally when closing the device the queue memzone should be
> freed. But the memzone will be not freed, when device setup
> ops like:
> 
> rte_eth_bond_slave_remove
> -->__eth_bond_slave_remove_lock_free
> ---->slave_remove
> ------>rte_eth_dev_internal_reset
> -------->rte_eth_dev_rx_queue_config
> ---------->eth_dev_rx_queue_config
> ------------>em_rx_queue_release
> rte_eth_dev_close
> -->eth_em_close
> ---->em_dev_free_queues
> ------>em_rx_queue_release
>       (not been called due to nb_rx_queues and nb_tx_queues are 0)
> 
> And when queue number is changed to small size, the BIG memzone
> queue index will be lost. This will lead to a memory leak. So we
> should release the memzone when releasing queues.
> 
> Fixes: 460d1679586e ("drivers/net: delete HW rings while freeing queues")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
> ---
>  drivers/net/e1000/em_rxtx.c  | 8 ++++++--
>  drivers/net/e1000/igb_rxtx.c | 9 +++++++--
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 

Acked-by: Haiyue Wang <haiyue.wang@intel.com>

> --
> 2.23.0
  

Patch

diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index dfd8f2fd00..82928083f5 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -104,6 +104,7 @@  struct em_rx_queue {
 	uint8_t             hthresh;    /**< Host threshold register. */
 	uint8_t             wthresh;    /**< Write-back threshold register. */
 	uint8_t             crc_len;    /**< 0 if CRC stripped, 4 otherwise. */
+	const struct rte_memzone *mz;
 };
 
 /**
@@ -173,6 +174,7 @@  struct em_tx_queue {
 	struct em_ctx_info ctx_cache;
 	/**< Hardware context history.*/
 	uint64_t	       offloads; /**< offloads of DEV_TX_OFFLOAD_* */
+	const struct rte_memzone *mz;
 };
 
 #if 1
@@ -1116,6 +1118,7 @@  em_tx_queue_release(struct em_tx_queue *txq)
 	if (txq != NULL) {
 		em_tx_queue_release_mbufs(txq);
 		rte_free(txq->sw_ring);
+		rte_memzone_free(txq->mz);
 		rte_free(txq);
 	}
 }
@@ -1286,6 +1289,7 @@  eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			RTE_CACHE_LINE_SIZE)) == NULL)
 		return -ENOMEM;
 
+	txq->mz = tz;
 	/* Allocate software ring */
 	if ((txq->sw_ring = rte_zmalloc("txq->sw_ring",
 			sizeof(txq->sw_ring[0]) * nb_desc,
@@ -1338,6 +1342,7 @@  em_rx_queue_release(struct em_rx_queue *rxq)
 	if (rxq != NULL) {
 		em_rx_queue_release_mbufs(rxq);
 		rte_free(rxq->sw_ring);
+		rte_memzone_free(rxq->mz);
 		rte_free(rxq);
 	}
 }
@@ -1452,6 +1457,7 @@  eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 			RTE_CACHE_LINE_SIZE)) == NULL)
 		return -ENOMEM;
 
+	rxq->mz = rz;
 	/* Allocate software ring. */
 	if ((rxq->sw_ring = rte_zmalloc("rxq->sw_ring",
 			sizeof (rxq->sw_ring[0]) * nb_desc,
@@ -1611,14 +1617,12 @@  em_dev_free_queues(struct rte_eth_dev *dev)
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		eth_em_rx_queue_release(dev->data->rx_queues[i]);
 		dev->data->rx_queues[i] = NULL;
-		rte_eth_dma_zone_free(dev, "rx_ring", i);
 	}
 	dev->data->nb_rx_queues = 0;
 
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		eth_em_tx_queue_release(dev->data->tx_queues[i]);
 		dev->data->tx_queues[i] = NULL;
-		rte_eth_dma_zone_free(dev, "tx_ring", i);
 	}
 	dev->data->nb_tx_queues = 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 278d5d2712..dc0de37246 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -112,6 +112,7 @@  struct igb_rx_queue {
 	uint8_t             drop_en;  /**< If not 0, set SRRCTL.Drop_En. */
 	uint32_t            flags;      /**< RX flags. */
 	uint64_t	    offloads;   /**< offloads of DEV_RX_OFFLOAD_* */
+	const struct rte_memzone *mz;
 };
 
 /**
@@ -186,6 +187,7 @@  struct igb_tx_queue {
 	struct igb_advctx_info ctx_cache[IGB_CTX_NUM];
 	/**< Hardware context history.*/
 	uint64_t	       offloads; /**< offloads of DEV_TX_OFFLOAD_* */
+	const struct rte_memzone *mz;
 };
 
 #if 1
@@ -1276,6 +1278,7 @@  igb_tx_queue_release(struct igb_tx_queue *txq)
 	if (txq != NULL) {
 		igb_tx_queue_release_mbufs(txq);
 		rte_free(txq->sw_ring);
+		rte_memzone_free(txq->mz);
 		rte_free(txq);
 	}
 }
@@ -1545,6 +1548,7 @@  eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 		return -ENOMEM;
 	}
 
+	txq->mz = tz;
 	txq->nb_tx_desc = nb_desc;
 	txq->pthresh = tx_conf->tx_thresh.pthresh;
 	txq->hthresh = tx_conf->tx_thresh.hthresh;
@@ -1601,6 +1605,7 @@  igb_rx_queue_release(struct igb_rx_queue *rxq)
 	if (rxq != NULL) {
 		igb_rx_queue_release_mbufs(rxq);
 		rte_free(rxq->sw_ring);
+		rte_memzone_free(rxq->mz);
 		rte_free(rxq);
 	}
 }
@@ -1746,6 +1751,8 @@  eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 		igb_rx_queue_release(rxq);
 		return -ENOMEM;
 	}
+
+	rxq->mz = rz;
 	rxq->rdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDT(rxq->reg_idx));
 	rxq->rdh_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDH(rxq->reg_idx));
 	rxq->rx_ring_phys_addr = rz->iova;
@@ -1885,14 +1892,12 @@  igb_dev_free_queues(struct rte_eth_dev *dev)
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		eth_igb_rx_queue_release(dev->data->rx_queues[i]);
 		dev->data->rx_queues[i] = NULL;
-		rte_eth_dma_zone_free(dev, "rx_ring", i);
 	}
 	dev->data->nb_rx_queues = 0;
 
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		eth_igb_tx_queue_release(dev->data->tx_queues[i]);
 		dev->data->tx_queues[i] = NULL;
-		rte_eth_dma_zone_free(dev, "tx_ring", i);
 	}
 	dev->data->nb_tx_queues = 0;
 }