[dpdk-dev] [PATCH v2 4/5] ethdev: allow to get RSS hash functions and key
Ivan Boule
ivan.boule at 6wind.com
Fri May 16 10:58:42 CEST 2014
1) Add a new function "rss_hash_conf_get" in the PMD API to retrieve the
current configuration of the RSS functions and/or of the RSS key used
by a NIC to compute the RSS hash of input packets.
The new function uses the existing data structure "rte_eth_rss_conf" for
returning the RSS hash configuration.
2) Add the ixgbe-specific function "ixgbe_dev_rss_hash_conf_get" and the
igb-specific function "eth_igb_rss_hash_conf_get" to retrieve the RSS
hash configuration of ixgbe and igb controllers respectively.
3) Add the command "show port X rss-hash [key]" in the testpmd application
to display the RSS hash configuration of port X.
Signed-off-by: Ivan Boule <ivan.boule at 6wind.com>
---
app/test-pmd/cmdline.c | 63 +++++++++++++++++++++++++++++++++
app/test-pmd/config.c | 65 +++++++++++++++++++++++++++++++++++
app/test-pmd/testpmd.h | 2 ++
lib/librte_ether/rte_ethdev.c | 15 ++++++++
lib/librte_ether/rte_ethdev.h | 23 +++++++++++++
lib/librte_pmd_e1000/e1000_ethdev.h | 3 ++
lib/librte_pmd_e1000/igb_ethdev.c | 1 +
lib/librte_pmd_e1000/igb_rxtx.c | 52 ++++++++++++++++++++++++++++
lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 3 +-
lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 3 ++
lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 53 ++++++++++++++++++++++++++++
11 files changed, 282 insertions(+), 1 deletion(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 407a2b9..0b6749c 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -182,6 +182,10 @@ static void cmd_help_long_parsed(void *parsed_result,
"show port (info|stats|fdir|stat_qmap) (port_id|all)\n"
" Display information for port_id, or all.\n\n"
+ "show port rss-hash [key]\n"
+ " Display the RSS hash functions and RSS hash key"
+ " of port X\n\n"
+
"clear port (info|stats|fdir|stat_qmap) (port_id|all)\n"
" Clear information for port_id, or all.\n\n"
@@ -1364,6 +1368,63 @@ cmdline_parse_inst_t cmd_showport_reta = {
},
};
+/* *** Show RSS hash configuration *** */
+struct cmd_showport_rss_hash {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss_hash;
+ cmdline_fixed_string_t key; /* optional argument */
+};
+
+static void cmd_showport_rss_hash_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *show_rss_key)
+{
+ struct cmd_showport_rss_hash *res = parsed_result;
+
+ port_rss_hash_conf_show(res->port_id, show_rss_key != NULL);
+}
+
+cmdline_parse_token_string_t cmd_showport_rss_hash_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
+cmdline_parse_token_string_t cmd_showport_rss_hash_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
+cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
+ "rss-hash");
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
+
+cmdline_parse_inst_t cmd_showport_rss_hash = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = NULL,
+ .help_str = "show port X rss-hash (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_showport_rss_hash_key = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = "show_rss_key",
+ .help_str = "show port X rss-hash key (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ (void *)&cmd_showport_rss_hash_rss_key,
+ NULL,
+ },
+};
+
/* *** Configure DCB *** */
struct cmd_config_dcb {
cmdline_fixed_string_t port;
@@ -5259,6 +5320,8 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_mirror_mask,
(cmdline_parse_inst_t *)&cmd_set_mirror_link,
(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
+ (cmdline_parse_inst_t *)&cmd_showport_rss_hash,
+ (cmdline_parse_inst_t *)&cmd_showport_rss_hash_key,
(cmdline_parse_inst_t *)&cmd_dump,
(cmdline_parse_inst_t *)&cmd_dump_one,
NULL,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 404f84e..614f28f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -682,6 +682,71 @@ port_rss_reta_info(portid_t port_id,struct rte_eth_rss_reta *reta_conf)
}
/*
+ * Displays the RSS hash functions of a port, and, optionaly, the RSS hash
+ * key of the port.
+ */
+void
+port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
+{
+ struct rte_eth_rss_conf rss_conf;
+ uint8_t rss_key[10 * 4];
+ uint16_t rss_hf;
+ uint8_t i;
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ /* Get RSS hash key if asked to display it */
+ rss_conf.rss_key = (show_rss_key) ? rss_key : NULL;
+ diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+ if (diag != 0) {
+ switch (diag) {
+ case -ENODEV:
+ printf("port index %d invalid\n", port_id);
+ break;
+ case -ENOTSUP:
+ printf("operation not supported by device\n");
+ break;
+ default:
+ printf("operation failed - diag=%d\n", diag);
+ break;
+ }
+ return;
+ }
+ rss_hf = rss_conf.rss_hf;
+ if (rss_hf == 0) {
+ printf("RSS disabled\n");
+ return;
+ }
+ printf("RSS functions:\n ");
+ if (rss_hf & ETH_RSS_IPV4)
+ printf("ip4");
+ if (rss_hf & ETH_RSS_IPV4_TCP)
+ printf(" tcp4");
+ if (rss_hf & ETH_RSS_IPV4_UDP)
+ printf(" udp4");
+ if (rss_hf & ETH_RSS_IPV6)
+ printf(" ip6");
+ if (rss_hf & ETH_RSS_IPV6_EX)
+ printf(" ip6-ex");
+ if (rss_hf & ETH_RSS_IPV6_TCP)
+ printf(" tcp6");
+ if (rss_hf & ETH_RSS_IPV6_TCP_EX)
+ printf(" tcp6-ex");
+ if (rss_hf & ETH_RSS_IPV6_UDP)
+ printf(" udp6");
+ if (rss_hf & ETH_RSS_IPV6_UDP_EX)
+ printf(" udp6-ex");
+ printf("\n");
+ if (! show_rss_key)
+ return;
+ printf("RSS key:\n");
+ for (i = 0; i < sizeof(rss_key); i++)
+ printf("%02X", rss_key[i]);
+ printf("\n");
+}
+
+/*
* Setup forwarding configuration for each logical core.
*/
static void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index ffd3495..b9d47c4 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -523,6 +523,8 @@ void set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on);
void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,
uint64_t vf_mask, uint8_t on);
+void port_rss_hash_conf_show(portid_t port_id, int show_rss_key);
+
/*
* Work-around of a compilation error with ICC on invocations of the
* rte_be_to_cpu_16() function.
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 91375a1..dabbdd2 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1594,6 +1594,21 @@ rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
}
int
+rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
+ return (*dev->dev_ops->rss_hash_conf_get)(dev, rss_conf);
+}
+
+int
rte_eth_led_on(uint8_t port_id)
{
struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index efb421a..43d6a83 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -972,6 +972,10 @@ typedef int (*rss_hash_update_t)(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
/**< @internal Update RSS hash configuration of an Ethernet device */
+typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf);
+/**< @internal Get current RSS hash configuration of an Ethernet device */
+
typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
/**< @internal Turn on SW controllable LED on an Ethernet device */
@@ -1161,6 +1165,8 @@ struct eth_dev_ops {
/** Configure RSS hash protocols. */
rss_hash_update_t rss_hash_update;
+ /** Get current RSS hash configuration. */
+ rss_hash_conf_get_t rss_hash_conf_get;
};
/**
@@ -2883,6 +2889,23 @@ int rte_eth_dev_bypass_wd_reset(uint8_t port);
int rte_eth_dev_rss_hash_update(uint8_t port_id,
struct rte_eth_rss_conf *rss_conf);
+ /**
+ * Retrieve current configuration of Receive Side Scaling hash computation
+ * of Ethernet device.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param rss_conf
+ * Where to store the current RSS hash configuration of the Ethernet device.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if port identifier is invalid.
+ * - (-ENOTSUP) if hardware doesn't support RSS.
+ */
+int
+rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
+ struct rte_eth_rss_conf *rss_conf);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d9dc8d1..8790601 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -141,6 +141,9 @@ uint16_t eth_igb_recv_scattered_pkts(void *rxq,
int eth_igb_rss_hash_update(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
+int eth_igb_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf);
+
int eth_igbvf_rx_init(struct rte_eth_dev *dev);
void eth_igbvf_tx_init(struct rte_eth_dev *dev);
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 130ee86..02e0a95 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -194,6 +194,7 @@ static struct eth_dev_ops eth_igb_ops = {
.reta_update = eth_igb_rss_reta_update,
.reta_query = eth_igb_rss_reta_query,
.rss_hash_update = eth_igb_rss_hash_update,
+ .rss_hash_conf_get = eth_igb_rss_hash_conf_get,
};
/*
diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c
index 7ce8d23..6b48df5 100644
--- a/lib/librte_pmd_e1000/igb_rxtx.c
+++ b/lib/librte_pmd_e1000/igb_rxtx.c
@@ -1593,6 +1593,58 @@ eth_igb_rss_hash_update(struct rte_eth_dev *dev,
return 0;
}
+int eth_igb_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct e1000_hw *hw;
+ uint8_t *hash_key;
+ uint32_t rss_key;
+ uint32_t mrqc;
+ uint16_t rss_hf;
+ uint16_t i;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ hash_key = rss_conf->rss_key;
+ if (hash_key != NULL) {
+ /* Return RSS hash key */
+ for (i = 0; i < 10; i++) {
+ rss_key = E1000_READ_REG_ARRAY(hw, E1000_RSSRK(0), i);
+ hash_key[(i * 4)] = rss_key & 0x000000FF;
+ hash_key[(i * 4) + 1] = (rss_key >> 8) & 0x000000FF;
+ hash_key[(i * 4) + 2] = (rss_key >> 16) & 0x000000FF;
+ hash_key[(i * 4) + 3] = (rss_key >> 24) & 0x000000FF;
+ }
+ }
+
+ /* Get RSS functions configured in MRQC register */
+ mrqc = E1000_READ_REG(hw, E1000_MRQC);
+ if ((mrqc & E1000_MRQC_ENABLE_RSS_4Q) == 0) { /* RSS is disabled */
+ rss_conf->rss_hf = 0;
+ return 0;
+ }
+ rss_hf = 0;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV4)
+ rss_hf |= ETH_RSS_IPV4;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP)
+ rss_hf |= ETH_RSS_IPV4_TCP;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6)
+ rss_hf |= ETH_RSS_IPV6;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_EX)
+ rss_hf |= ETH_RSS_IPV6_EX;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP)
+ rss_hf |= ETH_RSS_IPV6_TCP;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP_EX)
+ rss_hf |= ETH_RSS_IPV6_TCP_EX;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_UDP)
+ rss_hf |= ETH_RSS_IPV4_UDP;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_UDP)
+ rss_hf |= ETH_RSS_IPV6_UDP;
+ if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_UDP_EX)
+ rss_hf |= ETH_RSS_IPV6_UDP_EX;
+ rss_conf->rss_hf = rss_hf;
+ return 0;
+}
+
static void
igb_rss_configure(struct rte_eth_dev *dev)
{
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 5a84b3d..79d59ef 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -300,7 +300,8 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
.bypass_ver_show = ixgbe_bypass_ver_show,
.bypass_wd_reset = ixgbe_bypass_wd_reset,
#endif /* RTE_NIC_BYPASS */
- .rss_hash_update = ixgbe_dev_rss_hash_update,
+ .rss_hash_update = ixgbe_dev_rss_hash_update,
+ .rss_hash_conf_get = ixgbe_dev_rss_hash_conf_get,
};
/*
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index 06d51ab..846db0a 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -238,6 +238,9 @@ uint16_t ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
int ixgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
+int ixgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf);
+
/*
* Flow director function prototypes
*/
diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
index c5d9589..c04118c 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
@@ -2369,6 +2369,59 @@ ixgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
return 0;
}
+int
+ixgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct ixgbe_hw *hw;
+ uint8_t *hash_key;
+ uint32_t mrqc;
+ uint32_t rss_key;
+ uint16_t rss_hf;
+ uint16_t i;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ hash_key = rss_conf->rss_key;
+ if (hash_key != NULL) {
+ /* Return RSS hash key */
+ for (i = 0; i < 10; i++) {
+ rss_key = IXGBE_READ_REG_ARRAY(hw, IXGBE_RSSRK(0), i);
+ hash_key[(i * 4)] = rss_key & 0x000000FF;
+ hash_key[(i * 4) + 1] = (rss_key >> 8) & 0x000000FF;
+ hash_key[(i * 4) + 2] = (rss_key >> 16) & 0x000000FF;
+ hash_key[(i * 4) + 3] = (rss_key >> 24) & 0x000000FF;
+ }
+ }
+
+ /* Get RSS functions configured in MRQC register */
+ mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ if ((mrqc & IXGBE_MRQC_RSSEN) == 0) { /* RSS is disabled */
+ rss_conf->rss_hf = 0;
+ return 0;
+ }
+ rss_hf = 0;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV4)
+ rss_hf |= ETH_RSS_IPV4;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV4_TCP)
+ rss_hf |= ETH_RSS_IPV4_TCP;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6)
+ rss_hf |= ETH_RSS_IPV6;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6_EX)
+ rss_hf |= ETH_RSS_IPV6_EX;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6_TCP)
+ rss_hf |= ETH_RSS_IPV6_TCP;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP)
+ rss_hf |= ETH_RSS_IPV6_TCP_EX;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV4_UDP)
+ rss_hf |= ETH_RSS_IPV4_UDP;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6_UDP)
+ rss_hf |= ETH_RSS_IPV6_UDP;
+ if (mrqc & IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP)
+ rss_hf |= ETH_RSS_IPV6_UDP_EX;
+ rss_conf->rss_hf = rss_hf;
+ return 0;
+}
+
static void
ixgbe_rss_configure(struct rte_eth_dev *dev)
{
--
1.7.10.4
More information about the dev
mailing list