[2/2] net/mlx4: fix PCI probe error flow

Message ID 1610555333-18961-3-git-send-email-michaelba@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Raslan Darawsheh
Headers
Series net/mlx4: fix PCI probe and remove functions |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-testing success Testing PASS

Commit Message

Michael Baum Jan. 13, 2021, 4:28 p.m. UTC
In mlx4 PCI probing, there are some validations for the Ethernet device
configuration.
From each PCI device the function creates one or two Ethernet devices.

When one of validations fails during the creation of the second device,
the first device is not freed what caused a memory leak.

Free it.

Fixes: 7fae69eeff13 ("mlx4: new poll mode driver")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx4/mlx4.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)
  

Patch

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 7460afa..92b0427 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -860,6 +860,7 @@  struct mlx4_conf {
 		struct ibv_pd *pd = NULL;
 		struct mlx4_priv *priv = NULL;
 		struct rte_eth_dev *eth_dev = NULL;
+		struct rte_eth_dev *prev_dev = NULL;
 		struct rte_ether_addr mac;
 		char name[RTE_ETH_NAME_MAX_LEN];
 
@@ -880,7 +881,7 @@  struct mlx4_conf {
 				ERROR("can not attach rte ethdev");
 				rte_errno = ENOMEM;
 				err = rte_errno;
-				goto error;
+				goto err_secondary;
 			}
 			priv = eth_dev->data->dev_private;
 			if (!priv->verbs_alloc_ctx.enabled) {
@@ -889,24 +890,24 @@  struct mlx4_conf {
 				      " from Verbs");
 				rte_errno = ENOTSUP;
 				err = rte_errno;
-				goto error;
+				goto err_secondary;
 			}
 			eth_dev->device = &pci_dev->device;
 			eth_dev->dev_ops = &mlx4_dev_sec_ops;
 			err = mlx4_proc_priv_init(eth_dev);
 			if (err)
-				goto error;
+				goto err_secondary;
 			/* Receive command fd from primary process. */
 			err = mlx4_mp_req_verbs_cmd_fd(eth_dev);
 			if (err < 0) {
 				err = rte_errno;
-				goto error;
+				goto err_secondary;
 			}
 			/* Remap UAR for Tx queues. */
 			err = mlx4_tx_uar_init_secondary(eth_dev, err);
 			if (err) {
 				err = rte_errno;
-				goto error;
+				goto err_secondary;
 			}
 			/*
 			 * Ethdev pointer is still required as input since
@@ -918,7 +919,14 @@  struct mlx4_conf {
 			claim_zero(mlx4_glue->close_device(ctx));
 			rte_eth_copy_pci_info(eth_dev, pci_dev);
 			rte_eth_dev_probing_finish(eth_dev);
+			prev_dev = eth_dev;
 			continue;
+err_secondary:
+			claim_zero(mlx4_glue->close_device(ctx));
+			rte_eth_dev_release_port(eth_dev);
+			if (prev_dev)
+				rte_eth_dev_release_port(prev_dev);
+			break;
 		}
 		/* Check port status. */
 		err = mlx4_glue->query_port(ctx, port, &port_attr);
@@ -1093,6 +1101,7 @@  struct mlx4_conf {
 				 priv, mem_event_cb);
 		rte_rwlock_write_unlock(&mlx4_shared_data->mem_event_rwlock);
 		rte_eth_dev_probing_finish(eth_dev);
+		prev_dev = eth_dev;
 		continue;
 port_error:
 		rte_free(priv);
@@ -1107,14 +1116,10 @@  struct mlx4_conf {
 			eth_dev->data->mac_addrs = NULL;
 			rte_eth_dev_release_port(eth_dev);
 		}
+		if (prev_dev)
+			mlx4_dev_close(prev_dev);
 		break;
 	}
-	/*
-	 * XXX if something went wrong in the loop above, there is a resource
-	 * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
-	 * long as the dpdk does not provide a way to deallocate a ethdev and a
-	 * way to enumerate the registered ethdevs to free the previous ones.
-	 */
 error:
 	if (attr_ctx)
 		claim_zero(mlx4_glue->close_device(attr_ctx));