]> err.no Git - linux-2.6/blobdiff - net/core/netpoll.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[linux-2.6] / net / core / netpoll.c
index 95daba6249676dc8e466303279cadc1223e57d81..c499b5c69bedbce96611baaec02eb9cfcb0798a6 100644 (file)
@@ -67,7 +67,7 @@ static void queue_process(struct work_struct *work)
                local_irq_save(flags);
                netif_tx_lock(dev);
                if ((netif_queue_stopped(dev) ||
-                    netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+                    netif_subqueue_stopped(dev, skb)) ||
                     dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
                        netif_tx_unlock(dev);
@@ -116,6 +116,29 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
  * network adapter, forcing superfluous retries and possibly timeouts.
  * Thus, we set our budget to greater than 1.
  */
+static int poll_one_napi(struct netpoll_info *npinfo,
+                        struct napi_struct *napi, int budget)
+{
+       int work;
+
+       /* net_rx_action's ->poll() invocations and our's are
+        * synchronized by this test which is only made while
+        * holding the napi->poll_lock.
+        */
+       if (!test_bit(NAPI_STATE_SCHED, &napi->state))
+               return budget;
+
+       npinfo->rx_flags |= NETPOLL_RX_DROP;
+       atomic_inc(&trapped);
+
+       work = napi->poll(napi, budget);
+
+       atomic_dec(&trapped);
+       npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+
+       return budget - work;
+}
+
 static void poll_napi(struct netpoll *np)
 {
        struct netpoll_info *npinfo = np->dev->npinfo;
@@ -123,17 +146,13 @@ static void poll_napi(struct netpoll *np)
        int budget = 16;
 
        list_for_each_entry(napi, &np->dev->napi_list, dev_list) {
-               if (test_bit(NAPI_STATE_SCHED, &napi->state) &&
-                   napi->poll_owner != smp_processor_id() &&
+               if (napi->poll_owner != smp_processor_id() &&
                    spin_trylock(&napi->poll_lock)) {
-                       npinfo->rx_flags |= NETPOLL_RX_DROP;
-                       atomic_inc(&trapped);
-
-                       napi->poll(napi, budget);
-
-                       atomic_dec(&trapped);
-                       npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+                       budget = poll_one_napi(npinfo, napi, budget);
                        spin_unlock(&napi->poll_lock);
+
+                       if (!budget)
+                               break;
                }
        }
 }
@@ -269,7 +288,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
                     tries > 0; --tries) {
                        if (netif_tx_trylock(dev)) {
                                if (!netif_queue_stopped(dev) &&
-                                   !netif_subqueue_stopped(dev, skb->queue_mapping))
+                                   !netif_subqueue_stopped(dev, skb))
                                        status = dev->hard_start_xmit(skb, dev);
                                netif_tx_unlock(dev);