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.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index c327c9edadc5..a1a9a7abff50 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -33,6 +33,7 @@
33#define MAX_UDP_CHUNK 1460 33#define MAX_UDP_CHUNK 1460
34#define MAX_SKBS 32 34#define MAX_SKBS 32
35#define MAX_QUEUE_DEPTH (MAX_SKBS / 2) 35#define MAX_QUEUE_DEPTH (MAX_SKBS / 2)
36#define MAX_RETRIES 20000
36 37
37static DEFINE_SPINLOCK(skb_list_lock); 38static DEFINE_SPINLOCK(skb_list_lock);
38static int nr_skbs; 39static int nr_skbs;
@@ -248,14 +249,14 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
248 int status; 249 int status;
249 struct netpoll_info *npinfo; 250 struct netpoll_info *npinfo;
250 251
251repeat: 252 if (!np || !np->dev || !netif_running(np->dev)) {
252 if(!np || !np->dev || !netif_running(np->dev)) {
253 __kfree_skb(skb); 253 __kfree_skb(skb);
254 return; 254 return;
255 } 255 }
256 256
257 /* avoid recursion */
258 npinfo = np->dev->npinfo; 257 npinfo = np->dev->npinfo;
258
259 /* avoid recursion */
259 if (npinfo->poll_owner == smp_processor_id() || 260 if (npinfo->poll_owner == smp_processor_id() ||
260 np->dev->xmit_lock_owner == smp_processor_id()) { 261 np->dev->xmit_lock_owner == smp_processor_id()) {
261 if (np->drop) 262 if (np->drop)
@@ -265,30 +266,37 @@ repeat:
265 return; 266 return;
266 } 267 }
267 268
268 spin_lock(&np->dev->xmit_lock); 269 do {
269 np->dev->xmit_lock_owner = smp_processor_id(); 270 npinfo->tries--;
271 spin_lock(&np->dev->xmit_lock);
272 np->dev->xmit_lock_owner = smp_processor_id();
270 273
271 /* 274 /*
272 * network drivers do not expect to be called if the queue is 275 * network drivers do not expect to be called if the queue is
273 * stopped. 276 * stopped.
274 */ 277 */
275 if (netif_queue_stopped(np->dev)) { 278 if (netif_queue_stopped(np->dev)) {
279 np->dev->xmit_lock_owner = -1;
280 spin_unlock(&np->dev->xmit_lock);
281 netpoll_poll(np);
282 udelay(50);
283 continue;
284 }
285
286 status = np->dev->hard_start_xmit(skb, np->dev);
276 np->dev->xmit_lock_owner = -1; 287 np->dev->xmit_lock_owner = -1;
277 spin_unlock(&np->dev->xmit_lock); 288 spin_unlock(&np->dev->xmit_lock);
278 289
279 netpoll_poll(np); 290 /* success */
280 goto repeat; 291 if(!status) {
281 } 292 npinfo->tries = MAX_RETRIES; /* reset */
282 293 return;
283 status = np->dev->hard_start_xmit(skb, np->dev); 294 }
284 np->dev->xmit_lock_owner = -1;
285 spin_unlock(&np->dev->xmit_lock);
286 295
287 /* transmit busy */ 296 /* transmit busy */
288 if(status) {
289 netpoll_poll(np); 297 netpoll_poll(np);
290 goto repeat; 298 udelay(50);
291 } 299 } while (npinfo->tries > 0);
292} 300}
293 301
294void netpoll_send_udp(struct netpoll *np, const char *msg, int len) 302void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
@@ -349,15 +357,11 @@ static void arp_reply(struct sk_buff *skb)
349 unsigned char *arp_ptr; 357 unsigned char *arp_ptr;
350 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; 358 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
351 u32 sip, tip; 359 u32 sip, tip;
352 unsigned long flags;
353 struct sk_buff *send_skb; 360 struct sk_buff *send_skb;
354 struct netpoll *np = NULL; 361 struct netpoll *np = NULL;
355 362
356 spin_lock_irqsave(&npinfo->rx_lock, flags);
357 if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev) 363 if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev)
358 np = npinfo->rx_np; 364 np = npinfo->rx_np;
359 spin_unlock_irqrestore(&npinfo->rx_lock, flags);
360
361 if (!np) 365 if (!np)
362 return; 366 return;
363 367
@@ -639,9 +643,11 @@ int netpoll_setup(struct netpoll *np)
639 if (!npinfo) 643 if (!npinfo)
640 goto release; 644 goto release;
641 645
646 npinfo->rx_flags = 0;
642 npinfo->rx_np = NULL; 647 npinfo->rx_np = NULL;
643 npinfo->poll_lock = SPIN_LOCK_UNLOCKED; 648 npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
644 npinfo->poll_owner = -1; 649 npinfo->poll_owner = -1;
650 npinfo->tries = MAX_RETRIES;
645 npinfo->rx_lock = SPIN_LOCK_UNLOCKED; 651 npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
646 } else 652 } else
647 npinfo = ndev->npinfo; 653 npinfo = ndev->npinfo;
@@ -718,9 +724,16 @@ int netpoll_setup(struct netpoll *np)
718 npinfo->rx_np = np; 724 npinfo->rx_np = np;
719 spin_unlock_irqrestore(&npinfo->rx_lock, flags); 725 spin_unlock_irqrestore(&npinfo->rx_lock, flags);
720 } 726 }
727
728 /* fill up the skb queue */
729 refill_skbs();
730
721 /* last thing to do is link it to the net device structure */ 731 /* last thing to do is link it to the net device structure */
722 ndev->npinfo = npinfo; 732 ndev->npinfo = npinfo;
723 733
734 /* avoid racing with NAPI reading npinfo */
735 synchronize_rcu();
736
724 return 0; 737 return 0;
725 738
726 release: 739 release: