]>
Commit | Line | Data |
---|---|---|
2289b8c5 SL |
1 | From b4e94d8462c7cb873e499c57f501fe19bee90c84 Mon Sep 17 00:00:00 2001 |
2 | From: Bernd Eckstein <3erndeckstein@gmail.com> | |
3 | Date: Mon, 20 May 2019 17:31:09 +0200 | |
4 | Subject: usbnet: ipheth: fix racing condition | |
5 | ||
6 | [ Upstream commit 94d250fae48e6f873d8362308f5c4d02cd1b1fd2 ] | |
7 | ||
8 | Fix a racing condition in ipheth.c that can lead to slow performance. | |
9 | ||
10 | Bug: In ipheth_tx(), netif_wake_queue() may be called on the callback | |
11 | ipheth_sndbulk_callback(), _before_ netif_stop_queue() is called. | |
12 | When this happens, the queue is stopped longer than it needs to be, | |
13 | thus reducing network performance. | |
14 | ||
15 | Fix: Move netif_stop_queue() in front of usb_submit_urb(). Now the order | |
16 | is always correct. In case, usb_submit_urb() fails, the queue is woken up | |
17 | again as callback will not fire. | |
18 | ||
19 | Testing: This racing condition is usually not noticeable, as it has to | |
20 | occur very frequently to slowdown the network. The callback from the USB | |
21 | is usually triggered slow enough, so the situation does not appear. | |
22 | However, on a Ubuntu Linux on VMWare Workstation, running on Windows 10, | |
23 | the we loose the race quite often and the following speedup can be noticed: | |
24 | ||
25 | Without this patch: Download: 4.10 Mbit/s, Upload: 4.01 Mbit/s | |
26 | With this patch: Download: 36.23 Mbit/s, Upload: 17.61 Mbit/s | |
27 | ||
28 | Signed-off-by: Oliver Zweigle <Oliver.Zweigle@faro.com> | |
29 | Signed-off-by: Bernd Eckstein <3ernd.Eckstein@gmail.com> | |
30 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
31 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
32 | --- | |
33 | drivers/net/usb/ipheth.c | 3 ++- | |
34 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
35 | ||
36 | diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c | |
37 | index 3d8a70d3ea9b..3d71f1716390 100644 | |
38 | --- a/drivers/net/usb/ipheth.c | |
39 | +++ b/drivers/net/usb/ipheth.c | |
40 | @@ -437,17 +437,18 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) | |
41 | dev); | |
42 | dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | |
43 | ||
44 | + netif_stop_queue(net); | |
45 | retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC); | |
46 | if (retval) { | |
47 | dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", | |
48 | __func__, retval); | |
49 | dev->net->stats.tx_errors++; | |
50 | dev_kfree_skb_any(skb); | |
51 | + netif_wake_queue(net); | |
52 | } else { | |
53 | dev->net->stats.tx_packets++; | |
54 | dev->net->stats.tx_bytes += skb->len; | |
55 | dev_consume_skb_any(skb); | |
56 | - netif_stop_queue(net); | |
57 | } | |
58 | ||
59 | return NETDEV_TX_OK; | |
60 | -- | |
61 | 2.20.1 | |
62 |