DPDK patches and discussions
 help / color / mirror / Atom feed
From: Rasesh Mody <rasesh.mody@cavium.com>
To: <ferruh.yigit@intel.com>, <dev@dpdk.org>
Cc: Harish Patil <harish.patil@cavium.com>,
	<Dept-EngDPDKDev@cavium.com>,
	Rasesh Mody <rasesh.mody@cavium.com>
Subject: [dpdk-dev] [PATCH v2 1/8] net/qede: fix DMA memory leak
Date: Sat, 1 Jul 2017 12:29:55 -0700	[thread overview]
Message-ID: <1498937402-25547-2-git-send-email-rasesh.mody@cavium.com> (raw)
In-Reply-To: <1498729889-21524-1-git-send-email-rasesh.mody@cavium.com>

From: Harish Patil <harish.patil@cavium.com>

Implement the macro OSAL_DMA_FREE_COHERENT to release DMA memories.
Track all DMA memory allocations using an array of memzone pointers and
use that to free memory resoureces along with other resource deallocation.
With this change there is no need to alter the base code to additionally
pass an unique string needed for memzone creation.

Fixes: ec94dbc57362 ("qede: add base driver")

Signed-off-by: Harish Patil <harish.patil@cavium.com>
Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/bcm_osal.c |   36 +++++++++++++++++++++++++++
 drivers/net/qede/base/bcm_osal.h |    6 +++--
 drivers/net/qede/qede_ethdev.c   |    9 +------
 drivers/net/qede/qede_rxtx.c     |   50 +++++++++++++++++++++++++++++++-------
 4 files changed, 82 insertions(+), 19 deletions(-)

diff --git a/drivers/net/qede/base/bcm_osal.c b/drivers/net/qede/base/bcm_osal.c
index 3f895cd..1ccfad0 100644
--- a/drivers/net/qede/base/bcm_osal.c
+++ b/drivers/net/qede/base/bcm_osal.c
@@ -16,6 +16,10 @@
 #include "ecore_mcp_api.h"
 #include "ecore_l2_api.h"
 
+/* Array of memzone pointers */
+static const struct rte_memzone *ecore_mz_mapping[RTE_MAX_MEMZONE];
+/* Counter to track current memzone allocated */
+uint16_t ecore_mz_count;
 
 unsigned long qede_log2_align(unsigned long n)
 {
@@ -118,6 +122,13 @@ void *osal_dma_alloc_coherent(struct ecore_dev *p_dev,
 	uint32_t core_id = rte_lcore_id();
 	unsigned int socket_id;
 
+	if (ecore_mz_count >= RTE_MAX_MEMZONE) {
+		DP_ERR(p_dev, "Memzone allocation count exceeds %u\n",
+		       RTE_MAX_MEMZONE);
+		*phys = 0;
+		return OSAL_NULL;
+	}
+
 	OSAL_MEM_ZERO(mz_name, sizeof(*mz_name));
 	snprintf(mz_name, sizeof(mz_name) - 1, "%lx",
 					(unsigned long)rte_get_timer_cycles());
@@ -134,6 +145,7 @@ void *osal_dma_alloc_coherent(struct ecore_dev *p_dev,
 		return OSAL_NULL;
 	}
 	*phys = mz->phys_addr;
+	ecore_mz_mapping[ecore_mz_count++] = mz;
 	DP_VERBOSE(p_dev, ECORE_MSG_PROBE,
 		   "size=%zu phys=0x%" PRIx64 " virt=%p on socket=%u\n",
 		   mz->len, mz->phys_addr, mz->addr, socket_id);
@@ -148,6 +160,13 @@ void *osal_dma_alloc_coherent_aligned(struct ecore_dev *p_dev,
 	uint32_t core_id = rte_lcore_id();
 	unsigned int socket_id;
 
+	if (ecore_mz_count >= RTE_MAX_MEMZONE) {
+		DP_ERR(p_dev, "Memzone allocation count exceeds %u\n",
+		       RTE_MAX_MEMZONE);
+		*phys = 0;
+		return OSAL_NULL;
+	}
+
 	OSAL_MEM_ZERO(mz_name, sizeof(*mz_name));
 	snprintf(mz_name, sizeof(mz_name) - 1, "%lx",
 					(unsigned long)rte_get_timer_cycles());
@@ -163,12 +182,29 @@ void *osal_dma_alloc_coherent_aligned(struct ecore_dev *p_dev,
 		return OSAL_NULL;
 	}
 	*phys = mz->phys_addr;
+	ecore_mz_mapping[ecore_mz_count++] = mz;
 	DP_VERBOSE(p_dev, ECORE_MSG_PROBE,
 		   "aligned memory size=%zu phys=0x%" PRIx64 " virt=%p core=%d\n",
 		   mz->len, mz->phys_addr, mz->addr, core_id);
 	return mz->addr;
 }
 
+void osal_dma_free_mem(struct ecore_dev *p_dev, dma_addr_t phys)
+{
+	uint16_t j;
+
+	for (j = 0 ; j < ecore_mz_count; j++) {
+		if (phys == ecore_mz_mapping[j]->phys_addr) {
+			DP_VERBOSE(p_dev, ECORE_MSG_SP,
+				"Free memzone %s\n", ecore_mz_mapping[j]->name);
+			rte_memzone_free(ecore_mz_mapping[j]);
+			return;
+		}
+	}
+
+	DP_ERR(p_dev, "Unexpected memory free request\n");
+}
+
 #ifdef CONFIG_ECORE_ZIPPED_FW
 u32 qede_unzip_data(struct ecore_hwfn *p_hwfn, u32 input_len,
 		    u8 *input_buf, u32 max_size, u8 *unzip_buf)
diff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm_osal.h
index 340d5f0..444512c 100644
--- a/drivers/net/qede/base/bcm_osal.h
+++ b/drivers/net/qede/base/bcm_osal.h
@@ -107,14 +107,16 @@
 void *osal_dma_alloc_coherent_aligned(struct ecore_dev *, dma_addr_t *,
 				      size_t, int);
 
+void osal_dma_free_mem(struct ecore_dev *edev, dma_addr_t phys);
+
 #define OSAL_DMA_ALLOC_COHERENT(dev, phys, size) \
 	osal_dma_alloc_coherent(dev, phys, size)
 
 #define OSAL_DMA_ALLOC_COHERENT_ALIGNED(dev, phys, size, align) \
 	osal_dma_alloc_coherent_aligned(dev, phys, size, align)
 
-/* TODO: */
-#define OSAL_DMA_FREE_COHERENT(dev, virt, phys, size) nothing
+#define OSAL_DMA_FREE_COHERENT(dev, virt, phys, size) \
+	osal_dma_free_mem(dev, phys)
 
 /* HW reads/writes */
 
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 6380c2b..3e9f359 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1143,7 +1143,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	 * again and the fastpath pointers will be reinitialized there.
 	 */
 	if (qdev->num_tx_queues != eth_dev->data->nb_tx_queues ||
-			qdev->num_rx_queues != eth_dev->data->nb_rx_queues) {
+	    qdev->num_rx_queues != eth_dev->data->nb_rx_queues) {
 		qede_dealloc_fp_resc(eth_dev);
 		/* Proceed with updated queue count */
 		qdev->num_tx_queues = eth_dev->data->nb_tx_queues;
@@ -1373,7 +1373,6 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
-	uint8_t i;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -1389,12 +1388,6 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
 	qede_fdir_dealloc_resc(eth_dev);
 	qede_dealloc_fp_resc(eth_dev);
 
-	for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
-		if (eth_dev->data->rx_queues[i])
-			eth_dev->data->rx_queues[i] = NULL;
-	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
-		if (eth_dev->data->tx_queues[i])
-			eth_dev->data->tx_queues[i] = NULL;
 	eth_dev->data->nb_rx_queues = 0;
 	eth_dev->data->nb_tx_queues = 0;
 
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index f65c833..5c9a4dd 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -149,7 +149,7 @@ static inline int qede_alloc_rx_buffer(struct qede_rx_queue *rxq)
 		DP_NOTICE(edev, false,
 			  "Unable to alloc memory for cqe ring on socket %u\n",
 			  socket_id);
-		/* TBD: Freeing RX BD ring */
+		qdev->ops->common->chain_free(edev, &rxq->rx_bd_ring);
 		rte_free(rxq->sw_rx_ring);
 		rte_free(rxq);
 		return -ENOMEM;
@@ -300,6 +300,7 @@ static int qede_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 		DP_ERR(edev,
 		       "Unable to allocate memory for txbd ring on socket %u",
 		       socket_id);
+		qdev->ops->common->chain_free(edev, &txq->tx_pbl);
 		qede_tx_queue_release(txq);
 		return -ENOMEM;
 	}
@@ -363,23 +364,23 @@ void qede_tx_queue_release(void *tx_queue)
 qede_alloc_mem_sb(struct qede_dev *qdev, struct ecore_sb_info *sb_info,
 		  uint16_t sb_id)
 {
-	struct ecore_dev *edev = &qdev->edev;
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	struct status_block *sb_virt;
 	dma_addr_t sb_phys;
 	int rc;
 
-	sb_virt = OSAL_DMA_ALLOC_COHERENT(edev, &sb_phys, sizeof(*sb_virt));
-
+	sb_virt = OSAL_DMA_ALLOC_COHERENT(edev, &sb_phys,
+					  sizeof(struct status_block));
 	if (!sb_virt) {
 		DP_ERR(edev, "Status block allocation failed\n");
 		return -ENOMEM;
 	}
-
 	rc = qdev->ops->common->sb_init(edev, sb_info, sb_virt,
 					sb_phys, sb_id);
 	if (rc) {
 		DP_ERR(edev, "Status block initialization failed\n");
-		/* TBD: No dma_free_coherent possible */
+		OSAL_DMA_FREE_COHERENT(edev, sb_virt, sb_phys,
+				       sizeof(struct status_block));
 		return rc;
 	}
 
@@ -437,9 +438,12 @@ int qede_alloc_fp_resc(struct qede_dev *qdev)
 void qede_dealloc_fp_resc(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
-	__rte_unused struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	struct qede_fastpath *fp;
+	struct qede_rx_queue *rxq;
+	struct qede_tx_queue *txq;
 	uint16_t sb_idx;
+	uint8_t i;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -447,10 +451,38 @@ void qede_dealloc_fp_resc(struct rte_eth_dev *eth_dev)
 		fp = &qdev->fp_array[sb_idx];
 		DP_INFO(edev, "Free sb_info index 0x%x\n",
 				fp->sb_info->igu_sb_id);
-		if (fp->sb_info)
+		if (fp->sb_info) {
+			OSAL_DMA_FREE_COHERENT(edev, fp->sb_info->sb_virt,
+				fp->sb_info->sb_phys,
+				sizeof(struct status_block));
 			rte_free(fp->sb_info);
-		fp->sb_info = NULL;
+			fp->sb_info = NULL;
+		}
 	}
+
+	/* Free packet buffers and ring memories */
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		if (eth_dev->data->rx_queues[i]) {
+			qede_rx_queue_release(eth_dev->data->rx_queues[i]);
+			rxq = eth_dev->data->rx_queues[i];
+			qdev->ops->common->chain_free(edev,
+						      &rxq->rx_bd_ring);
+			qdev->ops->common->chain_free(edev,
+						      &rxq->rx_comp_ring);
+			eth_dev->data->rx_queues[i] = NULL;
+		}
+	}
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		if (eth_dev->data->tx_queues[i]) {
+			txq = eth_dev->data->tx_queues[i];
+			qede_tx_queue_release(eth_dev->data->tx_queues[i]);
+			qdev->ops->common->chain_free(edev,
+						      &txq->tx_pbl);
+			eth_dev->data->tx_queues[i] = NULL;
+		}
+	}
+
 	if (qdev->fp_array)
 		rte_free(qdev->fp_array);
 	qdev->fp_array = NULL;
-- 
1.7.10.3

  parent reply	other threads:[~2017-07-01 19:30 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-29  9:51 [dpdk-dev] [PATCH 0/9] net/qede: update PMD to 2.5.1.1 Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 1/9] net/qede: fix DMA memory leak Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 2/9] net/qede: add notifying HW errors Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 3/9] net/qede: limit ring size to 32k Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 4/9] net/qede: comments traces and format changes Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 5/9] net/qede: change debug verbosity of PMD messages Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 6/9] net/qede: set mdump flag Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 7/9] net/qede: add missing check for VNI Rasesh Mody
2017-06-29  9:51 ` [dpdk-dev] [PATCH 8/9] net/qede: use newer packet mbuf allocate API Rasesh Mody
2017-06-29 12:55   ` Ferruh Yigit
2017-07-01 19:34     ` Mody, Rasesh
2017-06-29  9:51 ` [dpdk-dev] [PATCH 9/9] net/qede: update PMD version to 2.5.1.1 Rasesh Mody
2017-06-29 12:16 ` [dpdk-dev] [PATCH 0/9] net/qede: update PMD " Ferruh Yigit
2017-07-01 19:29 ` [dpdk-dev] [PATCH v2 0/8] " Rasesh Mody
2017-07-05 10:01   ` Ferruh Yigit
2017-07-08 18:35     ` Mody, Rasesh
2017-07-01 19:29 ` Rasesh Mody [this message]
2017-07-01 19:29 ` [dpdk-dev] [PATCH v2 2/8] net/qede: add notifying HW errors Rasesh Mody
2017-07-01 19:29 ` [dpdk-dev] [PATCH v2 3/8] net/qede: limit ring size to 32k Rasesh Mody
2017-07-01 19:29 ` [dpdk-dev] [PATCH v2 4/8] net/qede: comments traces and format changes Rasesh Mody
2017-07-01 19:29 ` [dpdk-dev] [PATCH v2 5/8] net/qede: change debug verbosity of PMD messages Rasesh Mody
2017-07-01 19:30 ` [dpdk-dev] [PATCH v2 6/8] net/qede: set mdump flag Rasesh Mody
2017-07-01 19:30 ` [dpdk-dev] [PATCH v2 7/8] net/qede: add missing check for VNI Rasesh Mody
2017-07-03 10:08   ` Ferruh Yigit
2017-07-01 19:30 ` [dpdk-dev] [PATCH v2 8/8] net/qede: update PMD version to 2.5.1.1 Rasesh Mody
2017-07-03 10:06   ` Ferruh Yigit
2017-07-05  9:57     ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1498937402-25547-2-git-send-email-rasesh.mody@cavium.com \
    --to=rasesh.mody@cavium.com \
    --cc=Dept-EngDPDKDev@cavium.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=harish.patil@cavium.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).