diff options
-rw-r--r-- | net/core/netpoll.c | 42 |
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 | ||
251 | repeat: | 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 | ||