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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).