|
@@ -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;
|
|
|
}
|
|
|
|