Skip to content

Commit f0f2b99

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. Generic PHYs do not support LEDs anyway, so don't bother registering them. Fixes: 01e5b72 ("net: phy: Add a binding for PHY LEDs") Signed-off-by: Sean Anderson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e18f348 commit f0f2b99

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

drivers/net/phy/phy_device.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3416,7 +3416,8 @@ static int phy_probe(struct device *dev)
34163416
/* Get the LEDs from the device tree, and instantiate standard
34173417
* LEDs for them.
34183418
*/
3419-
if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
3419+
if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev) &&
3420+
!phy_driver_is_genphy_10g(phydev))
34203421
err = of_phy_leds(phydev);
34213422

34223423
out:
@@ -3433,7 +3434,8 @@ static int phy_remove(struct device *dev)
34333434

34343435
cancel_delayed_work_sync(&phydev->state_queue);
34353436

3436-
if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
3437+
if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev) &&
3438+
!phy_driver_is_genphy_10g(phydev))
34373439
phy_leds_unregister(phydev);
34383440

34393441
phydev->state = PHY_DOWN;

0 commit comments

Comments
 (0)