Skip to content

Commit 65841fd

Browse files
Ming Leidavem330
authored andcommitted
usbnet: handle remote wakeup asap
If usbnet is resumed by remote wakeup, generally there are some packets comming to be handled, so allocate and submit rx URBs in usbnet_resume to avoid delays introduced by tasklet. Otherwise, usbnet may have been runtime suspended before the usbnet_bh is executed to schedule Rx URBs. Without the patch, usbnet can't recieve any packets from peer in runtime suspend state if runtime PM is enabled and autosuspend_delay is set as zero. Signed-off-by: Ming Lei <ming.lei@canonical.com> Acked-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5eeb313 commit 65841fd

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

drivers/net/usb/usbnet.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,21 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
12041204
}
12051205
EXPORT_SYMBOL_GPL(usbnet_start_xmit);
12061206

1207+
static void rx_alloc_submit(struct usbnet *dev, gfp_t flags)
1208+
{
1209+
struct urb *urb;
1210+
int i;
1211+
1212+
/* don't refill the queue all at once */
1213+
for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) {
1214+
urb = usb_alloc_urb(0, flags);
1215+
if (urb != NULL) {
1216+
if (rx_submit(dev, urb, flags) == -ENOLINK)
1217+
return;
1218+
}
1219+
}
1220+
}
1221+
12071222
/*-------------------------------------------------------------------------*/
12081223

12091224
// tasklet (work deferred from completions, in_irq) or timer
@@ -1243,26 +1258,14 @@ static void usbnet_bh (unsigned long param)
12431258
!timer_pending (&dev->delay) &&
12441259
!test_bit (EVENT_RX_HALT, &dev->flags)) {
12451260
int temp = dev->rxq.qlen;
1246-
int qlen = RX_QLEN (dev);
1247-
1248-
if (temp < qlen) {
1249-
struct urb *urb;
1250-
int i;
1251-
1252-
// don't refill the queue all at once
1253-
for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
1254-
urb = usb_alloc_urb (0, GFP_ATOMIC);
1255-
if (urb != NULL) {
1256-
if (rx_submit (dev, urb, GFP_ATOMIC) ==
1257-
-ENOLINK)
1258-
return;
1259-
}
1260-
}
1261+
1262+
if (temp < RX_QLEN(dev)) {
1263+
rx_alloc_submit(dev, GFP_ATOMIC);
12611264
if (temp != dev->rxq.qlen)
12621265
netif_dbg(dev, link, dev->net,
12631266
"rxqlen %d --> %d\n",
12641267
temp, dev->rxq.qlen);
1265-
if (dev->rxq.qlen < qlen)
1268+
if (dev->rxq.qlen < RX_QLEN(dev))
12661269
tasklet_schedule (&dev->bh);
12671270
}
12681271
if (dev->txq.qlen < TX_QLEN (dev))
@@ -1572,6 +1575,13 @@ int usbnet_resume (struct usb_interface *intf)
15721575
spin_unlock_irq(&dev->txq.lock);
15731576

15741577
if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
1578+
/* handle remote wakeup ASAP */
1579+
if (!dev->wait &&
1580+
netif_device_present(dev->net) &&
1581+
!timer_pending(&dev->delay) &&
1582+
!test_bit(EVENT_RX_HALT, &dev->flags))
1583+
rx_alloc_submit(dev, GFP_KERNEL);
1584+
15751585
if (!(dev->txq.qlen >= TX_QLEN(dev)))
15761586
netif_tx_wake_all_queues(dev->net);
15771587
tasklet_schedule (&dev->bh);

0 commit comments

Comments
 (0)