[v5,5/5] net/gve: add RSS redirection table update support

Message ID 20240131221308.2208815-6-joshwash@google.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series net/gve: RSS Support for GVE Driver |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/intel-Functional success Functional PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-compile-arm64-testing success Testing PASS

Commit Message

Joshua Washington Jan. 31, 2024, 10:13 p.m. UTC
  This patch introduces support for updating the RSS redirection table in
the GVE PMD through the implementation of rss_reta_update and
rss_reta_query.

Due to an infrastructure limitation, the RSS hash key must be manually
configured before the redirection table can be updated or queried. The
redirection table is expected to be exactly 128 bytes.

Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Rushil Gupta <rushilg@google.com>
Reviewed-by: Jeroen de Borst <jeroendb@google.com>
---
 doc/guides/nics/features/gve.ini |  1 +
 doc/guides/nics/gve.rst          |  8 +++
 drivers/net/gve/gve_ethdev.c     | 95 ++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)
  

Patch

diff --git a/doc/guides/nics/features/gve.ini b/doc/guides/nics/features/gve.ini
index 4381b1565f..8dfa229bb0 100644
--- a/doc/guides/nics/features/gve.ini
+++ b/doc/guides/nics/features/gve.ini
@@ -10,6 +10,7 @@  MTU update           = Y
 TSO                  = Y
 RSS hash             = Y
 RSS key update       = Y
+RSS reta update      = Y
 L4 checksum offload  = Y
 Basic stats          = Y
 Linux                = Y
diff --git a/doc/guides/nics/gve.rst b/doc/guides/nics/gve.rst
index 908b2aab11..69e4eaabdb 100644
--- a/doc/guides/nics/gve.rst
+++ b/doc/guides/nics/gve.rst
@@ -71,6 +71,7 @@  Supported features of the GVE PMD are:
 - Tx multi-segments (Scatter Tx)
 - Tx UDP/TCP/SCTP Checksum
 - RSS hash configuration
+- RSS redirection table query and update
 
 Currently, only GQI_QPL and GQI_RDA queue format are supported in PMD.
 Jumbo Frame is not supported in PMD for now.
@@ -92,3 +93,10 @@  Note that the initial configuration requires a hash key to be provided if one
 had not been provided before. Attempting to set hash types alone without the
 existence of a set key will result in a failed request.
 
+As stated above, the RSS redirection table has exactly 128 entries. The RSS hash
+must be configured before the redirection table can be updated using the standard
+interface. Because the initial RSS hash creates a default redirection table, the
+redirection table will be available for querying upon initial hash configuration.
+When performing redirection table updates, it is possible to update individual
+table entries.
+
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index 2a68d31808..3b8ec5872d 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -770,6 +770,97 @@  gve_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+gve_rss_reta_update(struct rte_eth_dev *dev,
+	struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
+{
+	struct gve_priv *priv = dev->data->dev_private;
+	struct gve_rss_config gve_rss_conf;
+	int table_id;
+	int err;
+	int i;
+
+	/* RSS key must be set before the redirection table can be set. */
+	if (!priv->rss_config.key || priv->rss_config.key_size == 0) {
+		PMD_DRV_LOG(ERR, "RSS hash key msut be set before the "
+			"redirection table can be updated.");
+		return -ENOTSUP;
+	}
+
+	if (reta_size != GVE_RSS_INDIR_SIZE) {
+		PMD_DRV_LOG(ERR, "Redirection table must have %hu elements",
+			(uint16_t)GVE_RSS_INDIR_SIZE);
+		return -EINVAL;
+	}
+
+	err = gve_init_rss_config_from_priv(priv, &gve_rss_conf);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Error allocating new RSS config.");
+		return err;
+	}
+
+	table_id = 0;
+	for (i = 0; i < priv->rss_config.indir_size; i++) {
+		int table_entry = i % RTE_ETH_RETA_GROUP_SIZE;
+		if (reta_conf[table_id].mask & (1ULL << table_entry))
+			gve_rss_conf.indir[i] =
+				reta_conf[table_id].reta[table_entry];
+
+		if (table_entry == RTE_ETH_RETA_GROUP_SIZE - 1)
+			table_id++;
+	}
+
+	err = gve_adminq_configure_rss(priv, &gve_rss_conf);
+	if (err)
+		PMD_DRV_LOG(ERR, "Problem configuring RSS with device.");
+	else
+		gve_update_priv_rss_config(priv, &gve_rss_conf);
+
+	gve_free_rss_config(&gve_rss_conf);
+	return err;
+}
+
+static int
+gve_rss_reta_query(struct rte_eth_dev *dev,
+	struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
+{
+	struct gve_priv *priv = dev->data->dev_private;
+	int table_id;
+	int i;
+
+	if (!(dev->data->dev_conf.rxmode.offloads &
+		RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
+		PMD_DRV_LOG(ERR, "RSS not configured.");
+		return -ENOTSUP;
+	}
+
+	/* RSS key must be set before the redirection table can be queried. */
+	if (!priv->rss_config.key) {
+		PMD_DRV_LOG(ERR, "RSS hash key must be set before the "
+			"redirection table can be initialized.");
+		return -ENOTSUP;
+	}
+
+	if (reta_size != priv->rss_config.indir_size) {
+		PMD_DRV_LOG(ERR, "RSS redirection table must have %d entries.",
+			priv->rss_config.indir_size);
+		return -EINVAL;
+	}
+
+	table_id = 0;
+	for (i = 0; i < priv->rss_config.indir_size; i++) {
+		int table_entry = i % RTE_ETH_RETA_GROUP_SIZE;
+		if (reta_conf[table_id].mask & (1ULL << table_entry))
+			reta_conf[table_id].reta[table_entry] =
+				priv->rss_config.indir[i];
+
+		if (table_entry == RTE_ETH_RETA_GROUP_SIZE - 1)
+			table_id++;
+	}
+
+	return 0;
+}
+
 static const struct eth_dev_ops gve_eth_dev_ops = {
 	.dev_configure        = gve_dev_configure,
 	.dev_start            = gve_dev_start,
@@ -792,6 +883,8 @@  static const struct eth_dev_ops gve_eth_dev_ops = {
 	.xstats_get_names     = gve_xstats_get_names,
 	.rss_hash_update      = gve_rss_hash_update,
 	.rss_hash_conf_get    = gve_rss_hash_conf_get,
+	.reta_update          = gve_rss_reta_update,
+	.reta_query           = gve_rss_reta_query,
 };
 
 static const struct eth_dev_ops gve_eth_dev_ops_dqo = {
@@ -816,6 +909,8 @@  static const struct eth_dev_ops gve_eth_dev_ops_dqo = {
 	.xstats_get_names     = gve_xstats_get_names,
 	.rss_hash_update      = gve_rss_hash_update,
 	.rss_hash_conf_get    = gve_rss_hash_conf_get,
+	.reta_update          = gve_rss_reta_update,
+	.reta_query           = gve_rss_reta_query,
 };
 
 static void