diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/netpoll.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 4de62f1f4134..c66df2f45d26 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -658,8 +658,11 @@ int netpoll_setup(struct netpoll *np) | |||
658 | npinfo->tries = MAX_RETRIES; | 658 | npinfo->tries = MAX_RETRIES; |
659 | spin_lock_init(&npinfo->rx_lock); | 659 | spin_lock_init(&npinfo->rx_lock); |
660 | skb_queue_head_init(&npinfo->arp_tx); | 660 | skb_queue_head_init(&npinfo->arp_tx); |
661 | } else | 661 | atomic_set(&npinfo->refcnt, 1); |
662 | } else { | ||
662 | npinfo = ndev->npinfo; | 663 | npinfo = ndev->npinfo; |
664 | atomic_inc(&npinfo->refcnt); | ||
665 | } | ||
663 | 666 | ||
664 | if (!ndev->poll_controller) { | 667 | if (!ndev->poll_controller) { |
665 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 668 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
@@ -766,12 +769,22 @@ void netpoll_cleanup(struct netpoll *np) | |||
766 | 769 | ||
767 | if (np->dev) { | 770 | if (np->dev) { |
768 | npinfo = np->dev->npinfo; | 771 | npinfo = np->dev->npinfo; |
769 | if (npinfo && npinfo->rx_np == np) { | 772 | if (npinfo) { |
770 | spin_lock_irqsave(&npinfo->rx_lock, flags); | 773 | if (npinfo->rx_np == np) { |
771 | npinfo->rx_np = NULL; | 774 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
772 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | 775 | npinfo->rx_np = NULL; |
773 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | 776 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; |
777 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
778 | } | ||
779 | |||
780 | np->dev->npinfo = NULL; | ||
781 | if (atomic_dec_and_test(&npinfo->refcnt)) { | ||
782 | skb_queue_purge(&npinfo->arp_tx); | ||
783 | |||
784 | kfree(npinfo); | ||
785 | } | ||
774 | } | 786 | } |
787 | |||
775 | dev_put(np->dev); | 788 | dev_put(np->dev); |
776 | } | 789 | } |
777 | 790 | ||