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

Reply via email to