On Tue, Feb 18, 2020 at 3:35 PM Maxime Coquelin <maxime.coque...@redhat.com> wrote: > > 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") > > Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> > --- > drivers/net/vhost/rte_eth_vhost.c | 21 ++++++++++++++------- > 1 file changed, 14 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/vhost/rte_eth_vhost.c > b/drivers/net/vhost/rte_eth_vhost.c > index 90263ae77c..c0056bc8bf 100644 > --- a/drivers/net/vhost/rte_eth_vhost.c > +++ b/drivers/net/vhost/rte_eth_vhost.c > @@ -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: > + pthread_mutex_lock(&internal_list_lock); > + TAILQ_REMOVE(&internal_list, list, next); > + pthread_mutex_unlock(&internal_list_lock); > + vring_states[eth_dev->data->port_id] = NULL;
We allocate/store in vring_states after inserting list in &internal_list. Probably nitpicking but I would expect the opposite order on cleanup. > rte_free(vring_state); > +free_list: > rte_free(list); > > return -1; > -- > 2.24.1 > In any case, Reviewed-by: David Marchand <david.march...@redhat.com> -- David Marchand