aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index de1b26aa572..abe6e3a4cc4 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -119,19 +119,22 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
119static void poll_napi(struct netpoll *np) 119static void poll_napi(struct netpoll *np)
120{ 120{
121 struct netpoll_info *npinfo = np->dev->npinfo; 121 struct netpoll_info *npinfo = np->dev->npinfo;
122 struct napi_struct *napi;
122 int budget = 16; 123 int budget = 16;
123 124
124 if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && 125 list_for_each_entry(napi, &np->dev->napi_list, dev_list) {
125 npinfo->poll_owner != smp_processor_id() && 126 if (test_bit(NAPI_STATE_SCHED, &napi->state) &&
126 spin_trylock(&npinfo->poll_lock)) { 127 napi->poll_owner != smp_processor_id() &&
127 npinfo->rx_flags |= NETPOLL_RX_DROP; 128 spin_trylock(&napi->poll_lock)) {
128 atomic_inc(&trapped); 129 npinfo->rx_flags |= NETPOLL_RX_DROP;
130 atomic_inc(&trapped);
129 131
130 np->dev->poll(np->dev, &budget); 132 napi->poll(napi, budget);
131 133
132 atomic_dec(&trapped); 134 atomic_dec(&trapped);
133 npinfo->rx_flags &= ~NETPOLL_RX_DROP; 135 npinfo->rx_flags &= ~NETPOLL_RX_DROP;
134 spin_unlock(&npinfo->poll_lock); 136 spin_unlock(&napi->poll_lock);
137 }
135 } 138 }
136} 139}
137 140
@@ -157,7 +160,7 @@ void netpoll_poll(struct netpoll *np)
157 160
158 /* Process pending work on NIC */ 161 /* Process pending work on NIC */
159 np->dev->poll_controller(np->dev); 162 np->dev->poll_controller(np->dev);
160 if (np->dev->poll) 163 if (!list_empty(&np->dev->napi_list))
161 poll_napi(np); 164 poll_napi(np);
162 165
163 service_arp_queue(np->dev->npinfo); 166 service_arp_queue(np->dev->npinfo);
@@ -233,6 +236,17 @@ repeat:
233 return skb; 236 return skb;
234} 237}
235 238
239static int netpoll_owner_active(struct net_device *dev)
240{
241 struct napi_struct *napi;
242
243 list_for_each_entry(napi, &dev->napi_list, dev_list) {
244 if (napi->poll_owner == smp_processor_id())
245 return 1;
246 }
247 return 0;
248}
249
236static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) 250static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
237{ 251{
238 int status = NETDEV_TX_BUSY; 252 int status = NETDEV_TX_BUSY;
@@ -246,8 +260,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
246 } 260 }
247 261
248 /* don't get messages out of order, and no recursion */ 262 /* don't get messages out of order, and no recursion */
249 if (skb_queue_len(&npinfo->txq) == 0 && 263 if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) {
250 npinfo->poll_owner != smp_processor_id()) {
251 unsigned long flags; 264 unsigned long flags;
252 265
253 local_irq_save(flags); 266 local_irq_save(flags);
@@ -652,8 +665,6 @@ int netpoll_setup(struct netpoll *np)
652 665
653 npinfo->rx_flags = 0; 666 npinfo->rx_flags = 0;
654 npinfo->rx_np = NULL; 667 npinfo->rx_np = NULL;
655 spin_lock_init(&npinfo->poll_lock);
656 npinfo->poll_owner = -1;
657 668
658 spin_lock_init(&npinfo->rx_lock); 669 spin_lock_init(&npinfo->rx_lock);
659 skb_queue_head_init(&npinfo->arp_tx); 670 skb_queue_head_init(&npinfo->arp_tx);