Commit 739d18cc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parent 5ec353db
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -810,13 +810,10 @@ int efx_ethtool_get_rxfh_fields(struct net_device *net_dev,

	ctx = &efx->rss_context.priv;

	mutex_lock(&net_dev->ethtool->rss_lock);
	if (info->rss_context) {
		ctx = efx_find_rss_context_entry(efx, info->rss_context);
		if (!ctx) {
			rc = -ENOENT;
			goto out_unlock;
		}
		if (!ctx)
			return -ENOENT;
	}

	data = 0;
@@ -850,8 +847,6 @@ int efx_ethtool_get_rxfh_fields(struct net_device *net_dev,
	}
out_setdata_unlock:
	info->data = data;
out_unlock:
	mutex_unlock(&net_dev->ethtool->rss_lock);
	return rc;
}

+10 −5
Original line number Diff line number Diff line
@@ -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)