Commit 6c43ff18 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

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: default avatarStephen Hemminger <shemminger@osdl.org>
parent b41848b6
...@@ -55,9 +55,25 @@ static void queue_process(void *p) ...@@ -55,9 +55,25 @@ static void queue_process(void *p)
struct netpoll_info *npinfo = p; struct netpoll_info *npinfo = p;
struct sk_buff *skb; struct sk_buff *skb;
while ((skb = skb_dequeue(&npinfo->txq))) while ((skb = skb_dequeue(&npinfo->txq))) {
dev_queue_xmit(skb); struct net_device *dev = skb->dev;
if (!netif_device_present(dev) || !netif_running(dev)) {
__kfree_skb(skb);
continue;
}
netif_tx_lock_bh(dev);
if (netif_queue_stopped(dev) ||
dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb);
netif_tx_unlock_bh(dev);
schedule_delayed_work(&npinfo->tx_work, HZ/10);
return;
}
netif_tx_unlock_bh(dev);
}
} }
void netpoll_queue(struct sk_buff *skb) void netpoll_queue(struct sk_buff *skb)
...@@ -765,6 +781,7 @@ void netpoll_cleanup(struct netpoll *np) ...@@ -765,6 +781,7 @@ void netpoll_cleanup(struct netpoll *np)
if (atomic_dec_and_test(&npinfo->refcnt)) { if (atomic_dec_and_test(&npinfo->refcnt)) {
skb_queue_purge(&npinfo->arp_tx); skb_queue_purge(&npinfo->arp_tx);
skb_queue_purge(&npinfo->txq); skb_queue_purge(&npinfo->txq);
cancel_rearming_delayed_work(&npinfo->tx_work);
flush_scheduled_work(); flush_scheduled_work();
kfree(npinfo); kfree(npinfo);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment