]> git.droids-corp.org - dpdk.git/commitdiff
net/vhost: fix setup error path
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Tue, 18 Feb 2020 17:22:39 +0000 (18:22 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Feb 2020 12:51:06 +0000 (13:51 +0100)
If for some reason vhost_driver_setup() fails, the list
element for the device may be freed without being removed
from the internal list of devices.

This patch fixes all the error paths, by unregistering the
device from Vhost library it has been registered, remove
the device from the list, reset device vring_state pointer
from the global table and only free vring state if it had
been allocated.

Fixes: 3d01b759d267 ("net/vhost: delay driver setup")
Cc: stable@dpdk.org
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
drivers/net/vhost/rte_eth_vhost.c

index 90263ae77c04bdcfe297a7fb12be6d2c418949a7..4a7b1b608c724d7bcaf3d0ff94c4e87a784c56b9 100644 (file)
@@ -878,12 +878,12 @@ vhost_driver_setup(struct rte_eth_dev *eth_dev)
 
        list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
        if (list == NULL)
-               goto error;
+               return -1;
 
        vring_state = rte_zmalloc_socket(name, sizeof(*vring_state),
                                         0, numa_node);
        if (vring_state == NULL)
-               goto error;
+               goto free_list;
 
        list->eth_dev = eth_dev;
        pthread_mutex_lock(&internal_list_lock);
@@ -894,30 +894,37 @@ vhost_driver_setup(struct rte_eth_dev *eth_dev)
        vring_states[eth_dev->data->port_id] = vring_state;
 
        if (rte_vhost_driver_register(internal->iface_name, internal->flags))
-               goto error;
+               goto list_remove;
 
        if (internal->disable_flags) {
                if (rte_vhost_driver_disable_features(internal->iface_name,
                                                      internal->disable_flags))
-                       goto error;
+                       goto drv_unreg;
        }
 
        if (rte_vhost_driver_callback_register(internal->iface_name,
                                               &vhost_ops) < 0) {
                VHOST_LOG(ERR, "Can't register callbacks\n");
-               goto error;
+               goto drv_unreg;
        }
 
        if (rte_vhost_driver_start(internal->iface_name) < 0) {
                VHOST_LOG(ERR, "Failed to start driver for %s\n",
                          internal->iface_name);
-               goto error;
+               goto drv_unreg;
        }
 
        return 0;
 
-error:
+drv_unreg:
+       rte_vhost_driver_unregister(internal->iface_name);
+list_remove:
+       vring_states[eth_dev->data->port_id] = NULL;
+       pthread_mutex_lock(&internal_list_lock);
+       TAILQ_REMOVE(&internal_list, list, next);
+       pthread_mutex_unlock(&internal_list_lock);
        rte_free(vring_state);
+free_list:
        rte_free(list);
 
        return -1;