aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netpoll.h1
-rw-r--r--net/core/netpoll.c13
2 files changed, 11 insertions, 3 deletions
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index bcd0ac33f592..be68d94b03d5 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -26,6 +26,7 @@ struct netpoll {
26struct netpoll_info { 26struct netpoll_info {
27 spinlock_t poll_lock; 27 spinlock_t poll_lock;
28 int poll_owner; 28 int poll_owner;
29 int tries;
29 int rx_flags; 30 int rx_flags;
30 spinlock_t rx_lock; 31 spinlock_t rx_lock;
31 struct netpoll *rx_np; /* netpoll that registered an rx_hook */ 32 struct netpoll *rx_np; /* netpoll that registered an rx_hook */
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 59ed186e4f46..d09affdbad3c 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;
@@ -265,7 +266,8 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
265 return; 266 return;
266 } 267 }
267 268
268 while (1) { 269 do {
270 npinfo->tries--;
269 spin_lock(&np->dev->xmit_lock); 271 spin_lock(&np->dev->xmit_lock);
270 np->dev->xmit_lock_owner = smp_processor_id(); 272 np->dev->xmit_lock_owner = smp_processor_id();
271 273
@@ -277,6 +279,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
277 np->dev->xmit_lock_owner = -1; 279 np->dev->xmit_lock_owner = -1;
278 spin_unlock(&np->dev->xmit_lock); 280 spin_unlock(&np->dev->xmit_lock);
279 netpoll_poll(np); 281 netpoll_poll(np);
282 udelay(50);
280 continue; 283 continue;
281 } 284 }
282 285
@@ -285,12 +288,15 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
285 spin_unlock(&np->dev->xmit_lock); 288 spin_unlock(&np->dev->xmit_lock);
286 289
287 /* success */ 290 /* success */
288 if(!status) 291 if(!status) {
292 npinfo->tries = MAX_RETRIES; /* reset */
289 return; 293 return;
294 }
290 295
291 /* transmit busy */ 296 /* transmit busy */
292 netpoll_poll(np); 297 netpoll_poll(np);
293 } 298 udelay(50);
299 } while (npinfo->tries > 0);
294} 300}
295 301
296void netpoll_send_udp(struct netpoll *np, const char *msg, int len) 302void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
@@ -642,6 +648,7 @@ int netpoll_setup(struct netpoll *np)
642 npinfo->rx_np = NULL; 648 npinfo->rx_np = NULL;
643 npinfo->poll_lock = SPIN_LOCK_UNLOCKED; 649 npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
644 npinfo->poll_owner = -1; 650 npinfo->poll_owner = -1;
651 npinfo->tries = MAX_RETRIES;
645 npinfo->rx_lock = SPIN_LOCK_UNLOCKED; 652 npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
646 } else 653 } else
647 npinfo = ndev->npinfo; 654 npinfo = ndev->npinfo;