]>
Commit | Line | Data |
---|---|---|
95244f99 GKH |
1 | From foo@baz Wed Dec 6 17:39:55 CET 2017 |
2 | From: Ross Lagerwall <ross.lagerwall@citrix.com> | |
3 | Date: Wed, 8 Feb 2017 10:57:37 +0000 | |
4 | Subject: xen-netfront: Improve error handling during initialization | |
5 | ||
6 | From: Ross Lagerwall <ross.lagerwall@citrix.com> | |
7 | ||
8 | ||
9 | [ Upstream commit e2e004acc7cbe3c531e752a270a74e95cde3ea48 ] | |
10 | ||
11 | This fixes a crash when running out of grant refs when creating many | |
12 | queues across many netdevs. | |
13 | ||
14 | * If creating queues fails (i.e. there are no grant refs available), | |
15 | call xenbus_dev_fatal() to ensure that the xenbus device is set to the | |
16 | closed state. | |
17 | * If no queues are created, don't call xennet_disconnect_backend as | |
18 | netdev->real_num_tx_queues will not have been set correctly. | |
19 | * If setup_netfront() fails, ensure that all the queues created are | |
20 | cleaned up, not just those that have been set up. | |
21 | * If any queues were set up and an error occurs, call | |
22 | xennet_destroy_queues() to clean up the napi context. | |
23 | * If any fatal error occurs, unregister and destroy the netdev to avoid | |
24 | leaving around a half setup network device. | |
25 | ||
26 | Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> | |
27 | Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> | |
28 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
29 | Signed-off-by: Sasha Levin <alexander.levin@verizon.com> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | --- | |
32 | drivers/net/xen-netfront.c | 29 +++++++++++------------------ | |
33 | 1 file changed, 11 insertions(+), 18 deletions(-) | |
34 | ||
35 | --- a/drivers/net/xen-netfront.c | |
36 | +++ b/drivers/net/xen-netfront.c | |
37 | @@ -1854,27 +1854,19 @@ static int talk_to_netback(struct xenbus | |
38 | xennet_destroy_queues(info); | |
39 | ||
40 | err = xennet_create_queues(info, &num_queues); | |
41 | - if (err < 0) | |
42 | - goto destroy_ring; | |
43 | + if (err < 0) { | |
44 | + xenbus_dev_fatal(dev, err, "creating queues"); | |
45 | + kfree(info->queues); | |
46 | + info->queues = NULL; | |
47 | + goto out; | |
48 | + } | |
49 | ||
50 | /* Create shared ring, alloc event channel -- for each queue */ | |
51 | for (i = 0; i < num_queues; ++i) { | |
52 | queue = &info->queues[i]; | |
53 | err = setup_netfront(dev, queue, feature_split_evtchn); | |
54 | - if (err) { | |
55 | - /* setup_netfront() will tidy up the current | |
56 | - * queue on error, but we need to clean up | |
57 | - * those already allocated. | |
58 | - */ | |
59 | - if (i > 0) { | |
60 | - rtnl_lock(); | |
61 | - netif_set_real_num_tx_queues(info->netdev, i); | |
62 | - rtnl_unlock(); | |
63 | - goto destroy_ring; | |
64 | - } else { | |
65 | - goto out; | |
66 | - } | |
67 | - } | |
68 | + if (err) | |
69 | + goto destroy_ring; | |
70 | } | |
71 | ||
72 | again: | |
73 | @@ -1964,9 +1956,10 @@ abort_transaction_no_dev_fatal: | |
74 | xenbus_transaction_end(xbt, 1); | |
75 | destroy_ring: | |
76 | xennet_disconnect_backend(info); | |
77 | - kfree(info->queues); | |
78 | - info->queues = NULL; | |
79 | + xennet_destroy_queues(info); | |
80 | out: | |
81 | + unregister_netdev(info->netdev); | |
82 | + xennet_free_netdev(info->netdev); | |
83 | return err; | |
84 | } | |
85 |