From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-ft4.fr.colt.net (smtp-ft4.fr.colt.net [213.41.78.208]) by dpdk.org (Postfix) with ESMTP id C6873B0A6 for ; Fri, 16 May 2014 10:58:44 +0200 (CEST) Received: from smtp-ex2.fr.colt.net (smtp-ex2.fr.colt.net [213.41.78.195]) by smtp-ft4.fr.colt.net (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id s4G8wrjb031161 for ; Fri, 16 May 2014 10:58:53 +0200 Received: from 33.106-14-84.ripe.coltfrance.com ([84.14.106.33] helo=proxy.6wind.com) by smtp-ex2.fr.colt.net with esmtp (Exim) (envelope-from ) id 1WlDyd-0004iV-2d for ; Fri, 16 May 2014 10:58:53 +0200 Received: from 6wind.com (unknown [10.16.0.189]) by proxy.6wind.com (Postfix) with SMTP id 731005AED3; Fri, 16 May 2014 10:58:50 +0200 (CEST) Received: by 6wind.com (sSMTP sendmail emulation); Fri, 16 May 2014 10:58:49 +0200 From: Ivan Boule To: dev@dpdk.org Date: Fri, 16 May 2014 10:58:42 +0200 Message-Id: <1400230723-2830-5-git-send-email-ivan.boule@6wind.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1400230723-2830-1-git-send-email-ivan.boule@6wind.com> References: <1400230723-2830-1-git-send-email-ivan.boule@6wind.com> X-ACL-Warn: 1/1 recipients OK. Subject: [dpdk-dev] [PATCH v2 4/5] ethdev: allow to get RSS hash functions and key X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 May 2014 08:58:45 -0000 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 --- 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