Skip to content

Commit ec988ad

Browse files
ffainellidavem330
authored andcommitted
phy: Don't increment MDIO bus refcount unless it's a different owner
Commit 3e3aaf6 ("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: 3e3aaf6 ("phy: fix mdiobus module safety") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a50af86 commit ec988ad

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

drivers/net/phy/phy_device.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,11 +857,17 @@ EXPORT_SYMBOL(phy_attached_print);
857857
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
858858
u32 flags, phy_interface_t interface)
859859
{
860+
struct module *ndev_owner = dev->dev.parent->driver->owner;
860861
struct mii_bus *bus = phydev->mdio.bus;
861862
struct device *d = &phydev->mdio.dev;
862863
int err;
863864

864-
if (!try_module_get(bus->owner)) {
865+
/* For Ethernet device drivers that register their own MDIO bus, we
866+
* will have bus->owner match ndev_mod, so we do not want to increment
867+
* our own module->refcnt here, otherwise we would not be able to
868+
* unload later on.
869+
*/
870+
if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
865871
dev_err(&dev->dev, "failed to get the bus module\n");
866872
return -EIO;
867873
}
@@ -921,7 +927,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
921927

922928
error:
923929
put_device(d);
924-
module_put(bus->owner);
930+
if (ndev_owner != bus->owner)
931+
module_put(bus->owner);
925932
return err;
926933
}
927934
EXPORT_SYMBOL(phy_attach_direct);
@@ -971,6 +978,8 @@ EXPORT_SYMBOL(phy_attach);
971978
*/
972979
void phy_detach(struct phy_device *phydev)
973980
{
981+
struct net_device *dev = phydev->attached_dev;
982+
struct module *ndev_owner = dev->dev.parent->driver->owner;
974983
struct mii_bus *bus;
975984
int i;
976985

@@ -998,7 +1007,8 @@ void phy_detach(struct phy_device *phydev)
9981007
bus = phydev->mdio.bus;
9991008

10001009
put_device(&phydev->mdio.dev);
1001-
module_put(bus->owner);
1010+
if (ndev_owner != bus->owner)
1011+
module_put(bus->owner);
10021012
}
10031013
EXPORT_SYMBOL(phy_detach);
10041014

0 commit comments

Comments
 (0)