Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ethtool: refactor checking max channels

Currently ethtool_set_channel calls separate functions to check whether
the new channel number violates rss configuration or flow steering
configuration.

Very soon we need to check whether the new channel number violates
memory provider configuration as well.

To do all 3 checks cleanly, add a wrapper around
ethtool_get_max_rxnfc_channel() and ethtool_get_max_rxfh_channel(),
which does both checks. We can later extend this wrapper to add the
memory provider check in one place.

Note that in the current code, we put a descriptive genl error message
when we run into issues. To preserve the error message, we pass the
genl_info* to the common helper. The ioctl calls can pass NULL instead.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20240808205345.2141858-1-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Mina Almasry and committed by
Jakub Kicinski
916b7d31 600a9193

+42 -30
+4 -16
net/ethtool/channels.c
··· 114 114 struct net_device *dev = req_info->dev; 115 115 struct ethtool_channels channels = {}; 116 116 struct nlattr **tb = info->attrs; 117 - u32 err_attr, max_rxfh_in_use; 118 - u64 max_rxnfc_in_use; 117 + u32 err_attr; 119 118 int ret; 120 119 121 120 dev->ethtool_ops->get_channels(dev, &channels); ··· 165 166 return -EINVAL; 166 167 } 167 168 168 - /* ensure the new Rx count fits within the configured Rx flow 169 - * indirection table/rxnfc settings 170 - */ 171 - if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use)) 172 - max_rxnfc_in_use = 0; 173 - max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev); 174 - if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) { 175 - GENL_SET_ERR_MSG_FMT(info, "requested channel counts are too low for existing indirection table (%d)", max_rxfh_in_use); 176 - return -EINVAL; 177 - } 178 - if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) { 179 - GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing ntuple filter settings"); 180 - return -EINVAL; 181 - } 169 + ret = ethtool_check_max_channel(dev, channels, info); 170 + if (ret) 171 + return ret; 182 172 183 173 /* Disabling channels, query zero-copy AF_XDP sockets */ 184 174 from_channel = channels.combined_count +
+30 -2
net/ethtool/common.c
··· 6 6 #include <linux/rtnetlink.h> 7 7 #include <linux/ptp_clock_kernel.h> 8 8 9 + #include "netlink.h" 9 10 #include "common.h" 10 11 11 12 const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = { ··· 540 539 return info.rule_cnt; 541 540 } 542 541 543 - int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max) 542 + static int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max) 544 543 { 545 544 const struct ethtool_ops *ops = dev->ethtool_ops; 546 545 struct ethtool_rxnfc *info; ··· 610 609 return max_ring; 611 610 } 612 611 613 - u32 ethtool_get_max_rxfh_channel(struct net_device *dev) 612 + static u32 ethtool_get_max_rxfh_channel(struct net_device *dev) 614 613 { 615 614 struct ethtool_rxfh_param rxfh = {}; 616 615 u32 dev_size, current_max; ··· 649 648 out_free: 650 649 kfree(rxfh.indir); 651 650 return current_max; 651 + } 652 + 653 + int ethtool_check_max_channel(struct net_device *dev, 654 + struct ethtool_channels channels, 655 + struct genl_info *info) 656 + { 657 + u64 max_rxnfc_in_use; 658 + u32 max_rxfh_in_use; 659 + 660 + /* ensure the new Rx count fits within the configured Rx flow 661 + * indirection table/rxnfc settings 662 + */ 663 + if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use)) 664 + max_rxnfc_in_use = 0; 665 + max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev); 666 + if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) { 667 + if (info) 668 + GENL_SET_ERR_MSG_FMT(info, "requested channel counts are too low for existing indirection table (%d)", max_rxfh_in_use); 669 + return -EINVAL; 670 + } 671 + if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) { 672 + if (info) 673 + GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing ntuple filter settings"); 674 + return -EINVAL; 675 + } 676 + 677 + return 0; 652 678 } 653 679 654 680 int ethtool_check_ops(const struct ethtool_ops *ops)
+5 -2
net/ethtool/common.h
··· 20 20 u8 duplex; 21 21 }; 22 22 23 + struct genl_info; 24 + 23 25 extern const char 24 26 netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]; 25 27 extern const char ··· 44 42 bool convert_legacy_settings_to_link_ksettings( 45 43 struct ethtool_link_ksettings *link_ksettings, 46 44 const struct ethtool_cmd *legacy_settings); 47 - u32 ethtool_get_max_rxfh_channel(struct net_device *dev); 48 - int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max); 45 + int ethtool_check_max_channel(struct net_device *dev, 46 + struct ethtool_channels channels, 47 + struct genl_info *info); 49 48 int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info); 50 49 51 50 extern const struct ethtool_phy_ops *ethtool_phy_ops;
+3 -10
net/ethtool/ioctl.c
··· 2069 2069 { 2070 2070 struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS }; 2071 2071 u16 from_channel, to_channel; 2072 - u64 max_rxnfc_in_use; 2073 - u32 max_rxfh_in_use; 2074 2072 unsigned int i; 2075 2073 int ret; 2076 2074 ··· 2098 2100 (!channels.rx_count || !channels.tx_count)) 2099 2101 return -EINVAL; 2100 2102 2101 - /* ensure the new Rx count fits within the configured Rx flow 2102 - * indirection table/rxnfc settings */ 2103 - if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use)) 2104 - max_rxnfc_in_use = 0; 2105 - max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev); 2106 - if (channels.combined_count + channels.rx_count <= 2107 - max_t(u64, max_rxnfc_in_use, max_rxfh_in_use)) 2108 - return -EINVAL; 2103 + ret = ethtool_check_max_channel(dev, channels, NULL); 2104 + if (ret) 2105 + return ret; 2109 2106 2110 2107 /* Disabling channels, query zero-copy AF_XDP sockets */ 2111 2108 from_channel = channels.combined_count +