Skip to content

Commit 6c43ff1

Browse files
Stephen HemmingerDavid S. Miller
authored andcommitted
netpoll deferred transmit path
When the netpoll beast got busy, he tended to babble. Instead of talking out of his large mouth as normal, he tended to try to snort out other orifices. This lead to words (skbs) ending up in odd places (like NIT) that he did not intend. The normal way of talking wouldn't work, but he could at least change to using the same tone all the time. Signed-off-by: Stephen Hemminger <[email protected]>
1 parent b41848b commit 6c43ff1

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

net/core/netpoll.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,25 @@ static void queue_process(void *p)
5555
struct netpoll_info *npinfo = p;
5656
struct sk_buff *skb;
5757

58-
while ((skb = skb_dequeue(&npinfo->txq)))
59-
dev_queue_xmit(skb);
58+
while ((skb = skb_dequeue(&npinfo->txq))) {
59+
struct net_device *dev = skb->dev;
6060

61+
if (!netif_device_present(dev) || !netif_running(dev)) {
62+
__kfree_skb(skb);
63+
continue;
64+
}
65+
66+
netif_tx_lock_bh(dev);
67+
if (netif_queue_stopped(dev) ||
68+
dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
69+
skb_queue_head(&npinfo->txq, skb);
70+
netif_tx_unlock_bh(dev);
71+
72+
schedule_delayed_work(&npinfo->tx_work, HZ/10);
73+
return;
74+
}
75+
netif_tx_unlock_bh(dev);
76+
}
6177
}
6278

6379
void netpoll_queue(struct sk_buff *skb)
@@ -765,6 +781,7 @@ void netpoll_cleanup(struct netpoll *np)
765781
if (atomic_dec_and_test(&npinfo->refcnt)) {
766782
skb_queue_purge(&npinfo->arp_tx);
767783
skb_queue_purge(&npinfo->txq);
784+
cancel_rearming_delayed_work(&npinfo->tx_work);
768785
flush_scheduled_work();
769786

770787
kfree(npinfo);

0 commit comments

Comments
 (0)