public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber•org>
To: David Miller <davem@davemloft•net>
Cc: netdev@vger•kernel.org
Subject: Re: [PATCH RFC] net: Fix inconsistent teardown and release of private netdev state.
Date: Mon, 8 May 2017 12:13:59 -0700	[thread overview]
Message-ID: <20170508121359.45e367e5@xeon-e3> (raw)
In-Reply-To: <20170508.125243.1637135196896174683.davem@davemloft.net>

On Mon, 08 May 2017 12:52:43 -0400 (EDT)
David Miller <davem@davemloft•net> wrote:

> Network devices can allocate reasources and private memory using
> netdev_ops->ndo_init().  However, the release of these resources
> can occur in one of two different places.
> 
> Either netdev_ops->ndo_uninit() or netdev->destructor().
> 
> The decision of which operation frees the resources depends upon
> whether it is necessary for all netdev refs to be released before it
> is safe to perform the freeing.
> 
> netdev_ops->ndo_uninit() presumably can occur right after the
> NETDEV_UNREGISTER notifier completes and the unicast and multicast
> address lists are flushed.
> 
> netdev->destructor(), on the other hand, does not run until the
> netdev references all go away.
> 
> Further complicating the situation is that netdev->destructor()
> almost universally does also a free_netdev().
> 
> This creates a problem for the logic in register_netdevice().
> Because all callers of register_netdevice() manage the freeing
> of the netdev, and invoke free_netdev(dev) if register_netdevice()
> fails.
> 
> If netdev_ops->ndo_init() succeeds, but something else fails inside
> of register_netdevice(), it does call ndo_ops->ndo_uninit().  But
> it is not able to invoke netdev->destructor().
> 
> This is because netdev->destructor() will do a free_netdev() and
> then the caller of register_netdevice() will do the same.
> 
> However, this means that the resources that would normally be released
> by netdev->destructor() will not be.
> 
> Over the years drivers have added local hacks to deal with this, by
> invoking their destructor parts by hand when register_netdevice()
> fails.
> 
> Many drivers do not try to deal with this, and instead we have leaks.
> 
> Let's close this hole by formalizing the distinction between what
> private things need to be freed up by netdev->destructor() and whether
> the driver needs unregister_netdevice() to perform the free_netdev().
> 
> netdev->priv_destructor() performs all actions to free up the private
> resources that used to be freed by netdev->destructor(), except for
> free_netdev().
> 
> netdev->needs_free_netdev is a boolean that indicates whether
> free_netdev() should be done at the end of unregister_netdevice().
> 
> Now, register_netdevice() can sanely release all resources after
> ndo_ops->ndo_init() succeeds, by invoking both ndo_ops->ndo_uninit()
> and netdev->priv_destructor().
> 
> And at the end of unregister_netdevice(), we invoke
> netdev->priv_destructor() and optionally call free_netdev().
> 
> Signed-off-by: David S. Miller <davem@davemloft•net>
> 

Thanks for addressing a confusing and messy semantic. If you merge
this then it would be good to update the documentation in Doucmentation/networking
to describe how drivers are supposed to behave.

The original semantics here evolved from a desire not to have to re-engineer
lots of device drivers. And your change does the same; ie. assume that there
is a reason the device needs special treatment on unregister.

An alternative and more difficult way of addressing the problem would
be to rework the drivers that define destructors to work with the simpler
model used by all the other drivers. What makes these drivers special,
and can they be fixed instead. Probably this won't work and would be too
much effort on lots of little used devices.

  reply	other threads:[~2017-05-08 19:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-08 16:52 [PATCH RFC] net: Fix inconsistent teardown and release of private netdev state David Miller
2017-05-08 19:13 ` Stephen Hemminger [this message]
2017-05-08 19:21   ` David Miller

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=20170508121359.45e367e5@xeon-e3 \
    --to=stephen@networkplumber$(echo .)org \
    --cc=davem@davemloft$(echo .)net \
    --cc=netdev@vger$(echo .)kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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