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.

Merge branch 'ethtool-use-the-rss-context-xarray-in-ring-deactivation-safety-check'

Jakub Kicinski says:

====================
ethtool: use the rss context XArray in ring deactivation safety-check

Now that we have an XArray storing information about all extra
RSS contexts - use it to extend checks already performed using
ethtool_get_max_rxfh_channel().
====================

Link: https://patch.msgid.link/20240710174043.754664-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+44 -19
+2 -4
net/ethtool/channels.c
··· 171 171 */ 172 172 if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use)) 173 173 max_rxnfc_in_use = 0; 174 - if (!netif_is_rxfh_configured(dev) || 175 - ethtool_get_max_rxfh_channel(dev, &max_rxfh_in_use)) 176 - max_rxfh_in_use = 0; 174 + max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev); 177 175 if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) { 178 - GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing indirection table settings"); 176 + GENL_SET_ERR_MSG_FMT(info, "requested channel counts are too low for existing indirection table (%d)", max_rxfh_in_use); 179 177 return -EINVAL; 180 178 } 181 179 if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) {
+40 -11
net/ethtool/common.c
··· 587 587 return err; 588 588 } 589 589 590 - int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max) 590 + static u32 ethtool_get_max_rss_ctx_channel(struct net_device *dev) 591 + { 592 + struct ethtool_rxfh_context *ctx; 593 + unsigned long context; 594 + u32 max_ring = 0; 595 + 596 + mutex_lock(&dev->ethtool->rss_lock); 597 + xa_for_each(&dev->ethtool->rss_ctx, context, ctx) { 598 + u32 i, *tbl; 599 + 600 + tbl = ethtool_rxfh_context_indir(ctx); 601 + for (i = 0; i < ctx->indir_size; i++) 602 + max_ring = max(max_ring, tbl[i]); 603 + } 604 + mutex_unlock(&dev->ethtool->rss_lock); 605 + 606 + return max_ring; 607 + } 608 + 609 + u32 ethtool_get_max_rxfh_channel(struct net_device *dev) 591 610 { 592 611 struct ethtool_rxfh_param rxfh = {}; 593 - u32 dev_size, current_max = 0; 612 + u32 dev_size, current_max; 594 613 int ret; 614 + 615 + /* While we do track whether RSS context has an indirection 616 + * table explicitly set by the user, no driver looks at that bit. 617 + * Assume drivers won't auto-regenerate the additional tables, 618 + * to be safe. 619 + */ 620 + current_max = ethtool_get_max_rss_ctx_channel(dev); 621 + 622 + if (!netif_is_rxfh_configured(dev)) 623 + return current_max; 595 624 596 625 if (!dev->ethtool_ops->get_rxfh_indir_size || 597 626 !dev->ethtool_ops->get_rxfh) 598 - return -EOPNOTSUPP; 627 + return current_max; 599 628 dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev); 600 629 if (dev_size == 0) 601 - return -EOPNOTSUPP; 630 + return current_max; 602 631 603 632 rxfh.indir = kcalloc(dev_size, sizeof(rxfh.indir[0]), GFP_USER); 604 633 if (!rxfh.indir) 605 - return -ENOMEM; 634 + return U32_MAX; 606 635 607 636 ret = dev->ethtool_ops->get_rxfh(dev, &rxfh); 608 - if (ret) 609 - goto out; 637 + if (ret) { 638 + current_max = U32_MAX; 639 + goto out_free; 640 + } 610 641 611 642 while (dev_size--) 612 643 current_max = max(current_max, rxfh.indir[dev_size]); 613 644 614 - *max = current_max; 615 - 616 - out: 645 + out_free: 617 646 kfree(rxfh.indir); 618 - return ret; 647 + return current_max; 619 648 } 620 649 621 650 int ethtool_check_ops(const struct ethtool_ops *ops)
+1 -1
net/ethtool/common.h
··· 42 42 bool convert_legacy_settings_to_link_ksettings( 43 43 struct ethtool_link_ksettings *link_ksettings, 44 44 const struct ethtool_cmd *legacy_settings); 45 - int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max); 45 + u32 ethtool_get_max_rxfh_channel(struct net_device *dev); 46 46 int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max); 47 47 int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info); 48 48
+1 -3
net/ethtool/ioctl.c
··· 2049 2049 * indirection table/rxnfc settings */ 2050 2050 if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use)) 2051 2051 max_rxnfc_in_use = 0; 2052 - if (!netif_is_rxfh_configured(dev) || 2053 - ethtool_get_max_rxfh_channel(dev, &max_rxfh_in_use)) 2054 - max_rxfh_in_use = 0; 2052 + max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev); 2055 2053 if (channels.combined_count + channels.rx_count <= 2056 2054 max_t(u64, max_rxnfc_in_use, max_rxfh_in_use)) 2057 2055 return -EINVAL;