Commit 72792461 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

net: ethtool: don't mux RXFH via rxnfc callbacks



All drivers have been converted. Stop using the rxnfc fallbacks
for Rx Flow Hashing configuration.

Joe pointed out in earlier review that in ethtool_set_rxfh()
we need both .get_rxnfc and .get_rxfh_fields, because we need
both the ring count and flow hashing (because we call
ethtool_check_flow_types()). IOW the existing check added
for transitioning drivers was buggy.

Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250618203823.1336156-11-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 188793f0
Loading
Loading
Loading
Loading
+18 −41
Original line number Diff line number Diff line
@@ -1037,33 +1037,21 @@ static int ethtool_check_xfrm_rxfh(u32 input_xfrm, u64 rxfh)
static int ethtool_check_flow_types(struct net_device *dev, u32 input_xfrm)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;
	struct ethtool_rxnfc info = {
		.cmd = ETHTOOL_GRXFH,
	};
	int err;
	u32 i;

	for (i = 0; i < __FLOW_TYPE_COUNT; i++) {
		if (!flow_type_hashable(i))
			continue;

		info.flow_type = i;

		if (ops->get_rxfh_fields) {
		struct ethtool_rxfh_fields fields = {
				.flow_type	= info.flow_type,
			.flow_type	= i,
		};

			if (ops->get_rxfh_fields(dev, &fields))
		if (!flow_type_hashable(i))
			continue;

			info.data = fields.data;
		} else {
			if (ops->get_rxnfc(dev, &info, NULL))
		if (ops->get_rxfh_fields(dev, &fields))
			continue;
		}

		err = ethtool_check_xfrm_rxfh(input_xfrm, info.data);
		err = ethtool_check_xfrm_rxfh(input_xfrm, fields.data);
		if (err)
			return err;
	}
@@ -1080,7 +1068,7 @@ ethtool_set_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
	size_t info_size = sizeof(info);
	int rc;

	if (!ops->set_rxnfc && !ops->set_rxfh_fields)
	if (!ops->set_rxfh_fields)
		return -EOPNOTSUPP;

	rc = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr);
@@ -1103,9 +1091,6 @@ ethtool_set_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
			return rc;
	}

	if (!ops->set_rxfh_fields)
		return ops->set_rxnfc(dev, &info);

	fields.data = info.data;
	fields.flow_type = info.flow_type & ~FLOW_RSS;
	if (info.flow_type & FLOW_RSS)
@@ -1120,9 +1105,10 @@ ethtool_get_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
	struct ethtool_rxnfc info;
	size_t info_size = sizeof(info);
	const struct ethtool_ops *ops = dev->ethtool_ops;
	struct ethtool_rxfh_fields fields = {};
	int ret;

	if (!ops->get_rxnfc && !ops->get_rxfh_fields)
	if (!ops->get_rxfh_fields)
		return -EOPNOTSUPP;

	ret = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr);
@@ -1133,11 +1119,7 @@ ethtool_get_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
	    !ops->rxfh_per_ctx_fields)
		return -EINVAL;

	if (ops->get_rxfh_fields) {
		struct ethtool_rxfh_fields fields = {
			.flow_type	= info.flow_type & ~FLOW_RSS,
		};

	fields.flow_type = info.flow_type & ~FLOW_RSS;
	if (info.flow_type & FLOW_RSS)
		fields.rss_context = info.rss_context;

@@ -1146,11 +1128,6 @@ ethtool_get_rxfh_fields(struct net_device *dev, u32 cmd, void __user *useraddr)
		return ret;

	info.data = fields.data;
	} else {
		ret = ops->get_rxnfc(dev, &info, NULL);
		if (ret < 0)
			return ret;
	}

	return ethtool_rxnfc_copy_to_user(useraddr, &info, info_size, NULL);
}
@@ -1528,7 +1505,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
	u8 *rss_config;
	int ret;

	if ((!ops->get_rxnfc && !ops->get_rxfh_fields) || !ops->set_rxfh)
	if (!ops->get_rxnfc || !ops->get_rxfh_fields || !ops->set_rxfh)
		return -EOPNOTSUPP;

	if (ops->get_rxfh_indir_size)