From: Johan Hovold <johan@kernel.org>
To: Florian Fainelli <f.fainelli@gmail.com>
Cc: Johan Hovold <johan@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
Vivien Didelot <vivien.didelot@savoirfairelinux.com>,
"David S. Miller" <davem@davemloft.net>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net: dsa: fix fixed-link-phy device leaks
Date: Thu, 17 Nov 2016 10:52:25 +0100 [thread overview]
Message-ID: <20161117095225.GC21237@localhost> (raw)
In-Reply-To: <8387696c-813a-4c88-5f10-7d2e5fdae6b8@gmail.com>
On Wed, Nov 16, 2016 at 10:14:10AM -0800, Florian Fainelli wrote:
> On 11/16/2016 09:11 AM, Johan Hovold wrote:
> > On Wed, Nov 16, 2016 at 09:06:26AM -0800, Florian Fainelli wrote:
> >> On 11/16/2016 06:47 AM, Johan Hovold wrote:
> >>> Make sure to drop the reference taken by of_phy_find_device() when
> >>> registering and deregistering the fixed-link PHY-device.
> >>>
> >>> Note that we need to put both references held at deregistration.
> >>>
> >>> Fixes: 39b0c705195e ("net: dsa: Allow configuration of CPU & DSA port
> >>> speeds/duplex")
> >>> Signed-off-by: Johan Hovold <johan@kernel.org>
> >>> ---
> >>>
> >>> Hi,
> >>>
> >>> This is one has been compile tested only, but fixes a couple of leaks
> >>> similar to one that was found in the cpsw driver for which I just posted
> >>> a patch.
> >>>
> >>> It turns out all drivers but DSA fail to deregister the fixed-link PHYs
> >>> registered by of_phy_register_fixed_link(). Due to the way this
> >>> interface was designed, deregistering such a PHY is a bit cumbersome and
> >>> looks like it would benefit from a common helper.
> >>>
> >>> However, perhaps the interface should instead be changed so that the PHY
> >>> device is returned so that drivers do not need to use
> >>> of_phy_find_device() when they need to access properties of the fixed
> >>> link (e.g. as in dsu_cpu_dsa_setup below).
> >>>
> >>> Thoughts?
> >>>
> >>> Thanks,
> >>> Johan
> >>>
> >>>
> >>> net/dsa/dsa.c | 8 +++++++-
> >>> 1 file changed, 7 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> >>> index a6902c1e2f28..798a6a776a5f 100644
> >>> --- a/net/dsa/dsa.c
> >>> +++ b/net/dsa/dsa.c
> >>> @@ -233,6 +233,8 @@ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,
> >>> genphy_read_status(phydev);
> >>> if (ds->ops->adjust_link)
> >>> ds->ops->adjust_link(ds, port, phydev);
> >>> +
> >>> + phy_device_free(phydev); /* of_phy_find_device */
> >>> }
> >>>
> >>> return 0;
> >>> @@ -509,8 +511,12 @@ void dsa_cpu_dsa_destroy(struct device_node *port_dn)
> >>> if (of_phy_is_fixed_link(port_dn)) {
> >>> phydev = of_phy_find_device(port_dn);
> >>> if (phydev) {
> >>> - phy_device_free(phydev);
> >>> fixed_phy_unregister(phydev);
> >>> + /* Put references taken by of_phy_find_device() and
> >>> + * of_phy_register_fixed_link().
> >>> + */
> >>> + phy_device_free(phydev);
> >>> + phy_device_free(phydev);
> >>
> >> Double free, this looks bogus here. Actually would not this mean a
> >> triple free since you already free in dsa_cpu_dsa_setup() which is
> >> paired with dsa_cpu_dsa_destroy()?
> >
> > The naming of phy_device_free() is unfortunate when it's really a put():
> >
> > void phy_device_free(struct phy_device *phydev)
> > {
> > put_device(&phydev->mdio.dev);
> > }
>
> Indeed, should have looked a little harder.
>
> >
> > which may need to be called multiple times, specifically after a call to
> > of_phy_find_device() which takes another reference.
> >
> > With this patch the refcounts are properly balanced.
>
> The intent of your patch is good, but it still feels like having to
> double imbalance the refcount is symptomatic of a larger issue here, it
> does not seem like having several refcounts are necessary, so we may
> really want to rework the API.
I'll cook something up for -next, but how about using
put_device(&phydev->mdio.dev)
for the reference taken by of_phy_find_device() (as some driver
already do) to fix the immediate leaks?
Then deregistration would look like:
phydev = of_phy_find_device(port_dn);
if (phydev) {
- phy_device_free(phydev);
fixed_phy_unregister(phydev);
+ put_device(&phydev->mdio.dev)
+ phy_device_free(phydev);
Thanks,
Johan
next prev parent reply other threads:[~2016-11-17 9:52 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-16 14:47 [PATCH] net: dsa: fix fixed-link-phy device leaks Johan Hovold
2016-11-16 17:06 ` Florian Fainelli
2016-11-16 17:11 ` Johan Hovold
2016-11-16 18:14 ` Florian Fainelli
2016-11-17 9:52 ` Johan Hovold [this message]
2016-11-17 16:47 ` Johan Hovold
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=20161117095225.GC21237@localhost \
--to=johan@kernel.org \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=vivien.didelot@savoirfairelinux.com \
/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.