aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/netpoll.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b9d9da082af2..59ed186e4f46 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -248,14 +248,14 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
248 int status; 248 int status;
249 struct netpoll_info *npinfo; 249 struct netpoll_info *npinfo;
250 250
251repeat: 251 if (!np || !np->dev || !netif_running(np->dev)) {
252 if(!np || !np->dev || !netif_running(np->dev)) {
253 __kfree_skb(skb); 252 __kfree_skb(skb);
254 return; 253 return;
255 } 254 }
256 255
257 /* avoid recursion */
258 npinfo = np->dev->npinfo; 256 npinfo = np->dev->npinfo;
257
258 /* avoid recursion */
259 if (npinfo->poll_owner == smp_processor_id() || 259 if (npinfo->poll_owner == smp_processor_id() ||
260 np->dev->xmit_lock_owner == smp_processor_id()) { 260 np->dev->xmit_lock_owner == smp_processor_id()) {
261 if (np->drop) 261 if (np->drop)
@@ -265,29 +265,31 @@ repeat:
265 return; 265 return;
266 } 266 }
267 267
268 spin_lock(&np->dev->xmit_lock); 268 while (1) {
269 np->dev->xmit_lock_owner = smp_processor_id(); 269 spin_lock(&np->dev->xmit_lock);
270 np->dev->xmit_lock_owner = smp_processor_id();
270 271
271 /* 272 /*
272 * network drivers do not expect to be called if the queue is 273 * network drivers do not expect to be called if the queue is
273 * stopped. 274 * stopped.
274 */ 275 */
275 if (netif_queue_stopped(np->dev)) { 276 if (netif_queue_stopped(np->dev)) {
277 np->dev->xmit_lock_owner = -1;
278 spin_unlock(&np->dev->xmit_lock);
279 netpoll_poll(np);
280 continue;
281 }
282
283 status = np->dev->hard_start_xmit(skb, np->dev);
276 np->dev->xmit_lock_owner = -1; 284 np->dev->xmit_lock_owner = -1;
277 spin_unlock(&np->dev->xmit_lock); 285 spin_unlock(&np->dev->xmit_lock);
278 286
279 netpoll_poll(np); 287 /* success */
280 goto repeat; 288 if(!status)
281 } 289 return;
282
283 status = np->dev->hard_start_xmit(skb, np->dev);
284 np->dev->xmit_lock_owner = -1;
285 spin_unlock(&np->dev->xmit_lock);
286 290
287 /* transmit busy */ 291 /* transmit busy */
288 if(status) {
289 netpoll_poll(np); 292 netpoll_poll(np);
290 goto repeat;
291 } 293 }
292} 294}
293 295