Skip to content

Commit

Permalink
netpoll deferred transmit path
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Dec 3, 2006
1 parent b41848b commit 6c43ff1
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,25 @@ static void queue_process(void *p)
struct netpoll_info *npinfo = p;
struct sk_buff *skb;

while ((skb = skb_dequeue(&npinfo->txq)))
dev_queue_xmit(skb);
while ((skb = skb_dequeue(&npinfo->txq))) {
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)
Expand Down Expand Up @@ -765,6 +781,7 @@ void netpoll_cleanup(struct netpoll *np)
if (atomic_dec_and_test(&npinfo->refcnt)) {
skb_queue_purge(&npinfo->arp_tx);
skb_queue_purge(&npinfo->txq);
cancel_rearming_delayed_work(&npinfo->tx_work);
flush_scheduled_work();

kfree(npinfo);
Expand Down

0 comments on commit 6c43ff1

Please sign in to comment.