Skip to content

Commit a44312d

Browse files
Sean Andersonkuba-moo
authored andcommitted
net: phy: Don't register LEDs for genphy
If a PHY has no driver, the genphy driver is probed/removed directly in phy_attach/detach. If the PHY's ofnode has an "leds" subnode, then the LEDs will be (un)registered when probing/removing the genphy driver. This could occur if the leds are for a non-generic driver that isn't loaded for whatever reason. Synchronously removing the PHY device in phy_detach leads to the following deadlock: rtnl_lock() ndo_close() ... phy_detach() phy_remove() phy_leds_unregister() led_classdev_unregister() led_trigger_set() netdev_trigger_deactivate() unregister_netdevice_notifier() rtnl_lock() There is a corresponding deadlock on the open/register side of things (and that one is reported by lockdep), but it requires a race while this one is deterministic. Regular drivers do not have this problem since they are probed asynchronously (without RTNL held). Generic PHYs do not support LEDs anyway, so don't bother registering them. [JakubL this is a net-next version of commit f0f2b99 ("net: phy: Don't register LEDs for genphy"), which uses APIs removed in -next.] Signed-off-by: Sean Anderson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent ff2ac4d commit a44312d

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/net/phy/phy_device.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,7 +3502,7 @@ static int phy_probe(struct device *dev)
35023502
/* Get the LEDs from the device tree, and instantiate standard
35033503
* LEDs for them.
35043504
*/
3505-
if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
3505+
if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev))
35063506
err = of_phy_leds(phydev);
35073507

35083508
out:
@@ -3519,7 +3519,7 @@ static int phy_remove(struct device *dev)
35193519

35203520
cancel_delayed_work_sync(&phydev->state_queue);
35213521

3522-
if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
3522+
if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev))
35233523
phy_leds_unregister(phydev);
35243524

35253525
phydev->state = PHY_DOWN;

0 commit comments

Comments
 (0)