From: "Gao Feng" <gfree.wind@foxmail.com>
To: "'David Miller'" <davem@davemloft.net>
Cc: <jiri@resnulli.us>, <mareklindner@neomailbox.ch>,
<sw@simonwunderlich.de>, <a@unstable.cc>, <kuznet@ms2.inr.ac.ru>,
<jmorris@namei.org>, <yoshfuji@linux-ipv6.org>, <kaber@trash.net>,
<steffen.klassert@secunet.com>, <herbert@gondor.apana.org.au>,
<netdev@vger.kernel.org>
Subject: RE: [PATCH net v4 00/12] Fix possbile memleaks when fail to register_netdevice
Date: Mon, 8 May 2017 12:18:44 +0800 [thread overview]
Message-ID: <004f01d2c7b2$2f951050$8ebf30f0$@foxmail.com> (raw)
In-Reply-To: <20170507.182550.695836233888168365.davem@davemloft.net>
Hi David,
> From: David Miller [mailto:davem@davemloft.net]
> From: gfree.wind@foxmail.com
> Date: Tue, 2 May 2017 13:58:42 +0800
>
> > These following drivers allocate kinds of resources in its ndo_init
> > func, free some of them or all in the destructor func. Then there is
> > one memleak that some errors happen after register_netdevice invokes
> > the ndo_init callback. Because only the ndo_uninit callback is invoked
> > in the error handler of register_netdevice, but destructor not.
> >
> > In my original approach, I tried to free the resources in the newlink
> > func when fail to register_netdevice, like destructor did except not
> > free the net_dev. This method is not good when destructor is changed,
> > and the memleak could be not fixed when there is no newlink callback.
> >
> > Now create one new func used to free the resources in the destructor,
> > and the ndo_uninit func also could invokes it when fail to register
> > the net_device by comparing the dev->reg_state with
> > NETREG_UNINITIALIZED. If there is no existing ndo_uninit, just add
> > one.
> >
> > This solution doesn't only make sure free all resources in any case,
> > but also follows the original desgin that some resources could be kept
> > until the destructor executes normally after register the device
> > successfully.
>
> Device private teardown is in two stages for the following reason.
> The issue is that netdev_ops->ndo_init() allocates two types of resources.
>
> One type is OK to release during destruction before the netdev refs goes
to
> zero. This is what netdev_ops->ndo_uninit() is for.
>
> The second type is for releasing things which are not safe to drop until
the very
> last netdev reference disappears. This is what
> netdev->destructor() is for.
>
> If you look around there are hacks in place all over to try and deal with
this
> issue. Basically, look for code that checks the return value of
> register_netdev() and if an error is indicated it does some local driver
state
> freeing. Bonding is one example. It is trying to deal with the problem
this
> patch set is targetting.
Yes. When I was fixing this bug, I had found the bond had deal with this
issue, frees the resources by itself.
>
> What really needs to happen is we must divorce the logic of
> dev->destructor() from free_netdev().
>
> That way we can do the free_netdev in the unregister netdevice path after
> calling netdev->destructor().
>
> Then the only issue callers of register_netdevice() need to be aware of is
that if
> an error is returned, that caller must call free_netdev(). Which has been
the
> case for decades.
>
> So I would fix this as follows:
>
> 1) Rename netdev->destructor() into "netdev->priv_destructor()" It
> performs all post ndo_ops->ndo_uninit() cleanups, _except_
> free_netdev(). Update all drivers with netdev->destructor().
>
> 2) Add a boolean state to netdev, which indicates if free_netdev()
> should be performed after netdev->priv_destructor() during
> unregister.
>
> That provides all of the flexibility necessary to fix this bug in the
core.
>
> In register_netdevice() if something after ndo_ops->ndo_init() succeeeds,
we
> invoke _both_ ndo_ops->ndo_uninit() and
> netdev->priv_destructor(). We do not look at the netdev "needs
> free_netdev()" boolean.
>
> In netdev_run_todo(), where we have the one and only
> netdev->destructor() call, change it to:
>
> if (dev->priv_destructor)
> dev->priv_destructor(dev);
> if (dev->needs_free_netdev)
> free_netdev(dev);
>
> That fixes the bug in all cases. And makes the purpose and logic
extremely
> clear. Also, no internal state tests leak into the drivers.
>
> Finally, drivers that try to cover up this issue, such as bonding, need to
be
> changed to no try and free up device private state if their invocation of
> register_netdevice() fails.
>
> Thanks.
Ok. It is better to fix it by changing the framework of net_dev.
I was afraid that I would bring other bugs if I changed it.
Because it would affect too many codes.
I would like to see you fix it by yourself.
Best Regards
Feng
prev parent reply other threads:[~2017-05-08 4:19 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-02 5:58 [PATCH net v4 00/12] Fix possbile memleaks when fail to register_netdevice gfree.wind
2017-05-02 5:58 ` [PATCH net v4 01/12] driver: dummy: Fix one possbile memleak " gfree.wind
2017-05-02 5:58 ` [PATCH net v4 02/12] driver: ifb: " gfree.wind
2017-05-02 5:58 ` [PATCH net v4 03/12] driver: loopback: " gfree.wind
2017-05-02 5:58 ` [PATCH net v4 04/12] driver: team: " gfree.wind
2017-05-02 5:58 ` [PATCH net v4 05/12] driver: veth: " gfree.wind
2017-05-02 5:58 ` [PATCH net v4 06/12] net: ip6_gre: " gfree.wind
2017-05-02 6:59 ` [PATCH net v4 07/12] ip6_tunnel: " gfree.wind
2017-05-02 11:10 ` [PATCH net v4 00/12] Fix possbile memleaks " Gao Feng
2017-05-02 13:34 ` [PATCH net v4 08/12] net: ip6_vti: Fix one possbile memleak " gfree.wind
2017-05-02 13:37 ` [PATCH net v4 09/12] net: ip_tunnel: " gfree.wind
2017-05-02 13:39 ` [PATCH net v4 10/12] net: sit: " gfree.wind
2017-05-02 13:41 ` [PATCH net v4 11/12] net: vlan: " gfree.wind
2017-05-02 14:17 ` [PATCH net v4 12/12] net: batman-adv: " gfree.wind
2017-05-02 19:30 ` [PATCH net v4 00/12] Fix possbile memleaks " David Miller
2017-05-03 0:33 ` Gao Feng
2017-05-07 22:25 ` David Miller
2017-05-08 4:18 ` Gao Feng [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='004f01d2c7b2$2f951050$8ebf30f0$@foxmail.com' \
--to=gfree.wind@foxmail.com \
--cc=a@unstable.cc \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=jiri@resnulli.us \
--cc=jmorris@namei.org \
--cc=kaber@trash.net \
--cc=kuznet@ms2.inr.ac.ru \
--cc=mareklindner@neomailbox.ch \
--cc=netdev@vger.kernel.org \
--cc=steffen.klassert@secunet.com \
--cc=sw@simonwunderlich.de \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.