diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/netpoll.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index ab3c0c9713b0..c327c9edadc5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -349,11 +349,15 @@ static void arp_reply(struct sk_buff *skb) | |||
349 | unsigned char *arp_ptr; | 349 | unsigned char *arp_ptr; |
350 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; | 350 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; |
351 | u32 sip, tip; | 351 | u32 sip, tip; |
352 | unsigned long flags; | ||
352 | struct sk_buff *send_skb; | 353 | struct sk_buff *send_skb; |
353 | struct netpoll *np = NULL; | 354 | struct netpoll *np = NULL; |
354 | 355 | ||
355 | if (npinfo) | 356 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
356 | np = npinfo->np; | 357 | if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev) |
358 | np = npinfo->rx_np; | ||
359 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
360 | |||
357 | if (!np) | 361 | if (!np) |
358 | return; | 362 | return; |
359 | 363 | ||
@@ -436,9 +440,9 @@ int __netpoll_rx(struct sk_buff *skb) | |||
436 | int proto, len, ulen; | 440 | int proto, len, ulen; |
437 | struct iphdr *iph; | 441 | struct iphdr *iph; |
438 | struct udphdr *uh; | 442 | struct udphdr *uh; |
439 | struct netpoll *np = skb->dev->npinfo->np; | 443 | struct netpoll *np = skb->dev->npinfo->rx_np; |
440 | 444 | ||
441 | if (!np->rx_hook) | 445 | if (!np) |
442 | goto out; | 446 | goto out; |
443 | if (skb->dev->type != ARPHRD_ETHER) | 447 | if (skb->dev->type != ARPHRD_ETHER) |
444 | goto out; | 448 | goto out; |
@@ -619,6 +623,7 @@ int netpoll_setup(struct netpoll *np) | |||
619 | struct net_device *ndev = NULL; | 623 | struct net_device *ndev = NULL; |
620 | struct in_device *in_dev; | 624 | struct in_device *in_dev; |
621 | struct netpoll_info *npinfo; | 625 | struct netpoll_info *npinfo; |
626 | unsigned long flags; | ||
622 | 627 | ||
623 | if (np->dev_name) | 628 | if (np->dev_name) |
624 | ndev = dev_get_by_name(np->dev_name); | 629 | ndev = dev_get_by_name(np->dev_name); |
@@ -634,9 +639,10 @@ int netpoll_setup(struct netpoll *np) | |||
634 | if (!npinfo) | 639 | if (!npinfo) |
635 | goto release; | 640 | goto release; |
636 | 641 | ||
637 | npinfo->np = NULL; | 642 | npinfo->rx_np = NULL; |
638 | npinfo->poll_lock = SPIN_LOCK_UNLOCKED; | 643 | npinfo->poll_lock = SPIN_LOCK_UNLOCKED; |
639 | npinfo->poll_owner = -1; | 644 | npinfo->poll_owner = -1; |
645 | npinfo->rx_lock = SPIN_LOCK_UNLOCKED; | ||
640 | } else | 646 | } else |
641 | npinfo = ndev->npinfo; | 647 | npinfo = ndev->npinfo; |
642 | 648 | ||
@@ -706,9 +712,13 @@ int netpoll_setup(struct netpoll *np) | |||
706 | np->name, HIPQUAD(np->local_ip)); | 712 | np->name, HIPQUAD(np->local_ip)); |
707 | } | 713 | } |
708 | 714 | ||
709 | if(np->rx_hook) | 715 | if (np->rx_hook) { |
710 | npinfo->rx_flags = NETPOLL_RX_ENABLED; | 716 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
711 | npinfo->np = np; | 717 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; |
718 | npinfo->rx_np = np; | ||
719 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
720 | } | ||
721 | /* last thing to do is link it to the net device structure */ | ||
712 | ndev->npinfo = npinfo; | 722 | ndev->npinfo = npinfo; |
713 | 723 | ||
714 | return 0; | 724 | return 0; |
@@ -723,11 +733,20 @@ int netpoll_setup(struct netpoll *np) | |||
723 | 733 | ||
724 | void netpoll_cleanup(struct netpoll *np) | 734 | void netpoll_cleanup(struct netpoll *np) |
725 | { | 735 | { |
736 | struct netpoll_info *npinfo; | ||
737 | unsigned long flags; | ||
738 | |||
726 | if (np->dev) { | 739 | if (np->dev) { |
727 | if (np->dev->npinfo) | 740 | npinfo = np->dev->npinfo; |
728 | np->dev->npinfo->np = NULL; | 741 | if (npinfo && npinfo->rx_np == np) { |
742 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
743 | npinfo->rx_np = NULL; | ||
744 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | ||
745 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
746 | } | ||
729 | dev_put(np->dev); | 747 | dev_put(np->dev); |
730 | } | 748 | } |
749 | |||
731 | np->dev = NULL; | 750 | np->dev = NULL; |
732 | } | 751 | } |
733 | 752 | ||