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: Track user-provided RSS indirection table size

Track the number of indirection table entries the user originally
provided (context 0/default as well!).

Replace IFF_RXFH_CONFIGURED with rss_indir_user_size: the flag is
redundant now that user_size captures the same information.

Add ethtool_rxfh_indir_lost() for drivers that must reset the
indirection table.

Convert bnxt and mlx5 to use it.

Signed-off-by: Björn Töpel <bjorn@kernel.org>
Link: https://patch.msgid.link/20260320085826.1957255-2-bjorn@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Björn Töpel and committed by
Jakub Kicinski
0475f9e7 9027497a

+70 -29
+1 -2
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 8118 8118 (bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) != 8119 8119 bnxt_get_nr_rss_ctxs(bp, rx_rings) || 8120 8120 bnxt_get_max_rss_ring(bp) >= rx_rings)) { 8121 - netdev_warn(bp->dev, "RSS table entries reverting to default\n"); 8122 - bp->dev->priv_flags &= ~IFF_RXFH_CONFIGURED; 8121 + ethtool_rxfh_indir_lost(bp->dev); 8123 8122 } 8124 8123 } 8125 8124 bp->rx_nr_rings = rx_rings;
+12 -9
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 6480 6480 6481 6481 /* max number of channels may have changed */ 6482 6482 max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); 6483 + 6484 + /* Locking is required by ethtool_rxfh_indir_lost() (sends 6485 + * ETHTOOL_MSG_RSS_NTF) and by netif_set_real_num_*_queues in case 6486 + * the netdev has been registered by this point (if this function 6487 + * was called in the reload or resume flow). 6488 + */ 6489 + if (need_lock) { 6490 + rtnl_lock(); 6491 + netdev_lock(priv->netdev); 6492 + } 6493 + 6483 6494 if (priv->channels.params.num_channels > max_nch) { 6484 6495 mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); 6485 6496 /* Reducing the number of channels - RXFH has to be reset, and 6486 6497 * mlx5e_num_channels_changed below will build the RQT. 6487 6498 */ 6488 - priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; 6499 + ethtool_rxfh_indir_lost(priv->netdev); 6489 6500 priv->channels.params.num_channels = max_nch; 6490 6501 if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) { 6491 6502 mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n"); ··· 6513 6502 /* 1. Set the real number of queues in the kernel the first time. 6514 6503 * 2. Set our default XPS cpumask. 6515 6504 * 3. Build the RQT. 6516 - * 6517 - * Locking is required by netif_set_real_num_*_queues in case the 6518 - * netdev has been registered by this point (if this function was called 6519 - * in the reload or resume flow). 6520 6505 */ 6521 - if (need_lock) { 6522 - rtnl_lock(); 6523 - netdev_lock(priv->netdev); 6524 - } 6525 6506 err = mlx5e_num_channels_changed(priv); 6526 6507 if (need_lock) { 6527 6508 netdev_unlock(priv->netdev);
+7
include/linux/ethtool.h
··· 176 176 * struct ethtool_rxfh_context - a custom RSS context configuration 177 177 * @indir_size: Number of u32 entries in indirection table 178 178 * @key_size: Size of hash key, in bytes 179 + * @indir_user_size: number of user provided entries for the 180 + * indirection table 179 181 * @priv_size: Size of driver private data, in bytes 180 182 * @hfunc: RSS hash function identifier. One of the %ETH_RSS_HASH_* 181 183 * @input_xfrm: Defines how the input data is transformed. Valid values are one ··· 188 186 struct ethtool_rxfh_context { 189 187 u32 indir_size; 190 188 u32 key_size; 189 + u32 indir_user_size; 191 190 u16 priv_size; 192 191 u8 hfunc; 193 192 u8 input_xfrm; ··· 217 214 } 218 215 219 216 void ethtool_rxfh_context_lost(struct net_device *dev, u32 context_id); 217 + void ethtool_rxfh_indir_lost(struct net_device *dev); 220 218 221 219 struct link_mode_info { 222 220 int speed; ··· 1341 1337 * @rss_ctx: XArray of custom RSS contexts 1342 1338 * @rss_lock: Protects entries in @rss_ctx. May be taken from 1343 1339 * within RTNL. 1340 + * @rss_indir_user_size: Number of user provided entries for the default 1341 + * (context 0) indirection table. 1344 1342 * @wol_enabled: Wake-on-LAN is enabled 1345 1343 * @module_fw_flash_in_progress: Module firmware flashing is in progress. 1346 1344 */ 1347 1345 struct ethtool_netdev_state { 1348 1346 struct xarray rss_ctx; 1349 1347 struct mutex rss_lock; 1348 + u32 rss_indir_user_size; 1350 1349 unsigned wol_enabled:1; 1351 1350 unsigned module_fw_flash_in_progress:1; 1352 1351 };
+1 -6
include/linux/netdevice.h
··· 1716 1716 * @IFF_OPENVSWITCH: device is a Open vSwitch master 1717 1717 * @IFF_L3MDEV_SLAVE: device is enslaved to an L3 master device 1718 1718 * @IFF_TEAM: device is a team device 1719 - * @IFF_RXFH_CONFIGURED: device has had Rx Flow indirection table configured 1720 1719 * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external 1721 1720 * entity (i.e. the master device for bridged veth) 1722 1721 * @IFF_MACSEC: device is a MACsec device ··· 1751 1752 IFF_OPENVSWITCH = 1<<20, 1752 1753 IFF_L3MDEV_SLAVE = 1<<21, 1753 1754 IFF_TEAM = 1<<22, 1754 - IFF_RXFH_CONFIGURED = 1<<23, 1755 1755 IFF_PHONY_HEADROOM = 1<<24, 1756 1756 IFF_MACSEC = 1<<25, 1757 1757 IFF_NO_RX_HANDLER = 1<<26, ··· 5578 5580 return netif_is_bond_slave(dev) || netif_is_team_port(dev); 5579 5581 } 5580 5582 5581 - static inline bool netif_is_rxfh_configured(const struct net_device *dev) 5582 - { 5583 - return dev->priv_flags & IFF_RXFH_CONFIGURED; 5584 - } 5583 + bool netif_is_rxfh_configured(const struct net_device *dev); 5585 5584 5586 5585 static inline bool netif_is_failover(const struct net_device *dev) 5587 5586 {
+28
net/ethtool/common.c
··· 1204 1204 } 1205 1205 EXPORT_SYMBOL(ethtool_rxfh_context_lost); 1206 1206 1207 + bool netif_is_rxfh_configured(const struct net_device *dev) 1208 + { 1209 + return dev->ethtool->rss_indir_user_size; 1210 + } 1211 + EXPORT_SYMBOL(netif_is_rxfh_configured); 1212 + 1213 + /** 1214 + * ethtool_rxfh_indir_lost - Notify core that the RSS indirection table was lost 1215 + * @dev: network device 1216 + * 1217 + * Drivers should call this when the device can no longer maintain the 1218 + * user-configured indirection table, typically after a HW fault recovery 1219 + * that reduced the maximum queue count. Marks the default RSS context 1220 + * indirection table as unconfigured and sends an %ETHTOOL_MSG_RSS_NTF 1221 + * notification. 1222 + */ 1223 + void ethtool_rxfh_indir_lost(struct net_device *dev) 1224 + { 1225 + WARN_ONCE(!rtnl_is_locked() && 1226 + !lockdep_is_held_type(&dev->ethtool->rss_lock, -1), 1227 + "RSS context lock assertion failed\n"); 1228 + 1229 + netdev_err(dev, "device error, RSS indirection table lost\n"); 1230 + dev->ethtool->rss_indir_user_size = 0; 1231 + ethtool_rss_notify(dev, ETHTOOL_MSG_RSS_NTF, 0); 1232 + } 1233 + EXPORT_SYMBOL(ethtool_rxfh_indir_lost); 1234 + 1207 1235 enum ethtool_link_medium ethtool_str_to_medium(const char *str) 1208 1236 { 1209 1237 int i;
+5 -4
net/ethtool/ioctl.c
··· 1405 1405 1406 1406 /* indicate whether rxfh was set to default */ 1407 1407 if (user_size == 0) 1408 - dev->priv_flags &= ~IFF_RXFH_CONFIGURED; 1408 + dev->ethtool->rss_indir_user_size = 0; 1409 1409 else 1410 - dev->priv_flags |= IFF_RXFH_CONFIGURED; 1410 + dev->ethtool->rss_indir_user_size = rxfh_dev.indir_size; 1411 1411 1412 1412 out_unlock: 1413 1413 mutex_unlock(&dev->ethtool->rss_lock); ··· 1722 1722 if (!rxfh_dev.rss_context) { 1723 1723 /* indicate whether rxfh was set to default */ 1724 1724 if (rxfh.indir_size == 0) 1725 - dev->priv_flags &= ~IFF_RXFH_CONFIGURED; 1725 + dev->ethtool->rss_indir_user_size = 0; 1726 1726 else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) 1727 - dev->priv_flags |= IFF_RXFH_CONFIGURED; 1727 + dev->ethtool->rss_indir_user_size = dev_indir_size; 1728 1728 } 1729 1729 /* Update rss_ctx tracking */ 1730 1730 if (rxfh_dev.rss_delete) { ··· 1737 1737 ctx->indir_configured = 1738 1738 rxfh.indir_size && 1739 1739 rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE; 1740 + ctx->indir_user_size = dev_indir_size; 1740 1741 } 1741 1742 if (rxfh_dev.key) { 1742 1743 memcpy(ethtool_rxfh_context_key(ctx), rxfh_dev.key,
+16 -8
net/ethtool/rss.c
··· 686 686 687 687 *mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size); 688 688 689 - return 0; 689 + return user_size; 690 690 691 691 err_free: 692 692 kfree(rxfh->indir); ··· 833 833 struct nlattr **tb = info->attrs; 834 834 struct rss_reply_data data = {}; 835 835 const struct ethtool_ops *ops; 836 + u32 indir_user_size; 836 837 int ret; 837 838 838 839 ops = dev->ethtool_ops; ··· 846 845 rxfh.rss_context = request->rss_context; 847 846 848 847 ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_reset, &mod); 849 - if (ret) 848 + if (ret < 0) 850 849 goto exit_clean_data; 850 + indir_user_size = ret; 851 851 indir_mod = !!tb[ETHTOOL_A_RSS_INDIR]; 852 852 853 853 rxfh.hfunc = data.hfunc; ··· 891 889 if (ret) 892 890 goto exit_unlock; 893 891 894 - if (ctx) 892 + if (ctx) { 895 893 rss_set_ctx_update(ctx, tb, &data, &rxfh); 896 - else if (indir_reset) 897 - dev->priv_flags &= ~IFF_RXFH_CONFIGURED; 898 - else if (indir_mod) 899 - dev->priv_flags |= IFF_RXFH_CONFIGURED; 894 + if (indir_user_size) 895 + ctx->indir_user_size = indir_user_size; 896 + } else if (indir_reset) { 897 + dev->ethtool->rss_indir_user_size = 0; 898 + } else if (indir_mod) { 899 + dev->ethtool->rss_indir_user_size = indir_user_size; 900 + } 900 901 901 902 exit_unlock: 902 903 mutex_unlock(&dev->ethtool->rss_lock); ··· 1004 999 const struct ethtool_ops *ops; 1005 1000 struct rss_req_info req = {}; 1006 1001 struct net_device *dev; 1002 + u32 indir_user_size; 1007 1003 struct sk_buff *rsp; 1008 1004 void *hdr; 1009 1005 u32 limit; ··· 1041 1035 goto exit_ops; 1042 1036 1043 1037 ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_dflt, &mod); 1044 - if (ret) 1038 + if (ret < 0) 1045 1039 goto exit_clean_data; 1040 + indir_user_size = ret; 1046 1041 1047 1042 ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod); 1048 1043 ··· 1087 1080 1088 1081 /* Store the config from rxfh to Xarray.. */ 1089 1082 rss_set_ctx_update(ctx, tb, &data, &rxfh); 1083 + ctx->indir_user_size = indir_user_size; 1090 1084 /* .. copy from Xarray to data. */ 1091 1085 __rss_prepare_ctx(dev, &data, ctx); 1092 1086