From 7be92514b99c15b89def6d72bbc84c354f89a025 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 15 May 2020 12:49:00 -0700 Subject: [PATCH 1/3] ethtool: check if there is at least one channel for TX/RX in the core Having a channel config with no ability to RX or TX traffic is clearly wrong. Check for this in the core so the drivers don't have to. Signed-off-by: Jakub Kicinski Reviewed-by: Michal Kubecek Signed-off-by: David S. Miller --- net/ethtool/channels.c | 20 ++++++++++++++++++-- net/ethtool/ioctl.c | 5 +++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/net/ethtool/channels.c b/net/ethtool/channels.c index 389924b65d05..3aa4975919d7 100644 --- a/net/ethtool/channels.c +++ b/net/ethtool/channels.c @@ -129,13 +129,13 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info) { struct nlattr *tb[ETHTOOL_A_CHANNELS_MAX + 1]; unsigned int from_channel, old_total, i; + bool mod = false, mod_combined = false; struct ethtool_channels channels = {}; struct ethnl_req_info req_info = {}; const struct nlattr *err_attr; const struct ethtool_ops *ops; struct net_device *dev; u32 max_rx_in_use = 0; - bool mod = false; int ret; ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb, @@ -170,7 +170,8 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info) ethnl_update_u32(&channels.other_count, tb[ETHTOOL_A_CHANNELS_OTHER_COUNT], &mod); ethnl_update_u32(&channels.combined_count, - tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT], &mod); + tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT], &mod_combined); + mod |= mod_combined; ret = 0; if (!mod) goto out_ops; @@ -193,6 +194,21 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info) goto out_ops; } + /* ensure there is at least one RX and one TX channel */ + if (!channels.combined_count && !channels.rx_count) + err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; + else if (!channels.combined_count && !channels.tx_count) + err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; + else + err_attr = NULL; + if (err_attr) { + if (mod_combined) + err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; + ret = -EINVAL; + NL_SET_ERR_MSG_ATTR(info->extack, err_attr, "requested channel counts would result in no RX or TX channel being configured"); + goto out_ops; + } + /* ensure the new Rx count fits within the configured Rx flow * indirection table settings */ diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 52102ab1709b..a574d60111fa 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1676,6 +1676,11 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, channels.other_count > curr.max_other) return -EINVAL; + /* ensure there is at least one RX and one TX channel */ + if (!channels.combined_count && + (!channels.rx_count || !channels.tx_count)) + return -EINVAL; + /* ensure the new Rx count fits within the configured Rx flow * indirection table settings */ if (netif_is_rxfh_configured(dev) && From 4df6ff2a99920254ce8c2a3c418ddabc69ff16fe Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 15 May 2020 12:49:01 -0700 Subject: [PATCH 2/3] nfp: don't check lack of RX/TX channels Core will now perform this check. Signed-off-by: Jakub Kicinski Reviewed-by: Michal Kubecek Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index a5aa3219d112..6eb9fb9a1814 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -1438,8 +1438,7 @@ static int nfp_net_set_channels(struct net_device *netdev, unsigned int total_rx, total_tx; /* Reject unsupported */ - if (!channel->combined_count || - channel->other_count != NFP_NET_NON_Q_VECTORS || + if (channel->other_count != NFP_NET_NON_Q_VECTORS || (channel->rx_count && channel->tx_count)) return -EINVAL; From 75c36dbb1c3790eab909344b758decce6bb432da Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 15 May 2020 12:49:02 -0700 Subject: [PATCH 3/3] ethtool: don't call set_channels in drivers if config didn't change Don't call drivers if nothing changed. Netlink code already contains this logic. Signed-off-by: Jakub Kicinski Reviewed-by: Michal Kubecek Signed-off-by: David S. Miller --- net/ethtool/ioctl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index a574d60111fa..eeb1137a3f23 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1669,6 +1669,12 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, dev->ethtool_ops->get_channels(dev, &curr); + if (channels.rx_count == curr.rx_count && + channels.tx_count == curr.tx_count && + channels.combined_count == curr.combined_count && + channels.other_count == curr.other_count) + return 0; + /* ensure new counts are within the maximums */ if (channels.rx_count > curr.max_rx || channels.tx_count > curr.max_tx ||