[v2,17/18] net/dpaa: improve the dpaa port cleanup

Message ID 20240823073240.3708320-18-hemant.agrawal@nxp.com (mailing list archive)
State Changes Requested
Delegated to: Ferruh Yigit
Headers
Series NXP DPAA ETH driver enhancement and fixes |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Hemant Agrawal Aug. 23, 2024, 7:32 a.m. UTC
From: Gagandeep Singh <g.singh@nxp.com>

During DPAA cleanup in FMCLESS mode, application can
see segmentation fault in device close API and in DPAA
destructor execution.
Segmentation fault in device close is because driver
reducing the number of queues initialised during
device configuration without releasing the actual queues.

And segmentation fault in DPAA destruction is because
it is trying to access RTE* devices whose memory has
been released in rte_eal_cleanup() call by the application.

This patch improves the behavior.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 33 +++++++++++----------------------
 drivers/net/dpaa/dpaa_flow.c   |  8 ++++----
 2 files changed, 15 insertions(+), 26 deletions(-)
  

Patch

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 133fbd5bc9..41ae033c75 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -561,10 +561,10 @@  static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	if (dpaa_intf->cgr_rx) {
 		for (loop = 0; loop < dpaa_intf->nb_rx_queues; loop++)
 			qman_delete_cgr(&dpaa_intf->cgr_rx[loop]);
+		rte_free(dpaa_intf->cgr_rx);
+		dpaa_intf->cgr_rx = NULL;
 	}
 
-	rte_free(dpaa_intf->cgr_rx);
-	dpaa_intf->cgr_rx = NULL;
 	/* Release TX congestion Groups */
 	if (dpaa_intf->cgr_tx) {
 		for (loop = 0; loop < MAX_DPAA_CORES; loop++)
@@ -578,6 +578,15 @@  static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 
 	rte_free(dpaa_intf->tx_queues);
 	dpaa_intf->tx_queues = NULL;
+	if (dpaa_intf->port_handle) {
+		if (dpaa_fm_deconfig(dpaa_intf, fif))
+			DPAA_PMD_WARN("DPAA FM "
+				"deconfig failed\n");
+	}
+	if (fif->num_profiles) {
+		if (dpaa_port_vsp_cleanup(dpaa_intf, fif))
+			DPAA_PMD_WARN("DPAA FM vsp cleanup failed\n");
+	}
 
 	return ret;
 }
@@ -2607,26 +2616,6 @@  static void __attribute__((destructor(102))) dpaa_finish(void)
 		return;
 
 	if (!(default_q || fmc_q)) {
-		unsigned int i;
-
-		for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-			if (rte_eth_devices[i].dev_ops == &dpaa_devops) {
-				struct rte_eth_dev *dev = &rte_eth_devices[i];
-				struct dpaa_if *dpaa_intf =
-					dev->data->dev_private;
-				struct fman_if *fif =
-					dev->process_private;
-				if (dpaa_intf->port_handle)
-					if (dpaa_fm_deconfig(dpaa_intf, fif))
-						DPAA_PMD_WARN("DPAA FM "
-							"deconfig failed");
-				if (fif->num_profiles) {
-					if (dpaa_port_vsp_cleanup(dpaa_intf,
-								  fif))
-						DPAA_PMD_WARN("DPAA FM vsp cleanup failed");
-				}
-			}
-		}
 		if (is_global_init)
 			if (dpaa_fm_term())
 				DPAA_PMD_WARN("DPAA FM term failed");
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 810b187405..2240f8d27c 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017-2019,2021 NXP
+ * Copyright 2017-2019,2021-2023 NXP
  */
 
 /* System headers */
@@ -812,8 +812,6 @@  int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
 		return -1;
 	}
 
-	dpaa_intf->nb_rx_queues = dev->data->nb_rx_queues;
-
 	/* Open FM Port and set it in port info */
 	ret = set_fm_port_handle(dpaa_intf, req_dist_set, fif);
 	if (ret) {
@@ -822,7 +820,7 @@  int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
 	}
 
 	if (fif->num_profiles) {
-		for (i = 0; i < dpaa_intf->nb_rx_queues; i++)
+		for (i = 0; i < dev->data->nb_rx_queues; i++)
 			dpaa_intf->rx_queues[i].vsp_id =
 				fm_default_vsp_id(fif);
 
@@ -1147,6 +1145,8 @@  int rte_pmd_dpaa_port_set_rate_limit(uint16_t port_id, uint16_t burst,
 
 	if (ret) {
 		DPAA_PMD_ERR("Failed to set rate limit ret = %#x\n", -ret);
+		if (!port_handle_exists)
+			fm_port_close(handle);
 		return -ret;
 	}