On Fri, Mar 25, 2016 at 07:33:42AM -0400, Neil Horman wrote: > On Thu, Mar 24, 2016 at 09:56:21PM -0500, Bjorn Helgaas wrote: > > netpoll_setup() does a dev_hold() on np->dev, the netpoll device. If it > > fails, it correctly does a dev_put() but leaves np->dev set. If we call > > netpoll_cleanup() after the failure, np->dev is still set so we do another > > dev_put(), which decrements the refcount an extra time. > > > > It's questionable to call netpoll_cleanup() after netpoll_setup() fails, > > but it can be difficult to find the problem, and we can easily avoid it in > > this case. The extra decrements can lead to hangs like this: > > > > unregister_netdevice: waiting for bond0 to become free. Usage count = -3 > > > > Set and clear np->dev at the points where we dev_hold() and dev_put() the > > device. > > > > Signed-off-by: Bjorn Helgaas <bhelg...@google.com> > > --- > > net/core/netpoll.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/net/core/netpoll.c b/net/core/netpoll.c > > index 94acfc8..a57bd17 100644 > > --- a/net/core/netpoll.c > > +++ b/net/core/netpoll.c > > @@ -603,7 +603,6 @@ int __netpoll_setup(struct netpoll *np, struct > > net_device *ndev) > > const struct net_device_ops *ops; > > int err; > > > > - np->dev = ndev; > > strlcpy(np->dev_name, ndev->name, IFNAMSIZ); > > INIT_WORK(&np->cleanup_work, netpoll_async_cleanup); > > > > @@ -670,6 +669,7 @@ int netpoll_setup(struct netpoll *np) > > goto unlock; > > } > > dev_hold(ndev); > > + np->dev = ndev; > > > > if (netdev_master_upper_dev_get(ndev)) { > > np_err(np, "%s is a slave device, aborting\n", np->dev_name); > > @@ -770,6 +770,7 @@ int netpoll_setup(struct netpoll *np) > > return 0; > > > > put: > > + np->dev = NULL; > > dev_put(ndev); > > unlock: > > rtnl_unlock(); > > > > Is this safe for stacked devices? It makes good sense for the typical case, > but > if you attempt to setup a netpoll client on a bridge/bond/vlan, etc, the lower > device will get its own netpoll struct registered and have no associated > np->dev > pointer. It not be a real problem in practice, But you probably want to check > to make sure that stacked devices which recursively call the netpoll api > don't > do anyting with the np->dev pointer.
You're right, there is an issue here. I reproduced a problem with a bond device. bond_netpoll_setup() calls __netpoll_setup() directly (not netpoll_setup()). I'll debug it more; just wanted to let you know there *is* a problem with this patch. Bjorn