From: "Björn Töpel" <bjorn@kernel.org>
To: Michael Chan <michael.chan@broadcom.com>,
Pavan Chebbi <pavan.chebbi@broadcom.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Saeed Mahameed <saeedm@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
Simon Horman <horms@kernel.org>, Shuah Khan <shuah@kernel.org>,
netdev@vger.kernel.org
Cc: "Björn Töpel" <bjorn@kernel.org>,
"Maxime Chevallier" <maxime.chevallier@bootlin.com>,
"Gal Pressman" <gal@nvidia.com>,
"Willem de Bruijn" <willemb@google.com>,
linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH net-next v6 1/4] ethtool: Track user-provided RSS indirection table size
Date: Wed, 18 Mar 2026 13:25:58 +0100 [thread overview]
Message-ID: <20260318122603.264550-2-bjorn@kernel.org> (raw)
In-Reply-To: <20260318122603.264550-1-bjorn@kernel.org>
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_clear() 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>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
include/linux/ethtool.h | 7 ++++++
include/linux/netdevice.h | 7 +-----
net/ethtool/common.c | 20 ++++++++++++++++
net/ethtool/ioctl.c | 9 +++----
| 24 ++++++++++++-------
7 files changed, 51 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index c982aac714d1..04da3f708b4b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -8117,7 +8117,7 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
bnxt_get_nr_rss_ctxs(bp, rx_rings) ||
bnxt_get_max_rss_ring(bp) >= rx_rings)) {
netdev_warn(bp->dev, "RSS table entries reverting to default\n");
- bp->dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ ethtool_rxfh_indir_clear(bp->dev);
}
}
bp->rx_nr_rings = rx_rings;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index f7009da94f0b..1a010a115cff 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6488,7 +6488,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
/* Reducing the number of channels - RXFH has to be reset, and
* mlx5e_num_channels_changed below will build the RQT.
*/
- priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ ethtool_rxfh_indir_clear(priv->netdev);
priv->channels.params.num_channels = max_nch;
if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n");
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 83c375840835..d4d3c57bc7c0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -176,6 +176,8 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
* struct ethtool_rxfh_context - a custom RSS context configuration
* @indir_size: Number of u32 entries in indirection table
* @key_size: Size of hash key, in bytes
+ * @indir_user_size: number of user provided entries for the
+ * indirection table
* @priv_size: Size of driver private data, in bytes
* @hfunc: RSS hash function identifier. One of the %ETH_RSS_HASH_*
* @input_xfrm: Defines how the input data is transformed. Valid values are one
@@ -186,6 +188,7 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
struct ethtool_rxfh_context {
u32 indir_size;
u32 key_size;
+ u32 indir_user_size;
u16 priv_size;
u8 hfunc;
u8 input_xfrm;
@@ -214,6 +217,7 @@ static inline u8 *ethtool_rxfh_context_key(struct ethtool_rxfh_context *ctx)
}
void ethtool_rxfh_context_lost(struct net_device *dev, u32 context_id);
+void ethtool_rxfh_indir_clear(struct net_device *dev);
struct link_mode_info {
int speed;
@@ -1333,12 +1337,15 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
* @rss_ctx: XArray of custom RSS contexts
* @rss_lock: Protects entries in @rss_ctx. May be taken from
* within RTNL.
+ * @rss_indir_user_size: Number of user provided entries for the default
+ * (context 0) indirection table.
* @wol_enabled: Wake-on-LAN is enabled
* @module_fw_flash_in_progress: Module firmware flashing is in progress.
*/
struct ethtool_netdev_state {
struct xarray rss_ctx;
struct mutex rss_lock;
+ u32 rss_indir_user_size;
unsigned wol_enabled:1;
unsigned module_fw_flash_in_progress:1;
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ae269a2e7f4d..dc28954d4df6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1714,7 +1714,6 @@ struct net_device_ops {
* @IFF_OPENVSWITCH: device is a Open vSwitch master
* @IFF_L3MDEV_SLAVE: device is enslaved to an L3 master device
* @IFF_TEAM: device is a team device
- * @IFF_RXFH_CONFIGURED: device has had Rx Flow indirection table configured
* @IFF_PHONY_HEADROOM: the headroom value is controlled by an external
* entity (i.e. the master device for bridged veth)
* @IFF_MACSEC: device is a MACsec device
@@ -1750,7 +1749,6 @@ enum netdev_priv_flags {
IFF_OPENVSWITCH = 1<<20,
IFF_L3MDEV_SLAVE = 1<<21,
IFF_TEAM = 1<<22,
- IFF_RXFH_CONFIGURED = 1<<23,
IFF_PHONY_HEADROOM = 1<<24,
IFF_MACSEC = 1<<25,
IFF_NO_RX_HANDLER = 1<<26,
@@ -5568,10 +5566,7 @@ static inline bool netif_is_lag_port(const struct net_device *dev)
return netif_is_bond_slave(dev) || netif_is_team_port(dev);
}
-static inline bool netif_is_rxfh_configured(const struct net_device *dev)
-{
- return dev->priv_flags & IFF_RXFH_CONFIGURED;
-}
+bool netif_is_rxfh_configured(const struct net_device *dev);
static inline bool netif_is_failover(const struct net_device *dev)
{
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index e252cf20c22f..ee91f1155830 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -1204,6 +1204,26 @@ void ethtool_rxfh_context_lost(struct net_device *dev, u32 context_id)
}
EXPORT_SYMBOL(ethtool_rxfh_context_lost);
+bool netif_is_rxfh_configured(const struct net_device *dev)
+{
+ return dev->ethtool->rss_indir_user_size;
+}
+EXPORT_SYMBOL(netif_is_rxfh_configured);
+
+/**
+ * ethtool_rxfh_indir_clear - Clear user indirection table config
+ * @dev: network device
+ *
+ * Mark the default RSS context indirection table as unconfigured and
+ * send an %ETHTOOL_MSG_RSS_NTF notification.
+ */
+void ethtool_rxfh_indir_clear(struct net_device *dev)
+{
+ dev->ethtool->rss_indir_user_size = 0;
+ ethtool_rss_notify(dev, ETHTOOL_MSG_RSS_NTF, 0);
+}
+EXPORT_SYMBOL(ethtool_rxfh_indir_clear);
+
enum ethtool_link_medium ethtool_str_to_medium(const char *str)
{
int i;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index ff4b4780d6af..3d31a5a041e3 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1404,9 +1404,9 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
/* indicate whether rxfh was set to default */
if (user_size == 0)
- dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ dev->ethtool->rss_indir_user_size = 0;
else
- dev->priv_flags |= IFF_RXFH_CONFIGURED;
+ dev->ethtool->rss_indir_user_size = rxfh_dev.indir_size;
out_unlock:
mutex_unlock(&dev->ethtool->rss_lock);
@@ -1721,9 +1721,9 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
if (!rxfh_dev.rss_context) {
/* indicate whether rxfh was set to default */
if (rxfh.indir_size == 0)
- dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ dev->ethtool->rss_indir_user_size = 0;
else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
- dev->priv_flags |= IFF_RXFH_CONFIGURED;
+ dev->ethtool->rss_indir_user_size = dev_indir_size;
}
/* Update rss_ctx tracking */
if (rxfh_dev.rss_delete) {
@@ -1736,6 +1736,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
ctx->indir_configured =
rxfh.indir_size &&
rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE;
+ ctx->indir_user_size = dev_indir_size;
}
if (rxfh_dev.key) {
memcpy(ethtool_rxfh_context_key(ctx), rxfh_dev.key,
--git a/net/ethtool/rss.c b/net/ethtool/rss.c
index da5934cceb07..e6fc6e64fb27 100644
--- a/net/ethtool/rss.c
+++ b/net/ethtool/rss.c
@@ -686,7 +686,7 @@ rss_set_prep_indir(struct net_device *dev, struct genl_info *info,
*mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size);
- return 0;
+ return user_size;
err_free:
kfree(rxfh->indir);
@@ -833,6 +833,7 @@ ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
struct nlattr **tb = info->attrs;
struct rss_reply_data data = {};
const struct ethtool_ops *ops;
+ u32 indir_user_size;
int ret;
ops = dev->ethtool_ops;
@@ -845,8 +846,9 @@ ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
rxfh.rss_context = request->rss_context;
ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_reset, &mod);
- if (ret)
+ if (ret < 0)
goto exit_clean_data;
+ indir_user_size = ret;
indir_mod = !!tb[ETHTOOL_A_RSS_INDIR];
rxfh.hfunc = data.hfunc;
@@ -889,12 +891,15 @@ ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
if (ret)
goto exit_unlock;
- if (ctx)
+ if (ctx) {
rss_set_ctx_update(ctx, tb, &data, &rxfh);
- else if (indir_reset)
- dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
- else if (indir_mod)
- dev->priv_flags |= IFF_RXFH_CONFIGURED;
+ if (indir_user_size)
+ ctx->indir_user_size = indir_user_size;
+ } else if (indir_reset) {
+ dev->ethtool->rss_indir_user_size = 0;
+ } else if (indir_mod) {
+ dev->ethtool->rss_indir_user_size = indir_user_size;
+ }
exit_unlock:
mutex_unlock(&dev->ethtool->rss_lock);
@@ -999,6 +1004,7 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
const struct ethtool_ops *ops;
struct rss_req_info req = {};
struct net_device *dev;
+ u32 indir_user_size;
struct sk_buff *rsp;
void *hdr;
u32 limit;
@@ -1035,8 +1041,9 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
goto exit_ops;
ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_dflt, &mod);
- if (ret)
+ if (ret < 0)
goto exit_clean_data;
+ indir_user_size = ret;
ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod);
@@ -1080,6 +1087,7 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
/* Store the config from rxfh to Xarray.. */
rss_set_ctx_update(ctx, tb, &data, &rxfh);
+ ctx->indir_user_size = indir_user_size;
/* .. copy from Xarray to data. */
__rss_prepare_ctx(dev, &data, ctx);
--
2.53.0
next prev parent reply other threads:[~2026-03-18 12:26 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-18 12:25 [PATCH net-next v6 0/4] ethtool: Dynamic RSS context indirection table resizing Björn Töpel
2026-03-18 12:25 ` Björn Töpel [this message]
2026-03-19 2:23 ` [PATCH net-next v6 1/4] ethtool: Track user-provided RSS indirection table size Jakub Kicinski
2026-03-18 12:25 ` [PATCH net-next v6 2/4] ethtool: Add RSS indirection table resize helpers Björn Töpel
2026-03-18 12:26 ` [PATCH net-next v6 3/4] bnxt_en: Resize RSS contexts on channel count change Björn Töpel
2026-03-18 12:26 ` [PATCH net-next v6 4/4] selftests: rss_drv: Add RSS indirection table resize tests Björn Töpel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260318122603.264550-2-bjorn@kernel.org \
--to=bjorn@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gal@nvidia.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=maxime.chevallier@bootlin.com \
--cc=mbloch@nvidia.com \
--cc=michael.chan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pavan.chebbi@broadcom.com \
--cc=saeedm@nvidia.com \
--cc=shuah@kernel.org \
--cc=tariqt@nvidia.com \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox