memif_create() returned -1 directly when the process-private allocation
or memif_socket_init() failed, leaving the port allocated by
rte_eth_vdev_allocate() registered and the process-private memory
leaked. Jump to an error label that frees the process-private data and
releases the port instead.
Fixes: 09c7e63a71f9 ("net/memif: introduce memory interface PMD")
Cc: [email protected]
Signed-off-by: Sriram Yagnaraman <[email protected]>
---
drivers/net/memif/rte_eth_memif.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/net/memif/rte_eth_memif.c
b/drivers/net/memif/rte_eth_memif.c
index e8950166b2..d805509391 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1964,18 +1964,18 @@ memif_create(struct rte_vdev_device *vdev, enum
memif_role_t role,
const unsigned int numa_node = vdev->device.numa_node;
const char *name = rte_vdev_device_name(vdev);
+ /* Allocate process-private data before reserving the port. */
+ process_private = rte_zmalloc(name, sizeof(struct pmd_process_private),
+ RTE_CACHE_LINE_SIZE);
+ if (process_private == NULL) {
+ MIF_LOG(ERR, "Failed to alloc memory for process private");
+ return -ENOMEM;
+ }
+
eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*pmd));
if (eth_dev == NULL) {
MIF_LOG(ERR, "%s: Unable to allocate device struct.", name);
- return -1;
- }
-
- process_private = (struct pmd_process_private *)
- rte_zmalloc(name, sizeof(struct pmd_process_private),
- RTE_CACHE_LINE_SIZE);
-
- if (process_private == NULL) {
- MIF_LOG(ERR, "Failed to alloc memory for process private");
+ rte_free(process_private);
return -1;
}
eth_dev->process_private = process_private;
@@ -1995,7 +1995,7 @@ memif_create(struct rte_vdev_device *vdev, enum
memif_role_t role,
ret = memif_socket_init(eth_dev, socket_filename);
if (ret < 0)
- return ret;
+ goto error;
memset(pmd->secret, 0, sizeof(char) * ETH_MEMIF_SECRET_SIZE);
if (secret != NULL)
@@ -2030,6 +2030,13 @@ memif_create(struct rte_vdev_device *vdev, enum
memif_role_t role,
rte_eth_dev_probing_finish(eth_dev);
return 0;
+
+error:
+ /* rte_eth_dev_release_port() does not free process_private. */
+ rte_free(eth_dev->process_private);
+ eth_dev->process_private = NULL;
+ rte_eth_dev_release_port(eth_dev);
+ return ret;
}
static int
--
2.43.7