[v6] examples: fix RSS hash function configuration

Message ID 20180704200222.60945-1-ferruh.yigit@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series [v6] examples: fix RSS hash function configuration |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ferruh Yigit July 4, 2018, 8:02 p.m. UTC
  ethdev layer introduced checks for application requested RSS hash
functions and returns error for ones unsupported by hardware

This check breaks some sample applications which blindly configures
RSS hash functions without checking underlying hardware support.

Updated examples to mask out unsupported RSS has functions during device
configuration.
Prints a log if configuration values updated by this check.

Fixes: aa1a6d87f15d ("ethdev: force RSS offload rules again")

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
Return error added in this release, so no need to backport the fix to
previous versions.

Cc: David Hunt <david.hunt@intel.com>
Cc: Liang Ma <liang.j.ma@intel.com>
Cc: Xueming Li <xuemingl@mellanox.com>

v2:
Cc: Remy Horton <remy.horton@intel.com>
* add app/test-eventdev
Cc: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>

v3:
* document rte_eth_dev_configure() API rss_hf restriction

v4:
* Flex tespmd "port config all rss xxx" command to mask out unsupported
values and print a log about the modification done to requested config

v5:
* fix local_rss_hf logic in testpmd (the one added in v4)

v6:
* don't remove offload flags from l3fwd-power
* rebase
---
 app/test-eventdev/test_perf_common.c          | 19 +++++++++++++---
 app/test-eventdev/test_pipeline_common.c      | 15 +++++++++++--
 app/test-pmd/cmdline.c                        | 16 +++++++++++---
 examples/bond/main.c                          | 12 ++++++++++
 examples/distributor/main.c                   | 11 ++++++++++
 examples/eventdev_pipeline/main.c             | 11 ++++++++++
 examples/ip_pipeline/link.c                   |  8 +++++--
 examples/ip_reassembly/main.c                 | 12 ++++++++++
 examples/ipsec-secgw/ipsec-secgw.c            | 12 ++++++++++
 examples/l3fwd-acl/main.c                     | 12 ++++++++++
 examples/l3fwd-power/main.c                   | 12 ++++++++++
 examples/l3fwd-vf/main.c                      | 12 ++++++++++
 examples/l3fwd/main.c                         | 12 ++++++++++
 examples/load_balancer/init.c                 | 12 ++++++++++
 examples/multi_process/symmetric_mp/main.c    | 12 ++++++++++
 .../performance-thread/l3fwd-thread/main.c    | 12 ++++++++++
 examples/qos_meter/main.c                     | 22 +++++++++++++++++++
 examples/vmdq_dcb/main.c                      | 13 +++++++++++
 lib/librte_ethdev/rte_ethdev.h                |  8 ++++---
 19 files changed, 230 insertions(+), 13 deletions(-)
  

Comments

Zhao, MeijuanX July 5, 2018, 8:17 a.m. UTC | #1
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
Sent: Thursday, July 5, 2018 4:02 AM
To: Jerin Jacob <jerin.jacob@caviumnetworks.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>; Doherty, Declan <declan.doherty@intel.com>; Chas Williams <chas3@att.com>; Richardson, Bruce <bruce.richardson@intel.com>; Hunt, David <david.hunt@intel.com>; Van Haaren, Harry <harry.van.haaren@intel.com>; Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Horton, Remy <remy.horton@intel.com>; Ori Kam <orika@mellanox.com>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Nicolau, Radu <radu.nicolau@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; Kantecki, Tomasz <tomasz.kantecki@intel.com>; Burakov, Anatoly <anatoly.burakov@intel.com>; Mcnamara, John <john.mcnamara@intel.com>; Li, Xiaoyun <xiaoyun.li@intel.com>; Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko <arybchenko@solarflare.com>
Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Ma, Liang J <liang.j.ma@intel.com>; Xueming Li <xuemingl@mellanox.com>; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Subject: [dpdk-dev] [PATCH v6] examples: fix RSS hash function configuration

ethdev layer introduced checks for application requested RSS hash functions and returns error for ones unsupported by hardware

This check breaks some sample applications which blindly configures RSS hash functions without checking underlying hardware support.

Updated examples to mask out unsupported RSS has functions during device configuration.
Prints a log if configuration values updated by this check.

Fixes: aa1a6d87f15d ("ethdev: force RSS offload rules again")

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Tested-by: Zhao meijuan< meijuanx.zhao@intel.com >;Han yingya< yingyax.han@intel.com >
  
Hunt, David July 5, 2018, 9:30 a.m. UTC | #2
Hi Ferruh,


On 4/7/2018 9:02 PM, Ferruh Yigit wrote:
> ethdev layer introduced checks for application requested RSS hash
> functions and returns error for ones unsupported by hardware
>
> This check breaks some sample applications which blindly configures
> RSS hash functions without checking underlying hardware support.
>
> Updated examples to mask out unsupported RSS has functions during device
> configuration.
> Prints a log if configuration values updated by this check.
>
> Fixes: aa1a6d87f15d ("ethdev: force RSS offload rules again")
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> Return error added in this release, so no need to backport the fix to
> previous versions.
>
> Cc: David Hunt <david.hunt@intel.com>
> Cc: Liang Ma <liang.j.ma@intel.com>
> Cc: Xueming Li <xuemingl@mellanox.com>
>
> v2:
> Cc: Remy Horton <remy.horton@intel.com>
> * add app/test-eventdev
> Cc: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
>
> v3:
> * document rte_eth_dev_configure() API rss_hf restriction
>
> v4:
> * Flex tespmd "port config all rss xxx" command to mask out unsupported
> values and print a log about the modification done to requested config
>
> v5:
> * fix local_rss_hf logic in testpmd (the one added in v4)
>
> v6:
> * don't remove offload flags from l3fwd-power
> * rebase
> ---
>   app/test-eventdev/test_perf_common.c          | 19 +++++++++++++---
>   app/test-eventdev/test_pipeline_common.c      | 15 +++++++++++--
>   app/test-pmd/cmdline.c                        | 16 +++++++++++---
>   examples/bond/main.c                          | 12 ++++++++++
>   examples/distributor/main.c                   | 11 ++++++++++
>   examples/eventdev_pipeline/main.c             | 11 ++++++++++
>   examples/ip_pipeline/link.c                   |  8 +++++--
>   examples/ip_reassembly/main.c                 | 12 ++++++++++
>   examples/ipsec-secgw/ipsec-secgw.c            | 12 ++++++++++
>   examples/l3fwd-acl/main.c                     | 12 ++++++++++
>   examples/l3fwd-power/main.c                   | 12 ++++++++++
>   examples/l3fwd-vf/main.c                      | 12 ++++++++++
>   examples/l3fwd/main.c                         | 12 ++++++++++
>   examples/load_balancer/init.c                 | 12 ++++++++++
>   examples/multi_process/symmetric_mp/main.c    | 12 ++++++++++
>   .../performance-thread/l3fwd-thread/main.c    | 12 ++++++++++
>   examples/qos_meter/main.c                     | 22 +++++++++++++++++++
>   examples/vmdq_dcb/main.c                      | 13 +++++++++++
>   lib/librte_ethdev/rte_ethdev.h                |  8 ++++---
>   19 files changed, 230 insertions(+), 13 deletions(-)
>
> diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
> index eed80d1b1..d0d835d5e 100644
> --- a/app/test-eventdev/test_perf_common.c
> +++ b/app/test-eventdev/test_perf_common.c
> @@ -700,10 +700,23 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
>   	}
>   
>   	RTE_ETH_FOREACH_DEV(i) {
> +		struct rte_eth_dev_info dev_info;
> +		struct rte_eth_conf local_port_conf = port_conf;
> +
> +		rte_eth_dev_info_get(i, &dev_info);
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			evt_info("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				i,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
>   
> -		if (rte_eth_dev_configure(i, 1, 1,
> -					&port_conf)
> -				< 0) {
> +		if (rte_eth_dev_configure(i, 1, 1, &local_port_conf) < 0) {
>   			evt_err("Failed to configure eth port [%d]", i);
>   			return -EINVAL;
>   		}
> diff --git a/app/test-eventdev/test_pipeline_common.c b/app/test-eventdev/test_pipeline_common.c
> index 3bc9d513d..239c953e6 100644
> --- a/app/test-eventdev/test_pipeline_common.c
> +++ b/app/test-eventdev/test_pipeline_common.c
> @@ -240,16 +240,27 @@ pipeline_ethdev_setup(struct evt_test *test, struct evt_options *opt)
>   
>   	RTE_ETH_FOREACH_DEV(i) {
>   		struct rte_eth_dev_info dev_info;
> +		struct rte_eth_conf local_port_conf = port_conf;
>   
> -		memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
>   		rte_eth_dev_info_get(i, &dev_info);
>   		mt_state = !(dev_info.tx_offload_capa &
>   				DEV_TX_OFFLOAD_MT_LOCKFREE);
>   		rx_conf = dev_info.default_rxconf;
>   		rx_conf.offloads = port_conf.rxmode.offloads;
>   
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			evt_info("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				i,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		if (rte_eth_dev_configure(i, nb_queues, nb_queues,
> -					&port_conf)
> +					&local_port_conf)
>   				< 0) {
>   			evt_err("Failed to configure eth port [%d]\n", i);
>   			return -EINVAL;
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 27e2aa8c8..74a8cd99e 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -2058,11 +2058,21 @@ cmd_config_rss_parsed(void *parsed_result,
>   	rss_conf.rss_key = NULL;
>   	/* Update global configuration for RSS types. */
>   	RTE_ETH_FOREACH_DEV(i) {
> -		if (use_default) {
> -			rte_eth_dev_info_get(i, &dev_info);
> +		struct rte_eth_rss_conf local_rss_conf;
> +
> +		rte_eth_dev_info_get(i, &dev_info);
> +		if (use_default)
>   			rss_conf.rss_hf = dev_info.flow_type_rss_offloads;
> +
> +		local_rss_conf = rss_conf;
> +		local_rss_conf.rss_hf = rss_conf.rss_hf &
> +			dev_info.flow_type_rss_offloads;
> +		if (local_rss_conf.rss_hf != rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				i, rss_conf.rss_hf, local_rss_conf.rss_hf);
>   		}
> -		diag = rte_eth_dev_rss_hash_update(i, &rss_conf);
> +		diag = rte_eth_dev_rss_hash_update(i, &local_rss_conf);
>   		if (diag < 0) {
>   			all_updated = 0;
>   			printf("Configuration of RSS hash at ethernet port %d "
> diff --git a/examples/bond/main.c b/examples/bond/main.c
> index 98415d66d..23d0981ab 100644
> --- a/examples/bond/main.c
> +++ b/examples/bond/main.c
> @@ -153,6 +153,18 @@ slave_port_init(uint16_t portid, struct rte_mempool *mbuf_pool)
>   	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		local_port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +		dev_info.flow_type_rss_offloads;
> +	if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			portid,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf,
> +			local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
>   	if (retval != 0)
>   		rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n",
> diff --git a/examples/distributor/main.c b/examples/distributor/main.c
> index 85881a2e8..03a05e3d9 100644
> --- a/examples/distributor/main.c
> +++ b/examples/distributor/main.c
> @@ -123,6 +123,17 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
>   		port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
>   
> +	port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +		dev_info.flow_type_rss_offloads;
> +	if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port,
> +			port_conf_default.rx_adv_conf.rss_conf.rss_hf,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf);
>   	if (retval != 0)
>   		return retval;
> diff --git a/examples/eventdev_pipeline/main.c b/examples/eventdev_pipeline/main.c
> index 7bc294946..700bc696f 100644
> --- a/examples/eventdev_pipeline/main.c
> +++ b/examples/eventdev_pipeline/main.c
> @@ -292,6 +292,17 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)
>   		port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
>   
> +	port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +		dev_info.flow_type_rss_offloads;
> +	if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port,
> +			port_conf_default.rx_adv_conf.rss_conf.rss_hf,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	/* Configure the Ethernet device. */
>   	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
>   	if (retval != 0)
> diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
> index 181c31f9c..805c2eb95 100644
> --- a/examples/ip_pipeline/link.c
> +++ b/examples/ip_pipeline/link.c
> @@ -152,8 +152,12 @@ link_create(const char *name, struct link_params *params)
>   	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
>   	if (rss) {
>   		port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
> -		port_conf.rx_adv_conf.rss_conf.rss_hf =
> -			ETH_RSS_IPV4 | ETH_RSS_IPV6;
> +		if (port_info.flow_type_rss_offloads & ETH_RSS_IPV4)
> +			port_conf.rx_adv_conf.rss_conf.rss_hf |=
> +				ETH_RSS_IPV4;
> +		if (port_info.flow_type_rss_offloads & ETH_RSS_IPV6)
> +			port_conf.rx_adv_conf.rss_conf.rss_hf |=
> +				ETH_RSS_IPV6;
>   	}
>   
>   	cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
> diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
> index 94e63fc6a..b830f67a5 100644
> --- a/examples/ip_reassembly/main.c
> +++ b/examples/ip_reassembly/main.c
> @@ -1082,6 +1082,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, 1, (uint16_t)n_tx_queue,
>   					    &local_port_conf);
>   		if (ret < 0) {
> diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
> index 199bae51b..68b346502 100644
> --- a/examples/ipsec-secgw/ipsec-secgw.c
> +++ b/examples/ipsec-secgw/ipsec-secgw.c
> @@ -1565,6 +1565,18 @@ port_init(uint16_t portid)
>   	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		local_port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +		dev_info.flow_type_rss_offloads;
> +	if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			portid,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf,
> +			local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
>   			&local_port_conf);
>   	if (ret < 0)
> diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
> index 55a5a69e5..7c063a8d0 100644
> --- a/examples/l3fwd-acl/main.c
> +++ b/examples/l3fwd-acl/main.c
> @@ -1925,6 +1925,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					(uint16_t)n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index 710b76d12..f6fabd95f 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -1692,6 +1692,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					(uint16_t)n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
> index 43e629828..5edd91a78 100644
> --- a/examples/l3fwd-vf/main.c
> +++ b/examples/l3fwd-vf/main.c
> @@ -980,6 +980,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					    n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> index faef9f1ac..ab019b9e4 100644
> --- a/examples/l3fwd/main.c
> +++ b/examples/l3fwd/main.c
> @@ -860,6 +860,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					(uint16_t)n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
> index 6aa079c69..f2045f235 100644
> --- a/examples/load_balancer/init.c
> +++ b/examples/load_balancer/init.c
> @@ -416,6 +416,18 @@ app_init_nics(void)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				port,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(
>   			port,
>   			(uint8_t) n_rx_queues,
> diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
> index c36326917..c6c6a537f 100644
> --- a/examples/multi_process/symmetric_mp/main.c
> +++ b/examples/multi_process/symmetric_mp/main.c
> @@ -199,6 +199,7 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
>   	uint16_t q;
>   	uint16_t nb_rxd = RX_RING_SIZE;
>   	uint16_t nb_txd = TX_RING_SIZE;
> +	uint64_t rss_hf_tmp;
>   
>   	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
>   		return 0;
> @@ -215,6 +216,17 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
>   	if (info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
> +	port_conf.rx_adv_conf.rss_conf.rss_hf &= info.flow_type_rss_offloads;
> +	if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port,
> +			rss_hf_tmp,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
>   	if (retval < 0)
>   		return retval;
> diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
> index d1e4a1880..5392fcea8 100644
> --- a/examples/performance-thread/l3fwd-thread/main.c
> +++ b/examples/performance-thread/l3fwd-thread/main.c
> @@ -3550,6 +3550,18 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
> +				port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +			printf("Port %u modified RSS hash function based on hardware support,"
> +				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +				portid,
> +				port_conf.rx_adv_conf.rss_conf.rss_hf,
> +				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
> +		}
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					(uint16_t)n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
> index ca0e9e863..5cf4e9dfa 100644
> --- a/examples/qos_meter/main.c
> +++ b/examples/qos_meter/main.c
> @@ -332,6 +332,17 @@ main(int argc, char **argv)
>   	rte_eth_dev_info_get(port_rx, &dev_info);
>   	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
> +	if (conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port_rx,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf,
> +			conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	ret = rte_eth_dev_configure(port_rx, 1, 1, &conf);
>   	if (ret < 0)
>   		rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_rx, ret);
> @@ -361,6 +372,17 @@ main(int argc, char **argv)
>   	rte_eth_dev_info_get(port_tx, &dev_info);
>   	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
> +	if (conf.rx_adv_conf.rss_conf.rss_hf !=
> +			port_conf.rx_adv_conf.rss_conf.rss_hf) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port_tx,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf,
> +			conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	ret = rte_eth_dev_configure(port_tx, 1, 1, &conf);
>   	if (ret < 0)
>   		rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_tx, ret);
> diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
> index 5a0463c58..646368395 100644
> --- a/examples/vmdq_dcb/main.c
> +++ b/examples/vmdq_dcb/main.c
> @@ -196,6 +196,7 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
>   	uint16_t queues_per_pool;
>   	uint32_t max_nb_pools;
>   	struct rte_eth_txconf txq_conf;
> +	uint64_t rss_hf_tmp;
>   
>   	/*
>   	 * The max pool number from dev_info will be used to validate the pool
> @@ -256,6 +257,18 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
>   	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   		port_conf.txmode.offloads |=
>   			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +	rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
> +	port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +		dev_info.flow_type_rss_offloads;
> +	if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
> +		printf("Port %u modified RSS hash function based on hardware support,"
> +			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
> +			port,
> +			rss_hf_tmp,
> +			port_conf.rx_adv_conf.rss_conf.rss_hf);
> +	}
> +
>   	/*
>   	 * Though in this example, all queues including pf queues are setup.
>   	 * This is because VMDQ queues doesn't always start from zero, and the
> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index 6d4caff6b..f5f593b31 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -1515,9 +1515,11 @@ const char * __rte_experimental rte_eth_dev_tx_offload_name(uint64_t offload);
>    *        the [rt]x_offload_capa returned from rte_eth_dev_infos_get().
>    *        Any type of device supported offloading set in the input argument
>    *        eth_conf->[rt]xmode.offloads to rte_eth_dev_configure() is enabled
> - *        on all queues and it can't be disabled in rte_eth_[rt]x_queue_setup().
> - *     - the Receive Side Scaling (RSS) configuration when using multiple RX
> - *         queues per port.
> + *        on all queues and it can't be disabled in rte_eth_[rt]x_queue_setup()
> + *     -  the Receive Side Scaling (RSS) configuration when using multiple RX
> + *        queues per port. Any RSS hash function set in eth_conf->rss_conf.rss_hf
> + *        must be within the flow_type_rss_offloads provided by drivers via
> + *        rte_eth_dev_infos_get() API.
>    *
>    *   Embedding all configuration information in a single data structure
>    *   is the more flexible method that allows the addition of new features

Looks good to me.

Acked-by: David Hunt <david.hunt@intel.com <mailto:david.hunt@intel.com>>
  
Ferruh Yigit July 5, 2018, 1:09 p.m. UTC | #3
On 7/5/2018 10:30 AM, Hunt, David wrote:
> Hi Ferruh,
> 
> 
> On 4/7/2018 9:02 PM, Ferruh Yigit wrote:
>> ethdev layer introduced checks for application requested RSS hash
>> functions and returns error for ones unsupported by hardware
>>
>> This check breaks some sample applications which blindly configures
>> RSS hash functions without checking underlying hardware support.
>>
>> Updated examples to mask out unsupported RSS has functions during device
>> configuration.
>> Prints a log if configuration values updated by this check.
>>
>> Fixes: aa1a6d87f15d ("ethdev: force RSS offload rules again")
>>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>Tested-by: Meijuan Zhao <meijuanx.zhao@intel.com>
Tested-by: Yingya Han <yingyax.han@intel.com>
> Acked-by: David Hunt <david.hunt@intel.com>
Applied to dpdk-next-net/master, thanks.
  

Patch

diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index eed80d1b1..d0d835d5e 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -700,10 +700,23 @@  perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 	}
 
 	RTE_ETH_FOREACH_DEV(i) {
+		struct rte_eth_dev_info dev_info;
+		struct rte_eth_conf local_port_conf = port_conf;
+
+		rte_eth_dev_info_get(i, &dev_info);
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			evt_info("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				i,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
 
-		if (rte_eth_dev_configure(i, 1, 1,
-					&port_conf)
-				< 0) {
+		if (rte_eth_dev_configure(i, 1, 1, &local_port_conf) < 0) {
 			evt_err("Failed to configure eth port [%d]", i);
 			return -EINVAL;
 		}
diff --git a/app/test-eventdev/test_pipeline_common.c b/app/test-eventdev/test_pipeline_common.c
index 3bc9d513d..239c953e6 100644
--- a/app/test-eventdev/test_pipeline_common.c
+++ b/app/test-eventdev/test_pipeline_common.c
@@ -240,16 +240,27 @@  pipeline_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 
 	RTE_ETH_FOREACH_DEV(i) {
 		struct rte_eth_dev_info dev_info;
+		struct rte_eth_conf local_port_conf = port_conf;
 
-		memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
 		rte_eth_dev_info_get(i, &dev_info);
 		mt_state = !(dev_info.tx_offload_capa &
 				DEV_TX_OFFLOAD_MT_LOCKFREE);
 		rx_conf = dev_info.default_rxconf;
 		rx_conf.offloads = port_conf.rxmode.offloads;
 
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			evt_info("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				i,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		if (rte_eth_dev_configure(i, nb_queues, nb_queues,
-					&port_conf)
+					&local_port_conf)
 				< 0) {
 			evt_err("Failed to configure eth port [%d]\n", i);
 			return -EINVAL;
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 27e2aa8c8..74a8cd99e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2058,11 +2058,21 @@  cmd_config_rss_parsed(void *parsed_result,
 	rss_conf.rss_key = NULL;
 	/* Update global configuration for RSS types. */
 	RTE_ETH_FOREACH_DEV(i) {
-		if (use_default) {
-			rte_eth_dev_info_get(i, &dev_info);
+		struct rte_eth_rss_conf local_rss_conf;
+
+		rte_eth_dev_info_get(i, &dev_info);
+		if (use_default)
 			rss_conf.rss_hf = dev_info.flow_type_rss_offloads;
+
+		local_rss_conf = rss_conf;
+		local_rss_conf.rss_hf = rss_conf.rss_hf &
+			dev_info.flow_type_rss_offloads;
+		if (local_rss_conf.rss_hf != rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				i, rss_conf.rss_hf, local_rss_conf.rss_hf);
 		}
-		diag = rte_eth_dev_rss_hash_update(i, &rss_conf);
+		diag = rte_eth_dev_rss_hash_update(i, &local_rss_conf);
 		if (diag < 0) {
 			all_updated = 0;
 			printf("Configuration of RSS hash at ethernet port %d "
diff --git a/examples/bond/main.c b/examples/bond/main.c
index 98415d66d..23d0981ab 100644
--- a/examples/bond/main.c
+++ b/examples/bond/main.c
@@ -153,6 +153,18 @@  slave_port_init(uint16_t portid, struct rte_mempool *mbuf_pool)
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		local_port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+		dev_info.flow_type_rss_offloads;
+	if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			portid,
+			port_conf.rx_adv_conf.rss_conf.rss_hf,
+			local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
 	if (retval != 0)
 		rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n",
diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index 85881a2e8..03a05e3d9 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -123,6 +123,17 @@  port_init(uint16_t port, struct rte_mempool *mbuf_pool)
 		port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 
+	port_conf.rx_adv_conf.rss_conf.rss_hf &=
+		dev_info.flow_type_rss_offloads;
+	if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port,
+			port_conf_default.rx_adv_conf.rss_conf.rss_hf,
+			port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf);
 	if (retval != 0)
 		return retval;
diff --git a/examples/eventdev_pipeline/main.c b/examples/eventdev_pipeline/main.c
index 7bc294946..700bc696f 100644
--- a/examples/eventdev_pipeline/main.c
+++ b/examples/eventdev_pipeline/main.c
@@ -292,6 +292,17 @@  port_init(uint8_t port, struct rte_mempool *mbuf_pool)
 		port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 
+	port_conf.rx_adv_conf.rss_conf.rss_hf &=
+		dev_info.flow_type_rss_offloads;
+	if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port,
+			port_conf_default.rx_adv_conf.rss_conf.rss_hf,
+			port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	/* Configure the Ethernet device. */
 	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
 	if (retval != 0)
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
index 181c31f9c..805c2eb95 100644
--- a/examples/ip_pipeline/link.c
+++ b/examples/ip_pipeline/link.c
@@ -152,8 +152,12 @@  link_create(const char *name, struct link_params *params)
 	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
 	if (rss) {
 		port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
-		port_conf.rx_adv_conf.rss_conf.rss_hf =
-			ETH_RSS_IPV4 | ETH_RSS_IPV6;
+		if (port_info.flow_type_rss_offloads & ETH_RSS_IPV4)
+			port_conf.rx_adv_conf.rss_conf.rss_hf |=
+				ETH_RSS_IPV4;
+		if (port_info.flow_type_rss_offloads & ETH_RSS_IPV6)
+			port_conf.rx_adv_conf.rss_conf.rss_hf |=
+				ETH_RSS_IPV6;
 	}
 
 	cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 94e63fc6a..b830f67a5 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -1082,6 +1082,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, 1, (uint16_t)n_tx_queue,
 					    &local_port_conf);
 		if (ret < 0) {
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 199bae51b..68b346502 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1565,6 +1565,18 @@  port_init(uint16_t portid)
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		local_port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+		dev_info.flow_type_rss_offloads;
+	if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			portid,
+			port_conf.rx_adv_conf.rss_conf.rss_hf,
+			local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
 			&local_port_conf);
 	if (ret < 0)
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 55a5a69e5..7c063a8d0 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1925,6 +1925,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, nb_rx_queue,
 					(uint16_t)n_tx_queue, &local_port_conf);
 		if (ret < 0)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 710b76d12..f6fabd95f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1692,6 +1692,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, nb_rx_queue,
 					(uint16_t)n_tx_queue, &local_port_conf);
 		if (ret < 0)
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 43e629828..5edd91a78 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -980,6 +980,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, nb_rx_queue,
 					    n_tx_queue, &local_port_conf);
 		if (ret < 0)
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index faef9f1ac..ab019b9e4 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -860,6 +860,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, nb_rx_queue,
 					(uint16_t)n_tx_queue, &local_port_conf);
 		if (ret < 0)
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index 6aa079c69..f2045f235 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -416,6 +416,18 @@  app_init_nics(void)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				port,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(
 			port,
 			(uint8_t) n_rx_queues,
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index c36326917..c6c6a537f 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -199,6 +199,7 @@  smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
 	uint16_t q;
 	uint16_t nb_rxd = RX_RING_SIZE;
 	uint16_t nb_txd = TX_RING_SIZE;
+	uint64_t rss_hf_tmp;
 
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
 		return 0;
@@ -215,6 +216,17 @@  smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
 	if (info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
+	port_conf.rx_adv_conf.rss_conf.rss_hf &= info.flow_type_rss_offloads;
+	if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port,
+			rss_hf_tmp,
+			port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
 	if (retval < 0)
 		return retval;
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index d1e4a1880..5392fcea8 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3550,6 +3550,18 @@  main(int argc, char **argv)
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+			dev_info.flow_type_rss_offloads;
+		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+				port_conf.rx_adv_conf.rss_conf.rss_hf) {
+			printf("Port %u modified RSS hash function based on hardware support,"
+				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+				portid,
+				port_conf.rx_adv_conf.rss_conf.rss_hf,
+				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+		}
+
 		ret = rte_eth_dev_configure(portid, nb_rx_queue,
 					(uint16_t)n_tx_queue, &local_port_conf);
 		if (ret < 0)
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index ca0e9e863..5cf4e9dfa 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -332,6 +332,17 @@  main(int argc, char **argv)
 	rte_eth_dev_info_get(port_rx, &dev_info);
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
+	if (conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port_rx,
+			port_conf.rx_adv_conf.rss_conf.rss_hf,
+			conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	ret = rte_eth_dev_configure(port_rx, 1, 1, &conf);
 	if (ret < 0)
 		rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_rx, ret);
@@ -361,6 +372,17 @@  main(int argc, char **argv)
 	rte_eth_dev_info_get(port_tx, &dev_info);
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
+	if (conf.rx_adv_conf.rss_conf.rss_hf !=
+			port_conf.rx_adv_conf.rss_conf.rss_hf) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port_tx,
+			port_conf.rx_adv_conf.rss_conf.rss_hf,
+			conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	ret = rte_eth_dev_configure(port_tx, 1, 1, &conf);
 	if (ret < 0)
 		rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_tx, ret);
diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
index 5a0463c58..646368395 100644
--- a/examples/vmdq_dcb/main.c
+++ b/examples/vmdq_dcb/main.c
@@ -196,6 +196,7 @@  port_init(uint16_t port, struct rte_mempool *mbuf_pool)
 	uint16_t queues_per_pool;
 	uint32_t max_nb_pools;
 	struct rte_eth_txconf txq_conf;
+	uint64_t rss_hf_tmp;
 
 	/*
 	 * The max pool number from dev_info will be used to validate the pool
@@ -256,6 +257,18 @@  port_init(uint16_t port, struct rte_mempool *mbuf_pool)
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		port_conf.txmode.offloads |=
 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+	rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
+	port_conf.rx_adv_conf.rss_conf.rss_hf &=
+		dev_info.flow_type_rss_offloads;
+	if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
+		printf("Port %u modified RSS hash function based on hardware support,"
+			"requested:%#"PRIx64" configured:%#"PRIx64"\n",
+			port,
+			rss_hf_tmp,
+			port_conf.rx_adv_conf.rss_conf.rss_hf);
+	}
+
 	/*
 	 * Though in this example, all queues including pf queues are setup.
 	 * This is because VMDQ queues doesn't always start from zero, and the
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 6d4caff6b..f5f593b31 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1515,9 +1515,11 @@  const char * __rte_experimental rte_eth_dev_tx_offload_name(uint64_t offload);
  *        the [rt]x_offload_capa returned from rte_eth_dev_infos_get().
  *        Any type of device supported offloading set in the input argument
  *        eth_conf->[rt]xmode.offloads to rte_eth_dev_configure() is enabled
- *        on all queues and it can't be disabled in rte_eth_[rt]x_queue_setup().
- *     - the Receive Side Scaling (RSS) configuration when using multiple RX
- *         queues per port.
+ *        on all queues and it can't be disabled in rte_eth_[rt]x_queue_setup()
+ *     -  the Receive Side Scaling (RSS) configuration when using multiple RX
+ *        queues per port. Any RSS hash function set in eth_conf->rss_conf.rss_hf
+ *        must be within the flow_type_rss_offloads provided by drivers via
+ *        rte_eth_dev_infos_get() API.
  *
  *   Embedding all configuration information in a single data structure
  *   is the more flexible method that allows the addition of new features