]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ethtool: don't mux RXFH via rxnfc callbacks
authorJakub Kicinski <kuba@kernel.org>
Wed, 18 Jun 2025 20:38:23 +0000 (13:38 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 21 Jun 2025 14:55:00 +0000 (07:55 -0700)
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: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250618203823.1336156-11-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ethtool/ioctl.c

index a14cf901c32d6bdf5fedcb17f2e2f272078af821..82cde640aa87b1d9e95bc3114f8558a1bcf22a40 100644 (file)
@@ -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++) {
+               struct ethtool_rxfh_fields fields = {
+                       .flow_type      = 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,
-                       };
-
-                       if (ops->get_rxfh_fields(dev, &fields))
-                               continue;
-
-                       info.data = fields.data;
-               } else {
-                       if (ops->get_rxnfc(dev, &info, NULL))
-                               continue;
-               }
+               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,24 +1119,15 @@ 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,
-               };
-
-               if (info.flow_type & FLOW_RSS)
-                       fields.rss_context = info.rss_context;
+       fields.flow_type = info.flow_type & ~FLOW_RSS;
+       if (info.flow_type & FLOW_RSS)
+               fields.rss_context = info.rss_context;
 
-               ret = ops->get_rxfh_fields(dev, &fields);
-               if (ret < 0)
-                       return ret;
+       ret = ops->get_rxfh_fields(dev, &fields);
+       if (ret < 0)
+               return ret;
 
-               info.data = fields.data;
-       } else {
-               ret = ops->get_rxnfc(dev, &info, NULL);
-               if (ret < 0)
-                       return ret;
-       }
+       info.data = fields.data;
 
        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)