aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-10-26 18:46:53 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:22:35 -0500
commit6c43ff18f91e54aa7555d8ae4f26eab7da5bce68 (patch)
tree6db170a9a05bc78b3d0e992877da7eab0c8650de /net/core/netpoll.c
parentb41848b61bae30e3661efd4ec62ea380cedef687 (diff)
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 <shemminger@osdl.org>
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 621baa5da49f..93cb828f3aaf 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -55,9 +55,25 @@ static void queue_process(void *p)
55 struct netpoll_info *npinfo = p; 55 struct netpoll_info *npinfo = p;
56 struct sk_buff *skb; 56 struct sk_buff *skb;
57 57
58 while ((skb = skb_dequeue(&npinfo->txq))) 58 while ((skb = skb_dequeue(&npinfo->txq))) {
59 dev_queue_xmit(skb); 59 struct net_device *dev = skb->dev;
60 60
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 }
61} 77}
62 78
63void netpoll_queue(struct sk_buff *skb) 79void netpoll_queue(struct sk_buff *skb)
@@ -765,6 +781,7 @@ void netpoll_cleanup(struct netpoll *np)
765 if (atomic_dec_and_test(&npinfo->refcnt)) { 781 if (atomic_dec_and_test(&npinfo->refcnt)) {
766 skb_queue_purge(&npinfo->arp_tx); 782 skb_queue_purge(&npinfo->arp_tx);
767 skb_queue_purge(&npinfo->txq); 783 skb_queue_purge(&npinfo->txq);
784 cancel_rearming_delayed_work(&npinfo->tx_work);
768 flush_scheduled_work(); 785 flush_scheduled_work();
769 786
770 kfree(npinfo); 787 kfree(npinfo);