Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300 board)
and bcmgenet.
Thanks!
drivers/net/phy/phy_device.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
@@ -857,11 +857,17 @@ EXPORT_SYMBOL(phy_attached_print);intphy_attach_direct(structnet_device*dev,structphy_device*phydev,u32flags,phy_interface_tinterface){+structmodule*ndev_owner=dev->dev.parent->driver->owner;structmii_bus*bus=phydev->mdio.bus;structdevice*d=&phydev->mdio.dev;interr;-if(!try_module_get(bus->owner)){+/* For Ethernet device drivers that register their own MDIO bus, we+*willhavebus->ownermatchndev_mod,sowedonotwanttoincrement+*ourownmodule->refcnthere,otherwisewewouldnotbeableto+*unloadlateron.+*/+if(ndev_owner!=bus->owner&&!try_module_get(bus->owner)){dev_err(&dev->dev,"failed to get the bus module\n");return-EIO;}
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
From: Johan Hovold <johan@kernel.org> Date: 2016-12-08 16:27:37
On Tue, Dec 06, 2016 at 08:54:43PM -0800, Florian Fainelli wrote:
quoted hunk
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300 board)
and bcmgenet.
Thanks!
drivers/net/phy/phy_device.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Is this really safe? A driver does not need to set a parent device, and
in that case you get a NULL-deref here (I tried using cpsw).
struct mii_bus *bus = phydev->mdio.bus;
struct device *d = &phydev->mdio.dev;
int err;
- if (!try_module_get(bus->owner)) {
+ /* For Ethernet device drivers that register their own MDIO bus, we
+ * will have bus->owner match ndev_mod, so we do not want to increment
You also wanted s/ndev_mod/ndev_owner/ here.
+ * our own module->refcnt here, otherwise we would not be able to
+ * unload later on.
+ */
+ if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
dev_err(&dev->dev, "failed to get the bus module\n");
return -EIO;
On Tue, Dec 06, 2016 at 08:54:43PM -0800, Florian Fainelli wrote:
quoted
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300 board)
and bcmgenet.
Thanks!
drivers/net/phy/phy_device.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Is this really safe? A driver does not need to set a parent device, and
in that case you get a NULL-deref here (I tried using cpsw).
Humm, cpsw does call SET_NETDEV_DEV() which should take care of that, is
the call made too late? Do you have an example oops?
I don't mind safeguarding this with a check against dev->dev.parent, but
I would like to fix the drivers where relevant too, since
SET_NETDEV_DEV() should really be called, otherwise a number of things
just don't work
quoted
struct mii_bus *bus = phydev->mdio.bus;
struct device *d = &phydev->mdio.dev;
int err;
- if (!try_module_get(bus->owner)) {
+ /* For Ethernet device drivers that register their own MDIO bus, we
+ * will have bus->owner match ndev_mod, so we do not want to increment
You also wanted s/ndev_mod/ndev_owner/ here.
Meh, it's merged now, but thanks, I will fix this once we find out the
proper solution for cpsw.
--
Florian
From: Johan Hovold <johan@kernel.org> Date: 2016-12-08 17:01:23
On Thu, Dec 08, 2016 at 08:47:54AM -0800, Florian Fainelli wrote:
On 12/08/2016 08:27 AM, Johan Hovold wrote:
quoted
On Tue, Dec 06, 2016 at 08:54:43PM -0800, Florian Fainelli wrote:
quoted
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300 board)
and bcmgenet.
Thanks!
drivers/net/phy/phy_device.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Is this really safe? A driver does not need to set a parent device, and
in that case you get a NULL-deref here (I tried using cpsw).
Humm, cpsw does call SET_NETDEV_DEV() which should take care of that, is
the call made too late? Do you have an example oops?
Sorry if I was being unclear, cpsw does set a parent device, but there
are network driver that do not. Perhaps such drivers will never hit this
code path, but I can't say for sure and everything appear to work for
cpsw if you comment out that SET_NETDEV_DEV (well, at least before this
patch).
I don't mind safeguarding this with a check against dev->dev.parent, but
I would like to fix the drivers where relevant too, since
SET_NETDEV_DEV() should really be called, otherwise a number of things
just don't work
I grepped for for register_netdev and think I saw a number of drivers
which do not call SET_NETDEV_DEV.
Again, perhaps they will never hit this path, but thought I should ask.
Johan
On Thu, Dec 08, 2016 at 08:47:54AM -0800, Florian Fainelli wrote:
quoted
On 12/08/2016 08:27 AM, Johan Hovold wrote:
quoted
On Tue, Dec 06, 2016 at 08:54:43PM -0800, Florian Fainelli wrote:
quoted
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way we
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any removal.
Fix this by comparing the network device's device driver owner against
the MDIO bus driver owner, and only if they are different, increment the
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300 board)
and bcmgenet.
Thanks!
drivers/net/phy/phy_device.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Is this really safe? A driver does not need to set a parent device, and
in that case you get a NULL-deref here (I tried using cpsw).
Humm, cpsw does call SET_NETDEV_DEV() which should take care of that, is
the call made too late? Do you have an example oops?
Sorry if I was being unclear, cpsw does set a parent device, but there
are network driver that do not. Perhaps such drivers will never hit this
code path, but I can't say for sure and everything appear to work for
cpsw if you comment out that SET_NETDEV_DEV (well, at least before this
patch).
You were clear, I did not understand that you exercised this with cpsw
to see whether this was safe in all conditions.
quoted
I don't mind safeguarding this with a check against dev->dev.parent, but
I would like to fix the drivers where relevant too, since
SET_NETDEV_DEV() should really be called, otherwise a number of things
just don't work
I grepped for for register_netdev and think I saw a number of drivers
which do not call SET_NETDEV_DEV.
Again, perhaps they will never hit this path, but thought I should ask.
You are absolutely right, this is a potential problem, so far I found
two legitimate drivers that do not call SET_NETDEV_DEV (lantiq_etop.c
and cpmac.c, both fixed), and Freescale's FMAN driver, which I have a
hard time understanding what it does with mac_dev->net_dev...
Thanks!
--
Florian
From: netdev-owner@vger.kernel.org On Behalf Of Florian Fainelli
Sent: Thursday, December 08, 2016 7:54 PM
To: Johan Hovold <johan@kernel.org>
On 12/08/2016 09:01 AM, Johan Hovold wrote:
quoted
On Thu, Dec 08, 2016 at 08:47:54AM -0800, Florian Fainelli wrote:
quoted
On 12/08/2016 08:27 AM, Johan Hovold wrote:
quoted
On Tue, Dec 06, 2016 at 08:54:43PM -0800, Florian Fainelli wrote:
quoted
Commit 3e3aaf649416 ("phy: fix mdiobus module safety") fixed the way
we
quoted
quoted
quoted
quoted
dealt with MDIO bus module reference count, but sort of introduced a
regression in that, if an Ethernet driver registers its own MDIO bus
driver, as is common, we will end up with the Ethernet driver's
module->refnct set to 1, thus preventing this driver from any
removal.
quoted
quoted
quoted
quoted
Fix this by comparing the network device's device driver owner
against
quoted
quoted
quoted
quoted
the MDIO bus driver owner, and only if they are different, increment
the
quoted
quoted
quoted
quoted
MDIO bus module refcount.
Fixes: 3e3aaf649416 ("phy: fix mdiobus module safety")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Russell,
I verified this against the ethoc driver primarily (on a TS7300
Is this really safe? A driver does not need to set a parent device,
and
quoted
quoted
quoted
in that case you get a NULL-deref here (I tried using cpsw).
Humm, cpsw does call SET_NETDEV_DEV() which should take care of that,
is
quoted
quoted
the call made too late? Do you have an example oops?
Sorry if I was being unclear, cpsw does set a parent device, but there
are network driver that do not. Perhaps such drivers will never hit this
code path, but I can't say for sure and everything appear to work for
cpsw if you comment out that SET_NETDEV_DEV (well, at least before this
patch).
You were clear, I did not understand that you exercised this with cpsw
to see whether this was safe in all conditions.
quoted
quoted
I don't mind safeguarding this with a check against dev->dev.parent,
but
quoted
quoted
I would like to fix the drivers where relevant too, since
SET_NETDEV_DEV() should really be called, otherwise a number of things
just don't work
I grepped for for register_netdev and think I saw a number of drivers
which do not call SET_NETDEV_DEV.
Again, perhaps they will never hit this path, but thought I should ask.
You are absolutely right, this is a potential problem, so far I found
two legitimate drivers that do not call SET_NETDEV_DEV (lantiq_etop.c
and cpmac.c, both fixed), and Freescale's FMAN driver, which I have a
hard time understanding what it does with mac_dev->net_dev...
Thanks!
--
Florian
Hi Florian,
The Freescale DPAA Ethernet driver is in drivers/net/ethernet/freescale/dpaa:
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:2501: SET_NETDEV_DEV(net_dev, dev);
and it is making use of the MAC and ports driver in the FMan driver (and of the
QBMan drivers in drivers/soc/fsl/qbman but that's off topic). You need to look
at the net-next tree for this, the drivers were gradually added.
Madalin