Skip to content

Commit 93ec2c7

Browse files
Stephen HemmingerDavid S. Miller
authored andcommitted
netpoll info leak
After looking harder, Steve noticed that the netpoll beast leaked a little every time it shutdown for a nap. Not a big leak, but a nuisance kind of thing. He took out his refcount duct tape and patched the leak. It was overkill since there was already other locking in that area, but it looked clean and wouldn't attract fleas. Signed-off-by: Stephen Hemminger <[email protected]>
1 parent a1bcfac commit 93ec2c7

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

include/linux/netpoll.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct netpoll {
2525
};
2626

2727
struct netpoll_info {
28+
atomic_t refcnt;
2829
spinlock_t poll_lock;
2930
int poll_owner;
3031
int tries;

net/core/netpoll.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,11 @@ int netpoll_setup(struct netpoll *np)
658658
npinfo->tries = MAX_RETRIES;
659659
spin_lock_init(&npinfo->rx_lock);
660660
skb_queue_head_init(&npinfo->arp_tx);
661-
} else
661+
atomic_set(&npinfo->refcnt, 1);
662+
} else {
662663
npinfo = ndev->npinfo;
664+
atomic_inc(&npinfo->refcnt);
665+
}
663666

664667
if (!ndev->poll_controller) {
665668
printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
@@ -766,12 +769,22 @@ void netpoll_cleanup(struct netpoll *np)
766769

767770
if (np->dev) {
768771
npinfo = np->dev->npinfo;
769-
if (npinfo && npinfo->rx_np == np) {
770-
spin_lock_irqsave(&npinfo->rx_lock, flags);
771-
npinfo->rx_np = NULL;
772-
npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
773-
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
772+
if (npinfo) {
773+
if (npinfo->rx_np == np) {
774+
spin_lock_irqsave(&npinfo->rx_lock, flags);
775+
npinfo->rx_np = NULL;
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+
}
774786
}
787+
775788
dev_put(np->dev);
776789
}
777790

0 commit comments

Comments
 (0)