summaryrefslogtreecommitdiff
path: root/net/ethtool
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-06-26 23:28:47 +0300
committerJakub Kicinski <kuba@kernel.org>2025-06-30 18:41:24 +0300
commit739d18cce105ce3c8437ad56bec3fbe62f0210bb (patch)
treebc59f40f9855d3806c8da78454b763c7c2bff45c /net/ethtool
parent5ec353dbff4fd5fed21fa2104c3e01444cc06c89 (diff)
downloadlinux-739d18cce105ce3c8437ad56bec3fbe62f0210bb.tar.xz
net: ethtool: move rxfh_fields callbacks under the rss_lock
Netlink code will want to perform the RSS_SET operation atomically under the rss_lock. sfc wants to hold the rss_lock in rxfh_fields_get, which makes that difficult. Lets move the locking up to the core so that for all driver-facing callbacks rss_lock is taken consistently by the core. Link: https://patch.msgid.link/20250626202848.104457-3-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ethtool')
-rw-r--r--net/ethtool/ioctl.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index ce7d720b3c79..df376628ba19 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1096,7 +1096,10 @@ ethtool_set_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
if (info.flow_type & FLOW_RSS)
fields.rss_context = info.rss_context;
- return ops->set_rxfh_fields(dev, &fields, NULL);
+ mutex_lock(&dev->ethtool->rss_lock);
+ rc = ops->set_rxfh_fields(dev, &fields, NULL);
+ mutex_unlock(&dev->ethtool->rss_lock);
+ return rc;
}
static noinline_for_stack int
@@ -1123,7 +1126,9 @@ ethtool_get_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
if (info.flow_type & FLOW_RSS)
fields.rss_context = info.rss_context;
+ mutex_lock(&dev->ethtool->rss_lock);
ret = ops->get_rxfh_fields(dev, &fields);
+ mutex_unlock(&dev->ethtool->rss_lock);
if (ret < 0)
return ret;
@@ -1553,10 +1558,6 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
rxfh.input_xfrm == RXH_XFRM_NO_CHANGE))
return -EINVAL;
- ret = ethtool_check_flow_types(dev, rxfh.input_xfrm);
- if (ret)
- return ret;
-
indir_bytes = dev_indir_size * sizeof(rxfh_dev.indir[0]);
/* Check settings which may be global rather than per RSS-context */
@@ -1617,6 +1618,10 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
mutex_lock(&dev->ethtool->rss_lock);
+ ret = ethtool_check_flow_types(dev, rxfh.input_xfrm);
+ if (ret)
+ goto out_unlock;
+
if (rxfh.rss_context && rxfh_dev.rss_delete) {
ret = ethtool_check_rss_ctx_busy(dev, rxfh.rss_context);
if (ret)