diff options
author | stephen hemminger <shemminger@vyatta.com> | 2010-04-28 08:25:28 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-30 16:15:38 -0700 |
commit | 81a2e36df7de8bf9417de67f9d54b4f740072ed0 (patch) | |
tree | 7e419501ef2fe5d1b7a480044a4016cc3205c44f /drivers/net/forcedeth.c | |
parent | f84af32cbca70a3c6d30463dc08c7984af11c277 (diff) | |
download | op-kernel-dev-81a2e36df7de8bf9417de67f9d54b4f740072ed0.zip op-kernel-dev-81a2e36df7de8bf9417de67f9d54b4f740072ed0.tar.gz |
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.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index a1c0e7b..5cf0e66 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); |