forcedeth: Stay in NAPI as long as there's work
authorstephen hemminger <shemminger@vyatta.com>
Wed, 28 Apr 2010 08:25:28 +0000 (08:25 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Apr 2010 23:15:38 +0000 (16:15 -0700)
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>
drivers/net/forcedeth.c

index a1c0e7b..5cf0e66 100644 (file)
@@ -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);