* [PATCH net 1/2] net: phylink: fix ethtool -A with attached PHYs
2020-06-23 16:46 [PATCH net 0/2] Two phylink pause fixes Russell King - ARM Linux admin
@ 2020-06-23 16:47 ` Russell King
2020-06-23 16:47 ` [PATCH net 2/2] net: phylink: ensure manual pause mode configuration takes effect Russell King
2020-06-24 3:54 ` [PATCH net 0/2] Two phylink pause fixes David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Russell King @ 2020-06-23 16:47 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
Cc: David S. Miller, netdev, Jakub Kicinski
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: f904f15ea9b5 ("net: phylink: allow ethtool -A to change flow control advertisement")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 0ab65fb75258..453f9a399bb1 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1502,18 +1502,20 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
linkmode_set_pause(config->advertising, pause->tx_pause,
pause->rx_pause);
- /* If we have a PHY, phylib will call our link state function if the
- * mode has changed, which will trigger a resolve and update the MAC
- * configuration.
+ if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
+ &pl->phylink_disable_state))
+ phylink_pcs_config(pl, true, &pl->link_config);
+
+ mutex_unlock(&pl->state_mutex);
+
+ /* If we have a PHY, a change of the pause frame advertisement will
+ * cause phylib to renegotiate (if AN is enabled) which will in turn
+ * call our phylink_phy_change() and trigger a resolve. Note that
+ * we can't hold our state mutex while calling phy_set_asym_pause().
*/
- if (pl->phydev) {
+ if (pl->phydev)
phy_set_asym_pause(pl->phydev, pause->rx_pause,
pause->tx_pause);
- } else if (!test_bit(PHYLINK_DISABLE_STOPPED,
- &pl->phylink_disable_state)) {
- phylink_pcs_config(pl, true, &pl->link_config);
- }
- mutex_unlock(&pl->state_mutex);
return 0;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH net 2/2] net: phylink: ensure manual pause mode configuration takes effect
2020-06-23 16:46 [PATCH net 0/2] Two phylink pause fixes Russell King - ARM Linux admin
2020-06-23 16:47 ` [PATCH net 1/2] net: phylink: fix ethtool -A with attached PHYs Russell King
@ 2020-06-23 16:47 ` Russell King
2020-06-24 3:54 ` [PATCH net 0/2] Two phylink pause fixes David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Russell King @ 2020-06-23 16:47 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
Cc: David S. Miller, netdev, Jakub Kicinski
We have been relying on link events and mac_config() when the manual
pause modes are changed. With recent developments, such as moving
the programming of link state to mac_link_up(), this no longer works.
To ensure that we update the MAC, we must generate a link-down followed
by a link-up event; we can do that by setting mac_link_dropped and
triggering a resolve.
Fixes: 91a208f2185a ("net: phylink: propagate resolved link config via mac_link_up()")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 453f9a399bb1..3b7c70e6c5dd 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1463,6 +1463,8 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
struct ethtool_pauseparam *pause)
{
struct phylink_link_state *config = &pl->link_config;
+ bool manual_changed;
+ int pause_state;
ASSERT_RTNL();
@@ -1477,15 +1479,15 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
!pause->autoneg && pause->rx_pause != pause->tx_pause)
return -EINVAL;
- mutex_lock(&pl->state_mutex);
- config->pause = 0;
+ pause_state = 0;
if (pause->autoneg)
- config->pause |= MLO_PAUSE_AN;
+ pause_state |= MLO_PAUSE_AN;
if (pause->rx_pause)
- config->pause |= MLO_PAUSE_RX;
+ pause_state |= MLO_PAUSE_RX;
if (pause->tx_pause)
- config->pause |= MLO_PAUSE_TX;
+ pause_state |= MLO_PAUSE_TX;
+ mutex_lock(&pl->state_mutex);
/*
* See the comments for linkmode_set_pause(), wrt the deficiencies
* with the current implementation. A solution to this issue would
@@ -1502,6 +1504,12 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
linkmode_set_pause(config->advertising, pause->tx_pause,
pause->rx_pause);
+ manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN ||
+ (!(pause_state & MLO_PAUSE_AN) &&
+ (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK);
+
+ config->pause = pause_state;
+
if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
&pl->phylink_disable_state))
phylink_pcs_config(pl, true, &pl->link_config);
@@ -1517,6 +1525,15 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
phy_set_asym_pause(pl->phydev, pause->rx_pause,
pause->tx_pause);
+ /* If the manual pause settings changed, make sure we trigger a
+ * resolve to update their state; we can not guarantee that the
+ * link will cycle.
+ */
+ if (manual_changed) {
+ pl->mac_link_dropped = true;
+ phylink_run_resolve(pl);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH net 0/2] Two phylink pause fixes
2020-06-23 16:46 [PATCH net 0/2] Two phylink pause fixes Russell King - ARM Linux admin
2020-06-23 16:47 ` [PATCH net 1/2] net: phylink: fix ethtool -A with attached PHYs Russell King
2020-06-23 16:47 ` [PATCH net 2/2] net: phylink: ensure manual pause mode configuration takes effect Russell King
@ 2020-06-24 3:54 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2020-06-24 3:54 UTC (permalink / raw)
To: linux; +Cc: andrew, f.fainelli, hkallweit1, kuba, netdev
From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
Date: Tue, 23 Jun 2020 17:46:42 +0100
> While testing, I discovered two issues with ethtool -A with phylink.
> First, if there is a PHY bound to the network device, we hit a
> deadlock when phylib tries to notify us of the link changing as a
> result of triggering a renegotiation.
>
> Second, when we are manually forcing the pause settings, and there
> is no renegotiation triggered, we do not update the MAC via the new
> mac_link_up approach.
>
> These two patches solve both problems, and will need to be backported
> to v5.7; they do not apply cleanly there due to the introduction of
> PCS in the v5.8 merge window.
Series applied, thank you.
^ permalink raw reply [flat|nested] 4+ messages in thread