diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 73f596a90c69..f17f602e6171 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -87,8 +87,7 @@ struct netfront_cb { | |||
87 | /* IRQ name is queue name with "-tx" or "-rx" appended */ | 87 | /* IRQ name is queue name with "-tx" or "-rx" appended */ |
88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) | 88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) |
89 | 89 | ||
90 | static DECLARE_WAIT_QUEUE_HEAD(module_load_q); | 90 | static DECLARE_WAIT_QUEUE_HEAD(module_wq); |
91 | static DECLARE_WAIT_QUEUE_HEAD(module_unload_q); | ||
92 | 91 | ||
93 | struct netfront_stats { | 92 | struct netfront_stats { |
94 | u64 packets; | 93 | u64 packets; |
@@ -909,7 +908,11 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue, | |||
909 | BUG_ON(pull_to <= skb_headlen(skb)); | 908 | BUG_ON(pull_to <= skb_headlen(skb)); |
910 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); | 909 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); |
911 | } | 910 | } |
912 | BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS); | 911 | if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) { |
912 | queue->rx.rsp_cons = ++cons; | ||
913 | kfree_skb(nskb); | ||
914 | return ~0U; | ||
915 | } | ||
913 | 916 | ||
914 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | 917 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, |
915 | skb_frag_page(nfrag), | 918 | skb_frag_page(nfrag), |
@@ -1046,6 +1049,8 @@ err: | |||
1046 | skb->len += rx->status; | 1049 | skb->len += rx->status; |
1047 | 1050 | ||
1048 | i = xennet_fill_frags(queue, skb, &tmpq); | 1051 | i = xennet_fill_frags(queue, skb, &tmpq); |
1052 | if (unlikely(i == ~0U)) | ||
1053 | goto err; | ||
1049 | 1054 | ||
1050 | if (rx->flags & XEN_NETRXF_csum_blank) | 1055 | if (rx->flags & XEN_NETRXF_csum_blank) |
1051 | skb->ip_summed = CHECKSUM_PARTIAL; | 1056 | skb->ip_summed = CHECKSUM_PARTIAL; |
@@ -1332,11 +1337,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1332 | netif_carrier_off(netdev); | 1337 | netif_carrier_off(netdev); |
1333 | 1338 | ||
1334 | xenbus_switch_state(dev, XenbusStateInitialising); | 1339 | xenbus_switch_state(dev, XenbusStateInitialising); |
1335 | wait_event(module_load_q, | 1340 | wait_event(module_wq, |
1336 | xenbus_read_driver_state(dev->otherend) != | 1341 | xenbus_read_driver_state(dev->otherend) != |
1337 | XenbusStateClosed && | 1342 | XenbusStateClosed && |
1338 | xenbus_read_driver_state(dev->otherend) != | 1343 | xenbus_read_driver_state(dev->otherend) != |
1339 | XenbusStateUnknown); | 1344 | XenbusStateUnknown); |
1340 | return netdev; | 1345 | return netdev; |
1341 | 1346 | ||
1342 | exit: | 1347 | exit: |
@@ -2010,15 +2015,14 @@ static void netback_changed(struct xenbus_device *dev, | |||
2010 | 2015 | ||
2011 | dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state)); | 2016 | dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state)); |
2012 | 2017 | ||
2018 | wake_up_all(&module_wq); | ||
2019 | |||
2013 | switch (backend_state) { | 2020 | switch (backend_state) { |
2014 | case XenbusStateInitialising: | 2021 | case XenbusStateInitialising: |
2015 | case XenbusStateInitialised: | 2022 | case XenbusStateInitialised: |
2016 | case XenbusStateReconfiguring: | 2023 | case XenbusStateReconfiguring: |
2017 | case XenbusStateReconfigured: | 2024 | case XenbusStateReconfigured: |
2018 | break; | ||
2019 | |||
2020 | case XenbusStateUnknown: | 2025 | case XenbusStateUnknown: |
2021 | wake_up_all(&module_unload_q); | ||
2022 | break; | 2026 | break; |
2023 | 2027 | ||
2024 | case XenbusStateInitWait: | 2028 | case XenbusStateInitWait: |
@@ -2034,12 +2038,10 @@ static void netback_changed(struct xenbus_device *dev, | |||
2034 | break; | 2038 | break; |
2035 | 2039 | ||
2036 | case XenbusStateClosed: | 2040 | case XenbusStateClosed: |
2037 | wake_up_all(&module_unload_q); | ||
2038 | if (dev->state == XenbusStateClosed) | 2041 | if (dev->state == XenbusStateClosed) |
2039 | break; | 2042 | break; |
2040 | /* Missed the backend's CLOSING state -- fallthrough */ | 2043 | /* Missed the backend's CLOSING state -- fallthrough */ |
2041 | case XenbusStateClosing: | 2044 | case XenbusStateClosing: |
2042 | wake_up_all(&module_unload_q); | ||
2043 | xenbus_frontend_closed(dev); | 2045 | xenbus_frontend_closed(dev); |
2044 | break; | 2046 | break; |
2045 | } | 2047 | } |
@@ -2147,14 +2149,14 @@ static int xennet_remove(struct xenbus_device *dev) | |||
2147 | 2149 | ||
2148 | if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { | 2150 | if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { |
2149 | xenbus_switch_state(dev, XenbusStateClosing); | 2151 | xenbus_switch_state(dev, XenbusStateClosing); |
2150 | wait_event(module_unload_q, | 2152 | wait_event(module_wq, |
2151 | xenbus_read_driver_state(dev->otherend) == | 2153 | xenbus_read_driver_state(dev->otherend) == |
2152 | XenbusStateClosing || | 2154 | XenbusStateClosing || |
2153 | xenbus_read_driver_state(dev->otherend) == | 2155 | xenbus_read_driver_state(dev->otherend) == |
2154 | XenbusStateUnknown); | 2156 | XenbusStateUnknown); |
2155 | 2157 | ||
2156 | xenbus_switch_state(dev, XenbusStateClosed); | 2158 | xenbus_switch_state(dev, XenbusStateClosed); |
2157 | wait_event(module_unload_q, | 2159 | wait_event(module_wq, |
2158 | xenbus_read_driver_state(dev->otherend) == | 2160 | xenbus_read_driver_state(dev->otherend) == |
2159 | XenbusStateClosed || | 2161 | XenbusStateClosed || |
2160 | xenbus_read_driver_state(dev->otherend) == | 2162 | xenbus_read_driver_state(dev->otherend) == |