public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
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>,
	Simon Horman <horms@kernel.org>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Cc: "Björn Töpel" <bjorn@kernel.org>,
	"Willem de Bruijn" <willemb@google.com>
Subject: [PATCH net-next 3/5] netdevsim: Add RSS context support with dynamic table sizing
Date: Tue,  3 Mar 2026 19:15:31 +0100	[thread overview]
Message-ID: <20260303181535.2671734-4-bjorn@kernel.org> (raw)
In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org>

Add RSS indirection table, hash key, and non-default RSS context
support to netdevsim. The create/modify/remove context callbacks are
no-ops; the core manages context state in its xarray.

The table size is dynamic: roundup_pow_of_two(channels) * 16, capped
at NSIM_RSS_INDIR_MAX (128). This mimics drivers like bnxt where the
table size changes with the queue count.

nsim_set_channels() uses the core resize helpers to fold/unfold tables
on channel count changes, exercising the full resize path.

Signed-off-by: Björn Töpel <bjorn@kernel.org>
---
 drivers/net/netdevsim/ethtool.c   | 119 +++++++++++++++++++++++++++++-
 drivers/net/netdevsim/netdevsim.h |   4 +
 2 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 36a201533aae..c6d60b467054 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -2,6 +2,7 @@
 // Copyright (c) 2020 Facebook
 
 #include <linux/debugfs.h>
+#include <linux/ethtool.h>
 #include <linux/random.h>
 #include <net/netdev_queues.h>
 
@@ -117,19 +118,121 @@ nsim_wake_queues(struct net_device *dev)
 	rcu_read_unlock();
 }
 
+static u32 nsim_get_rx_ring_count(struct net_device *dev)
+{
+	struct netdevsim *ns = netdev_priv(dev);
+
+	return ns->ethtool.channels;
+}
+
+static u32 nsim_rss_indir_size(u32 channels)
+{
+	return min_t(u32, roundup_pow_of_two(channels) * 16, NSIM_RSS_INDIR_MAX);
+}
+
+static u32 nsim_get_rxfh_indir_size(struct net_device *dev)
+{
+	struct netdevsim *ns = netdev_priv(dev);
+
+	return nsim_rss_indir_size(ns->ethtool.channels);
+}
+
+static u32 nsim_get_rxfh_key_size(struct net_device *dev)
+{
+	return NSIM_RSS_HKEY_SIZE;
+}
+
+static int nsim_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh)
+{
+	u32 indir_size = nsim_get_rxfh_indir_size(dev);
+	struct netdevsim *ns = netdev_priv(dev);
+
+	rxfh->hfunc = ETH_RSS_HASH_TOP;
+
+	if (rxfh->indir)
+		memcpy(rxfh->indir, ns->ethtool.rss_indir_tbl, indir_size * sizeof(u32));
+	if (rxfh->key)
+		memcpy(rxfh->key, ns->ethtool.rss_hkey, NSIM_RSS_HKEY_SIZE);
+
+	return 0;
+}
+
+static int nsim_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
+			 struct netlink_ext_ack *extack)
+{
+	u32 indir_size = nsim_get_rxfh_indir_size(dev);
+	struct netdevsim *ns = netdev_priv(dev);
+
+	if (rxfh->indir)
+		memcpy(ns->ethtool.rss_indir_tbl, rxfh->indir, indir_size * sizeof(u32));
+	if (rxfh->key)
+		memcpy(ns->ethtool.rss_hkey, rxfh->key, NSIM_RSS_HKEY_SIZE);
+
+	return 0;
+}
+
+static int nsim_create_rxfh_context(struct net_device *dev, struct ethtool_rxfh_context *ctx,
+				    const struct ethtool_rxfh_param *rxfh,
+				    struct netlink_ext_ack *extack)
+{
+	return 0;
+}
+
+static int nsim_modify_rxfh_context(struct net_device *dev, struct ethtool_rxfh_context *ctx,
+				    const struct ethtool_rxfh_param *rxfh,
+				    struct netlink_ext_ack *extack)
+{
+	return 0;
+}
+
+static int nsim_remove_rxfh_context(struct net_device *dev, struct ethtool_rxfh_context *ctx,
+				    u32 rss_context, struct netlink_ext_ack *extack)
+{
+	return 0;
+}
+
+static void nsim_rss_init(struct netdevsim *ns)
+{
+	u32 i, indir_size = nsim_rss_indir_size(ns->ethtool.channels);
+
+	for (i = 0; i < indir_size; i++)
+		ns->ethtool.rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, ns->ethtool.channels);
+}
+
 static int
 nsim_set_channels(struct net_device *dev, struct ethtool_channels *ch)
 {
 	struct netdevsim *ns = netdev_priv(dev);
+	u32 old_indir_size, new_indir_size;
 	int err;
 
-	err = netif_set_real_num_queues(dev, ch->combined_count,
-					ch->combined_count);
+	old_indir_size = nsim_get_rxfh_indir_size(dev);
+	new_indir_size = nsim_rss_indir_size(ch->combined_count);
+
+	if (old_indir_size != new_indir_size) {
+		if (netif_is_rxfh_configured(dev) &&
+		    ethtool_rxfh_indir_can_resize(ns->ethtool.rss_indir_tbl,
+						  old_indir_size, new_indir_size))
+			return -EINVAL;
+
+		err = ethtool_rxfh_contexts_resize_all(dev, new_indir_size);
+		if (err)
+			return err;
+
+		if (netif_is_rxfh_configured(dev))
+			ethtool_rxfh_indir_resize(ns->ethtool.rss_indir_tbl,
+						  old_indir_size, new_indir_size);
+	}
+
+	err = netif_set_real_num_queues(dev, ch->combined_count, ch->combined_count);
 	if (err)
 		return err;
 
 	ns->ethtool.channels = ch->combined_count;
 
+	if (old_indir_size != new_indir_size && !netif_is_rxfh_configured(dev))
+		nsim_rss_init(ns);
+
 	/* Only wake up queues if devices are linked */
 	if (rcu_access_pointer(ns->peer))
 		nsim_wake_queues(dev);
@@ -209,6 +312,7 @@ static const struct ethtool_ops nsim_ethtool_ops = {
 	.supported_coalesce_params	= ETHTOOL_COALESCE_ALL_PARAMS,
 	.supported_ring_params		= ETHTOOL_RING_USE_TCP_DATA_SPLIT |
 					  ETHTOOL_RING_USE_HDS_THRS,
+	.rxfh_indir_space		= NSIM_RSS_INDIR_MAX,
 	.get_pause_stats	        = nsim_get_pause_stats,
 	.get_pauseparam		        = nsim_get_pauseparam,
 	.set_pauseparam		        = nsim_set_pauseparam,
@@ -218,10 +322,18 @@ static const struct ethtool_ops nsim_ethtool_ops = {
 	.set_ringparam			= nsim_set_ringparam,
 	.get_channels			= nsim_get_channels,
 	.set_channels			= nsim_set_channels,
+	.get_rx_ring_count		= nsim_get_rx_ring_count,
 	.get_fecparam			= nsim_get_fecparam,
 	.set_fecparam			= nsim_set_fecparam,
 	.get_fec_stats			= nsim_get_fec_stats,
 	.get_ts_info			= nsim_get_ts_info,
+	.get_rxfh_indir_size		= nsim_get_rxfh_indir_size,
+	.get_rxfh_key_size		= nsim_get_rxfh_key_size,
+	.get_rxfh			= nsim_get_rxfh,
+	.set_rxfh			= nsim_set_rxfh,
+	.create_rxfh_context		= nsim_create_rxfh_context,
+	.modify_rxfh_context		= nsim_modify_rxfh_context,
+	.remove_rxfh_context		= nsim_remove_rxfh_context,
 };
 
 static void nsim_ethtool_ring_init(struct netdevsim *ns)
@@ -250,6 +362,9 @@ void nsim_ethtool_init(struct netdevsim *ns)
 
 	ns->ethtool.channels = ns->nsim_bus_dev->num_queues;
 
+	nsim_rss_init(ns);
+	get_random_bytes(ns->ethtool.rss_hkey, NSIM_RSS_HKEY_SIZE);
+
 	ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);
 
 	debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index f767fc8a7505..3c6dd9a98deb 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -82,6 +82,8 @@ struct nsim_ethtool_pauseparam {
 	bool report_stats_tx;
 };
 
+#define NSIM_RSS_INDIR_MAX	128
+#define NSIM_RSS_HKEY_SIZE	40
 struct nsim_ethtool {
 	u32 get_err;
 	u32 set_err;
@@ -90,6 +92,8 @@ struct nsim_ethtool {
 	struct ethtool_coalesce coalesce;
 	struct ethtool_ringparam ring;
 	struct ethtool_fecparam fec;
+	u32 rss_indir_tbl[NSIM_RSS_INDIR_MAX];
+	u8 rss_hkey[NSIM_RSS_HKEY_SIZE];
 };
 
 struct nsim_rq {
-- 
2.53.0


  parent reply	other threads:[~2026-03-03 18:15 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-03 18:15 [PATCH net-next 0/5] ethtool: Dynamic RSS context indirection table resizing Björn Töpel
2026-03-03 18:15 ` [PATCH net-next 1/5] ethtool: Add RSS indirection table resize helpers Björn Töpel
2026-03-04  0:03   ` Jakub Kicinski
2026-03-04 11:37     ` Björn Töpel
2026-03-04 17:09       ` Jakub Kicinski
2026-03-03 18:15 ` [PATCH net-next 2/5] bnxt_en: Resize RSS contexts on channel count change Björn Töpel
2026-03-03 19:20   ` Michael Chan
2026-03-04 11:38     ` Björn Töpel
2026-03-04  0:05   ` Jakub Kicinski
2026-03-04 11:39     ` Björn Töpel
2026-03-03 18:15 ` Björn Töpel [this message]
2026-03-04  0:07   ` [PATCH net-next 3/5] netdevsim: Add RSS context support with dynamic table sizing Jakub Kicinski
2026-03-04 11:40     ` Björn Töpel
2026-03-03 18:15 ` [PATCH net-next 4/5] selftests: netdevsim: Add RSS indirection table resize test Björn Töpel
2026-03-04  0:07   ` Jakub Kicinski
2026-03-03 18:15 ` [PATCH net-next 5/5] selftests: rss_drv: Add RSS indirection table resize tests Björn Töpel
2026-03-04  0:16   ` Jakub Kicinski
2026-03-04  8:23 ` [PATCH net-next 0/5] ethtool: Dynamic RSS context indirection table resizing Pavan Chebbi

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=20260303181535.2671734-4-bjorn@kernel.org \
    --to=bjorn@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=michael.chan@broadcom.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pavan.chebbi@broadcom.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