Skip to content

Commit c718af2

Browse files
Russell Kingdavem330
authored andcommitted
net: phylink: fix ethtool -A with attached PHYs
Fix a phylink's ethtool set_pauseparam support deadlock caused by phylib interacting with phylink: we must not hold the state lock while calling phylib functions that may call into phylink_phy_change(). Fixes: f904f15 ("net: phylink: allow ethtool -A to change flow control advertisement") Signed-off-by: Russell King <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 41b14fb commit c718af2

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

drivers/net/phy/phylink.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,18 +1502,20 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
15021502
linkmode_set_pause(config->advertising, pause->tx_pause,
15031503
pause->rx_pause);
15041504

1505-
/* If we have a PHY, phylib will call our link state function if the
1506-
* mode has changed, which will trigger a resolve and update the MAC
1507-
* configuration.
1505+
if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
1506+
&pl->phylink_disable_state))
1507+
phylink_pcs_config(pl, true, &pl->link_config);
1508+
1509+
mutex_unlock(&pl->state_mutex);
1510+
1511+
/* If we have a PHY, a change of the pause frame advertisement will
1512+
* cause phylib to renegotiate (if AN is enabled) which will in turn
1513+
* call our phylink_phy_change() and trigger a resolve. Note that
1514+
* we can't hold our state mutex while calling phy_set_asym_pause().
15081515
*/
1509-
if (pl->phydev) {
1516+
if (pl->phydev)
15101517
phy_set_asym_pause(pl->phydev, pause->rx_pause,
15111518
pause->tx_pause);
1512-
} else if (!test_bit(PHYLINK_DISABLE_STOPPED,
1513-
&pl->phylink_disable_state)) {
1514-
phylink_pcs_config(pl, true, &pl->link_config);
1515-
}
1516-
mutex_unlock(&pl->state_mutex);
15171519

15181520
return 0;
15191521
}

0 commit comments

Comments
 (0)