aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2010-04-28 08:25:28 +0000
committerDavid S. Miller <davem@davemloft.net>2010-04-30 16:15:38 -0700
commit81a2e36df7de8bf9417de67f9d54b4f740072ed0 (patch)
tree7e419501ef2fe5d1b7a480044a4016cc3205c44f /drivers/net/forcedeth.c
parentnet: ip_queue_rcv_skb() helper (diff)
downloadlinux-dev-81a2e36df7de8bf9417de67f9d54b4f740072ed0.tar.xz
linux-dev-81a2e36df7de8bf9417de67f9d54b4f740072ed0.zip
forcedeth: Stay in NAPI as long as there's work
The following does the same thing without the extra overhead of testing all the registers. It also handles the out of memory case. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Tested-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index a1c0e7bb70e8..5cf0e6615695 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3743,23 +3743,26 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
int retcode;
- int tx_work, rx_work;
+ int rx_count, tx_work=0, rx_work=0;
- if (!nv_optimized(np)) {
- spin_lock_irqsave(&np->lock, flags);
- tx_work = nv_tx_done(dev, np->tx_ring_size);
- spin_unlock_irqrestore(&np->lock, flags);
+ do {
+ if (!nv_optimized(np)) {
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work += nv_tx_done(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
- rx_work = nv_rx_process(dev, budget);
- retcode = nv_alloc_rx(dev);
- } else {
- spin_lock_irqsave(&np->lock, flags);
- tx_work = nv_tx_done_optimized(dev, np->tx_ring_size);
- spin_unlock_irqrestore(&np->lock, flags);
+ rx_count = nv_rx_process(dev, budget);
+ retcode = nv_alloc_rx(dev);
+ } else {
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work += nv_tx_done_optimized(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
- rx_work = nv_rx_process_optimized(dev, budget);
- retcode = nv_alloc_rx_optimized(dev);
- }
+ rx_count = nv_rx_process_optimized(dev, budget);
+ retcode = nv_alloc_rx_optimized(dev);
+ }
+ } while (retcode == 0 &&
+ rx_count > 0 && (rx_work += rx_count) < budget);
if (retcode) {
spin_lock_irqsave(&np->lock, flags);