aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
authorJakub Kicinski <kuba@kernel.org>2026-06-04 17:29:02 -0700
committerJakub Kicinski <kuba@kernel.org>2026-06-09 10:13:04 -0700
commitded86da4bbb78cad74cecc368fee3ae3a296e2ca (patch)
tree5881ec9b5c0f2a3b4adc1705f6562877a7a1f1b7 /net
parent8845484367dade6811bbc3c0c1d66a2a0721c3c0 (diff)
downloadath-ded86da4bbb78cad74cecc368fee3ae3a296e2ca.tar.gz
net: ethtool: relax ethnl_req_get_phydev() locking assertion
phydev <> netdev linking and lifecycle depends on rtnl_lock. We want to switch to instance locks for most ethtool ops. Let's add an assert that ops locked devices don't use phydev today. If one does we can either opt the phy ops out of being purely ops locked, or do deeper surgery to make phy locking ops-compatible. I don't think there's any fundamental challenge to make that work. Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260605002912.3456868-3-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/ethtool/netlink.c6
-rw-r--r--net/ethtool/netlink.h7
-rw-r--r--net/ethtool/phy.c1
3 files changed, 8 insertions, 6 deletions
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index c4054a9795ffb..afafed7385841 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -226,11 +226,13 @@ struct phy_device *ethnl_req_get_phydev(const struct ethnl_req_info *req_info,
{
struct phy_device *phydev;
- ASSERT_RTNL();
-
if (!req_info->dev)
return NULL;
+ /* If there is no PHY in sight there's no need for assert locking */
+ if (!phy_link_topo_empty(req_info->dev))
+ ASSERT_RTNL();
+
if (!req_info->phy_index)
return req_info->dev->phydev;
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index f94aaa66379cd..4ca2eca2e94b1 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -275,14 +275,15 @@ static inline void ethnl_parse_header_dev_put(struct ethnl_req_info *req_info)
/**
* ethnl_req_get_phydev() - Gets the phy_device targeted by this request,
- * if any. Must be called under rntl_lock().
+ * if any.
* @req_info: The ethnl request to get the phy from.
* @tb: The netlink attributes array, for error reporting.
* @header: The netlink header index, used for error reporting.
* @extack: The netlink extended ACK, for error reporting.
*
- * The caller must hold RTNL, until it's done interacting with the returned
- * phy_device.
+ * If a phy_device is returned the caller must hold rtnl_lock when calling
+ * this function, and until it's done interacting with the returned phy_device.
+ * IOW caller must hold rtnl_lock unless they know netdev has no phy_device.
*
* Return: A phy_device pointer corresponding either to the passed phy_index
* if one is provided. If not, the phy_device attached to the
diff --git a/net/ethtool/phy.c b/net/ethtool/phy.c
index ddc6eab701ed6..018b0412be862 100644
--- a/net/ethtool/phy.c
+++ b/net/ethtool/phy.c
@@ -78,7 +78,6 @@ static int phy_prepare_data(const struct ethnl_req_info *req_info,
struct phy_device *phydev;
int ret;
- /* RTNL is held by the caller */
phydev = ethnl_req_get_phydev(req_info, tb, ETHTOOL_A_PHY_HEADER,
info->extack);
if (IS_ERR_OR_NULL(phydev))