* [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules
@ 2022-11-29 14:12 Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code Vladimir Oltean
` (13 more replies)
0 siblings, 14 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
This patch set deliberately targets net-next and lacks Fixes: tags due
to caution on my part.
While testing some SFP modules on the Solidrun Honeycomb LX2K platform,
I noticed that rebooting causes a deadlock:
============================================
WARNING: possible recursive locking detected
6.1.0-rc5-07010-ga9b9500ffaac-dirty #656 Not tainted
--------------------------------------------
systemd-shutdow/1 is trying to acquire lock:
ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
but task is already holding lock:
ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(rtnl_mutex);
lock(rtnl_mutex);
*** DEADLOCK ***
May be due to missing lock nesting notation
6 locks held by systemd-shutdow/1:
#0: ffffa62db6863c70 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0xd4/0x260
#1: ffff2f2b0176f100 (&dev->mutex){....}-{4:4}, at: device_shutdown+0xf4/0x260
#2: ffff2f2b017be900 (&dev->mutex){....}-{4:4}, at: device_shutdown+0x104/0x260
#3: ffff2f2b017680f0 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x40/0x260
#4: ffff2f2b0e1608f0 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x40/0x260
#5: ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
stack backtrace:
CPU: 6 PID: 1 Comm: systemd-shutdow Not tainted 6.1.0-rc5-07010-ga9b9500ffaac-dirty #656
Hardware name: SolidRun LX2160A Honeycomb (DT)
Call trace:
lock_acquire+0x68/0x84
__mutex_lock+0x98/0x460
mutex_lock_nested+0x2c/0x40
rtnl_lock+0x1c/0x30
sfp_bus_del_upstream+0x1c/0xac
phylink_destroy+0x1c/0x50
dpaa2_mac_disconnect+0x28/0x70
dpaa2_eth_remove+0x1dc/0x1f0
fsl_mc_driver_remove+0x24/0x60
device_remove+0x70/0x80
device_release_driver_internal+0x1f0/0x260
device_links_unbind_consumers+0xe0/0x110
device_release_driver_internal+0x138/0x260
device_release_driver+0x18/0x24
bus_remove_device+0x12c/0x13c
device_del+0x16c/0x424
fsl_mc_device_remove+0x28/0x40
__fsl_mc_device_remove+0x10/0x20
device_for_each_child+0x5c/0xac
dprc_remove+0x94/0xb4
fsl_mc_driver_remove+0x24/0x60
device_remove+0x70/0x80
device_release_driver_internal+0x1f0/0x260
device_release_driver+0x18/0x24
bus_remove_device+0x12c/0x13c
device_del+0x16c/0x424
fsl_mc_bus_remove+0x8c/0x10c
fsl_mc_bus_shutdown+0x10/0x20
platform_shutdown+0x24/0x3c
device_shutdown+0x15c/0x260
kernel_restart+0x40/0xa4
__do_sys_reboot+0x1e4/0x260
__arm64_sys_reboot+0x24/0x30
But fixing this appears to be not so simple. The patch set represents my
attempt to address it.
In short, the problem is that dpaa2_mac_connect() and dpaa2_mac_disconnect()
call 2 phylink functions in a row, one takes rtnl_lock() itself -
phylink_create(), and one which requires rtnl_lock() to be held by the
caller - phylink_fwnode_phy_connect(). The existing approach in the
drivers is too simple. We take rtnl_lock() when calling dpaa2_mac_connect(),
which is what results in the deadlock.
Fixing just that creates another problem. The drivers make use of
rtnl_lock() for serializing with other code paths too. I think I've
found all those code paths, and established other mechanisms for
serializing with them.
Vladimir Oltean (12):
net: dpaa2-eth: don't use -ENOTSUPP error code
net: dpaa2: replace dpaa2_mac_is_type_fixed() with
dpaa2_mac_is_type_phy()
net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start()
net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect()
net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call
net: dpaa2-switch: assign port_priv->mac after dpaa2_mac_connect()
call
net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing
net: dpaa2-switch replace direct MAC access with
dpaa2_switch_port_has_mac()
net: dpaa2-eth: connect to MAC before requesting the "endpoint
changed" IRQ
net: dpaa2-eth: serialize changes to priv->mac with a mutex
net: dpaa2-switch: serialize changes to priv->mac with a mutex
net: dpaa2-mac: move rtnl_lock() only around
phylink_{,dis}connect_phy()
.../freescale/dpaa2/mac-phy-support.rst | 9 +-
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 87 ++++++++++++-------
.../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 11 +--
.../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 70 ++++++++++-----
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 16 +++-
.../net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++-
.../freescale/dpaa2/dpaa2-switch-ethtool.c | 45 ++++++----
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 59 +++++++++----
.../ethernet/freescale/dpaa2/dpaa2-switch.h | 9 +-
9 files changed, 212 insertions(+), 104 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:48 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy() Vladimir Oltean
` (12 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
dpaa2_eth_setup_dpni() is called from the probe path and
dpaa2_eth_set_link_ksettings() is propagated to user space.
include/linux/errno.h says that ENOTSUPP is "Defined for the NFSv3
protocol". Conventional wisdom has it to not use it in networking
drivers. Replace it with -EOPNOTSUPP.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +-
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 97e1856641b4..515fcd18ed72 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -3791,7 +3791,7 @@ static int dpaa2_eth_setup_dpni(struct fsl_mc_device *ls_dev)
dev_err(dev, "DPNI version %u.%u not supported, need >= %u.%u\n",
priv->dpni_ver_major, priv->dpni_ver_minor,
DPNI_VER_MAJOR, DPNI_VER_MINOR);
- err = -ENOTSUPP;
+ err = -EOPNOTSUPP;
goto close;
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index 32a38a03db57..ac3a7f2897be 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -117,7 +117,7 @@ dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
if (!dpaa2_eth_is_type_phy(priv))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy()
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:50 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start() Vladimir Oltean
` (11 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
dpaa2_mac_is_type_fixed() is a header with no implementation and no
callers, which is referenced from the documentation though. It can be
deleted.
On the other hand, it would be useful to reuse the code between
dpaa2_eth_is_type_phy() and dpaa2_switch_port_is_type_phy(). That common
code should be called dpaa2_mac_is_type_phy(), so let's create that.
The removal and the addition are merged into the same patch because,
in fact, is_type_phy() is the logical opposite of is_type_fixed().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../ethernet/freescale/dpaa2/mac-phy-support.rst | 9 ++++++---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 7 +------
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++++++++--
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h | 7 +------
4 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
index 51e6624fb774..1d2f55feca24 100644
--- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
+++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
@@ -181,10 +181,13 @@ when necessary using the below listed API::
- int dpaa2_mac_connect(struct dpaa2_mac *mac);
- void dpaa2_mac_disconnect(struct dpaa2_mac *mac);
-A phylink integration is necessary only when the partner DPMAC is not of TYPE_FIXED.
-One can check for this condition using the below API::
+A phylink integration is necessary only when the partner DPMAC is not of
+``TYPE_FIXED``. This means it is either of ``TYPE_PHY``, or of
+``TYPE_BACKPLANE`` (the difference being the two that in the ``TYPE_BACKPLANE``
+mode, the MC firmware does not access the PCS registers). One can check for
+this condition using the following helper::
- - bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,struct fsl_mc_io *mc_io);
+ - static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac);
Before connection to a MAC, the caller must allocate and populate the
dpaa2_mac structure with the associated net_device, a pointer to the MC portal
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 5d0fc432e5b2..04270ae44d84 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -768,12 +768,7 @@ static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
{
- if (priv->mac &&
- (priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
- priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
- return true;
-
- return false;
+ return dpaa2_mac_is_type_phy(priv->mac);
}
static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
index a58cab188a99..c1ec9efd413a 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
@@ -30,8 +30,14 @@ struct dpaa2_mac {
struct phy *serdes_phy;
};
-bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
- struct fsl_mc_io *mc_io);
+static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac)
+{
+ if (!mac)
+ return false;
+
+ return mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
+ mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE;
+}
int dpaa2_mac_open(struct dpaa2_mac *mac);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
index 0002dca4d417..9898073abe01 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
@@ -230,12 +230,7 @@ static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
static inline bool
dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
{
- if (port_priv->mac &&
- (port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
- port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
- return true;
-
- return false;
+ return dpaa2_mac_is_type_phy(port_priv->mac);
}
static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start()
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy() Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:51 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect() Vladimir Oltean
` (10 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
The phylink handling is intended to be hidden inside the dpaa2_mac
object. Move the phylink_start() call into dpaa2_mac_start(), and
phylink_stop() into dpaa2_mac_stop().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 5 +----
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 8 ++++++++
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 5 +----
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 515fcd18ed72..8896a3198bd2 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -2201,10 +2201,8 @@ static int dpaa2_eth_open(struct net_device *net_dev)
goto enable_err;
}
- if (dpaa2_eth_is_type_phy(priv)) {
+ if (dpaa2_eth_is_type_phy(priv))
dpaa2_mac_start(priv->mac);
- phylink_start(priv->mac->phylink);
- }
return 0;
@@ -2278,7 +2276,6 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
int retries = 10;
if (dpaa2_eth_is_type_phy(priv)) {
- phylink_stop(priv->mac->phylink);
dpaa2_mac_stop(priv->mac);
} else {
netif_tx_stop_all_queues(net_dev);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index 61d31ffb5d97..c22ce1c871f3 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -338,12 +338,20 @@ static void dpaa2_mac_set_supported_interfaces(struct dpaa2_mac *mac)
void dpaa2_mac_start(struct dpaa2_mac *mac)
{
+ ASSERT_RTNL();
+
if (mac->serdes_phy)
phy_power_on(mac->serdes_phy);
+
+ phylink_start(mac->phylink);
}
void dpaa2_mac_stop(struct dpaa2_mac *mac)
{
+ ASSERT_RTNL();
+
+ phylink_stop(mac->phylink);
+
if (mac->serdes_phy)
phy_power_off(mac->serdes_phy);
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index 14f739e04a3c..42d3290ccd8b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -702,10 +702,8 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
dpaa2_switch_enable_ctrl_if_napi(ethsw);
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
+ if (dpaa2_switch_port_is_type_phy(port_priv))
dpaa2_mac_start(port_priv->mac);
- phylink_start(port_priv->mac->phylink);
- }
return 0;
}
@@ -717,7 +715,6 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
int err;
if (dpaa2_switch_port_is_type_phy(port_priv)) {
- phylink_stop(port_priv->mac->phylink);
dpaa2_mac_stop(port_priv->mac);
} else {
netif_tx_stop_all_queues(netdev);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect()
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (2 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start() Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:51 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 05/12] net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call Vladimir Oltean
` (9 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
dpaa2_mac_disconnect() will only be called with a NULL mac->phylink if
dpaa2_mac_connect() failed, or was never called.
The callers are these:
dpaa2_eth_disconnect_mac():
if (dpaa2_eth_is_type_phy(priv))
dpaa2_mac_disconnect(priv->mac);
dpaa2_switch_port_disconnect_mac():
if (dpaa2_switch_port_is_type_phy(port_priv))
dpaa2_mac_disconnect(port_priv->mac);
priv->mac can be NULL, but in that case, dpaa2_eth_is_type_phy() returns
false, and dpaa2_mac_disconnect() is never called. Similar for
dpaa2-switch.
When priv->mac is non-NULL, it means that dpaa2_mac_connect() returned
zero (success), and therefore, priv->mac->phylink is also a valid
pointer.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index c22ce1c871f3..9d1e7026eaef 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -449,9 +449,6 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
{
- if (!mac->phylink)
- return;
-
phylink_disconnect_phy(mac->phylink);
phylink_destroy(mac->phylink);
dpaa2_pcs_destroy(mac);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 05/12] net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (3 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect() Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 06/12] net: dpaa2-switch: assign port_priv->mac " Vladimir Oltean
` (8 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
There are 2 requirements for correct code:
- Any time the driver accesses the priv->mac pointer at runtime, it
either holds NULL to indicate a DPNI-DPNI connection (or unconnected
DPNI), or a struct dpaa2_mac whose phylink instance was fully
initialized (created and connected to the PHY). No changes are made to
priv->mac while it is being used. Currently, rtnl_lock() watches over
the call to dpaa2_eth_connect_mac(), so it serves the purpose of
serializing this with all readers of priv->mac.
- dpaa2_mac_connect() should run unlocked, because inside it are 2
phylink calls with incompatible locking requirements: phylink_create()
requires that the rtnl_mutex isn't held, and phylink_fwnode_phy_connect()
requires that the rtnl_mutex is held. The only way to solve those
contradictory requirements is to let dpaa2_mac_connect() take
rtnl_lock() when it needs to.
To solve both requirements, we need to identify the writer side of the
priv->mac pointer, which can be wrapped in a mutex private to the driver
in a future patch. The dpaa2_mac_connect() cannot be part of the writer
side critical section, because of an AB/BA deadlock with rtnl_lock().
So the strategy needs to be that where we prepare the DPMAC by calling
dpaa2_mac_connect(), and only make priv->mac point to it once it's fully
prepared. This ensures that the writer side critical section has the
absolute minimum surface it can.
The reverse strategy is adopted in the dpaa2_eth_disconnect_mac() code
path. This makes sure that priv->mac is NULL when we start tearing down
the DPMAC that we disconnected from, and concurrent code will simply not
see it.
No locking changes in this patch (concurrent code is still blocked by
the rtnl_mutex).
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 21 +++++++++++--------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 8896a3198bd2..4dbf8a1651cd 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4624,9 +4624,8 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
err = dpaa2_mac_open(mac);
if (err)
goto err_free_mac;
- priv->mac = mac;
- if (dpaa2_eth_is_type_phy(priv)) {
+ if (dpaa2_mac_is_type_phy(mac)) {
err = dpaa2_mac_connect(mac);
if (err) {
if (err == -EPROBE_DEFER)
@@ -4640,11 +4639,12 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
}
}
+ priv->mac = mac;
+
return 0;
err_close_mac:
dpaa2_mac_close(mac);
- priv->mac = NULL;
err_free_mac:
kfree(mac);
return err;
@@ -4652,15 +4652,18 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
{
- if (dpaa2_eth_is_type_phy(priv))
- dpaa2_mac_disconnect(priv->mac);
+ struct dpaa2_mac *mac = priv->mac;
- if (!dpaa2_eth_has_mac(priv))
+ priv->mac = NULL;
+
+ if (!mac)
return;
- dpaa2_mac_close(priv->mac);
- kfree(priv->mac);
- priv->mac = NULL;
+ if (dpaa2_mac_is_type_phy(mac))
+ dpaa2_mac_disconnect(mac);
+
+ dpaa2_mac_close(mac);
+ kfree(mac);
}
static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 06/12] net: dpaa2-switch: assign port_priv->mac after dpaa2_mac_connect() call
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (4 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 05/12] net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing Vladimir Oltean
` (7 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
The dpaa2-switch has the exact same locking requirements when connected
to a DPMAC, so it needs port_priv->mac to always point either to NULL,
or to a DPMAC with a fully initialized phylink instance.
Make the same preparatory change in the dpaa2-switch driver as in the
dpaa2-eth one.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 21 +++++++++++--------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index 42d3290ccd8b..3b0963d95f67 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -1449,9 +1449,8 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
err = dpaa2_mac_open(mac);
if (err)
goto err_free_mac;
- port_priv->mac = mac;
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
+ if (dpaa2_mac_is_type_phy(mac)) {
err = dpaa2_mac_connect(mac);
if (err) {
netdev_err(port_priv->netdev,
@@ -1461,11 +1460,12 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
}
}
+ port_priv->mac = mac;
+
return 0;
err_close_mac:
dpaa2_mac_close(mac);
- port_priv->mac = NULL;
err_free_mac:
kfree(mac);
return err;
@@ -1473,15 +1473,18 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
{
- if (dpaa2_switch_port_is_type_phy(port_priv))
- dpaa2_mac_disconnect(port_priv->mac);
+ struct dpaa2_mac *mac = port_priv->mac;
- if (!dpaa2_switch_port_has_mac(port_priv))
+ port_priv->mac = NULL;
+
+ if (!mac)
return;
- dpaa2_mac_close(port_priv->mac);
- kfree(port_priv->mac);
- port_priv->mac = NULL;
+ if (dpaa2_mac_is_type_phy(mac))
+ dpaa2_mac_disconnect(mac);
+
+ dpaa2_mac_close(mac);
+ kfree(mac);
}
static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (5 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 06/12] net: dpaa2-switch: assign port_priv->mac " Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:54 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac() Vladimir Oltean
` (6 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC
objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S"
unstructured counters. Those counters are only shown for the entity
owning the netdev (DPNI, DPSW) if it's connected to a DPMAC.
The ethtool stringset code path is split into multiple callbacks, but
currently, connecting and disconnecting the DPMAC takes the rtnl_lock().
This blocks the entire ethtool code path from running, see
ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() ->
strset_prepare_data().
This is going to be a problem if we are going to no longer require
rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC
could appear between ops->get_sset_count() and ops->get_strings().
If it appears out of the blue, we will provide a stringset into an array
that was dimensioned thinking the DPMAC wouldn't be there => array
accessed out of bounds.
There isn't really a good way to work around that, and I don't want to
put too much pressure on the ethtool framework by playing locking games.
Just make the DPMAC counters be always available. They'll be zeroes if
the DPNI or DPSW isn't connected to a DPMAC.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 12 +++---------
.../ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 11 ++---------
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index ac3a7f2897be..bd87aa9ef686 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -185,7 +185,6 @@ static int dpaa2_eth_set_pauseparam(struct net_device *net_dev,
static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
- struct dpaa2_eth_priv *priv = netdev_priv(netdev);
u8 *p = data;
int i;
@@ -199,22 +198,17 @@ static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
strscpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
- if (dpaa2_eth_has_mac(priv))
- dpaa2_mac_get_strings(p);
+ dpaa2_mac_get_strings(p);
break;
}
}
static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
{
- int num_ss_stats = DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS;
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-
switch (sset) {
case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
- if (dpaa2_eth_has_mac(priv))
- num_ss_stats += dpaa2_mac_get_sset_count();
- return num_ss_stats;
+ return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS +
+ dpaa2_mac_get_sset_count();
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
index 720c9230cab5..40ee57ef55be 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
@@ -145,14 +145,9 @@ dpaa2_switch_set_link_ksettings(struct net_device *netdev,
static int
dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
{
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;
-
switch (sset) {
case ETH_SS_STATS:
- if (port_priv->mac)
- num_ss_stats += dpaa2_mac_get_sset_count();
- return num_ss_stats;
+ return DPAA2_SWITCH_NUM_COUNTERS + dpaa2_mac_get_sset_count();
default:
return -EOPNOTSUPP;
}
@@ -161,7 +156,6 @@ dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
u8 *p = data;
int i;
@@ -172,8 +166,7 @@ static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
- if (port_priv->mac)
- dpaa2_mac_get_strings(p);
+ dpaa2_mac_get_strings(p);
break;
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac()
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (6 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 18:55 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 09/12] net: dpaa2-eth: connect to MAC before requesting the "endpoint changed" IRQ Vladimir Oltean
` (5 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
The helper function will gain a lockdep annotation in a future patch.
Make sure to benefit from it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
index 40ee57ef55be..76a4b09e2854 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
@@ -189,7 +189,7 @@ static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev,
dpaa2_switch_ethtool_counters[i].name, err);
}
- if (port_priv->mac)
+ if (dpaa2_switch_port_has_mac(port_priv))
dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 09/12] net: dpaa2-eth: connect to MAC before requesting the "endpoint changed" IRQ
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (7 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac() Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 10/12] net: dpaa2-eth: serialize changes to priv->mac with a mutex Vladimir Oltean
` (4 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
dpaa2_eth_connect_mac() is called both from dpaa2_eth_probe() and from
dpni_irq0_handler_thread().
It could happen that the DPNI gets connected to a DPMAC on the fsl-mc
bus exactly during probe, as soon as the "endpoint change" interrupt is
requested in dpaa2_eth_setup_irqs(). This will cause the
dpni_irq0_handler_thread() to register a phylink instance for that DPMAC.
Then, the probing function will also try to register a phylink instance
for the same DPMAC, operation which should fail (and this will fail the
probing of the driver).
Reorder dpaa2_eth_setup_irqs() and dpaa2_eth_connect_mac(), such that
dpni_irq0_handler_thread() never races with the DPMAC-related portion of
the probing path.
Also reorder dpaa2_eth_disconnect_mac() to be in the mirror position of
dpaa2_eth_connect_mac() in the teardown path.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 4dbf8a1651cd..b77d292cd960 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4899,6 +4899,10 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
}
#endif
+ err = dpaa2_eth_connect_mac(priv);
+ if (err)
+ goto err_connect_mac;
+
err = dpaa2_eth_setup_irqs(dpni_dev);
if (err) {
netdev_warn(net_dev, "Failed to set link interrupt, fall back to polling\n");
@@ -4911,10 +4915,6 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
priv->do_link_poll = true;
}
- err = dpaa2_eth_connect_mac(priv);
- if (err)
- goto err_connect_mac;
-
err = dpaa2_eth_dl_alloc(priv);
if (err)
goto err_dl_register;
@@ -4948,13 +4948,13 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
err_dl_trap_register:
dpaa2_eth_dl_free(priv);
err_dl_register:
- dpaa2_eth_disconnect_mac(priv);
-err_connect_mac:
if (priv->do_link_poll)
kthread_stop(priv->poll_thread);
else
fsl_mc_free_irqs(dpni_dev);
err_poll_thread:
+ dpaa2_eth_disconnect_mac(priv);
+err_connect_mac:
dpaa2_eth_free_rings(priv);
err_alloc_rings:
err_csum:
@@ -5002,9 +5002,6 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
#endif
unregister_netdev(net_dev);
- rtnl_lock();
- dpaa2_eth_disconnect_mac(priv);
- rtnl_unlock();
dpaa2_eth_dl_port_del(priv);
dpaa2_eth_dl_traps_unregister(priv);
@@ -5015,6 +5012,9 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
else
fsl_mc_free_irqs(ls_dev);
+ rtnl_lock();
+ dpaa2_eth_disconnect_mac(priv);
+ rtnl_unlock();
dpaa2_eth_free_rings(priv);
free_percpu(priv->fd);
free_percpu(priv->sgt_cache);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 10/12] net: dpaa2-eth: serialize changes to priv->mac with a mutex
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (8 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 09/12] net: dpaa2-eth: connect to MAC before requesting the "endpoint changed" IRQ Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 11/12] net: dpaa2-switch: " Vladimir Oltean
` (3 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
The dpaa2 architecture permits dynamic connections between objects on
the fsl-mc bus, specifically between a DPNI object (represented by a
struct net_device) and a DPMAC object (represented by a struct phylink).
The DPNI driver is notified when those connections are created/broken
through the dpni_irq0_handler_thread() method. To ensure that ethtool
operations, as well as netdev up/down operations serialize with the
connection/disconnection of the DPNI with a DPMAC,
dpni_irq0_handler_thread() takes the rtnl_lock() to block those other
operations from taking place.
There is code called by dpaa2_mac_connect() which wants to acquire the
rtnl_mutex once again, see phylink_create() -> phylink_register_sfp() ->
sfp_bus_add_upstream() -> rtnl_lock(). So the strategy doesn't quite
work out, even though it's fairly simple.
Create a different strategy, where all code paths in the dpaa2-eth
driver access priv->mac only while they are holding priv->mac_lock.
The phylink instance is not created or connected to the PHY under the
priv->mac_lock, but only assigned to priv->mac then. This will eliminate
the reliance on the rtnl_mutex.
Add lockdep annotations and put comments where holding the lock is not
necessary, and priv->mac can be dereferenced freely.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++++++--
.../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 ++
.../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 58 +++++++++++++++----
3 files changed, 91 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index b77d292cd960..3ed54c147e98 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -2147,8 +2147,11 @@ static int dpaa2_eth_link_state_update(struct dpaa2_eth_priv *priv)
/* When we manage the MAC/PHY using phylink there is no need
* to manually update the netif_carrier.
+ * We can avoid locking because we are called from the "link changed"
+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
+ * (the writer to priv->mac), so we cannot race with it.
*/
- if (dpaa2_eth_is_type_phy(priv))
+ if (dpaa2_mac_is_type_phy(priv->mac))
goto out;
/* Chech link state; speed / duplex changes are not treated yet */
@@ -2179,6 +2182,8 @@ static int dpaa2_eth_open(struct net_device *net_dev)
dpaa2_eth_seed_pools(priv);
+ mutex_lock(&priv->mac_lock);
+
if (!dpaa2_eth_is_type_phy(priv)) {
/* We'll only start the txqs when the link is actually ready;
* make sure we don't race against the link up notification,
@@ -2197,6 +2202,7 @@ static int dpaa2_eth_open(struct net_device *net_dev)
err = dpni_enable(priv->mc_io, 0, priv->mc_token);
if (err < 0) {
+ mutex_unlock(&priv->mac_lock);
netdev_err(net_dev, "dpni_enable() failed\n");
goto enable_err;
}
@@ -2204,6 +2210,8 @@ static int dpaa2_eth_open(struct net_device *net_dev)
if (dpaa2_eth_is_type_phy(priv))
dpaa2_mac_start(priv->mac);
+ mutex_unlock(&priv->mac_lock);
+
return 0;
enable_err:
@@ -2275,6 +2283,8 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
int dpni_enabled = 0;
int retries = 10;
+ mutex_lock(&priv->mac_lock);
+
if (dpaa2_eth_is_type_phy(priv)) {
dpaa2_mac_stop(priv->mac);
} else {
@@ -2282,6 +2292,8 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
netif_carrier_off(net_dev);
}
+ mutex_unlock(&priv->mac_lock);
+
/* On dpni_disable(), the MC firmware will:
* - stop MAC Rx and wait for all Rx frames to be enqueued to software
* - cut off WRIOP dequeues from egress FQs and wait until transmission
@@ -2607,12 +2619,20 @@ static int dpaa2_eth_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct dpaa2_eth_priv *priv = netdev_priv(dev);
+ int err;
if (cmd == SIOCSHWTSTAMP)
return dpaa2_eth_ts_ioctl(dev, rq, cmd);
- if (dpaa2_eth_is_type_phy(priv))
- return phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
+ mutex_lock(&priv->mac_lock);
+
+ if (dpaa2_eth_is_type_phy(priv)) {
+ err = phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
+ mutex_unlock(&priv->mac_lock);
+ return err;
+ }
+
+ mutex_unlock(&priv->mac_lock);
return -EOPNOTSUPP;
}
@@ -4639,7 +4659,9 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
}
}
+ mutex_lock(&priv->mac_lock);
priv->mac = mac;
+ mutex_unlock(&priv->mac_lock);
return 0;
@@ -4652,9 +4674,12 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
{
- struct dpaa2_mac *mac = priv->mac;
+ struct dpaa2_mac *mac;
+ mutex_lock(&priv->mac_lock);
+ mac = priv->mac;
priv->mac = NULL;
+ mutex_unlock(&priv->mac_lock);
if (!mac)
return;
@@ -4673,6 +4698,7 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev);
struct net_device *net_dev = dev_get_drvdata(dev);
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ bool had_mac;
int err;
err = dpni_get_irq_status(dpni_dev->mc_io, 0, dpni_dev->mc_handle,
@@ -4690,7 +4716,12 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
dpaa2_eth_update_tx_fqids(priv);
rtnl_lock();
- if (dpaa2_eth_has_mac(priv))
+ /* We can avoid locking because the "endpoint changed" IRQ
+ * handler is the only one who changes priv->mac at runtime,
+ * so we are not racing with anyone.
+ */
+ had_mac = !!priv->mac;
+ if (had_mac)
dpaa2_eth_disconnect_mac(priv);
else
dpaa2_eth_connect_mac(priv);
@@ -4792,6 +4823,8 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
priv->net_dev = net_dev;
SET_NETDEV_DEVLINK_PORT(net_dev, &priv->devlink_port);
+ mutex_init(&priv->mac_lock);
+
priv->iommu_domain = iommu_get_domain_for_dev(dev);
priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 04270ae44d84..d56d7a13262e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -615,6 +615,8 @@ struct dpaa2_eth_priv {
#endif
struct dpaa2_mac *mac;
+ /* Serializes changes to priv->mac */
+ struct mutex mac_lock;
struct workqueue_struct *dpaa2_ptp_wq;
struct work_struct tx_onestep_tstamp;
struct sk_buff_head tx_skbs;
@@ -768,11 +770,15 @@ static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
{
+ lockdep_assert_held(&priv->mac_lock);
+
return dpaa2_mac_is_type_phy(priv->mac);
}
static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
{
+ lockdep_assert_held(&priv->mac_lock);
+
return priv->mac ? true : false;
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index bd87aa9ef686..e80e9388c71f 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -85,11 +85,16 @@ static void dpaa2_eth_get_drvinfo(struct net_device *net_dev,
static int dpaa2_eth_nway_reset(struct net_device *net_dev)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ int err = -EOPNOTSUPP;
+
+ mutex_lock(&priv->mac_lock);
if (dpaa2_eth_is_type_phy(priv))
- return phylink_ethtool_nway_reset(priv->mac->phylink);
+ err = phylink_ethtool_nway_reset(priv->mac->phylink);
+
+ mutex_unlock(&priv->mac_lock);
- return -EOPNOTSUPP;
+ return err;
}
static int
@@ -97,10 +102,18 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
struct ethtool_link_ksettings *link_settings)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ int err;
- if (dpaa2_eth_is_type_phy(priv))
- return phylink_ethtool_ksettings_get(priv->mac->phylink,
- link_settings);
+ mutex_lock(&priv->mac_lock);
+
+ if (dpaa2_eth_is_type_phy(priv)) {
+ err = phylink_ethtool_ksettings_get(priv->mac->phylink,
+ link_settings);
+ mutex_unlock(&priv->mac_lock);
+ return err;
+ }
+
+ mutex_unlock(&priv->mac_lock);
link_settings->base.autoneg = AUTONEG_DISABLE;
if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX))
@@ -115,11 +128,17 @@ dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
const struct ethtool_link_ksettings *link_settings)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ int err = -EOPNOTSUPP;
- if (!dpaa2_eth_is_type_phy(priv))
- return -EOPNOTSUPP;
+ mutex_lock(&priv->mac_lock);
+
+ if (dpaa2_eth_is_type_phy(priv))
+ err = phylink_ethtool_ksettings_set(priv->mac->phylink,
+ link_settings);
- return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
+ mutex_unlock(&priv->mac_lock);
+
+ return err;
}
static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
@@ -128,11 +147,16 @@ static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
u64 link_options = priv->link_state.options;
+ mutex_lock(&priv->mac_lock);
+
if (dpaa2_eth_is_type_phy(priv)) {
phylink_ethtool_get_pauseparam(priv->mac->phylink, pause);
+ mutex_unlock(&priv->mac_lock);
return;
}
+ mutex_unlock(&priv->mac_lock);
+
pause->rx_pause = dpaa2_eth_rx_pause_enabled(link_options);
pause->tx_pause = dpaa2_eth_tx_pause_enabled(link_options);
pause->autoneg = AUTONEG_DISABLE;
@@ -151,9 +175,17 @@ static int dpaa2_eth_set_pauseparam(struct net_device *net_dev,
return -EOPNOTSUPP;
}
- if (dpaa2_eth_is_type_phy(priv))
- return phylink_ethtool_set_pauseparam(priv->mac->phylink,
- pause);
+ mutex_lock(&priv->mac_lock);
+
+ if (dpaa2_eth_is_type_phy(priv)) {
+ err = phylink_ethtool_set_pauseparam(priv->mac->phylink,
+ pause);
+ mutex_unlock(&priv->mac_lock);
+ return err;
+ }
+
+ mutex_unlock(&priv->mac_lock);
+
if (pause->autoneg)
return -EOPNOTSUPP;
@@ -309,8 +341,12 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
}
*(data + i++) = buf_cnt_total;
+ mutex_lock(&priv->mac_lock);
+
if (dpaa2_eth_has_mac(priv))
dpaa2_mac_get_ethtool_stats(priv->mac, data + i);
+
+ mutex_unlock(&priv->mac_lock);
}
static int dpaa2_eth_prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask,
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 11/12] net: dpaa2-switch: serialize changes to priv->mac with a mutex
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (9 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 10/12] net: dpaa2-eth: serialize changes to priv->mac with a mutex Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 12/12] net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy() Vladimir Oltean
` (2 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
The dpaa2-switch driver uses a DPMAC in the same way as the dpaa2-eth
driver, so we need to duplicate the locking solution established by the
previous change to the switch driver as well.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
.../freescale/dpaa2/dpaa2-switch-ethtool.c | 32 +++++++++++++++----
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 31 ++++++++++++++++--
.../ethernet/freescale/dpaa2/dpaa2-switch.h | 2 ++
3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
index 76a4b09e2854..6bc1988be311 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
@@ -60,11 +60,18 @@ dpaa2_switch_get_link_ksettings(struct net_device *netdev,
{
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
struct dpsw_link_state state = {0};
- int err = 0;
+ int err;
+
+ mutex_lock(&port_priv->mac_lock);
- if (dpaa2_switch_port_is_type_phy(port_priv))
- return phylink_ethtool_ksettings_get(port_priv->mac->phylink,
- link_ksettings);
+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
+ err = phylink_ethtool_ksettings_get(port_priv->mac->phylink,
+ link_ksettings);
+ mutex_unlock(&port_priv->mac_lock);
+ return err;
+ }
+
+ mutex_unlock(&port_priv->mac_lock);
err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
port_priv->ethsw_data->dpsw_handle,
@@ -99,9 +106,16 @@ dpaa2_switch_set_link_ksettings(struct net_device *netdev,
bool if_running;
int err = 0, ret;
- if (dpaa2_switch_port_is_type_phy(port_priv))
- return phylink_ethtool_ksettings_set(port_priv->mac->phylink,
- link_ksettings);
+ mutex_lock(&port_priv->mac_lock);
+
+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
+ err = phylink_ethtool_ksettings_set(port_priv->mac->phylink,
+ link_ksettings);
+ mutex_unlock(&port_priv->mac_lock);
+ return err;
+ }
+
+ mutex_unlock(&port_priv->mac_lock);
/* Interface needs to be down to change link settings */
if_running = netif_running(netdev);
@@ -189,8 +203,12 @@ static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev,
dpaa2_switch_ethtool_counters[i].name, err);
}
+ mutex_lock(&port_priv->mac_lock);
+
if (dpaa2_switch_port_has_mac(port_priv))
dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
+
+ mutex_unlock(&port_priv->mac_lock);
}
const struct ethtool_ops dpaa2_switch_port_ethtool_ops = {
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index 3b0963d95f67..0472e24191ad 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -602,8 +602,11 @@ static int dpaa2_switch_port_link_state_update(struct net_device *netdev)
/* When we manage the MAC/PHY using phylink there is no need
* to manually update the netif_carrier.
+ * We can avoid locking because we are called from the "link changed"
+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
+ * (the writer to port_priv->mac), so we cannot race with it.
*/
- if (dpaa2_switch_port_is_type_phy(port_priv))
+ if (dpaa2_mac_is_type_phy(port_priv->mac))
return 0;
/* Interrupts are received even though no one issued an 'ifconfig up'
@@ -683,6 +686,8 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
struct ethsw_core *ethsw = port_priv->ethsw_data;
int err;
+ mutex_lock(&port_priv->mac_lock);
+
if (!dpaa2_switch_port_is_type_phy(port_priv)) {
/* Explicitly set carrier off, otherwise
* netif_carrier_ok() will return true and cause 'ip link show'
@@ -696,6 +701,7 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
port_priv->ethsw_data->dpsw_handle,
port_priv->idx);
if (err) {
+ mutex_unlock(&port_priv->mac_lock);
netdev_err(netdev, "dpsw_if_enable err %d\n", err);
return err;
}
@@ -705,6 +711,8 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
if (dpaa2_switch_port_is_type_phy(port_priv))
dpaa2_mac_start(port_priv->mac);
+ mutex_unlock(&port_priv->mac_lock);
+
return 0;
}
@@ -714,6 +722,8 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
struct ethsw_core *ethsw = port_priv->ethsw_data;
int err;
+ mutex_lock(&port_priv->mac_lock);
+
if (dpaa2_switch_port_is_type_phy(port_priv)) {
dpaa2_mac_stop(port_priv->mac);
} else {
@@ -721,6 +731,8 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
netif_carrier_off(netdev);
}
+ mutex_unlock(&port_priv->mac_lock);
+
err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
port_priv->ethsw_data->dpsw_handle,
port_priv->idx);
@@ -1460,7 +1472,9 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
}
}
+ mutex_lock(&port_priv->mac_lock);
port_priv->mac = mac;
+ mutex_unlock(&port_priv->mac_lock);
return 0;
@@ -1473,9 +1487,12 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
{
- struct dpaa2_mac *mac = port_priv->mac;
+ struct dpaa2_mac *mac;
+ mutex_lock(&port_priv->mac_lock);
+ mac = port_priv->mac;
port_priv->mac = NULL;
+ mutex_unlock(&port_priv->mac_lock);
if (!mac)
return;
@@ -1494,6 +1511,7 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
struct ethsw_port_priv *port_priv;
u32 status = ~0;
int err, if_id;
+ bool had_mac;
err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
DPSW_IRQ_INDEX_IF, &status);
@@ -1512,7 +1530,12 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
rtnl_lock();
- if (dpaa2_switch_port_has_mac(port_priv))
+ /* We can avoid locking because the "endpoint changed" IRQ
+ * handler is the only one who changes priv->mac at runtime,
+ * so we are not racing with anyone.
+ */
+ had_mac = !!port_priv->mac;
+ if (had_mac)
dpaa2_switch_port_disconnect_mac(port_priv);
else
dpaa2_switch_port_connect_mac(port_priv);
@@ -3255,6 +3278,8 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
port_priv->netdev = port_netdev;
port_priv->ethsw_data = ethsw;
+ mutex_init(&port_priv->mac_lock);
+
port_priv->idx = port_idx;
port_priv->stp_state = BR_STATE_FORWARDING;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
index 9898073abe01..42b3ca73f55d 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
@@ -161,6 +161,8 @@ struct ethsw_port_priv {
struct dpaa2_switch_filter_block *filter_block;
struct dpaa2_mac *mac;
+ /* Protects against changes to port_priv->mac */
+ struct mutex mac_lock;
};
/* Switch data */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH net-next 12/12] net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy()
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (10 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 11/12] net: dpaa2-switch: " Vladimir Oltean
@ 2022-11-29 14:12 ` Vladimir Oltean
2022-11-30 16:30 ` [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Ioana Ciornei
2022-12-01 12:50 ` patchwork-bot+netdevbpf
13 siblings, 0 replies; 21+ messages in thread
From: Vladimir Oltean @ 2022-11-29 14:12 UTC (permalink / raw)
To: netdev
Cc: Ioana Ciornei, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Russell King, linux-doc, linux-kernel
After the introduction of a private mac_lock that serializes access to
priv->mac (and port_priv->mac in the switch), the only remaining purpose
of rtnl_lock() is to satisfy the locking requirements of
phylink_fwnode_phy_connect() and phylink_disconnect_phy().
But the functions these live in, dpaa2_mac_connect() and
dpaa2_mac_disconnect(), have contradictory locking requirements.
While phylink_fwnode_phy_connect() wants rtnl_lock() to be held,
phylink_create() wants it to not be held.
Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch
drivers) to only surround the phylink calls that require it, in the
dpaa2-mac library code.
This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect()
run unlocked, and there isn't any danger of an AB/BA deadlock between
the rtnl_mutex and other private locks.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ----
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 5 +++++
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ----
3 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 3ed54c147e98..0c35abb7d065 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4715,7 +4715,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
dpaa2_eth_update_tx_fqids(priv);
- rtnl_lock();
/* We can avoid locking because the "endpoint changed" IRQ
* handler is the only one who changes priv->mac at runtime,
* so we are not racing with anyone.
@@ -4725,7 +4724,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
dpaa2_eth_disconnect_mac(priv);
else
dpaa2_eth_connect_mac(priv);
- rtnl_unlock();
}
return IRQ_HANDLED;
@@ -5045,9 +5043,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
else
fsl_mc_free_irqs(ls_dev);
- rtnl_lock();
dpaa2_eth_disconnect_mac(priv);
- rtnl_unlock();
dpaa2_eth_free_rings(priv);
free_percpu(priv->fd);
free_percpu(priv->sgt_cache);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index 9d1e7026eaef..8ba4ea4adeb3 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -431,7 +431,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
}
mac->phylink = phylink;
+ rtnl_lock();
err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
+ rtnl_unlock();
if (err) {
netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
goto err_phylink_destroy;
@@ -449,7 +451,10 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
{
+ rtnl_lock();
phylink_disconnect_phy(mac->phylink);
+ rtnl_unlock();
+
phylink_destroy(mac->phylink);
dpaa2_pcs_destroy(mac);
of_phy_put(mac->serdes_phy);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index 0472e24191ad..f4ae4289c41a 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -1529,7 +1529,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
}
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
- rtnl_lock();
/* We can avoid locking because the "endpoint changed" IRQ
* handler is the only one who changes priv->mac at runtime,
* so we are not racing with anyone.
@@ -1539,7 +1538,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
dpaa2_switch_port_disconnect_mac(port_priv);
else
dpaa2_switch_port_connect_mac(port_priv);
- rtnl_unlock();
}
out:
@@ -2957,9 +2955,7 @@ static void dpaa2_switch_remove_port(struct ethsw_core *ethsw,
{
struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
- rtnl_lock();
dpaa2_switch_port_disconnect_mac(port_priv);
- rtnl_unlock();
free_netdev(port_priv->netdev);
ethsw->ports[port_idx] = NULL;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code
2022-11-29 14:12 ` [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code Vladimir Oltean
@ 2022-11-29 18:48 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:48 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:10PM +0200, Vladimir Oltean wrote:
> dpaa2_eth_setup_dpni() is called from the probe path and
> dpaa2_eth_set_link_ksettings() is propagated to user space.
>
> include/linux/errno.h says that ENOTSUPP is "Defined for the NFSv3
> protocol". Conventional wisdom has it to not use it in networking
> drivers. Replace it with -EOPNOTSUPP.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy()
2022-11-29 14:12 ` [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy() Vladimir Oltean
@ 2022-11-29 18:50 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:50 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:11PM +0200, Vladimir Oltean wrote:
> dpaa2_mac_is_type_fixed() is a header with no implementation and no
> callers, which is referenced from the documentation though. It can be
> deleted.
>
> On the other hand, it would be useful to reuse the code between
> dpaa2_eth_is_type_phy() and dpaa2_switch_port_is_type_phy(). That common
> code should be called dpaa2_mac_is_type_phy(), so let's create that.
>
> The removal and the addition are merged into the same patch because,
> in fact, is_type_phy() is the logical opposite of is_type_fixed().
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start()
2022-11-29 14:12 ` [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start() Vladimir Oltean
@ 2022-11-29 18:51 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:51 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:12PM +0200, Vladimir Oltean wrote:
> The phylink handling is intended to be hidden inside the dpaa2_mac
> object. Move the phylink_start() call into dpaa2_mac_start(), and
> phylink_stop() into dpaa2_mac_stop().
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect()
2022-11-29 14:12 ` [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect() Vladimir Oltean
@ 2022-11-29 18:51 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:51 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:13PM +0200, Vladimir Oltean wrote:
> dpaa2_mac_disconnect() will only be called with a NULL mac->phylink if
> dpaa2_mac_connect() failed, or was never called.
>
> The callers are these:
>
> dpaa2_eth_disconnect_mac():
>
> if (dpaa2_eth_is_type_phy(priv))
> dpaa2_mac_disconnect(priv->mac);
>
> dpaa2_switch_port_disconnect_mac():
>
> if (dpaa2_switch_port_is_type_phy(port_priv))
> dpaa2_mac_disconnect(port_priv->mac);
>
> priv->mac can be NULL, but in that case, dpaa2_eth_is_type_phy() returns
> false, and dpaa2_mac_disconnect() is never called. Similar for
> dpaa2-switch.
>
> When priv->mac is non-NULL, it means that dpaa2_mac_connect() returned
> zero (success), and therefore, priv->mac->phylink is also a valid
> pointer.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing
2022-11-29 14:12 ` [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing Vladimir Oltean
@ 2022-11-29 18:54 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:54 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:16PM +0200, Vladimir Oltean wrote:
> DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC
> objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S"
> unstructured counters. Those counters are only shown for the entity
> owning the netdev (DPNI, DPSW) if it's connected to a DPMAC.
>
> The ethtool stringset code path is split into multiple callbacks, but
> currently, connecting and disconnecting the DPMAC takes the rtnl_lock().
> This blocks the entire ethtool code path from running, see
> ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() ->
> strset_prepare_data().
>
> This is going to be a problem if we are going to no longer require
> rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC
> could appear between ops->get_sset_count() and ops->get_strings().
> If it appears out of the blue, we will provide a stringset into an array
> that was dimensioned thinking the DPMAC wouldn't be there => array
> accessed out of bounds.
>
> There isn't really a good way to work around that, and I don't want to
> put too much pressure on the ethtool framework by playing locking games.
> Just make the DPMAC counters be always available. They'll be zeroes if
> the DPNI or DPSW isn't connected to a DPMAC.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac()
2022-11-29 14:12 ` [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac() Vladimir Oltean
@ 2022-11-29 18:55 ` Andrew Lunn
0 siblings, 0 replies; 21+ messages in thread
From: Andrew Lunn @ 2022-11-29 18:55 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, Ioana Ciornei, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King, linux-doc,
linux-kernel
On Tue, Nov 29, 2022 at 04:12:17PM +0200, Vladimir Oltean wrote:
> The helper function will gain a lockdep annotation in a future patch.
> Make sure to benefit from it.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (11 preceding siblings ...)
2022-11-29 14:12 ` [PATCH net-next 12/12] net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy() Vladimir Oltean
@ 2022-11-30 16:30 ` Ioana Ciornei
2022-12-01 12:50 ` patchwork-bot+netdevbpf
13 siblings, 0 replies; 21+ messages in thread
From: Ioana Ciornei @ 2022-11-30 16:30 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev@vger.kernel.org, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
On Tue, Nov 29, 2022 at 04:12:09PM +0200, Vladimir Oltean wrote:
> This patch set deliberately targets net-next and lacks Fixes: tags due
> to caution on my part.
>
> While testing some SFP modules on the Solidrun Honeycomb LX2K platform,
> I noticed that rebooting causes a deadlock:
>
> ============================================
> WARNING: possible recursive locking detected
> 6.1.0-rc5-07010-ga9b9500ffaac-dirty #656 Not tainted
> --------------------------------------------
> systemd-shutdow/1 is trying to acquire lock:
> ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
>
> but task is already holding lock:
> ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
>
> other info that might help us debug this:
> Possible unsafe locking scenario:
>
> CPU0
> ----
> lock(rtnl_mutex);
> lock(rtnl_mutex);
>
> *** DEADLOCK ***
>
> May be due to missing lock nesting notation
>
> 6 locks held by systemd-shutdow/1:
> #0: ffffa62db6863c70 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0xd4/0x260
> #1: ffff2f2b0176f100 (&dev->mutex){....}-{4:4}, at: device_shutdown+0xf4/0x260
> #2: ffff2f2b017be900 (&dev->mutex){....}-{4:4}, at: device_shutdown+0x104/0x260
> #3: ffff2f2b017680f0 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x40/0x260
> #4: ffff2f2b0e1608f0 (&dev->mutex){....}-{4:4}, at: device_release_driver_internal+0x40/0x260
> #5: ffffa62db6cf42f0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x1c/0x30
>
> stack backtrace:
> CPU: 6 PID: 1 Comm: systemd-shutdow Not tainted 6.1.0-rc5-07010-ga9b9500ffaac-dirty #656
> Hardware name: SolidRun LX2160A Honeycomb (DT)
> Call trace:
> lock_acquire+0x68/0x84
> __mutex_lock+0x98/0x460
> mutex_lock_nested+0x2c/0x40
> rtnl_lock+0x1c/0x30
> sfp_bus_del_upstream+0x1c/0xac
> phylink_destroy+0x1c/0x50
> dpaa2_mac_disconnect+0x28/0x70
> dpaa2_eth_remove+0x1dc/0x1f0
> fsl_mc_driver_remove+0x24/0x60
> device_remove+0x70/0x80
> device_release_driver_internal+0x1f0/0x260
> device_links_unbind_consumers+0xe0/0x110
> device_release_driver_internal+0x138/0x260
> device_release_driver+0x18/0x24
> bus_remove_device+0x12c/0x13c
> device_del+0x16c/0x424
> fsl_mc_device_remove+0x28/0x40
> __fsl_mc_device_remove+0x10/0x20
> device_for_each_child+0x5c/0xac
> dprc_remove+0x94/0xb4
> fsl_mc_driver_remove+0x24/0x60
> device_remove+0x70/0x80
> device_release_driver_internal+0x1f0/0x260
> device_release_driver+0x18/0x24
> bus_remove_device+0x12c/0x13c
> device_del+0x16c/0x424
> fsl_mc_bus_remove+0x8c/0x10c
> fsl_mc_bus_shutdown+0x10/0x20
> platform_shutdown+0x24/0x3c
> device_shutdown+0x15c/0x260
> kernel_restart+0x40/0xa4
> __do_sys_reboot+0x1e4/0x260
> __arm64_sys_reboot+0x24/0x30
>
> But fixing this appears to be not so simple. The patch set represents my
> attempt to address it.
>
> In short, the problem is that dpaa2_mac_connect() and dpaa2_mac_disconnect()
> call 2 phylink functions in a row, one takes rtnl_lock() itself -
> phylink_create(), and one which requires rtnl_lock() to be held by the
> caller - phylink_fwnode_phy_connect(). The existing approach in the
> drivers is too simple. We take rtnl_lock() when calling dpaa2_mac_connect(),
> which is what results in the deadlock.
>
> Fixing just that creates another problem. The drivers make use of
> rtnl_lock() for serializing with other code paths too. I think I've
> found all those code paths, and established other mechanisms for
> serializing with them.
>
> Vladimir Oltean (12):
> net: dpaa2-eth: don't use -ENOTSUPP error code
> net: dpaa2: replace dpaa2_mac_is_type_fixed() with
> dpaa2_mac_is_type_phy()
> net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start()
> net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect()
> net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call
> net: dpaa2-switch: assign port_priv->mac after dpaa2_mac_connect()
> call
> net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing
> net: dpaa2-switch replace direct MAC access with
> dpaa2_switch_port_has_mac()
> net: dpaa2-eth: connect to MAC before requesting the "endpoint
> changed" IRQ
> net: dpaa2-eth: serialize changes to priv->mac with a mutex
> net: dpaa2-switch: serialize changes to priv->mac with a mutex
> net: dpaa2-mac: move rtnl_lock() only around
> phylink_{,dis}connect_phy()
>
> .../freescale/dpaa2/mac-phy-support.rst | 9 +-
> .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 87 ++++++++++++-------
> .../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 11 +--
> .../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 70 ++++++++++-----
> .../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 16 +++-
> .../net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++-
> .../freescale/dpaa2/dpaa2-switch-ethtool.c | 45 ++++++----
> .../ethernet/freescale/dpaa2/dpaa2-switch.c | 59 +++++++++----
> .../ethernet/freescale/dpaa2/dpaa2-switch.h | 9 +-
> 9 files changed, 212 insertions(+), 104 deletions(-)
For the entire patch set:
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
` (12 preceding siblings ...)
2022-11-30 16:30 ` [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Ioana Ciornei
@ 2022-12-01 12:50 ` patchwork-bot+netdevbpf
13 siblings, 0 replies; 21+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-12-01 12:50 UTC (permalink / raw)
To: Vladimir Oltean
Cc: netdev, ioana.ciornei, davem, edumazet, kuba, pabeni, linux,
linux-doc, linux-kernel
Hello:
This series was applied to netdev/net-next.git (master)
by Paolo Abeni <pabeni@redhat.com>:
On Tue, 29 Nov 2022 16:12:09 +0200 you wrote:
> This patch set deliberately targets net-next and lacks Fixes: tags due
> to caution on my part.
>
> While testing some SFP modules on the Solidrun Honeycomb LX2K platform,
> I noticed that rebooting causes a deadlock:
>
> ============================================
> WARNING: possible recursive locking detected
> 6.1.0-rc5-07010-ga9b9500ffaac-dirty #656 Not tainted
>
> [...]
Here is the summary with links:
- [net-next,01/12] net: dpaa2-eth: don't use -ENOTSUPP error code
https://git.kernel.org/netdev/net-next/c/91c71bf14da4
- [net-next,02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy()
https://git.kernel.org/netdev/net-next/c/320fefa9e2ed
- [net-next,03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start()
https://git.kernel.org/netdev/net-next/c/385333888154
- [net-next,04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect()
https://git.kernel.org/netdev/net-next/c/ccbd7822950f
- [net-next,05/12] net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call
https://git.kernel.org/netdev/net-next/c/02d61948e8da
- [net-next,06/12] net: dpaa2-switch: assign port_priv->mac after dpaa2_mac_connect() call
https://git.kernel.org/netdev/net-next/c/88d64367cea0
- [net-next,07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing
https://git.kernel.org/netdev/net-next/c/29811d6e19d7
- [net-next,08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac()
https://git.kernel.org/netdev/net-next/c/bc230671bfb2
- [net-next,09/12] net: dpaa2-eth: connect to MAC before requesting the "endpoint changed" IRQ
https://git.kernel.org/netdev/net-next/c/55f90a4d07ec
- [net-next,10/12] net: dpaa2-eth: serialize changes to priv->mac with a mutex
https://git.kernel.org/netdev/net-next/c/2291982e29b1
- [net-next,11/12] net: dpaa2-switch: serialize changes to priv->mac with a mutex
https://git.kernel.org/netdev/net-next/c/3c7f44fa9c4c
- [net-next,12/12] net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy()
https://git.kernel.org/netdev/net-next/c/87db82cb6149
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2022-12-01 12:50 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-29 14:12 [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 01/12] net: dpaa2-eth: don't use -ENOTSUPP error code Vladimir Oltean
2022-11-29 18:48 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 02/12] net: dpaa2: replace dpaa2_mac_is_type_fixed() with dpaa2_mac_is_type_phy() Vladimir Oltean
2022-11-29 18:50 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 03/12] net: dpaa2-mac: absorb phylink_start() call into dpaa2_mac_start() Vladimir Oltean
2022-11-29 18:51 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 04/12] net: dpaa2-mac: remove defensive check in dpaa2_mac_disconnect() Vladimir Oltean
2022-11-29 18:51 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 05/12] net: dpaa2-eth: assign priv->mac after dpaa2_mac_connect() call Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 06/12] net: dpaa2-switch: assign port_priv->mac " Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 07/12] net: dpaa2: publish MAC stringset to ethtool -S even if MAC is missing Vladimir Oltean
2022-11-29 18:54 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 08/12] net: dpaa2-switch replace direct MAC access with dpaa2_switch_port_has_mac() Vladimir Oltean
2022-11-29 18:55 ` Andrew Lunn
2022-11-29 14:12 ` [PATCH net-next 09/12] net: dpaa2-eth: connect to MAC before requesting the "endpoint changed" IRQ Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 10/12] net: dpaa2-eth: serialize changes to priv->mac with a mutex Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 11/12] net: dpaa2-switch: " Vladimir Oltean
2022-11-29 14:12 ` [PATCH net-next 12/12] net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy() Vladimir Oltean
2022-11-30 16:30 ` [PATCH net-next 00/12] Fix rtnl_mutex deadlock with DPAA2 and SFP modules Ioana Ciornei
2022-12-01 12:50 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).