Skip to content

Commit a88a7be

Browse files
committed
Merge branch 'mdio_module_unload'
Ezequiel Garcia says: ==================== net: phy: Prevent an MDIO bus from being unloaded while in use Changes from v1: * Dropped the unneeded module_put() on phy_attach_direct(). The motivation of this small series is to fix the current lack of relationship between an ethernet driver and the MDIO bus behind the PHY device. In such cases, we would find no visible link between the drivers: $ lsmod Module Size Used by Not tainted mvmdio 2941 0 mvneta 22069 0 Which means nothing prevents the MDIO driver from being removed: $ modprobe -r mvmdio # Unable to handle kernel NULL pointer dereference at virtual address 00000060 pgd = c0004000 [00000060] *pgd=00000000 Internal error: Oops: 17 [#1] SMP ARM Modules linked in: mvneta [last unloaded: mvmdio] CPU: 0 PID: 22 Comm: kworker/0:1 Not tainted 3.16.0-rc5-01127-g62c0816-dirty #608 Workqueue: events_power_efficient phy_state_machine task: df5ec840 ti: df67a000 task.ti: df67a000 PC is at phy_state_machine+0x1c/0x468 LR is at phy_state_machine+0x18/0x468 [snip] This patchset fixes this problem by adding a pair of module_{get,put}, so the module reference count is increased when the PHY device is attached and is decreased when the PHY is detached. Tested with mvneta and mv643xx_eth drivers, which depend on the mvmdio driver to handle MDIO. This series applies on both net and net-next branches. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 042d765 + b3565f2 commit a88a7be

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

drivers/net/phy/mdio_bus.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ int mdiobus_register(struct mii_bus *bus)
255255

256256
bus->dev.parent = bus->parent;
257257
bus->dev.class = &mdio_bus_class;
258+
bus->dev.driver = bus->parent->driver;
258259
bus->dev.groups = NULL;
259260
dev_set_name(&bus->dev, "%s", bus->id);
260261

drivers/net/phy/phy_device.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
575575
u32 flags, phy_interface_t interface)
576576
{
577577
struct device *d = &phydev->dev;
578+
struct module *bus_module;
578579
int err;
579580

580581
/* Assume that if there is no driver, that it doesn't
@@ -599,6 +600,14 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
599600
return -EBUSY;
600601
}
601602

603+
/* Increment the bus module reference count */
604+
bus_module = phydev->bus->dev.driver ?
605+
phydev->bus->dev.driver->owner : NULL;
606+
if (!try_module_get(bus_module)) {
607+
dev_err(&dev->dev, "failed to get the bus module\n");
608+
return -EIO;
609+
}
610+
602611
phydev->attached_dev = dev;
603612
dev->phydev = phydev;
604613

@@ -664,6 +673,10 @@ EXPORT_SYMBOL(phy_attach);
664673
void phy_detach(struct phy_device *phydev)
665674
{
666675
int i;
676+
677+
if (phydev->bus->dev.driver)
678+
module_put(phydev->bus->dev.driver->owner);
679+
667680
phydev->attached_dev->phydev = NULL;
668681
phydev->attached_dev = NULL;
669682
phy_suspend(phydev);

0 commit comments

Comments
 (0)