aboutsummaryrefslogtreecommitdiffstats
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
parentf84af32cbca70a3c6d30463dc08c7984af11c277 (diff)
downloadkernel_samsung_smdk4412-81a2e36df7de8bf9417de67f9d54b4f740072ed0.zip
kernel_samsung_smdk4412-81a2e36df7de8bf9417de67f9d54b4f740072ed0.tar.gz
kernel_samsung_smdk4412-81a2e36df7de8bf9417de67f9d54b4f740072ed0.tar.bz2
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>
-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 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);