xen-netfront: Improve error handling during initialization
This fixes a crash when running out of grant refs when creating many queues across many netdevs. * If creating queues fails (i.e. there are no grant refs available), call xenbus_dev_fatal() to ensure that the xenbus device is set to the closed state. * If no queues are created, don't call xennet_disconnect_backend as netdev->real_num_tx_queues will not have been set correctly. * If setup_netfront() fails, ensure that all the queues created are cleaned up, not just those that have been set up. * If any queues were set up and an error occurs, call xennet_destroy_queues() to clean up the napi context. * If any fatal error occurs, unregister and destroy the netdev to avoid leaving around a half setup network device. Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1b5805c29c
commit
e2e004acc7
@ -1830,27 +1830,19 @@ static int talk_to_netback(struct xenbus_device *dev,
|
||||
xennet_destroy_queues(info);
|
||||
|
||||
err = xennet_create_queues(info, &num_queues);
|
||||
if (err < 0)
|
||||
goto destroy_ring;
|
||||
if (err < 0) {
|
||||
xenbus_dev_fatal(dev, err, "creating queues");
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create shared ring, alloc event channel -- for each queue */
|
||||
for (i = 0; i < num_queues; ++i) {
|
||||
queue = &info->queues[i];
|
||||
err = setup_netfront(dev, queue, feature_split_evtchn);
|
||||
if (err) {
|
||||
/* setup_netfront() will tidy up the current
|
||||
* queue on error, but we need to clean up
|
||||
* those already allocated.
|
||||
*/
|
||||
if (i > 0) {
|
||||
rtnl_lock();
|
||||
netif_set_real_num_tx_queues(info->netdev, i);
|
||||
rtnl_unlock();
|
||||
goto destroy_ring;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
goto destroy_ring;
|
||||
}
|
||||
|
||||
again:
|
||||
@ -1940,9 +1932,10 @@ abort_transaction_no_dev_fatal:
|
||||
xenbus_transaction_end(xbt, 1);
|
||||
destroy_ring:
|
||||
xennet_disconnect_backend(info);
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
xennet_destroy_queues(info);
|
||||
out:
|
||||
unregister_netdev(info->netdev);
|
||||
xennet_free_netdev(info->netdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user