DPDK patches and discussions
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* Re: [dpdk-dev] [PATCH] ethdev: remove experimental flag of ports enumeration
  @ 2018-04-25 10:52  0%     ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-04-25 10:52 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On 4/25/2018 11:29 AM, Thomas Monjalon wrote:
> 25/04/2018 12:21, Ferruh Yigit:
>> On 4/24/2018 3:15 AM, Thomas Monjalon wrote:
>>> The basic operations for ports enumeration should not be
>>> considered as experimental in DPDK 18.05.
>>>
>>> The iterator RTE_ETH_FOREACH_DEV was introduced in DPDK 17.05.
>>> It uses the function the rte_eth_find_next_owned_by() to get
>>> only ownerless ports. Its API can be considered stable.
>>> So the flag experimental is removed from rte_eth_find_next_owned_by().
>>>
>>> The flag experimental is removed from rte_eth_dev_count_avail()
>>> which is the new name of the old function rte_eth_dev_count().
>>>
>>> The flag experimental is set to rte_eth_dev_count_total()
>>> in the .c file for consistency with the declaration in the .h file.
>>>
>>> A lot of internal applications are fixed to not allow experimental API.
>>>
>>> Fixes: 8728ccf37615 ("fix ethdev ports enumeration")
>>> Fixes: d9a42a69febf ("ethdev: deprecate port count function")
>>> Fixes: e70e26861eaf ("net/mvpp2: fix build")
>>>
>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>
>> Getting some build errors [1], it seems some samples are using some other
>> experimental APIs so that we can't remove the flag for them.
>>
>>
>> [1]
>> .../dpdk/examples/tep_termination/main.c: In function ‘main’:
>> .../dpdk/examples/tep_termination/main.c:1209:3: error: ‘rte_ctrl_thread_create’
>> is deprecated: Symbol is not yet part of stable ABI
>> [-Werror=deprecated-declarations]
>>    ret = rte_ctrl_thread_create(&tid, "print-stats", NULL,
>>    ^~~
>>
>> .../dpdk/examples/vhost/main.c: In function ‘main’:
>> .../dpdk/examples/vhost/main.c:1497:3: error: ‘rte_ctrl_thread_create’ is
>> deprecated: Symbol is not yet part of stable ABI [-Werror=deprecated-declarations]
>>    ret = rte_ctrl_thread_create(&tid, "print-stats", NULL,
>>    ^~~
> 
> Ah sorry, I think it is due to a change in next-net.
> I have prepared this patch on master.
> 
> Please can you fix it when applying?

OK, I will.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal/service: remove experimental tags
  @ 2018-04-25 12:58  0%   ` Thomas Monjalon
  2018-04-30 13:53  0%     ` Alejandro Lucero
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-04-25 12:58 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev, Jerin Jacob

> > This commit removes the experimental tags from the
> > service cores functions, they now become part of the
> > main DPDK API/ABI.
> > 
> > Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> 
> Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

Acked-by: Thomas Monjalon <thomas@monjalon.net>

Applied, congratulations!

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v8 02/10] bond: replace rte_panic instances in bonding driver
  @ 2018-04-25 13:45  3%   ` Arnon Warshavsky
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Replace panic calls with log and return value.
Local functions to this file,
changing from void to int are non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/bonding/rte_eth_bond_8023ad.c         | 29 ++++++++++++++---------
 drivers/net/bonding/rte_eth_bond_8023ad_private.h |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c            | 22 ++++++++++++-----
 drivers/net/bonding/rte_eth_bond_pmd.c            |  9 ++++---
 drivers/net/bonding/rte_eth_bond_private.h        |  2 +-
 5 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index c452318..308e623 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -893,7 +893,7 @@
 			bond_mode_8023ad_periodic_cb, arg);
 }
 
-void
+int
 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
 				uint16_t slave_id)
 {
@@ -939,7 +939,7 @@
 	timer_cancel(&port->warning_timer);
 
 	if (port->mbuf_pool != NULL)
-		return;
+		return 0;
 
 	RTE_ASSERT(port->rx_ring == NULL);
 	RTE_ASSERT(port->tx_ring == NULL);
@@ -968,8 +968,9 @@
 	/* Any memory allocation failure in initialization is critical because
 	 * resources can't be free, so reinitialization is impossible. */
 	if (port->mbuf_pool == NULL) {
-		rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
-			slave_id, mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
 
 	snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
@@ -977,8 +978,9 @@
 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
 
 	if (port->rx_ring == NULL) {
-		rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
-			mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create rx ring '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
 
 	/* TX ring is at least one pkt longer to make room for marker packet. */
@@ -987,9 +989,12 @@
 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
 
 	if (port->tx_ring == NULL) {
-		rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
-			mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Fail to create tx ring '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
+
+	return 0;
 }
 
 int
@@ -1143,9 +1148,11 @@
 	struct bond_dev_private *internals = bond_dev->data->dev_private;
 	uint8_t i;
 
-	for (i = 0; i < internals->active_slave_count; i++)
-		bond_mode_8023ad_activate_slave(bond_dev,
-				internals->active_slaves[i]);
+	for (i = 0; i < internals->active_slave_count; i++) {
+		if (!bond_mode_8023ad_activate_slave(bond_dev,
+						internals->active_slaves[i]))
+			return -1;
+	}
 
 	return 0;
 }
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad_private.h b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
index 0f490a5..96a42f2 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
@@ -263,7 +263,7 @@ struct mode8023ad_private {
  * @return
  *  0 on success, negative value otherwise.
  */
-void
+int
 bond_mode_8023ad_activate_slave(struct rte_eth_dev *dev, uint16_t port_id);
 
 /**
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index aa89425..657fd74 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -69,14 +69,15 @@
 	return 0;
 }
 
-void
+int
 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id)
 {
 	struct bond_dev_private *internals = eth_dev->data->dev_private;
 	uint8_t active_count = internals->active_slave_count;
 
 	if (internals->mode == BONDING_MODE_8023AD)
-		bond_mode_8023ad_activate_slave(eth_dev, port_id);
+		if (bond_mode_8023ad_activate_slave(eth_dev, port_id) != 0)
+			return -1;
 
 	if (internals->mode == BONDING_MODE_TLB
 			|| internals->mode == BONDING_MODE_ALB) {
@@ -94,6 +95,8 @@
 		bond_tlb_activate_slave(internals);
 	if (internals->mode == BONDING_MODE_ALB)
 		bond_mode_alb_client_list_upd(eth_dev);
+
+	return 0;
 }
 
 void
@@ -357,10 +360,17 @@
 				bond_ethdev_primary_set(internals,
 							slave_port_id);
 
-			if (find_slave_by_id(internals->active_slaves,
-					     internals->active_slave_count,
-					     slave_port_id) == internals->active_slave_count)
-				activate_slave(bonded_eth_dev, slave_port_id);
+			int rc =
+				find_slave_by_id(internals->active_slaves,
+					internals->active_slave_count,
+					slave_port_id);
+
+			if (rc == internals->active_slave_count) {
+				int rc = activate_slave(bonded_eth_dev,
+							slave_port_id);
+				if (rc != 0)
+					return -1;
+			}
 		}
 	}
 
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 09696ea..d2dbe4a 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1741,8 +1741,10 @@ struct bwg_slave {
 		/* Any memory allocation failure in initialization is critical because
 		 * resources can't be free, so reinitialization is impossible. */
 		if (port->slow_pool == NULL) {
-			rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
-				slave_id, mem_name, rte_strerror(rte_errno));
+			RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
+				__func__, slave_id,
+				mem_name, rte_strerror(rte_errno));
+			return -1;
 		}
 	}
 
@@ -2673,7 +2675,8 @@ struct bwg_slave {
 			mac_address_slaves_update(bonded_eth_dev);
 		}
 
-		activate_slave(bonded_eth_dev, port_id);
+		if (activate_slave(bonded_eth_dev, port_id) != 0)
+			return -1;
 
 		/* If user has defined the primary port then default to using it */
 		if (internals->user_defined_primary_port &&
diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h
index 94eca88..d99d42c 100644
--- a/drivers/net/bonding/rte_eth_bond_private.h
+++ b/drivers/net/bonding/rte_eth_bond_private.h
@@ -187,7 +187,7 @@ struct bond_dev_private {
 void
 deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
 
-void
+int
 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
 
 void
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 03/10] e1000: replace rte_panic instances in e1000 driver
    2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
@ 2018-04-25 13:45  3%   ` Arnon Warshavsky
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/e1000/e1000_ethdev.h |  2 +-
 drivers/net/e1000/igb_ethdev.c   |  4 +++-
 drivers/net/e1000/igb_pf.c       | 15 +++++++++------
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h
index 6354b89..2e527de 100644
--- a/drivers/net/e1000/e1000_ethdev.h
+++ b/drivers/net/e1000/e1000_ethdev.h
@@ -411,7 +411,7 @@ int eth_igb_rss_hash_conf_get(struct rte_eth_dev *dev,
 /*
  * misc function prototypes
  */
-void igb_pf_host_init(struct rte_eth_dev *eth_dev);
+int igb_pf_host_init(struct rte_eth_dev *eth_dev);
 
 void igb_pf_mbx_process(struct rte_eth_dev *eth_dev);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 9b808a9..67a32a2 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -833,7 +833,9 @@ static int igb_flex_filter_uninit(struct rte_eth_dev *eth_dev)
 	}
 
 	/* initialize PF if max_vfs not zero */
-	igb_pf_host_init(eth_dev);
+	error = igb_pf_host_init(eth_dev);
+	if (error != 0)
+		goto err_late;
 
 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
 	/* Set PF Reset Done bit so PF/VF Mail Ops can work */
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index b9f2e53..6e511a9 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -63,7 +63,7 @@ int igb_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num)
 	return 0;
 }
 
-void igb_pf_host_init(struct rte_eth_dev *eth_dev)
+int igb_pf_host_init(struct rte_eth_dev *eth_dev)
 {
 	struct e1000_vf_info **vfinfo =
 		E1000_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
@@ -74,7 +74,7 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 
 	RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
 	if (0 == (vf_num = dev_num_vf(eth_dev)))
-		return;
+		return 0;
 
 	if (hw->mac.type == e1000_i350)
 		nb_queue = 1;
@@ -82,11 +82,14 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 		/* per datasheet, it should be 2, but 1 seems correct */
 		nb_queue = 1;
 	else
-		return;
+		return 0;
 
 	*vfinfo = rte_zmalloc("vf_info", sizeof(struct e1000_vf_info) * vf_num, 0);
-	if (*vfinfo == NULL)
-		rte_panic("Cannot allocate memory for private VF data\n");
+	if (*vfinfo == NULL) {
+		PMD_DRV_LOG(CRIT, "%s(): Cannot allocate memory for private VF data\n",
+			__func__);
+		return -ENOMEM;
+	}
 
 	RTE_ETH_DEV_SRIOV(eth_dev).active = ETH_8_POOLS;
 	RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = nb_queue;
@@ -98,7 +101,7 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 	/* set mb interrupt mask */
 	igb_mb_intr_setup(eth_dev);
 
-	return;
+	return 0;
 }
 
 void igb_pf_host_uninit(struct rte_eth_dev *dev)
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 04/10] ixgbe: replace rte_panic instances in ixgbe driver
    2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
@ 2018-04-25 13:45  3%   ` Arnon Warshavsky
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c |  6 ++++--
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 +-
 drivers/net/ixgbe/ixgbe_pf.c     | 15 ++++++++++-----
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a5e2fc0..fb95cc7 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1061,7 +1061,7 @@ struct rte_ixgbe_xstats_name_off {
 		IXGBE_DEV_PRIVATE_TO_BW_CONF(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 	uint16_t csum;
-	int diag, i;
+	int diag, i, error;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1224,7 +1224,9 @@ struct rte_ixgbe_xstats_name_off {
 	memset(hwstrip, 0, sizeof(*hwstrip));
 
 	/* initialize PF if max_vfs not zero */
-	ixgbe_pf_host_init(eth_dev);
+	error = ixgbe_pf_host_init(eth_dev);
+	if (error != 0)
+		return error;
 
 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
 	/* let hardware know driver is loaded */
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 6550777..8bb41ec 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -661,7 +661,7 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev);
 
-void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);
+int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);
 
 void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev);
 
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 4e61310..81a9910 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -66,7 +66,7 @@ int ixgbe_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num)
 	return 0;
 }
 
-void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
+int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 {
 	struct ixgbe_vf_info **vfinfo =
 		IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
@@ -84,11 +84,14 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 	RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
-		return;
+		return 0;
 
 	*vfinfo = rte_zmalloc("vf_info", sizeof(struct ixgbe_vf_info) * vf_num, 0);
-	if (*vfinfo == NULL)
-		rte_panic("Cannot allocate memory for private VF data\n");
+	if (*vfinfo == NULL) {
+		PMD_DRV_LOG(ERR, "%s() Cannot allocate memory for private VF data\n",
+				__func__);
+		return -ENOMEM;
+	}
 
 	memset(mirror_info, 0, sizeof(struct ixgbe_mirror_info));
 	memset(uta_info, 0, sizeof(struct ixgbe_uta_info));
@@ -116,6 +119,8 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 
 	/* set mb interrupt mask */
 	ixgbe_mb_intr_setup(eth_dev);
+
+	return 0;
 }
 
 void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
@@ -203,7 +208,7 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
-		return -1;
+		return -ENOMEM;
 
 	/* enable VMDq and set the default pool for PF */
 	vtctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 06/10] kni: replace rte_panic instances in kni
                       ` (2 preceding siblings ...)
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
@ 2018-04-25 13:45  3%   ` Arnon Warshavsky
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
  2018-04-25 13:45  2%   ` [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 lib/librte_kni/rte_kni.c      | 18 ++++++++++++------
 lib/librte_kni/rte_kni_fifo.h | 11 ++++++++---
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 8a8f6c1..4dac407 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -353,37 +353,43 @@ struct rte_kni *
 	/* TX RING */
 	mz = slot->m_tx_q;
 	ctx->tx_q = mz->addr;
-	kni_fifo_init(ctx->tx_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->tx_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.tx_phys = mz->phys_addr;
 
 	/* RX RING */
 	mz = slot->m_rx_q;
 	ctx->rx_q = mz->addr;
-	kni_fifo_init(ctx->rx_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->rx_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.rx_phys = mz->phys_addr;
 
 	/* ALLOC RING */
 	mz = slot->m_alloc_q;
 	ctx->alloc_q = mz->addr;
-	kni_fifo_init(ctx->alloc_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->alloc_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.alloc_phys = mz->phys_addr;
 
 	/* FREE RING */
 	mz = slot->m_free_q;
 	ctx->free_q = mz->addr;
-	kni_fifo_init(ctx->free_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->free_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.free_phys = mz->phys_addr;
 
 	/* Request RING */
 	mz = slot->m_req_q;
 	ctx->req_q = mz->addr;
-	kni_fifo_init(ctx->req_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->req_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.req_phys = mz->phys_addr;
 
 	/* Response RING */
 	mz = slot->m_resp_q;
 	ctx->resp_q = mz->addr;
-	kni_fifo_init(ctx->resp_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->resp_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.resp_phys = mz->phys_addr;
 
 	/* Req/Resp sync mem area */
diff --git a/lib/librte_kni/rte_kni_fifo.h b/lib/librte_kni/rte_kni_fifo.h
index ac26a8c..5052015 100644
--- a/lib/librte_kni/rte_kni_fifo.h
+++ b/lib/librte_kni/rte_kni_fifo.h
@@ -7,17 +7,22 @@
 /**
  * Initializes the kni fifo structure
  */
-static void
+static int
 kni_fifo_init(struct rte_kni_fifo *fifo, unsigned size)
 {
 	/* Ensure size is power of 2 */
-	if (size & (size - 1))
-		rte_panic("KNI fifo size must be power of 2\n");
+	if (size & (size - 1)) {
+		RTE_LOG(CRIT, EAL, "%s(): KNI fifo size must be power of 2\n",
+				__func__);
+		return -1;
+	}
 
 	fifo->write = 0;
 	fifo->read = 0;
 	fifo->len = size;
 	fifo->elem_size = sizeof(void *);
+
+	return 0;
 }
 
 /**
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 08/10] eal: replace rte_panic instances in ethdev
                       ` (3 preceding siblings ...)
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
@ 2018-04-25 13:45  3%   ` Arnon Warshavsky
  2018-04-25 13:45  2%   ` [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 lib/librte_ether/rte_ethdev.c | 42 ++++++++++++++++++++++++++++++------------
 lib/librte_ether/rte_ethdev.h |  4 +++-
 2 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f0f53d4..940de15 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -194,7 +194,7 @@ enum {
 	return port_id;
 }
 
-static void
+static int
 rte_eth_dev_shared_data_prepare(void)
 {
 	const unsigned flags = 0;
@@ -210,8 +210,12 @@ enum {
 					rte_socket_id(), flags);
 		} else
 			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
-		if (mz == NULL)
-			rte_panic("Cannot allocate ethdev shared data\n");
+		if (mz == NULL) {
+			rte_spinlock_unlock(&rte_eth_shared_data_lock);
+			RTE_LOG(CRIT, EAL, "%s(): Cannot allocate ethdev shared data\n",
+					__func__);
+			return -1;
+		}
 
 		rte_eth_dev_shared_data = mz->addr;
 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
@@ -224,6 +228,8 @@ enum {
 	}
 
 	rte_spinlock_unlock(&rte_eth_shared_data_lock);
+
+	return 0;
 }
 
 struct rte_eth_dev *
@@ -274,7 +280,8 @@ struct rte_eth_dev *
 	uint16_t port_id;
 	struct rte_eth_dev *eth_dev = NULL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return NULL;
 
 	/* Synchronize port creation between primary and secondary threads. */
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
@@ -317,7 +324,8 @@ struct rte_eth_dev *
 	uint16_t i;
 	struct rte_eth_dev *eth_dev = NULL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return NULL;
 
 	/* Synchronize port attachment to primary port creation and release. */
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
@@ -345,7 +353,8 @@ struct rte_eth_dev *
 	if (eth_dev == NULL)
 		return -EINVAL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -399,7 +408,8 @@ struct rte_eth_dev *
 int __rte_experimental
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -450,7 +460,8 @@ struct rte_eth_dev *
 {
 	int ret;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -467,7 +478,8 @@ struct rte_eth_dev *
 			{.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
 	int ret;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -477,12 +489,15 @@ struct rte_eth_dev *
 	return ret;
 }
 
-void __rte_experimental
+int __rte_experimental
 rte_eth_dev_owner_delete(const uint64_t owner_id)
 {
 	uint16_t port_id;
+	int error;
 
-	rte_eth_dev_shared_data_prepare();
+	error = rte_eth_dev_shared_data_prepare();
+	if (error != 0)
+		return error;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -495,6 +510,8 @@ struct rte_eth_dev *
 	}
 
 	rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+	return 0;
 }
 
 int __rte_experimental
@@ -502,7 +519,8 @@ struct rte_eth_dev *
 {
 	int ret = 0;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b9eb8ae..46e5947 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1354,8 +1354,10 @@ int __rte_experimental rte_eth_dev_owner_unset(const uint16_t port_id,
  *
  * @param	owner_id
  *  The owner identifier.
+ *  @return
+ *  0 on success, negative errno value on error.
  */
-void __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
+int __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
 
 /**
  * @warning
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence
                       ` (4 preceding siblings ...)
  2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
@ 2018-04-25 13:45  2%   ` Arnon Warshavsky
  2018-04-25 13:53  0%     ` Burakov, Anatoly
  5 siblings, 1 reply; 200+ results
From: Arnon Warshavsky @ 2018-04-25 13:45 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Change some local functions return type from void to int.
This change does not break ABI as the functions are internal.
Panic thrown from threads was not handled in this patch

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 lib/librte_eal/bsdapp/eal/eal.c   |  69 +++++++++++++++++++-------
 lib/librte_eal/linuxapp/eal/eal.c | 101 ++++++++++++++++++++++++++------------
 2 files changed, 119 insertions(+), 51 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 10d8dc0..3110f53 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -151,7 +151,7 @@ enum rte_iova_mode
  * We also don't lock the whole file, so that in future we can use read-locks
  * on other parts, e.g. memzones, to detect if there are running secondary
  * processes. */
-static void
+static int
 rte_eal_config_create(void)
 {
 	void *rte_mem_cfg_addr;
@@ -160,60 +160,81 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	if (mem_cfg_fd < 0){
 		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+					__func__, pathname);
+			return -1;
+		}
 	}
 
 	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
 	if (retval < 0){
 		close(mem_cfg_fd);
-		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
 	if (retval < 0){
 		close(mem_cfg_fd);
-		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
-				"process running?\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'. Is another primary process running?\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 
 	if (rte_mem_cfg_addr == MAP_FAILED){
-		rte_panic("Cannot mmap memory for rte_config\n");
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+				__func__);
+		return -1;
 	}
 	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
 	rte_config.mem_config = rte_mem_cfg_addr;
+
+	return 0;
 }
 
 /* attach to an existing shared memory config */
-static void
+static int
 rte_eal_config_attach(void)
 {
 	void *rte_mem_cfg_addr;
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	if (mem_cfg_fd < 0){
 		mem_cfg_fd = open(pathname, O_RDWR);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+					__func__, pathname);
+			return -1;
+		}
 	}
 
 	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 	close(mem_cfg_fd);
-	if (rte_mem_cfg_addr == MAP_FAILED)
-		rte_panic("Cannot mmap memory for rte_config\n");
+	if (rte_mem_cfg_addr == MAP_FAILED) {
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+				__func__);
+		return -1;
+	}
 
 	rte_config.mem_config = rte_mem_cfg_addr;
+
+	return 0;
 }
 
 /* Detect if we are a primary or a secondary process */
@@ -237,23 +258,29 @@ enum rte_proc_type_t
 }
 
 /* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
 rte_config_init(void)
 {
 	rte_config.process_type = internal_config.process_type;
 
 	switch (rte_config.process_type){
 	case RTE_PROC_PRIMARY:
-		rte_eal_config_create();
+		if (rte_eal_config_create())
+			return -1;
 		break;
 	case RTE_PROC_SECONDARY:
-		rte_eal_config_attach();
+		if (rte_eal_config_attach())
+			return -1;
 		rte_eal_mcfg_wait_complete(rte_config.mem_config);
 		break;
 	case RTE_PROC_AUTO:
 	case RTE_PROC_INVALID:
-		rte_panic("Invalid process type\n");
+	default:
+		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
+				__func__, rte_config.process_type);
+		return -1;
 	}
+	return 0;
 }
 
 /* display usage */
@@ -552,7 +579,11 @@ static void rte_eal_init_alert(const char *msg)
 		return -1;
 	}
 
-	rte_config_init();
+	if (rte_config_init() != 0) {
+		rte_eal_init_alert("Failed to init configuration");
+		rte_errno = EFAULT;
+		return -1;
+	}
 
 	/* Put mp channel init before bus scan so that we can init the vdev
 	 * bus through mp channel in the secondary process before the bus scan.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 200e879..c0d704b 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -160,7 +160,7 @@ enum rte_iova_mode
  * We also don't lock the whole file, so that in future we can use read-locks
  * on other parts, e.g. memzones, to detect if there are running secondary
  * processes. */
-static void
+static int
 rte_eal_config_create(void)
 {
 	void *rte_mem_cfg_addr;
@@ -169,7 +169,7 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	/* map the config before hugepage address so that we don't waste a page */
 	if (internal_config.base_virtaddr != 0)
@@ -179,30 +179,42 @@ enum rte_iova_mode
 	else
 		rte_mem_cfg_addr = NULL;
 
-	if (mem_cfg_fd < 0){
+	if (mem_cfg_fd < 0) {
 		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+				__func__, pathname);
+			return -1;
+		}
 	}
 
 	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
-	if (retval < 0){
+	if (retval < 0) {
 		close(mem_cfg_fd);
-		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
-	if (retval < 0){
+	if (retval < 0) {
 		close(mem_cfg_fd);
-		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
-				"process running?\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'.Is another primary process running?\n",
+			__func__, pathname);
+		return -1;
 	}
 
 	rte_mem_cfg_addr = mmap(rte_mem_cfg_addr, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 
-	if (rte_mem_cfg_addr == MAP_FAILED){
-		rte_panic("Cannot mmap memory for rte_config\n");
+	if (rte_mem_cfg_addr == MAP_FAILED) {
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+			__func__);
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		return -1;
 	}
 	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
 	rte_config.mem_config = rte_mem_cfg_addr;
@@ -211,10 +223,11 @@ enum rte_iova_mode
 	 * processes could later map the config into this exact location */
 	rte_config.mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;
 
+	return 0;
 }
 
 /* attach to an existing shared memory config */
-static void
+static int
 rte_eal_config_attach(void)
 {
 	struct rte_mem_config *mem_config;
@@ -222,33 +235,42 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
-	if (mem_cfg_fd < 0){
+	if (mem_cfg_fd < 0) {
 		mem_cfg_fd = open(pathname, O_RDWR);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+						__func__, pathname);
+			return -1;
+		}
 	}
 
 	/* map it as read-only first */
 	mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config),
 			PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
-	if (mem_config == MAP_FAILED)
-		rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
-			  errno, strerror(errno));
+	if (mem_config == MAP_FAILED) {
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
+				__func__, errno, strerror(errno));
+		return -1;
+	}
 
 	rte_config.mem_config = mem_config;
+
+	return 0;
 }
 
 /* reattach the shared config at exact memory location primary process has it */
-static void
+static int
 rte_eal_config_reattach(void)
 {
 	struct rte_mem_config *mem_config;
 	void *rte_mem_cfg_addr;
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	/* save the address primary process has mapped shared config to */
 	rte_mem_cfg_addr = (void *) (uintptr_t) rte_config.mem_config->mem_cfg_addr;
@@ -263,16 +285,20 @@ enum rte_iova_mode
 	if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
 		if (mem_config != MAP_FAILED)
 			/* errno is stale, don't use */
-			rte_panic("Cannot mmap memory for rte_config at [%p], got [%p]"
-				  " - please use '--base-virtaddr' option\n",
-				  rte_mem_cfg_addr, mem_config);
+			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config at [%p], got [%p] - please use '--base-virtaddr' option\n",
+					__func__, rte_mem_cfg_addr, mem_config);
 		else
-			rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
-				  errno, strerror(errno));
+			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
+					__func__, errno, strerror(errno));
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		return -1;
 	}
 	close(mem_cfg_fd);
 
 	rte_config.mem_config = mem_config;
+
+	return 0;
 }
 
 /* Detect if we are a primary or a secondary process */
@@ -296,24 +322,32 @@ enum rte_proc_type_t
 }
 
 /* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
 rte_config_init(void)
 {
 	rte_config.process_type = internal_config.process_type;
 
 	switch (rte_config.process_type){
 	case RTE_PROC_PRIMARY:
-		rte_eal_config_create();
+		if (rte_eal_config_create())
+			return -1;
 		break;
 	case RTE_PROC_SECONDARY:
-		rte_eal_config_attach();
+		if (rte_eal_config_attach())
+			return -1;
 		rte_eal_mcfg_wait_complete(rte_config.mem_config);
-		rte_eal_config_reattach();
+		if (rte_eal_config_reattach())
+			return -1;
 		break;
 	case RTE_PROC_AUTO:
 	case RTE_PROC_INVALID:
-		rte_panic("Invalid process type\n");
+	default:
+		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
+				__func__, rte_config.process_type);
+		return -1;
 	}
+
+	return 0;
 }
 
 /* Unlocks hugepage directories that were locked by eal_hugepage_info_init */
@@ -833,6 +867,9 @@ static void rte_eal_init_alert(const char *msg)
 
 	rte_srand(rte_rdtsc());
 
+	if (rte_config_init() != 0)
+		return -1;
+
 	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) {
 		rte_eal_init_alert("Cannot init logging.");
 		rte_errno = ENOMEM;
-- 
1.8.3.1

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence
  2018-04-25 13:45  2%   ` [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
@ 2018-04-25 13:53  0%     ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-04-25 13:53 UTC (permalink / raw)
  To: Arnon Warshavsky, thomas, wenzhuo.lu, declan.doherty,
	jerin.jacob, bruce.richardson, ferruh.yigit
  Cc: dev

On 25-Apr-18 2:45 PM, Arnon Warshavsky wrote:
> Change some local functions return type from void to int.
> This change does not break ABI as the functions are internal.
> Panic thrown from threads was not handled in this patch
> 
> Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
> ---

<...>

>   	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
>   	if (retval < 0){
>   		close(mem_cfg_fd);
> -		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
> -				"process running?\n", pathname);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'. Is another primary process running?\n",
> +				__func__, pathname);
> +		return -1;
>   	}
>   
>   	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
>   				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
>   
>   	if (rte_mem_cfg_addr == MAP_FAILED){
> -		rte_panic("Cannot mmap memory for rte_config\n");
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
> +				__func__);
> +		return -1;

Still missing mem_cfg_fd close() and set to -1 here.

Once this is fixed,

Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>

And please keep my ack this time :)

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] malloc: add biggest free IOVA-contiguous element to stats
  @ 2018-04-25 14:40  4% ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-04-25 14:40 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain

On 25-Apr-18 3:10 PM, Anatoly Burakov wrote:
> User might be interested to find out what is the biggest chunk of
> IOVA-contiguous free space that can be allocated from malloc. Add
> relevant malloc-internal functions and expose this through malloc
> stats calculation call.
> 
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---

Note: this breaks the ABI, but ABI is already broken for this release, 
so it's OK.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v4 1/2] mbuf: support attaching external buffer to mbuf
  @ 2018-04-25 15:06  0%       ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-04-25 15:06 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Olivier Matz, Andrew Rybchenko, Yongseok Koh, wenzhuo.lu,
	jingjing.wu, dev, konstantin.ananyev, adrien.mazarguil,
	nelio.laranjeiro

On Tue, 24 Apr 2018 22:22:45 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:

> > > 
> > > I guess the problem that it changes INDIRECT semantics since EXTBUF
> > > is added as well. I think strictly speaking it is an API change.
> > > Is it OK to make it without announcement?  
> > 
> > In any case, there will be an ABI change, because an application
> > compiled for 18.02 will not be able to handle these new kind of
> > mbuf.
> > 
> > So unfortunatly yes, I think this kind of changes should first be
> > announced.
> > 
> > Thomas, what do you think?  
> 
> What is the impact for the application developer?
> Is there something to change in the application after this patch?

Maybe the use of external buffers should be negotiated as a receiver
flag (per queue) in the device driver.  If device wants external buffers
it sets that in capability flag, and only uses it application requests
it. This allows old applications to work with no semantic surprises.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v6 00/16] Flow API overhaul for switch offloads
  @ 2018-04-25 15:27  5% ` Adrien Mazarguil
  2018-04-25 15:27 15%   ` [dpdk-dev] [PATCH v6 01/16] ethdev: add error types to flow API Adrien Mazarguil
                     ` (14 more replies)
  0 siblings, 15 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev

As summarized in a prior RFC [1], the flow API (rte_flow) was chosen as a
means to manage switch offloads supported by many devices (usually going by
names such as E-Switch or vSwitch) through user-specified flow rules.

Combined with the need to support encap/decap actions, this requires a
change in the way flow actions are processed (in order and possibly
repeated) which modifies the behavior of some of the existing actions, thus
warranting a major ABI breakage.

Given this ABI breakage is also required by other work submitted for the
current release [2][3], this series addresses various longstanding issues
with the flow API and makes minor improvements in preparation for upcoming
features.

Changes summary:

- Additional error types.
- Clearer documentation.
- Improved C++ compatibility.
- Exhaustive RSS action.
- Consistent behavior of VLAN pattern item.
- New "transfer" attribute bringing consistency to VF/PF pattern items.
- Confusing "PORT" pattern item renamed "PHY_PORT", with new action
  counterpart.
- New "PORT_ID" pattern item and action to be used with port representors.

This series piggybacks on the major ABI update introduced by a prior
commit [4] for DPDK 18.05 and depends on several fixes [5] which must be
applied first.

[1] "[RFC] Switch device offload with DPDK"
    http://dpdk.org/ml/archives/dev/2018-March/092513.html

[2] commit 676b605182a5 ("doc: announce ethdev API change for RSS
    configuration")

[3] "[PATCH v1 00/21] MLX5 tunnel Rx offloading"
    http://dpdk.org/ml/archives/dev/2018-March/092264.html

[4] commit 653e038efc9b ("ethdev: remove versioning of filter control
    function")

[5] "[PATCH v6 00/11] Bunch of flow API-related fixes"
    http://dpdk.org/ml/archives/dev/2018-April/098035.html

v6 changes:

- Fixed mlx5 issue raised by Nelio in "ethdev: flatten RSS configuration in
  flow API".
- Updated release notes (API update / ABI breakage) in relevant patches.
- Removed Xueming's deprecation notice in "ethdev: add encap level to RSS
  flow API action" since it's covered by this series.
- Reworded a few patches as fixes since they address API flaws.
- Rebased series once again.

v5 changes:

- Fixed errors reported by GCC and Clang in patch 05/16 ("ethdev: alter
  behavior of flow API actions").
- Rebased series once again.

v4 changes:

- No change besides new acked-by lines, rebased series to address conflicts.

v3 changes:

- Rebased series, fixed latest conflicts.
- Addressed Andrew's comments, see affected patches for details:
  - Empty RSS types in flow rule means PMD-specific RSS instead of no RSS.
  - RSS hash function now explicitly compared against
    RTE_ETH_HASH_FUNCTION_DEFAULT instead of 0 in all PMDs.
  - sfc PMD updated to also accept Toeplitz.
  - Implicit VLAN TPID matching now removed from all PMDs.
  - Default mask upate for VLAN TCI now split as separate patch #11.
  - Ingress/egress definition clarified in patch #12.

v2 changes:

- Squashed "ethdev: update ABI for flow API functions" in subsequent
  patches.
- Emphasized ABI impact in relevant commit logs.
- Modified documentation in "ethdev: alter behavior of flow API actions" to
  describe how terminating flow rules without any action of the fate kind
  result in undefined behavior instead of dropping traffic.
- Fixed other minor documentation formatting issues.
- Modified "ethdev: refine TPID handling in flow API" as follows:
  - Using standard macro definitions for VLAN, QinQ and E-Tag EtherTypes.
  - Fixed endian conversion in sfc.
  - Replaced a condition in VLAN pattern item processing with an assertion
    check for i40e.

Adrien Mazarguil (16):
  ethdev: add error types to flow API
  ethdev: clarify flow API pattern items and actions
  doc: remove flow API migration section
  ethdev: remove DUP action from flow API
  ethdev: alter behavior of flow API actions
  ethdev: fix C99 flexible arrays from flow API
  ethdev: flatten RSS configuration in flow API
  ethdev: add hash function to RSS flow API action
  ethdev: add encap level to RSS flow API action
  ethdev: fix TPID handling in flow API
  ethdev: fix default VLAN TCI mask in flow API
  ethdev: add transfer attribute to flow API
  ethdev: fix behavior of VF/PF in flow API
  ethdev: rename physical port item in flow API
  ethdev: add physical port action to flow API
  ethdev: add port ID item and action to flow API

 app/test-pmd/cmdline_flow.c                 | 394 +++++++++++----
 app/test-pmd/config.c                       |  78 +--
 doc/guides/nics/tap.rst                     |   2 +-
 doc/guides/prog_guide/rte_flow.rst          | 618 ++++++++---------------
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_18_05.rst      |  48 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  60 ++-
 drivers/net/bnxt/bnxt_filter.c              |  49 +-
 drivers/net/e1000/e1000_ethdev.h            |  13 +-
 drivers/net/e1000/igb_ethdev.c              |   4 +-
 drivers/net/e1000/igb_flow.c                |  83 ++-
 drivers/net/e1000/igb_rxtx.c                |  55 +-
 drivers/net/enic/enic_flow.c                |  50 +-
 drivers/net/i40e/i40e_ethdev.c              |  57 ++-
 drivers/net/i40e/i40e_ethdev.h              |  15 +-
 drivers/net/i40e/i40e_flow.c                | 130 +++--
 drivers/net/ixgbe/ixgbe_ethdev.c            |   7 +-
 drivers/net/ixgbe/ixgbe_ethdev.h            |  13 +-
 drivers/net/ixgbe/ixgbe_flow.c              |  91 +++-
 drivers/net/ixgbe/ixgbe_rxtx.c              |  55 +-
 drivers/net/mlx4/mlx4.c                     |   2 +-
 drivers/net/mlx4/mlx4_flow.c                | 117 +++--
 drivers/net/mlx4/mlx4_flow.h                |   2 +-
 drivers/net/mlx4/mlx4_rxq.c                 |   2 +-
 drivers/net/mlx4/mlx4_rxtx.h                |   2 +-
 drivers/net/mlx5/mlx5_flow.c                | 316 ++++++------
 drivers/net/mlx5/mlx5_rxq.c                 |  26 +-
 drivers/net/mlx5/mlx5_rxtx.h                |  26 +-
 drivers/net/mvpp2/mrvl_flow.c               |  32 +-
 drivers/net/sfc/sfc_flow.c                  |  78 ++-
 drivers/net/tap/tap_flow.c                  |  49 +-
 examples/ipsec-secgw/ipsec.c                |  21 +-
 lib/librte_ether/rte_ethdev_version.map     |  16 +-
 lib/librte_ether/rte_flow.c                 |  68 +--
 lib/librte_ether/rte_flow.h                 | 339 ++++++++-----
 lib/librte_net/rte_ether.h                  |   1 +
 36 files changed, 1796 insertions(+), 1127 deletions(-)

-- 
2.11.0

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH v6 01/16] ethdev: add error types to flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
@ 2018-04-25 15:27 15%   ` Adrien Mazarguil
  2018-04-25 15:27 21%   ` [dpdk-dev] [PATCH v6 04/16] ethdev: remove DUP action from " Adrien Mazarguil
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev

These enable more precise reporting of objects responsible for errors.

This breaks ABI compatibility for the following public functions:

- rte_flow_create()
- rte_flow_destroy()
- rte_flow_error_set()
- rte_flow_flush()
- rte_flow_isolate()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

---

v6 changes:

Updated ABI changes section in release notes.
---
 app/test-pmd/config.c                   |  4 ++++
 doc/guides/rel_notes/release_18_05.rst  |  7 +++++++
 lib/librte_ether/rte_ethdev_version.map | 14 +++++++-------
 lib/librte_ether/rte_flow.h             |  4 ++++
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 216a7eb4e..b275d759d 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1261,8 +1261,12 @@ port_flow_complain(struct rte_flow_error *error)
 		[RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
 		[RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
 		[RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
+		[RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification",
+		[RTE_FLOW_ERROR_TYPE_ITEM_LAST] = "item specification range",
+		[RTE_FLOW_ERROR_TYPE_ITEM_MASK] = "item specification mask",
 		[RTE_FLOW_ERROR_TYPE_ITEM] = "specific pattern item",
 		[RTE_FLOW_ERROR_TYPE_ACTION_NUM] = "number of actions",
+		[RTE_FLOW_ERROR_TYPE_ACTION_CONF] = "action configuration",
 		[RTE_FLOW_ERROR_TYPE_ACTION] = "specific action",
 	};
 	const char *errstr;
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 752a2c308..e50caa74a 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -283,6 +283,13 @@ ABI Changes
   type ``uint16_t``: ``burst_size``, ``ring_size``, and ``nb_queues``. These
   are parameter values recommended for use by the PMD.
 
+* ethdev: ABI for most flow API functions was updated.
+
+  This includes functions ``rte_flow_create``, ``rte_flow_destroy``,
+  ``rte_flow_error_set``, ``rte_flow_flush``, ``rte_flow_isolate``,
+  ``rte_flow_query`` and ``rte_flow_validate``, due to changes in error type
+  definitions (``enum rte_flow_error_type``).
+
 
 Removed Items
 -------------
diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/rte_ethdev_version.map
index 02713e430..180d2ca2d 100644
--- a/lib/librte_ether/rte_ethdev_version.map
+++ b/lib/librte_ether/rte_ethdev_version.map
@@ -127,11 +127,6 @@ DPDK_17.02 {
 
 	_rte_eth_dev_reset;
 	rte_eth_dev_fw_version_get;
-	rte_flow_create;
-	rte_flow_destroy;
-	rte_flow_flush;
-	rte_flow_query;
-	rte_flow_validate;
 
 } DPDK_16.07;
 
@@ -153,7 +148,6 @@ DPDK_17.08 {
 	_rte_eth_dev_callback_process;
 	rte_eth_dev_adjust_nb_rx_tx_desc;
 	rte_flow_copy;
-	rte_flow_isolate;
 	rte_tm_capabilities_get;
 	rte_tm_hierarchy_commit;
 	rte_tm_level_capabilities_get;
@@ -192,7 +186,6 @@ DPDK_17.11 {
 	rte_eth_dev_get_sec_ctx;
 	rte_eth_dev_pool_ops_supported;
 	rte_eth_dev_reset;
-	rte_flow_error_set;
 
 } DPDK_17.08;
 
@@ -208,6 +201,13 @@ DPDK_18.05 {
 
 	rte_eth_dev_count_avail;
 	rte_eth_find_next_owned_by;
+	rte_flow_create;
+	rte_flow_destroy;
+	rte_flow_error_set;
+	rte_flow_flush;
+	rte_flow_isolate;
+	rte_flow_query;
+	rte_flow_validate;
 
 } DPDK_18.02;
 
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 44ae19d3b..26b95c772 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -1186,8 +1186,12 @@ enum rte_flow_error_type {
 	RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */
 	RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */
 	RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */
+	RTE_FLOW_ERROR_TYPE_ITEM_SPEC, /**< Item specification. */
+	RTE_FLOW_ERROR_TYPE_ITEM_LAST, /**< Item specification range. */
+	RTE_FLOW_ERROR_TYPE_ITEM_MASK, /**< Item specification mask. */
 	RTE_FLOW_ERROR_TYPE_ITEM, /**< Specific pattern item. */
 	RTE_FLOW_ERROR_TYPE_ACTION_NUM, /**< Number of actions. */
+	RTE_FLOW_ERROR_TYPE_ACTION_CONF, /**< Action configuration. */
 	RTE_FLOW_ERROR_TYPE_ACTION, /**< Specific action. */
 };
 
-- 
2.11.0

^ permalink raw reply	[relevance 15%]

* [dpdk-dev] [PATCH v6 04/16] ethdev: remove DUP action from flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
  2018-04-25 15:27 15%   ` [dpdk-dev] [PATCH v6 01/16] ethdev: add error types to flow API Adrien Mazarguil
@ 2018-04-25 15:27 21%   ` Adrien Mazarguil
  2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 05/16] ethdev: alter behavior of flow API actions Adrien Mazarguil
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev

Upcoming changes in relation to the handling of actions list will make the
DUP action redundant as specifying several QUEUE actions will achieve the
same behavior. Besides, no PMD implements this action.

By removing an entry from enum rte_flow_action_type, this patch breaks ABI
compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

---

v6 changes:

Updated API and ABI changes sections in release notes.
---
 app/test-pmd/cmdline_flow.c                 | 23 -----------------------
 app/test-pmd/config.c                       |  1 -
 doc/guides/prog_guide/rte_flow.rst          | 23 -----------------------
 doc/guides/rel_notes/release_18_05.rst      | 13 ++++++++-----
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  8 --------
 lib/librte_ether/rte_ethdev_version.map     |  2 +-
 lib/librte_ether/rte_flow.c                 |  1 -
 lib/librte_ether/rte_flow.h                 | 24 ------------------------
 8 files changed, 9 insertions(+), 86 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f0b4b7bc4..2ddb08feb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -164,8 +164,6 @@ enum index {
 	ACTION_QUEUE_INDEX,
 	ACTION_DROP,
 	ACTION_COUNT,
-	ACTION_DUP,
-	ACTION_DUP_INDEX,
 	ACTION_RSS,
 	ACTION_RSS_TYPES,
 	ACTION_RSS_TYPE,
@@ -625,7 +623,6 @@ static const enum index next_action[] = {
 	ACTION_QUEUE,
 	ACTION_DROP,
 	ACTION_COUNT,
-	ACTION_DUP,
 	ACTION_RSS,
 	ACTION_PF,
 	ACTION_VF,
@@ -645,12 +642,6 @@ static const enum index action_queue[] = {
 	ZERO,
 };
 
-static const enum index action_dup[] = {
-	ACTION_DUP_INDEX,
-	ACTION_NEXT,
-	ZERO,
-};
-
 static const enum index action_rss[] = {
 	ACTION_RSS_TYPES,
 	ACTION_RSS_KEY,
@@ -1597,20 +1588,6 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
-	[ACTION_DUP] = {
-		.name = "dup",
-		.help = "duplicate packets to a given queue index",
-		.priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
-		.next = NEXT(action_dup),
-		.call = parse_vc,
-	},
-	[ACTION_DUP_INDEX] = {
-		.name = "index",
-		.help = "queue index to duplicate packets to",
-		.next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
-		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
-		.call = parse_vc_conf,
-	},
 	[ACTION_RSS] = {
 		.name = "rss",
 		.help = "spread packets among several queues",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index b275d759d..9729177f8 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1082,7 +1082,6 @@ static const struct {
 	MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
 	MK_FLOW_ACTION(DROP, 0),
 	MK_FLOW_ACTION(COUNT, 0),
-	MK_FLOW_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
 	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 51826d04c..a237e4fd2 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1299,26 +1299,6 @@ Query structure to retrieve and reset flow rule counters:
    | ``bytes``     | out | number of bytes through this rule |
    +---------------+-----+-----------------------------------+
 
-Action: ``DUP``
-^^^^^^^^^^^^^^^
-
-Duplicates packets to a given queue index.
-
-This is normally combined with QUEUE, however when used alone, it is
-actually similar to QUEUE + PASSTHRU.
-
-- Non-terminating by default.
-
-.. _table_rte_flow_action_dup:
-
-.. table:: DUP
-
-   +-----------+------------------------------------+
-   | Field     | Value                              |
-   +===========+====================================+
-   | ``index`` | queue index to duplicate packet to |
-   +-----------+------------------------------------+
-
 Action: ``RSS``
 ^^^^^^^^^^^^^^^
 
@@ -2010,9 +1990,6 @@ Unsupported actions
   and tagging (`Action: MARK`_ or `Action: FLAG`_) may be implemented in
   software as long as the target queue is used by a single rule.
 
-- A rule specifying both `Action: DUP`_ + `Action: QUEUE`_ may be translated
-  to two hidden rules combining `Action: QUEUE`_ and `Action: PASSTHRU`_.
-
 - When a single target queue is provided, `Action: RSS`_ can also be
   implemented through `Action: QUEUE`_.
 
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index e50caa74a..d3b619216 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -243,6 +243,8 @@ API Changes
    fall-back value. Previously, setting ``nb_tx_desc`` to zero would have
    resulted in an error.
 
+* ethdev: unused DUP action was removed from the flow API.
+
 
 ABI Changes
 -----------
@@ -283,12 +285,13 @@ ABI Changes
   type ``uint16_t``: ``burst_size``, ``ring_size``, and ``nb_queues``. These
   are parameter values recommended for use by the PMD.
 
-* ethdev: ABI for most flow API functions was updated.
+* ethdev: ABI for all flow API functions was updated.
 
-  This includes functions ``rte_flow_create``, ``rte_flow_destroy``,
-  ``rte_flow_error_set``, ``rte_flow_flush``, ``rte_flow_isolate``,
-  ``rte_flow_query`` and ``rte_flow_validate``, due to changes in error type
-  definitions (``enum rte_flow_error_type``).
+  This includes functions ``rte_flow_copy``, ``rte_flow_create``,
+  ``rte_flow_destroy``, ``rte_flow_error_set``, ``rte_flow_flush``,
+  ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
+  changes in error type definitions (``enum rte_flow_error_type``) and
+  removal of the unused DUP action (``enum rte_flow_action_type``).
 
 
 Removed Items
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 06caea3f5..68c286bd4 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3387,10 +3387,6 @@ actions can sometimes be combined when the end result is unambiguous::
 
 ::
 
-   drop / dup index 6 / end # same as above
-
-::
-
    queue index 6 / rss queues 6 7 8 / end # queue has no effect
 
 ::
@@ -3424,10 +3420,6 @@ This section lists supported actions and their attributes, if any.
 
 - ``count``: enable counters for this rule.
 
-- ``dup``: duplicate packets to a given queue index.
-
-  - ``index {unsigned}``: queue index to duplicate packets to.
-
 - ``rss``: spread packets among several queues.
 
   - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/rte_ethdev_version.map
index 180d2ca2d..29ca68eb7 100644
--- a/lib/librte_ether/rte_ethdev_version.map
+++ b/lib/librte_ether/rte_ethdev_version.map
@@ -147,7 +147,6 @@ DPDK_17.08 {
 
 	_rte_eth_dev_callback_process;
 	rte_eth_dev_adjust_nb_rx_tx_desc;
-	rte_flow_copy;
 	rte_tm_capabilities_get;
 	rte_tm_hierarchy_commit;
 	rte_tm_level_capabilities_get;
@@ -201,6 +200,7 @@ DPDK_18.05 {
 
 	rte_eth_dev_count_avail;
 	rte_eth_find_next_owned_by;
+	rte_flow_copy;
 	rte_flow_create;
 	rte_flow_destroy;
 	rte_flow_error_set;
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index ada280810..80f9cb6cb 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -73,7 +73,6 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
 	MK_FLOW_ACTION(DROP, 0),
 	MK_FLOW_ACTION(COUNT, 0),
-	MK_FLOW_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
 	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index d28a2a473..6ace24ff4 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -961,16 +961,6 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_COUNT,
 
 	/**
-	 * Duplicates packets to a given queue index.
-	 *
-	 * This is normally combined with QUEUE, however when used alone, it
-	 * is actually similar to QUEUE + PASSTHRU.
-	 *
-	 * See struct rte_flow_action_dup.
-	 */
-	RTE_FLOW_ACTION_TYPE_DUP,
-
-	/**
 	 * Similar to QUEUE, except RSS is additionally performed on packets
 	 * to spread them among several queues according to the provided
 	 * parameters.
@@ -1052,20 +1042,6 @@ struct rte_flow_query_count {
 };
 
 /**
- * RTE_FLOW_ACTION_TYPE_DUP
- *
- * Duplicates packets to a given queue index.
- *
- * This is normally combined with QUEUE, however when used alone, it is
- * actually similar to QUEUE + PASSTHRU.
- *
- * Non-terminating by default.
- */
-struct rte_flow_action_dup {
-	uint16_t index; /**< Queue index to duplicate packets to. */
-};
-
-/**
  * RTE_FLOW_ACTION_TYPE_RSS
  *
  * Similar to QUEUE, except RSS is additionally performed on packets to
-- 
2.11.0

^ permalink raw reply	[relevance 21%]

* [dpdk-dev] [PATCH v6 05/16] ethdev: alter behavior of flow API actions
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
  2018-04-25 15:27 15%   ` [dpdk-dev] [PATCH v6 01/16] ethdev: add error types to flow API Adrien Mazarguil
  2018-04-25 15:27 21%   ` [dpdk-dev] [PATCH v6 04/16] ethdev: remove DUP action from " Adrien Mazarguil
@ 2018-04-25 15:27  7%   ` Adrien Mazarguil
  2018-04-25 15:27  8%   ` [dpdk-dev] [PATCH v6 06/16] ethdev: fix C99 flexible arrays from flow API Adrien Mazarguil
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Ajit Khaparde, Wenzhuo Lu, John Daley, Gaetan Rivet, Beilei Xing,
	Konstantin Ananyev, Nelio Laranjeiro, Andrew Rybchenko,
	Pascal Mazon

This patch makes the following changes to flow rule actions:

- List order now matters, they are redefined as performed first to last
  instead of "all simultaneously".

- Repeated actions are now supported (e.g. specifying QUEUE multiple times
  now duplicates traffic among them). Previously only the last action of
  any given kind was taken into account.

- No more distinction between terminating/non-terminating/meta actions.
  Flow rules themselves are now defined as always terminating unless a
  PASSTHRU action is specified.

These changes alter the behavior of flow rules in corner cases in order to
prepare the flow API for actions that modify traffic contents or properties
(e.g. encapsulation, compression) and for which order matter when combined.

Previously one would have to do so through multiple flow rules by combining
PASSTRHU with priority levels, however this proved overly complex to
implement at the PMD level, hence this simpler approach.

This breaks ABI compatibility for the following public functions:

- rte_flow_create()
- rte_flow_validate()

PMDs with rte_flow support are modified accordingly:

- bnxt: no change, implementation already forbids multiple actions and does
  not support PASSTHRU.

- e1000: no change, same as bnxt.

- enic: modified to forbid redundant actions, no support for default drop.

- failsafe: no change needed.

- i40e: no change, implementation already forbids multiple actions.

- ixgbe: same as i40e.

- mlx4: modified to forbid multiple fate-deciding actions and drop when
  unspecified.

- mlx5: same as mlx4, with other redundant actions also forbidden.

- sfc: same as mlx4.

- tap: implementation already complies with the new behavior except for
  the default pass-through modified as a default drop.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Reviewed-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: John Daley <johndale@cisco.com>
Cc: Gaetan Rivet <gaetan.rivet@6wind.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>

--

v6 changes:

Updated API and ABI changes sections in release notes.

v5 changes:

Fixed issues raised by GCC and Clang with overlap checks in both enic and
mlx5, as reported by Andrew [1].

[1] http://dpdk.org/ml/archives/dev/2018-April/097864.html
---
 doc/guides/prog_guide/rte_flow.rst     | 67 +++++++++++-----------------
 doc/guides/rel_notes/release_18_05.rst | 15 +++++--
 drivers/net/enic/enic_flow.c           | 25 +++++++++++
 drivers/net/mlx4/mlx4_flow.c           | 21 ++++++---
 drivers/net/mlx5/mlx5_flow.c           | 69 +++++++++++++----------------
 drivers/net/sfc/sfc_flow.c             | 22 ++++++---
 drivers/net/tap/tap_flow.c             | 11 +++++
 lib/librte_ether/rte_flow.h            | 54 +++++++---------------
 8 files changed, 150 insertions(+), 134 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a237e4fd2..80360d068 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -995,28 +995,27 @@ Actions
 
 Each possible action is represented by a type. Some have associated
 configuration structures. Several actions combined in a list can be assigned
-to a flow rule. That list is not ordered.
+to a flow rule and are performed in order.
 
 They fall in three categories:
 
-- Terminating actions that prevent processing matched packets by subsequent
-  flow rules, unless overridden with PASSTHRU.
+- Actions that modify the fate of matching traffic, for instance by dropping
+  or assigning it a specific destination.
 
-- Non-terminating actions that leave matched packets up for additional
-  processing by subsequent flow rules.
+- Actions that modify matching traffic contents or its properties. This
+  includes adding/removing encapsulation, encryption, compression and marks.
 
-- Other non-terminating meta actions that do not affect the fate of packets.
+- Actions related to the flow rule itself, such as updating counters or
+  making it non-terminating.
 
-When several actions are combined in a flow rule, they should all have
-different types (e.g. dropping a packet twice is not possible).
+Flow rules being terminating by default, not specifying any action of the
+fate kind results in undefined behavior. This applies to both ingress and
+egress.
 
-Only the last action of a given type is taken into account. PMDs still
-perform error checking on the entire list.
+PASSTHRU, when supported, makes a flow rule non-terminating.
 
 Like matching patterns, action lists are terminated by END items.
 
-*Note that PASSTHRU is the only action able to override a terminating rule.*
-
 Example of action that redirects packets to queue index 10:
 
 .. _table_rte_flow_action_example:
@@ -1029,12 +1028,11 @@ Example of action that redirects packets to queue index 10:
    | ``index`` | 10    |
    +-----------+-------+
 
-Action lists examples, their order is not significant, applications must
-consider all actions to be performed simultaneously:
+Actions are performed in list order:
 
-.. _table_rte_flow_count_and_drop:
+.. _table_rte_flow_count_then_drop:
 
-.. table:: Count and drop
+.. table:: Count then drop
 
    +-------+--------+
    | Index | Action |
@@ -1050,7 +1048,7 @@ consider all actions to be performed simultaneously:
 
 .. _table_rte_flow_mark_count_redirect:
 
-.. table:: Mark, count and redirect
+.. table:: Mark, count then redirect
 
    +-------+--------+-----------+-------+
    | Index | Action | Field     | Value |
@@ -1080,12 +1078,15 @@ consider all actions to be performed simultaneously:
    | 2     | END                        |
    +-------+----------------------------+
 
-In the above example, considering both actions are performed simultaneously,
-the end result is that only QUEUE has any effect.
+In the above example, while DROP and QUEUE must be performed in order, both
+have to happen before reaching END. Only QUEUE has a visible effect.
+
+Note that such a list may be thought as ambiguous and rejected on that
+basis.
 
-.. _table_rte_flow_redirect_queue_3:
+.. _table_rte_flow_redirect_queue_5_3:
 
-.. table:: Redirect to queue 3
+.. table:: Redirect to queues 5 and 3
 
    +-------+--------+-----------+-------+
    | Index | Action | Field     | Value |
@@ -1099,9 +1100,9 @@ the end result is that only QUEUE has any effect.
    | 3     | END                        |
    +-------+----------------------------+
 
-As previously described, only the last action of a given type found in the
-list is taken into account. The above example also shows that VOID is
-ignored.
+As previously described, all actions must be taken into account. This
+effectively duplicates traffic to both queues. The above example also shows
+that VOID is ignored.
 
 Action types
 ~~~~~~~~~~~~
@@ -1151,9 +1152,8 @@ PMDs.
 Action: ``PASSTHRU``
 ^^^^^^^^^^^^^^^^^^^^
 
-Leaves packets up for additional processing by subsequent flow rules. This
-is the default when a rule does not contain a terminating action, but can be
-specified to force a rule to become non-terminating.
+Leaves traffic up for additional processing by subsequent flow rules; makes
+a flow rule non-terminating.
 
 - No configurable properties.
 
@@ -1227,8 +1227,6 @@ Action: ``QUEUE``
 
 Assigns packets to a given queue index.
 
-- Terminating by default.
-
 .. _table_rte_flow_action_queue:
 
 .. table:: QUEUE
@@ -1245,8 +1243,6 @@ Action: ``DROP``
 Drop packets.
 
 - No configurable properties.
-- Terminating by default.
-- PASSTHRU overrides this action if both are specified.
 
 .. _table_rte_flow_action_drop:
 
@@ -1309,8 +1305,6 @@ Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
 overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
 field only, both can be requested simultaneously.
 
-- Terminating by default.
-
 .. _table_rte_flow_action_rss:
 
 .. table:: RSS
@@ -1331,7 +1325,6 @@ Action: ``PF``
 Redirects packets to the physical function (PF) of the current device.
 
 - No configurable properties.
-- Terminating by default.
 
 .. _table_rte_flow_action_pf:
 
@@ -1353,8 +1346,6 @@ ID instead of the specified one. This parameter may not be available and is
 not guaranteed to work properly if the VF part is matched by a prior flow
 rule or if packets are not addressed to a VF in the first place.
 
-- Terminating by default.
-
 .. _table_rte_flow_action_vf:
 
 .. table:: VF
@@ -1378,8 +1369,6 @@ action parameter. More than one flow can use the same MTR object through
 the meter action. The MTR object can be further updated or queried using
 the rte_mtr* API.
 
-- Non-terminating by default.
-
 .. _table_rte_flow_action_meter:
 
 .. table:: METER
@@ -1415,8 +1404,6 @@ direction.
 
 Multiple flows can be configured to use the same security session.
 
-- Non-terminating by default.
-
 .. _table_rte_flow_action_security:
 
 .. table:: SECURITY
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index d3b619216..1db6c5257 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -243,7 +243,15 @@ API Changes
    fall-back value. Previously, setting ``nb_tx_desc`` to zero would have
    resulted in an error.
 
-* ethdev: unused DUP action was removed from the flow API.
+* ethdev: several changes were made to the flow API.
+
+  * Unused DUP action was removed.
+  * Actions semantics in flow rules: list order now matters ("first
+    to last" instead of "all simultaneously"), repeated actions are now
+    all performed, and they do not individually have (non-)terminating
+    properties anymore.
+  * Flow rules are now always terminating unless a PASSTHRU action is
+    present.
 
 
 ABI Changes
@@ -290,8 +298,9 @@ ABI Changes
   This includes functions ``rte_flow_copy``, ``rte_flow_create``,
   ``rte_flow_destroy``, ``rte_flow_error_set``, ``rte_flow_flush``,
   ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
-  changes in error type definitions (``enum rte_flow_error_type``) and
-  removal of the unused DUP action (``enum rte_flow_action_type``).
+  changes in error type definitions (``enum rte_flow_error_type``), removal
+  of the unused DUP action (``enum rte_flow_action_type``) and modified
+  behavior for flow rule actions (see API changes).
 
 
 Removed Items
diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index b9f36587c..c34ae84d1 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -3,6 +3,7 @@
  */
 
 #include <errno.h>
+#include <stdint.h>
 #include <rte_log.h>
 #include <rte_ethdev_driver.h>
 #include <rte_flow_driver.h>
@@ -964,6 +965,9 @@ static int
 enic_copy_action_v1(const struct rte_flow_action actions[],
 		    struct filter_action_v2 *enic_action)
 {
+	enum { FATE = 1, };
+	uint32_t overlap = 0;
+
 	FLOW_TRACE();
 
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
@@ -975,6 +979,10 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
 				actions->conf;
+
+			if (overlap & FATE)
+				return ENOTSUP;
+			overlap |= FATE;
 			enic_action->rq_idx =
 				enic_rte_rq_idx_to_sop_idx(queue->index);
 			break;
@@ -984,6 +992,8 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
 			break;
 		}
 	}
+	if (!(overlap & FATE))
+		return ENOTSUP;
 	enic_action->type = FILTER_ACTION_RQ_STEERING;
 	return 0;
 }
@@ -1001,6 +1011,9 @@ static int
 enic_copy_action_v2(const struct rte_flow_action actions[],
 		    struct filter_action_v2 *enic_action)
 {
+	enum { FATE = 1, MARK = 2, };
+	uint32_t overlap = 0;
+
 	FLOW_TRACE();
 
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
@@ -1009,6 +1022,10 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
 				actions->conf;
+
+			if (overlap & FATE)
+				return ENOTSUP;
+			overlap |= FATE;
 			enic_action->rq_idx =
 				enic_rte_rq_idx_to_sop_idx(queue->index);
 			enic_action->flags |= FILTER_ACTION_RQ_STEERING_FLAG;
@@ -1019,6 +1036,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
 				(const struct rte_flow_action_mark *)
 				actions->conf;
 
+			if (overlap & MARK)
+				return ENOTSUP;
+			overlap |= MARK;
 			/* ENIC_MAGIC_FILTER_ID is reserved and is the highest
 			 * in the range of allows mark ids.
 			 */
@@ -1029,6 +1049,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_FLAG: {
+			if (overlap & MARK)
+				return ENOTSUP;
+			overlap |= MARK;
 			enic_action->filter_id = ENIC_MAGIC_FILTER_ID;
 			enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
 			break;
@@ -1044,6 +1067,8 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
 			break;
 		}
 	}
+	if (!(overlap & FATE))
+		return ENOTSUP;
 	enic_action->type = FILTER_ACTION_V2;
 	return 0;
 }
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 67fd568bc..15cdf07b7 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -637,6 +637,7 @@ mlx4_flow_prepare(struct priv *priv,
 	struct rte_flow temp = { .ibv_attr_size = sizeof(*temp.ibv_attr) };
 	struct rte_flow *flow = &temp;
 	const char *msg = NULL;
+	int overlap;
 
 	if (attr->group)
 		return rte_flow_error_set
@@ -656,6 +657,7 @@ mlx4_flow_prepare(struct priv *priv,
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
 			 NULL, "only ingress is supported");
 fill:
+	overlap = 0;
 	proc = mlx4_flow_proc_item_list;
 	/* Go over pattern. */
 	for (item = pattern; item->type; ++item) {
@@ -702,6 +704,16 @@ mlx4_flow_prepare(struct priv *priv,
 	}
 	/* Go over actions list. */
 	for (action = actions; action->type; ++action) {
+		/* This one may appear anywhere multiple times. */
+		if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
+			continue;
+		/* Fate-deciding actions may appear exactly once. */
+		if (overlap) {
+			msg = "cannot combine several fate-deciding actions,"
+				" choose between DROP, QUEUE or RSS";
+			goto exit_action_not_supported;
+		}
+		overlap = 1;
 		switch (action->type) {
 			const struct rte_flow_action_queue *queue;
 			const struct rte_flow_action_rss *rss;
@@ -709,8 +721,6 @@ mlx4_flow_prepare(struct priv *priv,
 			uint64_t fields;
 			unsigned int i;
 
-		case RTE_FLOW_ACTION_TYPE_VOID:
-			continue;
 		case RTE_FLOW_ACTION_TYPE_DROP:
 			flow->drop = 1;
 			break;
@@ -801,10 +811,9 @@ mlx4_flow_prepare(struct priv *priv,
 			goto exit_action_not_supported;
 		}
 	}
-	if (!flow->rss && !flow->drop)
-		return rte_flow_error_set
-			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-			 NULL, "no valid action");
+	/* When fate is unknown, drop traffic. */
+	if (!overlap)
+		flow->drop = 1;
 	/* Validation ends here. */
 	if (!addr) {
 		if (flow->rss)
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 1807e3f5b..586e780c4 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4,6 +4,7 @@
  */
 
 #include <sys/queue.h>
+#include <stdint.h>
 #include <string.h>
 
 /* Verbs header. */
@@ -646,6 +647,8 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 			  struct rte_flow_error *error,
 			  struct mlx5_flow_parse *parser)
 {
+	enum { FATE = 1, MARK = 2, COUNT = 4, };
+	uint32_t overlap = 0;
 	struct priv *priv = dev->data->dev_private;
 	int ret;
 
@@ -662,39 +665,31 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
 			continue;
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) {
+			if (overlap & FATE)
+				goto exit_action_overlap;
+			overlap |= FATE;
 			parser->drop = 1;
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
 				actions->conf;
-			uint16_t n;
-			uint16_t found = 0;
 
+			if (overlap & FATE)
+				goto exit_action_overlap;
+			overlap |= FATE;
 			if (!queue || (queue->index > (priv->rxqs_n - 1)))
 				goto exit_action_not_supported;
-			for (n = 0; n < parser->queues_n; ++n) {
-				if (parser->queues[n] == queue->index) {
-					found = 1;
-					break;
-				}
-			}
-			if (parser->queues_n > 1 && !found) {
-				rte_flow_error_set(error, ENOTSUP,
-					   RTE_FLOW_ERROR_TYPE_ACTION,
-					   actions,
-					   "queue action not in RSS queues");
-				return -rte_errno;
-			}
-			if (!found) {
-				parser->queues_n = 1;
-				parser->queues[0] = queue->index;
-			}
+			parser->queues_n = 1;
+			parser->queues[0] = queue->index;
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 			uint16_t n;
 
+			if (overlap & FATE)
+				goto exit_action_overlap;
+			overlap |= FATE;
 			if (!rss || !rss->num) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -702,26 +697,6 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 						   "no valid queues");
 				return -rte_errno;
 			}
-			if (parser->queues_n == 1) {
-				uint16_t found = 0;
-
-				assert(parser->queues_n);
-				for (n = 0; n < rss->num; ++n) {
-					if (parser->queues[0] ==
-					    rss->queue[n]) {
-						found = 1;
-						break;
-					}
-				}
-				if (!found) {
-					rte_flow_error_set(error, ENOTSUP,
-						   RTE_FLOW_ERROR_TYPE_ACTION,
-						   actions,
-						   "queue action not in RSS"
-						   " queues");
-					return -rte_errno;
-				}
-			}
 			if (rss->num > RTE_DIM(parser->queues)) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -755,6 +730,9 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 				(const struct rte_flow_action_mark *)
 				actions->conf;
 
+			if (overlap & MARK)
+				goto exit_action_overlap;
+			overlap |= MARK;
 			if (!mark) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -772,14 +750,23 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 			parser->mark = 1;
 			parser->mark_id = mark->id;
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_FLAG) {
+			if (overlap & MARK)
+				goto exit_action_overlap;
+			overlap |= MARK;
 			parser->mark = 1;
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_COUNT &&
 			   priv->config.flow_counter_en) {
+			if (overlap & COUNT)
+				goto exit_action_overlap;
+			overlap |= COUNT;
 			parser->count = 1;
 		} else {
 			goto exit_action_not_supported;
 		}
 	}
+	/* When fate is unknown, drop traffic. */
+	if (!(overlap & FATE))
+		parser->drop = 1;
 	if (parser->drop && parser->mark)
 		parser->mark = 0;
 	if (!parser->queues_n && !parser->drop) {
@@ -792,6 +779,10 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
 			   actions, "action not supported");
 	return -rte_errno;
+exit_action_overlap:
+	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
+			   actions, "overlapping actions are not supported");
+	return -rte_errno;
 }
 
 /**
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index fe4c0b0c5..056405515 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1467,10 +1467,19 @@ sfc_flow_parse_actions(struct sfc_adapter *sa,
 	}
 
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+		/* This one may appear anywhere multiple times. */
+		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID)
+			continue;
+		/* Fate-deciding actions may appear exactly once. */
+		if (is_specified) {
+			rte_flow_error_set
+				(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
+				 actions,
+				 "Cannot combine several fate-deciding actions,"
+				 "choose between QUEUE, RSS or DROP");
+			return -rte_errno;
+		}
 		switch (actions->type) {
-		case RTE_FLOW_ACTION_TYPE_VOID:
-			break;
-
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 			rc = sfc_flow_parse_queue(sa, actions->conf, flow);
 			if (rc != 0) {
@@ -1512,11 +1521,10 @@ sfc_flow_parse_actions(struct sfc_adapter *sa,
 		}
 	}
 
+	/* When fate is unknown, drop traffic. */
 	if (!is_specified) {
-		rte_flow_error_set(error, EINVAL,
-				   RTE_FLOW_ERROR_TYPE_ACTION_NUM, actions,
-				   "Action is unspecified");
-		return -rte_errno;
+		flow->spec.template.efs_dmaq_id =
+			EFX_FILTER_SPEC_RX_DMAQ_ID_DROP;
 	}
 
 	return 0;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 3b7a960b0..fe2f94010 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1140,6 +1140,7 @@ priv_flow_process(struct pmd_internals *pmd,
 		else
 			goto end;
 	}
+actions:
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
 		int err = 0;
 
@@ -1222,6 +1223,16 @@ priv_flow_process(struct pmd_internals *pmd,
 		if (err)
 			goto exit_action_not_supported;
 	}
+	/* When fate is unknown, drop traffic. */
+	if (!action) {
+		static const struct rte_flow_action drop[] = {
+			{ .type = RTE_FLOW_ACTION_TYPE_DROP, },
+			{ .type = RTE_FLOW_ACTION_TYPE_END, },
+		};
+
+		actions = drop;
+		goto actions;
+	}
 end:
 	if (flow)
 		tap_nlattr_nested_finish(&flow->msg); /* nested TCA_OPTIONS */
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 6ace24ff4..96184f030 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -859,32 +859,28 @@ struct rte_flow_item {
  *
  * Each possible action is represented by a type. Some have associated
  * configuration structures. Several actions combined in a list can be
- * affected to a flow rule. That list is not ordered.
+ * assigned to a flow rule and are performed in order.
  *
  * They fall in three categories:
  *
- * - Terminating actions that prevent processing matched packets by
- *   subsequent flow rules, unless overridden with PASSTHRU.
+ * - Actions that modify the fate of matching traffic, for instance by
+ *   dropping or assigning it a specific destination.
  *
- * - Non terminating actions that leave matched packets up for additional
- *   processing by subsequent flow rules.
+ * - Actions that modify matching traffic contents or its properties. This
+ *   includes adding/removing encapsulation, encryption, compression and
+ *   marks.
  *
- * - Other non terminating meta actions that do not affect the fate of
- *   packets.
+ * - Actions related to the flow rule itself, such as updating counters or
+ *   making it non-terminating.
  *
- * When several actions are combined in a flow rule, they should all have
- * different types (e.g. dropping a packet twice is not possible).
+ * Flow rules being terminating by default, not specifying any action of the
+ * fate kind results in undefined behavior. This applies to both ingress and
+ * egress.
  *
- * Only the last action of a given type is taken into account. PMDs still
- * perform error checking on the entire list.
- *
- * Note that PASSTHRU is the only action able to override a terminating
- * rule.
+ * PASSTHRU, when supported, makes a flow rule non-terminating.
  */
 enum rte_flow_action_type {
 	/**
-	 * [META]
-	 *
 	 * End marker for action lists. Prevents further processing of
 	 * actions, thereby ending the list.
 	 *
@@ -893,8 +889,6 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_END,
 
 	/**
-	 * [META]
-	 *
 	 * Used as a placeholder for convenience. It is ignored and simply
 	 * discarded by PMDs.
 	 *
@@ -903,18 +897,14 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VOID,
 
 	/**
-	 * Leaves packets up for additional processing by subsequent flow
-	 * rules. This is the default when a rule does not contain a
-	 * terminating action, but can be specified to force a rule to
-	 * become non-terminating.
+	 * Leaves traffic up for additional processing by subsequent flow
+	 * rules; makes a flow rule non-terminating.
 	 *
 	 * No associated configuration structure.
 	 */
 	RTE_FLOW_ACTION_TYPE_PASSTHRU,
 
 	/**
-	 * [META]
-	 *
 	 * Attaches an integer value to packets and sets PKT_RX_FDIR and
 	 * PKT_RX_FDIR_ID mbuf flags.
 	 *
@@ -923,8 +913,6 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_MARK,
 
 	/**
-	 * [META]
-	 *
 	 * Flags packets. Similar to MARK without a specific value; only
 	 * sets the PKT_RX_FDIR mbuf flag.
 	 *
@@ -949,9 +937,7 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_DROP,
 
 	/**
-	 * [META]
-	 *
-	 * Enables counters for this rule.
+	 * Enables counters for this flow rule.
 	 *
 	 * These counters can be retrieved and reset through rte_flow_query(),
 	 * see struct rte_flow_query_count.
@@ -1020,8 +1006,6 @@ struct rte_flow_action_mark {
  * RTE_FLOW_ACTION_TYPE_QUEUE
  *
  * Assign packets to a given queue index.
- *
- * Terminating by default.
  */
 struct rte_flow_action_queue {
 	uint16_t index; /**< Queue index to use. */
@@ -1050,8 +1034,6 @@ struct rte_flow_query_count {
  * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps
  * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only,
  * both can be requested simultaneously.
- *
- * Terminating by default.
  */
 struct rte_flow_action_rss {
 	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
@@ -1069,8 +1051,6 @@ struct rte_flow_action_rss {
  * and is not guaranteed to work properly if the VF part is matched by a
  * prior flow rule or if packets are not addressed to a VF in the first
  * place.
- *
- * Terminating by default.
  */
 struct rte_flow_action_vf {
 	uint32_t original:1; /**< Use original VF ID if possible. */
@@ -1085,8 +1065,6 @@ struct rte_flow_action_vf {
  *
  * Packets matched by items of this type can be either dropped or passed to the
  * next item with their color set by the MTR object.
- *
- * Non-terminating by default.
  */
 struct rte_flow_action_meter {
 	uint32_t mtr_id; /**< MTR object ID created with rte_mtr_create(). */
@@ -1116,8 +1094,6 @@ struct rte_flow_action_meter {
  * direction.
  *
  * Multiple flows can be configured to use the same security session.
- *
- * Non-terminating by default.
  */
 struct rte_flow_action_security {
 	void *security_session; /**< Pointer to security session structure. */
-- 
2.11.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v6 06/16] ethdev: fix C99 flexible arrays from flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (2 preceding siblings ...)
  2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 05/16] ethdev: alter behavior of flow API actions Adrien Mazarguil
@ 2018-04-25 15:27  8%   ` Adrien Mazarguil
  2018-04-25 15:27  3%   ` [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in " Adrien Mazarguil
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev

This patch replaces C99-style flexible arrays in struct rte_flow_action_rss
and struct rte_flow_item_raw with standard pointers to the same data.

They proved difficult to use in the field (e.g. no possibility of static
initialization) and unsuitable for C++ applications.

Affected PMDs and examples are updated accordingly.

This breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

--

v6 changes:

- Reworded patch title as a "fix" (not candidate for backports) since it
  addresses a flaw in the original API definition.
- Updated API and ABI changes sections in release notes.
---
 app/test-pmd/cmdline_flow.c            | 117 +++++++++++++++-------------
 app/test-pmd/config.c                  |  25 ++++--
 doc/guides/prog_guide/rte_flow.rst     |  18 ++---
 doc/guides/rel_notes/release_18_05.rst |   8 +-
 drivers/net/mlx4/mlx4_flow.c           |  22 +++---
 drivers/net/mlx5/mlx5_flow.c           |  20 ++---
 examples/ipsec-secgw/ipsec.c           |  17 ++--
 lib/librte_ether/rte_flow.c            |  25 ++++--
 lib/librte_ether/rte_flow.h            |   8 +-
 9 files changed, 141 insertions(+), 119 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 2ddb08feb..798b7948d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -179,25 +179,22 @@ enum index {
 	ACTION_METER_ID,
 };
 
-/** Size of pattern[] field in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 36
+/** Maximum size for pattern in struct rte_flow_item_raw. */
+#define ITEM_RAW_PATTERN_SIZE 40
 
 /** Storage size for struct rte_flow_item_raw including pattern. */
 #define ITEM_RAW_SIZE \
-	(offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
+	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
 /** Maximum number of queue indices in struct rte_flow_action_rss. */
 #define ACTION_RSS_QUEUE_NUM 32
 
 /** Storage for struct rte_flow_action_rss including external data. */
-union action_rss_data {
+struct action_rss_data {
 	struct rte_flow_action_rss conf;
-	struct {
-		uint8_t conf_data[offsetof(struct rte_flow_action_rss, queue)];
-		uint16_t queue[ACTION_RSS_QUEUE_NUM];
-		struct rte_eth_rss_conf rss_conf;
-		uint8_t rss_key[RSS_HASH_KEY_LENGTH];
-	} s;
+	uint16_t queue[ACTION_RSS_QUEUE_NUM];
+	struct rte_eth_rss_conf rss_conf;
+	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
 };
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -320,13 +317,6 @@ struct token {
 		.size = sizeof(*((s *)0)->f), \
 	})
 
-/** Static initializer for ARGS() with arbitrary size. */
-#define ARGS_ENTRY_USZ(s, f, sz) \
-	(&(const struct arg){ \
-		.offset = offsetof(s, f), \
-		.size = (sz), \
-	})
-
 /** Static initializer for ARGS() with arbitrary offset and size. */
 #define ARGS_ENTRY_ARB(o, s) \
 	(&(const struct arg){ \
@@ -1105,9 +1095,9 @@ static const struct token token_list[] = {
 			     NEXT_ENTRY(ITEM_PARAM_IS,
 					ITEM_PARAM_SPEC,
 					ITEM_PARAM_MASK)),
-		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, length),
-			     ARGS_ENTRY_USZ(struct rte_flow_item_raw,
-					    pattern,
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
+			     ARGS_ENTRY(struct rte_flow_item_raw, length),
+			     ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
 					    ITEM_RAW_PATTERN_SIZE)),
 	},
 	[ITEM_ETH] = {
@@ -1591,7 +1581,7 @@ static const struct token token_list[] = {
 	[ACTION_RSS] = {
 		.name = "rss",
 		.help = "spread packets among several queues",
-		.priv = PRIV_ACTION(RSS, sizeof(union action_rss_data)),
+		.priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
 		.next = NEXT(action_rss),
 		.call = parse_vc_action_rss,
 	},
@@ -1610,23 +1600,21 @@ static const struct token token_list[] = {
 		.name = "key",
 		.help = "RSS hash key",
 		.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
-		.args = ARGS(ARGS_ENTRY_ARB
-			     (((uintptr_t)&((union action_rss_data *)0)->
-			       s.rss_conf.rss_key_len),
+		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
+			     ARGS_ENTRY_ARB
+			     (offsetof(struct action_rss_data, rss_conf) +
+			      offsetof(struct rte_eth_rss_conf, rss_key_len),
 			      sizeof(((struct rte_eth_rss_conf *)0)->
 				     rss_key_len)),
-			     ARGS_ENTRY_ARB
-			     (((uintptr_t)((union action_rss_data *)0)->
-			       s.rss_key),
-			      RSS_HASH_KEY_LENGTH)),
+			     ARGS_ENTRY(struct action_rss_data, rss_key)),
 	},
 	[ACTION_RSS_KEY_LEN] = {
 		.name = "key_len",
 		.help = "RSS hash key length in bytes",
 		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
 		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
-			     (((uintptr_t)&((union action_rss_data *)0)->
-			       s.rss_conf.rss_key_len),
+			     (offsetof(struct action_rss_data, rss_conf) +
+			      offsetof(struct rte_eth_rss_conf, rss_key_len),
 			      sizeof(((struct rte_eth_rss_conf *)0)->
 				     rss_key_len),
 			      0,
@@ -2067,7 +2055,7 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 {
 	struct buffer *out = buf;
 	struct rte_flow_action *action;
-	union action_rss_data *action_rss_data;
+	struct action_rss_data *action_rss_data;
 	unsigned int i;
 	int ret;
 
@@ -2085,29 +2073,29 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 	ctx->objmask = NULL;
 	/* Set up default configuration. */
 	action_rss_data = ctx->object;
-	*action_rss_data = (union action_rss_data){
+	*action_rss_data = (struct action_rss_data){
 		.conf = (struct rte_flow_action_rss){
-			.rss_conf = &action_rss_data->s.rss_conf,
+			.rss_conf = &action_rss_data->rss_conf,
 			.num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
+			.queue = action_rss_data->queue,
 		},
+		.queue = { 0 },
+		.rss_conf = (struct rte_eth_rss_conf){
+			.rss_key = action_rss_data->rss_key,
+			.rss_key_len = sizeof(action_rss_data->rss_key),
+			.rss_hf = rss_hf,
+		},
+		.rss_key = "testpmd's default RSS hash key",
 	};
-	action_rss_data->s.rss_conf = (struct rte_eth_rss_conf){
-		.rss_key = action_rss_data->s.rss_key,
-		.rss_key_len = sizeof(action_rss_data->s.rss_key),
-		.rss_hf = rss_hf,
-	};
-	strncpy((void *)action_rss_data->s.rss_key,
-		"testpmd's default RSS hash key",
-		sizeof(action_rss_data->s.rss_key));
 	for (i = 0; i < action_rss_data->conf.num; ++i)
-		action_rss_data->conf.queue[i] = i;
+		action_rss_data->queue[i] = i;
 	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
 	    ctx->port != (portid_t)RTE_PORT_ALL) {
 		struct rte_eth_dev_info info;
 
 		rte_eth_dev_info_get(ctx->port, &info);
-		action_rss_data->s.rss_conf.rss_key_len =
-			RTE_MIN(sizeof(action_rss_data->s.rss_key),
+		action_rss_data->rss_conf.rss_key_len =
+			RTE_MIN(sizeof(action_rss_data->rss_key),
 				info.hash_key_size);
 	}
 	action->conf = &action_rss_data->conf;
@@ -2125,7 +2113,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
 			  void *buf, unsigned int size)
 {
 	static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
-	union action_rss_data *action_rss_data;
+	struct action_rss_data *action_rss_data;
 	unsigned int i;
 
 	(void)token;
@@ -2135,7 +2123,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
 		return -1;
 	if (!(ctx->objdata >> 16) && ctx->object) {
 		action_rss_data = ctx->object;
-		action_rss_data->s.rss_conf.rss_hf = 0;
+		action_rss_data->rss_conf.rss_hf = 0;
 	}
 	if (!strcmp_partial("end", str, len)) {
 		ctx->objdata &= 0xffff;
@@ -2154,7 +2142,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
 	if (!ctx->object)
 		return len;
 	action_rss_data = ctx->object;
-	action_rss_data->s.rss_conf.rss_hf |= rss_type_table[i].rss_type;
+	action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
 	return len;
 }
 
@@ -2169,7 +2157,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 			  void *buf, unsigned int size)
 {
 	static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
-	union action_rss_data *action_rss_data;
+	struct action_rss_data *action_rss_data;
 	int ret;
 	int i;
 
@@ -2186,10 +2174,9 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 	if (i >= ACTION_RSS_QUEUE_NUM)
 		return -1;
 	if (push_args(ctx,
-		      ARGS_ENTRY_ARB(offsetof(struct rte_flow_action_rss,
-					      queue) +
-				     i * sizeof(action_rss_data->s.queue[i]),
-				     sizeof(action_rss_data->s.queue[i]))))
+		      ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
+				     i * sizeof(action_rss_data->queue[i]),
+				     sizeof(action_rss_data->queue[i]))))
 		return -1;
 	ret = parse_int(ctx, token, str, len, NULL, 0);
 	if (ret < 0) {
@@ -2206,6 +2193,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 		return len;
 	action_rss_data = ctx->object;
 	action_rss_data->conf.num = i;
+	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
 	return len;
 }
 
@@ -2483,8 +2471,8 @@ parse_int(struct context *ctx, const struct token *token,
 /**
  * Parse a string.
  *
- * Two arguments (ctx->args) are retrieved from the stack to store data and
- * its length (in that order).
+ * Three arguments (ctx->args) are retrieved from the stack to store data,
+ * its actual length and address (in that order).
  */
 static int
 parse_string(struct context *ctx, const struct token *token,
@@ -2493,6 +2481,7 @@ parse_string(struct context *ctx, const struct token *token,
 {
 	const struct arg *arg_data = pop_args(ctx);
 	const struct arg *arg_len = pop_args(ctx);
+	const struct arg *arg_addr = pop_args(ctx);
 	char tmp[16]; /* Ought to be enough. */
 	int ret;
 
@@ -2503,6 +2492,11 @@ parse_string(struct context *ctx, const struct token *token,
 		push_args(ctx, arg_data);
 		return -1;
 	}
+	if (!arg_addr) {
+		push_args(ctx, arg_len);
+		push_args(ctx, arg_data);
+		return -1;
+	}
 	size = arg_data->size;
 	/* Bit-mask fill is not supported. */
 	if (arg_data->mask || size < len)
@@ -2525,8 +2519,23 @@ parse_string(struct context *ctx, const struct token *token,
 	memset((uint8_t *)buf + len, 0x00, size - len);
 	if (ctx->objmask)
 		memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
+	/* Save address if requested. */
+	if (arg_addr->size) {
+		memcpy((uint8_t *)ctx->object + arg_addr->offset,
+		       (void *[]){
+			(uint8_t *)ctx->object + arg_data->offset
+		       },
+		       arg_addr->size);
+		if (ctx->objmask)
+			memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
+			       (void *[]){
+				(uint8_t *)ctx->objmask + arg_data->offset
+			       },
+			       arg_addr->size);
+	}
 	return len;
 error:
+	push_args(ctx, arg_addr);
 	push_args(ctx, arg_len);
 	push_args(ctx, arg_data);
 	return -1;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9729177f8..eb7ac315e 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -994,7 +994,7 @@ static const struct {
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
 	MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
-	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */
+	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
 	MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
@@ -1043,14 +1043,20 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item,
 		union {
 			struct rte_flow_item_raw *raw;
 		} dst;
+		size_t off;
 
 	case RTE_FLOW_ITEM_TYPE_RAW:
 		src.raw = item_spec;
 		dst.raw = buf;
-		size = offsetof(struct rte_flow_item_raw, pattern) +
-			src.raw->length * sizeof(*src.raw->pattern);
-		if (dst.raw)
-			memcpy(dst.raw, src.raw, size);
+		off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw),
+				     sizeof(*src.raw->pattern));
+		size = off + src.raw->length * sizeof(*src.raw->pattern);
+		if (dst.raw) {
+			memcpy(dst.raw, src.raw, sizeof(*src.raw));
+			dst.raw->pattern = memcpy((uint8_t *)dst.raw + off,
+						  src.raw->pattern,
+						  size - off);
+		}
 		break;
 	default:
 		size = flow_item[item->type].size;
@@ -1082,7 +1088,7 @@ static const struct {
 	MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
 	MK_FLOW_ACTION(DROP, 0),
 	MK_FLOW_ACTION(COUNT, 0),
-	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
+	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
 	MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
@@ -1113,11 +1119,14 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 			*dst.rss = (struct rte_flow_action_rss){
 				.num = src.rss->num,
 			};
-		off += offsetof(struct rte_flow_action_rss, queue);
+		off += sizeof(*src.rss);
 		if (src.rss->num) {
+			off = RTE_ALIGN_CEIL(off, sizeof(double));
 			size = sizeof(*src.rss->queue) * src.rss->num;
 			if (dst.rss)
-				memcpy(dst.rss->queue, src.rss->queue, size);
+				dst.rss->queue = memcpy
+					((void *)((uintptr_t)dst.rss + off),
+					 src.rss->queue, size);
 			off += size;
 		}
 		off = RTE_ALIGN_CEIL(off, sizeof(double));
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 80360d068..acbeaacbd 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1309,15 +1309,15 @@ field only, both can be requested simultaneously.
 
 .. table:: RSS
 
-   +--------------+------------------------------+
-   | Field        | Value                        |
-   +==============+==============================+
-   | ``rss_conf`` | RSS parameters               |
-   +--------------+------------------------------+
-   | ``num``      | number of entries in queue[] |
-   +--------------+------------------------------+
-   | ``queue[]``  | queue indices to use         |
-   +--------------+------------------------------+
+   +--------------+--------------------------------+
+   | Field        | Value                          |
+   +==============+================================+
+   | ``rss_conf`` | RSS parameters                 |
+   +--------------+--------------------------------+
+   | ``num``      | number of entries in ``queue`` |
+   +--------------+--------------------------------+
+   | ``queue``    | queue indices to use           |
+   +--------------+--------------------------------+
 
 Action: ``PF``
 ^^^^^^^^^^^^^^
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 1db6c5257..ca173450c 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -252,6 +252,8 @@ API Changes
     properties anymore.
   * Flow rules are now always terminating unless a PASSTHRU action is
     present.
+  * C99-style flexible arrays were replaced with standard pointers in RSS
+    action and in RAW pattern item structures due to compatibility issues.
 
 
 ABI Changes
@@ -299,8 +301,10 @@ ABI Changes
   ``rte_flow_destroy``, ``rte_flow_error_set``, ``rte_flow_flush``,
   ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
   changes in error type definitions (``enum rte_flow_error_type``), removal
-  of the unused DUP action (``enum rte_flow_action_type``) and modified
-  behavior for flow rule actions (see API changes).
+  of the unused DUP action (``enum rte_flow_action_type``), modified
+  behavior for flow rule actions (see API changes) and removal of C99
+  flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
+  pattern item (``struct rte_flow_item_raw``).
 
 
 Removed Items
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 15cdf07b7..8feb6ae31 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -1282,14 +1282,16 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 	 */
 	uint32_t queues =
 		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
-	alignas(struct rte_flow_action_rss) uint8_t rss_conf_data
-		[offsetof(struct rte_flow_action_rss, queue) +
-		 sizeof(((struct rte_flow_action_rss *)0)->queue[0]) * queues];
-	struct rte_flow_action_rss *rss_conf = (void *)rss_conf_data;
+	uint16_t queue[queues];
+	struct rte_flow_action_rss action_rss = {
+		.rss_conf = NULL, /* Rely on default fallback settings. */
+		.num = queues,
+		.queue = queue,
+	};
 	struct rte_flow_action actions[] = {
 		{
 			.type = RTE_FLOW_ACTION_TYPE_RSS,
-			.conf = rss_conf,
+			.conf = &action_rss,
 		},
 		{
 			.type = RTE_FLOW_ACTION_TYPE_END,
@@ -1311,12 +1313,8 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 	if (!queues)
 		goto error;
 	/* Prepare default RSS configuration. */
-	*rss_conf = (struct rte_flow_action_rss){
-		.rss_conf = NULL, /* Rely on default fallback settings. */
-		.num = queues,
-	};
 	for (i = 0; i != queues; ++i)
-		rss_conf->queue[i] = i;
+		queue[i] = i;
 	/*
 	 * Set up VLAN item if filtering is enabled and at least one VLAN
 	 * filter is configured.
@@ -1375,7 +1373,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 			if (j != sizeof(mac->addr_bytes))
 				continue;
 			if (flow->rss->queues != queues ||
-			    memcmp(flow->rss->queue_id, rss_conf->queue,
+			    memcmp(flow->rss->queue_id, action_rss.queue,
 				   queues * sizeof(flow->rss->queue_id[0])))
 				continue;
 			break;
@@ -1415,7 +1413,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 		if (flow && flow->internal) {
 			assert(flow->rss);
 			if (flow->rss->queues != queues ||
-			    memcmp(flow->rss->queue_id, rss_conf->queue,
+			    memcmp(flow->rss->queue_id, action_rss.queue,
 				   queues * sizeof(flow->rss->queue_id[0])))
 				flow = NULL;
 		}
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 586e780c4..0c89bff45 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2456,9 +2456,16 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
 			.type = RTE_FLOW_ITEM_TYPE_END,
 		},
 	};
+	uint16_t queue[priv->reta_idx_n];
+	struct rte_flow_action_rss action_rss = {
+		.rss_conf = &priv->rss_conf,
+		.num = priv->reta_idx_n,
+		.queue = queue,
+	};
 	struct rte_flow_action actions[] = {
 		{
 			.type = RTE_FLOW_ACTION_TYPE_RSS,
+			.conf = &action_rss,
 		},
 		{
 			.type = RTE_FLOW_ACTION_TYPE_END,
@@ -2467,24 +2474,13 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
 	struct rte_flow *flow;
 	struct rte_flow_error error;
 	unsigned int i;
-	union {
-		struct rte_flow_action_rss rss;
-		struct {
-			const struct rte_eth_rss_conf *rss_conf;
-			uint16_t num;
-			uint16_t queue[RTE_MAX_QUEUES_PER_PORT];
-		} local;
-	} action_rss;
 
 	if (!priv->reta_idx_n) {
 		rte_errno = EINVAL;
 		return -rte_errno;
 	}
 	for (i = 0; i != priv->reta_idx_n; ++i)
-		action_rss.local.queue[i] = (*priv->reta_idx)[i];
-	action_rss.local.rss_conf = &priv->rss_conf;
-	action_rss.local.num = priv->reta_idx_n;
-	actions[0].conf = (const void *)&action_rss.rss;
+		queue[i] = (*priv->reta_idx)[i];
 	flow = mlx5_flow_list_create(dev, &priv->ctrl_flows, &attr, items,
 				     actions, &error);
 	if (!flow)
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index acdd1898b..5971937cf 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -187,14 +187,8 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 					.rss_key_len = 40,
 				};
 				struct rte_eth_dev *eth_dev;
-				union {
-					struct rte_flow_action_rss rss;
-					struct {
-					const struct rte_eth_rss_conf *rss_conf;
-					uint16_t num;
-					uint16_t queue[RTE_MAX_QUEUES_PER_PORT];
-					} local;
-				} action_rss;
+				uint16_t queue[RTE_MAX_QUEUES_PER_PORT];
+				struct rte_flow_action_rss action_rss;
 				unsigned int i;
 				unsigned int j;
 
@@ -208,9 +202,10 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 				for (i = 0, j = 0;
 				     i < eth_dev->data->nb_rx_queues; ++i)
 					if (eth_dev->data->rx_queues[i])
-						action_rss.local.queue[j++] = i;
-				action_rss.local.num = j;
-				action_rss.local.rss_conf = &rss_conf;
+						queue[j++] = i;
+				action_rss.rss_conf = &rss_conf;
+				action_rss.num = j;
+				action_rss.queue = queue;
 				ret = rte_flow_validate(sa->portid, &sa->attr,
 							sa->pattern, sa->action,
 							&err);
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 80f9cb6cb..bb19e28c6 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -39,7 +39,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
 	MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
-	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */
+	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
 	MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
@@ -73,7 +73,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
 	MK_FLOW_ACTION(DROP, 0),
 	MK_FLOW_ACTION(COUNT, 0),
-	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
+	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
 };
@@ -282,14 +282,20 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item,
 		union {
 			struct rte_flow_item_raw *raw;
 		} dst;
+		size_t off;
 
 	case RTE_FLOW_ITEM_TYPE_RAW:
 		src.raw = item_spec;
 		dst.raw = buf;
-		size = offsetof(struct rte_flow_item_raw, pattern) +
-			src.raw->length * sizeof(*src.raw->pattern);
-		if (dst.raw)
-			memcpy(dst.raw, src.raw, size);
+		off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw),
+				     sizeof(*src.raw->pattern));
+		size = off + src.raw->length * sizeof(*src.raw->pattern);
+		if (dst.raw) {
+			memcpy(dst.raw, src.raw, sizeof(*src.raw));
+			dst.raw->pattern = memcpy((uint8_t *)dst.raw + off,
+						  src.raw->pattern,
+						  size - off);
+		}
 		break;
 	default:
 		size = rte_flow_desc_item[item->type].size;
@@ -326,11 +332,14 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 			*dst.rss = (struct rte_flow_action_rss){
 				.num = src.rss->num,
 			};
-		off += offsetof(struct rte_flow_action_rss, queue);
+		off += sizeof(*src.rss);
 		if (src.rss->num) {
+			off = RTE_ALIGN_CEIL(off, sizeof(double));
 			size = sizeof(*src.rss->queue) * src.rss->num;
 			if (dst.rss)
-				memcpy(dst.rss->queue, src.rss->queue, size);
+				dst.rss->queue = memcpy
+					((void *)((uintptr_t)dst.rss + off),
+					 src.rss->queue, size);
 			off += size;
 		}
 		off = RTE_ALIGN_CEIL(off, sizeof(double));
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 96184f030..ad2e55b8e 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -14,6 +14,7 @@
  * associated actions in hardware through flow rules.
  */
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include <rte_arp.h>
@@ -432,7 +433,7 @@ struct rte_flow_item_raw {
 	int32_t offset; /**< Absolute or relative offset for pattern. */
 	uint16_t limit; /**< Search area limit for start of pattern. */
 	uint16_t length; /**< Pattern length. */
-	uint8_t pattern[]; /**< Byte string to look for. */
+	const uint8_t *pattern; /**< Byte string to look for. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */
@@ -444,6 +445,7 @@ static const struct rte_flow_item_raw rte_flow_item_raw_mask = {
 	.offset = 0xffffffff,
 	.limit = 0xffff,
 	.length = 0xffff,
+	.pattern = NULL,
 };
 #endif
 
@@ -1037,8 +1039,8 @@ struct rte_flow_query_count {
  */
 struct rte_flow_action_rss {
 	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
-	uint16_t num; /**< Number of entries in queue[]. */
-	uint16_t queue[]; /**< Queues indices to use. */
+	uint16_t num; /**< Number of entries in @p queue. */
+	const uint16_t *queue; /**< Queue indices to use. */
 };
 
 /**
-- 
2.11.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (3 preceding siblings ...)
  2018-04-25 15:27  8%   ` [dpdk-dev] [PATCH v6 06/16] ethdev: fix C99 flexible arrays from flow API Adrien Mazarguil
@ 2018-04-25 15:27  3%   ` Adrien Mazarguil
  2018-04-28  3:46  0%     ` Zhao1, Wei
  2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 08/16] ethdev: add hash function to RSS flow API action Adrien Mazarguil
                     ` (9 subsequent siblings)
  14 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Xueming Li, Wenzhuo Lu, Jingjing Wu, Beilei Xing, Qi Zhang,
	Konstantin Ananyev, Nelio Laranjeiro, Yongseok Koh,
	Andrew Rybchenko, Pascal Mazon, Radu Nicolau, Akhil Goyal

Since its inception, the rte_flow RSS action has been relying in part on
external struct rte_eth_rss_conf for compatibility with the legacy RSS API.
This structure lacks parameters such as the hash algorithm to use, and more
recently, a method to tell which layer RSS should be performed on [1].

Given struct rte_eth_rss_conf will never be flexible enough to represent a
complete RSS configuration (e.g. RETA table), this patch supersedes it by
extending the rte_flow RSS action directly.

A subsequent patch will add a field to use a non-default RSS hash
algorithm. To that end, a field named "types" replaces the field formerly
known as "rss_hf" and standing for "RSS hash functions" as it was
confusing. Actual RSS hash function types are defined by enum
rte_eth_hash_function.

This patch updates all PMDs and example applications accordingly.

It breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

[1] commit 676b605182a5 ("doc: announce ethdev API change for RSS
    configuration")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Xueming Li <xuemingl@mellanox.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Thomas Monjalon <thomas@monjalon.net>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: Jingjing Wu <jingjing.wu@intel.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>
Cc: Radu Nicolau <radu.nicolau@intel.com>
Cc: Akhil Goyal <akhil.goyal@nxp.com>

---

v6 changes:

- Fixed QUEUE action support in mlx5 according to Nelio's comment [1].
  This action relies on RSS to work and even though it targets a single Rx
  queue, a non-NULL hash key is required.
- Updated API and ABI changes sections in release notes.

[1] http://dpdk.org/ml/archives/dev/2018-April/098635.html

v3 changes:

Documentation update regarding the meaning of a 0 value for RSS types in
flow rules.

It used to implicitly mean "no RSS" but is redefined as requesting a kind
of "best-effort" mode from PMDs, i.e. anything ranging from empty to
all-inclusive RSS; what matters is it provides safe defaults that will work
regardless of PMD capabilities.
---
 app/test-pmd/cmdline_flow.c                 |  48 +++---
 app/test-pmd/config.c                       |  39 ++---
 doc/guides/prog_guide/rte_flow.rst          |  28 ++--
 doc/guides/rel_notes/release_18_05.rst      |  13 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   6 +-
 drivers/net/e1000/e1000_ethdev.h            |  13 +-
 drivers/net/e1000/igb_ethdev.c              |   4 +-
 drivers/net/e1000/igb_flow.c                |  31 ++--
 drivers/net/e1000/igb_rxtx.c                |  51 +++++-
 drivers/net/i40e/i40e_ethdev.c              |  53 +++++--
 drivers/net/i40e/i40e_ethdev.h              |  15 +-
 drivers/net/i40e/i40e_flow.c                |  47 +++---
 drivers/net/ixgbe/ixgbe_ethdev.c            |   4 +-
 drivers/net/ixgbe/ixgbe_ethdev.h            |  13 +-
 drivers/net/ixgbe/ixgbe_flow.c              |  30 ++--
 drivers/net/ixgbe/ixgbe_rxtx.c              |  51 +++++-
 drivers/net/mlx4/mlx4.c                     |   2 +-
 drivers/net/mlx4/mlx4_flow.c                |  61 +++----
 drivers/net/mlx4/mlx4_flow.h                |   2 +-
 drivers/net/mlx4/mlx4_rxq.c                 |   2 +-
 drivers/net/mlx4/mlx4_rxtx.h                |   2 +-
 drivers/net/mlx5/mlx5_flow.c                | 193 +++++++++++------------
 drivers/net/mlx5/mlx5_rxq.c                 |  26 +--
 drivers/net/mlx5/mlx5_rxtx.h                |  26 +--
 drivers/net/sfc/sfc_flow.c                  |  21 ++-
 drivers/net/tap/tap_flow.c                  |   8 +-
 examples/ipsec-secgw/ipsec.c                |  10 +-
 lib/librte_ether/rte_flow.c                 |  39 ++---
 lib/librte_ether/rte_flow.h                 |  12 +-
 29 files changed, 492 insertions(+), 358 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 798b7948d..c9c2c3ad9 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -192,9 +192,8 @@ enum index {
 /** Storage for struct rte_flow_action_rss including external data. */
 struct action_rss_data {
 	struct rte_flow_action_rss conf;
+	uint8_t key[RSS_HASH_KEY_LENGTH];
 	uint16_t queue[ACTION_RSS_QUEUE_NUM];
-	struct rte_eth_rss_conf rss_conf;
-	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
 };
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1587,7 +1586,7 @@ static const struct token token_list[] = {
 	},
 	[ACTION_RSS_TYPES] = {
 		.name = "types",
-		.help = "RSS hash types",
+		.help = "specific RSS hash types",
 		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
 	},
 	[ACTION_RSS_TYPE] = {
@@ -1602,21 +1601,21 @@ static const struct token token_list[] = {
 		.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
 		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
 			     ARGS_ENTRY_ARB
-			     (offsetof(struct action_rss_data, rss_conf) +
-			      offsetof(struct rte_eth_rss_conf, rss_key_len),
-			      sizeof(((struct rte_eth_rss_conf *)0)->
-				     rss_key_len)),
-			     ARGS_ENTRY(struct action_rss_data, rss_key)),
+			     (offsetof(struct action_rss_data, conf) +
+			      offsetof(struct rte_flow_action_rss, key_len),
+			      sizeof(((struct rte_flow_action_rss *)0)->
+				     key_len)),
+			     ARGS_ENTRY(struct action_rss_data, key)),
 	},
 	[ACTION_RSS_KEY_LEN] = {
 		.name = "key_len",
 		.help = "RSS hash key length in bytes",
 		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
 		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
-			     (offsetof(struct action_rss_data, rss_conf) +
-			      offsetof(struct rte_eth_rss_conf, rss_key_len),
-			      sizeof(((struct rte_eth_rss_conf *)0)->
-				     rss_key_len),
+			     (offsetof(struct action_rss_data, conf) +
+			      offsetof(struct rte_flow_action_rss, key_len),
+			      sizeof(((struct rte_flow_action_rss *)0)->
+				     key_len),
 			      0,
 			      RSS_HASH_KEY_LENGTH)),
 	},
@@ -2075,27 +2074,24 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 	action_rss_data = ctx->object;
 	*action_rss_data = (struct action_rss_data){
 		.conf = (struct rte_flow_action_rss){
-			.rss_conf = &action_rss_data->rss_conf,
-			.num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
+			.types = rss_hf,
+			.key_len = sizeof(action_rss_data->key),
+			.queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
+			.key = action_rss_data->key,
 			.queue = action_rss_data->queue,
 		},
+		.key = "testpmd's default RSS hash key",
 		.queue = { 0 },
-		.rss_conf = (struct rte_eth_rss_conf){
-			.rss_key = action_rss_data->rss_key,
-			.rss_key_len = sizeof(action_rss_data->rss_key),
-			.rss_hf = rss_hf,
-		},
-		.rss_key = "testpmd's default RSS hash key",
 	};
-	for (i = 0; i < action_rss_data->conf.num; ++i)
+	for (i = 0; i < action_rss_data->conf.queue_num; ++i)
 		action_rss_data->queue[i] = i;
 	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
 	    ctx->port != (portid_t)RTE_PORT_ALL) {
 		struct rte_eth_dev_info info;
 
 		rte_eth_dev_info_get(ctx->port, &info);
-		action_rss_data->rss_conf.rss_key_len =
-			RTE_MIN(sizeof(action_rss_data->rss_key),
+		action_rss_data->conf.key_len =
+			RTE_MIN(sizeof(action_rss_data->key),
 				info.hash_key_size);
 	}
 	action->conf = &action_rss_data->conf;
@@ -2123,7 +2119,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
 		return -1;
 	if (!(ctx->objdata >> 16) && ctx->object) {
 		action_rss_data = ctx->object;
-		action_rss_data->rss_conf.rss_hf = 0;
+		action_rss_data->conf.types = 0;
 	}
 	if (!strcmp_partial("end", str, len)) {
 		ctx->objdata &= 0xffff;
@@ -2142,7 +2138,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
 	if (!ctx->object)
 		return len;
 	action_rss_data = ctx->object;
-	action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
+	action_rss_data->conf.types |= rss_type_table[i].rss_type;
 	return len;
 }
 
@@ -2192,7 +2188,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 	if (!ctx->object)
 		return len;
 	action_rss_data = ctx->object;
-	action_rss_data->conf.num = i;
+	action_rss_data->conf.queue_num = i;
 	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
 	return len;
 }
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index eb7ac315e..4700dd674 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1117,40 +1117,27 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		off = 0;
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
-				.num = src.rss->num,
+				.types = src.rss->types,
+				.key_len = src.rss->key_len,
+				.queue_num = src.rss->queue_num,
 			};
 		off += sizeof(*src.rss);
-		if (src.rss->num) {
+		if (src.rss->key_len) {
 			off = RTE_ALIGN_CEIL(off, sizeof(double));
-			size = sizeof(*src.rss->queue) * src.rss->num;
+			size = sizeof(*src.rss->key) * src.rss->key_len;
 			if (dst.rss)
-				dst.rss->queue = memcpy
+				dst.rss->key = memcpy
 					((void *)((uintptr_t)dst.rss + off),
-					 src.rss->queue, size);
+					 src.rss->key, size);
 			off += size;
 		}
-		off = RTE_ALIGN_CEIL(off, sizeof(double));
-		if (dst.rss) {
-			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
-			*(struct rte_eth_rss_conf *)(uintptr_t)
-				dst.rss->rss_conf = (struct rte_eth_rss_conf){
-				.rss_key_len = src.rss->rss_conf->rss_key_len,
-				.rss_hf = src.rss->rss_conf->rss_hf,
-			};
-		}
-		off += sizeof(*src.rss->rss_conf);
-		if (src.rss->rss_conf->rss_key_len) {
+		if (src.rss->queue_num) {
 			off = RTE_ALIGN_CEIL(off, sizeof(double));
-			size = sizeof(*src.rss->rss_conf->rss_key) *
-				src.rss->rss_conf->rss_key_len;
-			if (dst.rss) {
-				((struct rte_eth_rss_conf *)(uintptr_t)
-				 dst.rss->rss_conf)->rss_key =
-					(void *)((uintptr_t)dst.rss + off);
-				memcpy(dst.rss->rss_conf->rss_key,
-				       src.rss->rss_conf->rss_key,
-				       size);
-			}
+			size = sizeof(*src.rss->queue) * src.rss->queue_num;
+			if (dst.rss)
+				dst.rss->queue = memcpy
+					((void *)((uintptr_t)dst.rss + off),
+					 src.rss->queue, size);
 			off += size;
 		}
 		size = off;
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index acbeaacbd..cf252eeba 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1301,6 +1301,12 @@ Action: ``RSS``
 Similar to QUEUE, except RSS is additionally performed on packets to spread
 them among several queues according to the provided parameters.
 
+Unlike global RSS settings used by other DPDK APIs, unsetting the ``types``
+field does not disable RSS in a flow rule. Doing so instead requests safe
+unspecified "best-effort" settings from the underlying PMD, which depending
+on the flow rule, may result in anything ranging from empty (single queue)
+to all-inclusive RSS.
+
 Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
 overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
 field only, both can be requested simultaneously.
@@ -1309,15 +1315,19 @@ field only, both can be requested simultaneously.
 
 .. table:: RSS
 
-   +--------------+--------------------------------+
-   | Field        | Value                          |
-   +==============+================================+
-   | ``rss_conf`` | RSS parameters                 |
-   +--------------+--------------------------------+
-   | ``num``      | number of entries in ``queue`` |
-   +--------------+--------------------------------+
-   | ``queue``    | queue indices to use           |
-   +--------------+--------------------------------+
+   +---------------+---------------------------------------------+
+   | Field         | Value                                       |
+   +===============+=============================================+
+   | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
+   +---------------+---------------------------------------------+
+   | ``key_len``   | hash key length in bytes                    |
+   +---------------+---------------------------------------------+
+   | ``queue_num`` | number of entries in ``queue``              |
+   +---------------+---------------------------------------------+
+   | ``key``       | hash key                                    |
+   +---------------+---------------------------------------------+
+   | ``queue``     | queue indices to use                        |
+   +---------------+---------------------------------------------+
 
 Action: ``PF``
 ^^^^^^^^^^^^^^
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index ca173450c..b702ac66a 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -254,6 +254,13 @@ API Changes
     present.
   * C99-style flexible arrays were replaced with standard pointers in RSS
     action and in RAW pattern item structures due to compatibility issues.
+  * The RSS action was modified to not rely on external
+    ``struct rte_eth_rss_conf`` anymore to instead expose its own and more
+    appropriately named configuration fields directly
+    (``rss_conf->rss_key`` => ``key``,
+    ``rss_conf->rss_key_len`` => ``key_len``,
+    ``rss_conf->rss_hf`` => ``types``,
+    ``num`` => ``queue_num``).
 
 
 ABI Changes
@@ -302,9 +309,9 @@ ABI Changes
   ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
   changes in error type definitions (``enum rte_flow_error_type``), removal
   of the unused DUP action (``enum rte_flow_action_type``), modified
-  behavior for flow rule actions (see API changes) and removal of C99
-  flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
-  pattern item (``struct rte_flow_item_raw``).
+  behavior for flow rule actions (see API changes), removal of C99 flexible
+  array from RAW pattern item (``struct rte_flow_item_raw``) and complete
+  rework of the RSS action definition (``struct rte_flow_action_rss``).
 
 
 Removed Items
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 68c286bd4..a12e0267a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3422,8 +3422,10 @@ This section lists supported actions and their attributes, if any.
 
 - ``rss``: spread packets among several queues.
 
-  - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
-    are the same as `set_hash_input_set`_, an empty list means none (0).
+  - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
+    tokens are the same as `set_hash_input_set`_, except that an empty list
+    does not disable RSS but instead requests unspecified "best-effort"
+    settings.
 
   - ``key {string}``: RSS hash key, overrides ``key_len``.
 
diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h
index 6354b894a..902001f36 100644
--- a/drivers/net/e1000/e1000_ethdev.h
+++ b/drivers/net/e1000/e1000_ethdev.h
@@ -4,6 +4,10 @@
 
 #ifndef _E1000_ETHDEV_H_
 #define _E1000_ETHDEV_H_
+
+#include <stdint.h>
+
+#include <rte_flow.h>
 #include <rte_time.h>
 #include <rte_pci.h>
 
@@ -27,6 +31,7 @@
 #define E1000_CTRL_EXT_EXTEND_VLAN  (1<<26)    /* EXTENDED VLAN */
 #define IGB_VFTA_SIZE 128
 
+#define IGB_HKEY_MAX_INDEX             10
 #define IGB_MAX_RX_QUEUE_NUM           8
 #define IGB_MAX_RX_QUEUE_NUM_82576     16
 
@@ -229,8 +234,8 @@ struct igb_ethertype_filter {
 };
 
 struct igb_rte_flow_rss_conf {
-	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
-	uint16_t num; /**< Number of entries in queue[]. */
+	struct rte_flow_action_rss conf; /**< RSS parameters. */
+	uint8_t key[IGB_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key. */
 	uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices to use. */
 };
 
@@ -501,6 +506,10 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev,
 int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
 			struct rte_eth_flex_filter *filter,
 			bool add);
+int igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
+		      const struct rte_flow_action_rss *in);
+int igb_action_rss_same(const struct rte_flow_action_rss *comp,
+			const struct rte_flow_action_rss *with);
 int igb_config_rss_filter(struct rte_eth_dev *dev,
 			struct igb_rte_flow_rss_conf *conf,
 			bool add);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index c35c9352a..140334772 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -41,8 +41,6 @@
 #define IGB_DEFAULT_TX_HTHRESH      1
 #define IGB_DEFAULT_TX_WTHRESH      ((hw->mac.type == e1000_82576) ? 1 : 16)
 
-#define IGB_HKEY_MAX_INDEX 10
-
 /* Bit shift and mask */
 #define IGB_4_BIT_WIDTH  (CHAR_BIT / 2)
 #define IGB_4_BIT_MASK   RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)
@@ -5662,7 +5660,7 @@ igb_rss_filter_restore(struct rte_eth_dev *dev)
 	struct e1000_filter_info *filter_info =
 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
-	if (filter_info->rss_info.num)
+	if (filter_info->rss_info.conf.queue_num)
 		igb_config_rss_filter(dev, &filter_info->rss_info, TRUE);
 }
 
diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index c0f5b5190..8dc5f75f2 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -1292,7 +1292,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 
 	rss = (const struct rte_flow_action_rss *)act->conf;
 
-	if (!rss || !rss->num) {
+	if (!rss || !rss->queue_num) {
 		rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION,
 				act,
@@ -1300,7 +1300,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 		return -rte_errno;
 	}
 
-	for (n = 0; n < rss->num; n++) {
+	for (n = 0; n < rss->queue_num; n++) {
 		if (rss->queue[n] >= dev->data->nb_rx_queues) {
 			rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1310,14 +1310,18 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 		}
 	}
 
-	if (rss->rss_conf)
-		rss_conf->rss_conf = *rss->rss_conf;
-	else
-		rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
-
-	for (n = 0; n < rss->num; ++n)
-		rss_conf->queue[n] = rss->queue[n];
-	rss_conf->num = rss->num;
+	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS hash key must be exactly 40 bytes");
+	if (rss->queue_num > RTE_DIM(rss_conf->queue))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "too many queues for RSS context");
+	if (igb_rss_conf_init(rss_conf, rss))
+		return rte_flow_error_set
+			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS context initialization failure");
 
 	/* check if the next not void item is END */
 	index++;
@@ -1518,9 +1522,8 @@ igb_flow_create(struct rte_eth_dev *dev,
 				PMD_DRV_LOG(ERR, "failed to allocate memory");
 				goto out;
 			}
-			rte_memcpy(&rss_filter_ptr->filter_info,
-				&rss_conf,
-				sizeof(struct igb_rte_flow_rss_conf));
+			igb_rss_conf_init(&rss_filter_ptr->filter_info,
+					  &rss_conf.conf);
 			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
 				rss_filter_ptr, entries);
 			flow->rule = rss_filter_ptr;
@@ -1757,7 +1760,7 @@ igb_clear_rss_filter(struct rte_eth_dev *dev)
 	struct e1000_filter_info *filter =
 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
-	if (filter->rss_info.num)
+	if (filter->rss_info.conf.queue_num)
 		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
 }
 
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 323913f0d..45bb3455c 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -2898,12 +2898,47 @@ igb_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 }
 
 int
+igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
+		  const struct rte_flow_action_rss *in)
+{
+	if (in->key_len > RTE_DIM(out->key) ||
+	    in->queue_num > RTE_DIM(out->queue))
+		return -EINVAL;
+	out->conf = (struct rte_flow_action_rss){
+		.types = in->types,
+		.key_len = in->key_len,
+		.queue_num = in->queue_num,
+		.key = memcpy(out->key, in->key, in->key_len),
+		.queue = memcpy(out->queue, in->queue,
+				sizeof(*in->queue) * in->queue_num),
+	};
+	return 0;
+}
+
+int
+igb_action_rss_same(const struct rte_flow_action_rss *comp,
+		    const struct rte_flow_action_rss *with)
+{
+	return (comp->types == with->types &&
+		comp->key_len == with->key_len &&
+		comp->queue_num == with->queue_num &&
+		!memcmp(comp->key, with->key, with->key_len) &&
+		!memcmp(comp->queue, with->queue,
+			sizeof(*with->queue) * with->queue_num));
+}
+
+int
 igb_config_rss_filter(struct rte_eth_dev *dev,
 		struct igb_rte_flow_rss_conf *conf, bool add)
 {
 	uint32_t shift;
 	uint16_t i, j;
-	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
+	struct rte_eth_rss_conf rss_conf = {
+		.rss_key = conf->conf.key_len ?
+			(void *)(uintptr_t)conf->conf.key : NULL,
+		.rss_key_len = conf->conf.key_len,
+		.rss_hf = conf->conf.types,
+	};
 	struct e1000_filter_info *filter_info =
 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -2911,8 +2946,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	if (!add) {
-		if (memcmp(conf, &filter_info->rss_info,
-			sizeof(struct igb_rte_flow_rss_conf)) == 0) {
+		if (igb_action_rss_same(&filter_info->rss_info.conf,
+					&conf->conf)) {
 			igb_rss_disable(dev);
 			memset(&filter_info->rss_info, 0,
 				sizeof(struct igb_rte_flow_rss_conf));
@@ -2921,7 +2956,7 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (filter_info->rss_info.num)
+	if (filter_info->rss_info.conf.queue_num)
 		return -EINVAL;
 
 	/* Fill in redirection table. */
@@ -2933,9 +2968,9 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
 		} reta;
 		uint8_t q_idx;
 
-		if (j == conf->num)
+		if (j == conf->conf.queue_num)
 			j = 0;
-		q_idx = conf->queue[j];
+		q_idx = conf->conf.queue[j];
 		reta.bytes[i & 3] = (uint8_t)(q_idx << shift);
 		if ((i & 3) == 3)
 			E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword);
@@ -2952,8 +2987,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
 		rss_conf.rss_key = rss_intel_key; /* Default hash key */
 	igb_hw_rss_hash_set(hw, &rss_conf);
 
-	rte_memcpy(&filter_info->rss_info,
-		conf, sizeof(struct igb_rte_flow_rss_conf));
+	if (igb_rss_conf_init(&filter_info->rss_info, &conf->conf))
+		return -EINVAL;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 78f2be7da..50e77901c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11,6 +11,7 @@
 #include <inttypes.h>
 #include <assert.h>
 
+#include <rte_common.h>
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
@@ -11650,7 +11651,7 @@ i40e_rss_filter_restore(struct i40e_pf *pf)
 {
 	struct i40e_rte_flow_rss_conf *conf =
 					&pf->rss_info;
-	if (conf->num)
+	if (conf->conf.queue_num)
 		i40e_config_rss_filter(pf, conf, TRUE);
 }
 
@@ -12182,18 +12183,52 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
 }
 
 int
+i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
+		   const struct rte_flow_action_rss *in)
+{
+	if (in->key_len > RTE_DIM(out->key) ||
+	    in->queue_num > RTE_DIM(out->queue))
+		return -EINVAL;
+	out->conf = (struct rte_flow_action_rss){
+		.types = in->types,
+		.key_len = in->key_len,
+		.queue_num = in->queue_num,
+		.key = memcpy(out->key, in->key, in->key_len),
+		.queue = memcpy(out->queue, in->queue,
+				sizeof(*in->queue) * in->queue_num),
+	};
+	return 0;
+}
+
+int
+i40e_action_rss_same(const struct rte_flow_action_rss *comp,
+		     const struct rte_flow_action_rss *with)
+{
+	return (comp->types == with->types &&
+		comp->key_len == with->key_len &&
+		comp->queue_num == with->queue_num &&
+		!memcmp(comp->key, with->key, with->key_len) &&
+		!memcmp(comp->queue, with->queue,
+			sizeof(*with->queue) * with->queue_num));
+}
+
+int
 i40e_config_rss_filter(struct i40e_pf *pf,
 		struct i40e_rte_flow_rss_conf *conf, bool add)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint32_t i, lut = 0;
 	uint16_t j, num;
-	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
+	struct rte_eth_rss_conf rss_conf = {
+		.rss_key = conf->conf.key_len ?
+			(void *)(uintptr_t)conf->conf.key : NULL,
+		.rss_key_len = conf->conf.key_len,
+		.rss_hf = conf->conf.types,
+	};
 	struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info;
 
 	if (!add) {
-		if (memcmp(conf, rss_info,
-			sizeof(struct i40e_rte_flow_rss_conf)) == 0) {
+		if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) {
 			i40e_pf_disable_rss(pf);
 			memset(rss_info, 0,
 				sizeof(struct i40e_rte_flow_rss_conf));
@@ -12202,7 +12237,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (rss_info->num)
+	if (rss_info->conf.queue_num)
 		return -EINVAL;
 
 	/* If both VMDQ and RSS enabled, not all of PF queues are configured.
@@ -12213,7 +12248,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
 	else
 		num = pf->dev_data->nb_rx_queues;
 
-	num = RTE_MIN(num, conf->num);
+	num = RTE_MIN(num, conf->conf.queue_num);
 	PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are configured",
 			num);
 
@@ -12226,7 +12261,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
 	for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
 		if (j == num)
 			j = 0;
-		lut = (lut << 8) | (conf->queue[j] & ((0x1 <<
+		lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 <<
 			hw->func_caps.rss_table_entry_width) - 1));
 		if ((i & 3) == 3)
 			I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
@@ -12251,8 +12286,8 @@ i40e_config_rss_filter(struct i40e_pf *pf,
 
 	i40e_hw_rss_hash_set(pf, &rss_conf);
 
-	rte_memcpy(rss_info,
-		conf, sizeof(struct i40e_rte_flow_rss_conf));
+	if (i40e_rss_conf_init(rss_info, &conf->conf))
+		return -EINVAL;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index d33b255e7..a0569d4ae 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -5,14 +5,19 @@
 #ifndef _I40E_ETHDEV_H_
 #define _I40E_ETHDEV_H_
 
+#include <stdint.h>
+
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
 #include <rte_kvargs.h>
 #include <rte_hash.h>
+#include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_tm_driver.h>
 #include "rte_pmd_i40e.h"
 
+#include "base/i40e_register.h"
+
 #define I40E_VLAN_TAG_SIZE        4
 
 #define I40E_AQ_LEN               32
@@ -878,9 +883,11 @@ struct i40e_customized_pctype {
 };
 
 struct i40e_rte_flow_rss_conf {
-	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
+	struct rte_flow_action_rss conf; /**< RSS parameters. */
 	uint16_t queue_region_conf; /**< Queue region config flag */
-	uint16_t num; /**< Number of entries in queue[]. */
+	uint8_t key[(I40E_VFQF_HKEY_MAX_INDEX > I40E_PFQF_HKEY_MAX_INDEX ?
+		     I40E_VFQF_HKEY_MAX_INDEX : I40E_PFQF_HKEY_MAX_INDEX) + 1 *
+		    sizeof(uint32_t)]; /* Hash key. */
 	uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use. */
 };
 
@@ -1219,6 +1226,10 @@ void i40e_init_queue_region_conf(struct rte_eth_dev *dev);
 void i40e_flex_payload_reg_set_default(struct i40e_hw *hw);
 int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
 int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
+int i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
+		       const struct rte_flow_action_rss *in);
+int i40e_action_rss_same(const struct rte_flow_action_rss *comp,
+			 const struct rte_flow_action_rss *with);
 int i40e_config_rss_filter(struct i40e_pf *pf,
 		struct i40e_rte_flow_rss_conf *conf, bool add);
 
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index d6f5e9923..ec6231003 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -4220,7 +4220,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 
 	if (action_flag) {
 		for (n = 0; n < 64; n++) {
-			if (rss->rss_conf->rss_hf & (hf_bit << n)) {
+			if (rss->types & (hf_bit << n)) {
 				conf_info->region[0].hw_flowtype[0] = n;
 				conf_info->region[0].flowtype_num = 1;
 				conf_info->queue_region_number = 1;
@@ -4236,12 +4236,12 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 	 * queue index for this port.
 	 */
 	if (conf_info->queue_region_number) {
-		for (i = 0; i < rss->num; i++) {
-			for (j = 0; j < rss_info->num; j++) {
-				if (rss->queue[i] == rss_info->queue[j])
+		for (i = 0; i < rss->queue_num; i++) {
+			for (j = 0; j < rss_info->conf.queue_num; j++) {
+				if (rss->queue[i] == rss_info->conf.queue[j])
 					break;
 			}
-			if (j == rss_info->num) {
+			if (j == rss_info->conf.queue_num) {
 				rte_flow_error_set(error, EINVAL,
 					RTE_FLOW_ERROR_TYPE_ACTION,
 					act,
@@ -4250,7 +4250,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 			}
 		}
 
-		for (i = 0; i < rss->num - 1; i++) {
+		for (i = 0; i < rss->queue_num - 1; i++) {
 			if (rss->queue[i + 1] != rss->queue[i] + 1) {
 				rte_flow_error_set(error, EINVAL,
 					RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4265,8 +4265,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 	for (n = 0; n < conf_info->queue_region_number; n++) {
 		if (conf_info->region[n].user_priority_num ||
 				conf_info->region[n].flowtype_num) {
-			if (!((rte_is_power_of_2(rss->num)) &&
-					rss->num <= 64)) {
+			if (!((rte_is_power_of_2(rss->queue_num)) &&
+					rss->queue_num <= 64)) {
 				rte_flow_error_set(error, EINVAL,
 					RTE_FLOW_ERROR_TYPE_ACTION,
 					act,
@@ -4294,7 +4294,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 			}
 
 			for (i = 0; i < info->queue_region_number; i++) {
-				if (info->region[i].queue_num == rss->num &&
+				if (info->region[i].queue_num ==
+				    rss->queue_num &&
 					info->region[i].queue_start_index ==
 						rss->queue[0])
 					break;
@@ -4310,7 +4311,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 				}
 
 				info->region[i].queue_num =
-					rss->num;
+					rss->queue_num;
 				info->region[i].queue_start_index =
 					rss->queue[0];
 				info->region[i].region_id =
@@ -4356,7 +4357,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 	if (rss_config->queue_region_conf)
 		return 0;
 
-	if (!rss || !rss->num) {
+	if (!rss || !rss->queue_num) {
 		rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION,
 				act,
@@ -4364,7 +4365,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 		return -rte_errno;
 	}
 
-	for (n = 0; n < rss->num; n++) {
+	for (n = 0; n < rss->queue_num; n++) {
 		if (rss->queue[n] >= dev->data->nb_rx_queues) {
 			rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4375,15 +4376,19 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 	}
 
 	/* Parse RSS related parameters from configuration */
-	if (rss->rss_conf)
-		rss_config->rss_conf = *rss->rss_conf;
-	else
-		rss_config->rss_conf.rss_hf =
-			pf->adapter->flow_types_mask;
+	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS hash key too large");
+	if (rss->queue_num > RTE_DIM(rss_config->queue))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "too many queues for RSS context");
+	if (i40e_rss_conf_init(rss_config, rss))
+		return rte_flow_error_set
+			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS context initialization failure");
 
-	for (n = 0; n < rss->num; ++n)
-		rss_config->queue[n] = rss->queue[n];
-	rss_config->num = rss->num;
 	index++;
 
 	/* check if the next not void action is END */
@@ -4903,7 +4908,7 @@ i40e_flow_flush_rss_filter(struct rte_eth_dev *dev)
 
 	ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
 
-	if (rss_info->num)
+	if (rss_info->conf.queue_num)
 		ret = i40e_config_rss_filter(pf, rss_info, FALSE);
 	return ret;
 }
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 92434809c..c00bdae3d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -100,8 +100,6 @@
 
 #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / sizeof(hw_stats->qprc[0]))
 
-#define IXGBE_HKEY_MAX_INDEX 10
-
 /* Additional timesync values. */
 #define NSEC_PER_SEC             1000000000L
 #define IXGBE_INCVAL_10GB        0x66666666
@@ -8371,7 +8369,7 @@ ixgbe_rss_filter_restore(struct rte_eth_dev *dev)
 	struct ixgbe_filter_info *filter_info =
 		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
-	if (filter_info->rss_info.num)
+	if (filter_info->rss_info.conf.queue_num)
 		ixgbe_config_rss_filter(dev,
 			&filter_info->rss_info, TRUE);
 }
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 655077700..9491b03f4 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -4,6 +4,9 @@
 
 #ifndef _IXGBE_ETHDEV_H_
 #define _IXGBE_ETHDEV_H_
+
+#include <stdint.h>
+
 #include "base/ixgbe_type.h"
 #include "base/ixgbe_dcb.h"
 #include "base/ixgbe_dcb_82599.h"
@@ -12,6 +15,7 @@
 #ifdef RTE_LIBRTE_SECURITY
 #include "ixgbe_ipsec.h"
 #endif
+#include <rte_flow.h>
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
@@ -39,6 +43,7 @@
 #define IXGBE_EXTENDED_VLAN	  (uint32_t)(1 << 26) /* EXTENDED VLAN ENABLE */
 #define IXGBE_VFTA_SIZE 128
 #define IXGBE_VLAN_TAG_SIZE 4
+#define IXGBE_HKEY_MAX_INDEX 10
 #define IXGBE_MAX_RX_QUEUE_NUM	128
 #define IXGBE_MAX_INTR_QUEUE_NUM	15
 #define IXGBE_VMDQ_DCB_NB_QUEUES     IXGBE_MAX_RX_QUEUE_NUM
@@ -196,8 +201,8 @@ struct ixgbe_hw_fdir_info {
 };
 
 struct ixgbe_rte_flow_rss_conf {
-	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
-	uint16_t num; /**< Number of entries in queue[]. */
+	struct rte_flow_action_rss conf; /**< RSS parameters. */
+	uint8_t key[IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key. */
 	uint16_t queue[IXGBE_MAX_RX_QUEUE_NUM]; /**< Queues indices to use. */
 };
 
@@ -696,6 +701,10 @@ void ixgbe_tm_conf_init(struct rte_eth_dev *dev);
 void ixgbe_tm_conf_uninit(struct rte_eth_dev *dev);
 int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx,
 			       uint16_t tx_rate);
+int ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
+			const struct rte_flow_action_rss *in);
+int ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
+			  const struct rte_flow_action_rss *with);
 int ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 		struct ixgbe_rte_flow_rss_conf *conf, bool add);
 
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
index abdeac28b..4e31c7c56 100644
--- a/drivers/net/ixgbe/ixgbe_flow.c
+++ b/drivers/net/ixgbe/ixgbe_flow.c
@@ -2761,7 +2761,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 
 	rss = (const struct rte_flow_action_rss *)act->conf;
 
-	if (!rss || !rss->num) {
+	if (!rss || !rss->queue_num) {
 		rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION,
 				act,
@@ -2769,7 +2769,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 		return -rte_errno;
 	}
 
-	for (n = 0; n < rss->num; n++) {
+	for (n = 0; n < rss->queue_num; n++) {
 		if (rss->queue[n] >= dev->data->nb_rx_queues) {
 			rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -2778,14 +2778,19 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 			return -rte_errno;
 		}
 	}
-	if (rss->rss_conf)
-		rss_conf->rss_conf = *rss->rss_conf;
-	else
-		rss_conf->rss_conf.rss_hf = IXGBE_RSS_OFFLOAD_ALL;
 
-	for (n = 0; n < rss->num; ++n)
-		rss_conf->queue[n] = rss->queue[n];
-	rss_conf->num = rss->num;
+	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS hash key must be exactly 40 bytes");
+	if (rss->queue_num > RTE_DIM(rss_conf->queue))
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "too many queues for RSS context");
+	if (ixgbe_rss_conf_init(rss_conf, rss))
+		return rte_flow_error_set
+			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "RSS context initialization failure");
 
 	/* check if the next not void item is END */
 	act = next_no_void_action(actions, act);
@@ -2834,7 +2839,7 @@ ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
 	struct ixgbe_filter_info *filter_info =
 		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
-	if (filter_info->rss_info.num)
+	if (filter_info->rss_info.conf.queue_num)
 		ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
 }
 
@@ -3153,9 +3158,8 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
 				PMD_DRV_LOG(ERR, "failed to allocate memory");
 				goto out;
 			}
-			rte_memcpy(&rss_filter_ptr->filter_info,
-				&rss_conf,
-				sizeof(struct ixgbe_rte_flow_rss_conf));
+			ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
+					    &rss_conf.conf);
 			TAILQ_INSERT_TAIL(&filter_rss_list,
 				rss_filter_ptr, entries);
 			flow->rule = rss_filter_ptr;
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index aed3f5a9a..9fbd7dbd7 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -5676,6 +5676,36 @@ ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev)
 }
 
 int
+ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
+		    const struct rte_flow_action_rss *in)
+{
+	if (in->key_len > RTE_DIM(out->key) ||
+	    in->queue_num > RTE_DIM(out->queue))
+		return -EINVAL;
+	out->conf = (struct rte_flow_action_rss){
+		.types = in->types,
+		.key_len = in->key_len,
+		.queue_num = in->queue_num,
+		.key = memcpy(out->key, in->key, in->key_len),
+		.queue = memcpy(out->queue, in->queue,
+				sizeof(*in->queue) * in->queue_num),
+	};
+	return 0;
+}
+
+int
+ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
+		      const struct rte_flow_action_rss *with)
+{
+	return (comp->types == with->types &&
+		comp->key_len == with->key_len &&
+		comp->queue_num == with->queue_num &&
+		!memcmp(comp->key, with->key, with->key_len) &&
+		!memcmp(comp->queue, with->queue,
+			sizeof(*with->queue) * with->queue_num));
+}
+
+int
 ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 		struct ixgbe_rte_flow_rss_conf *conf, bool add)
 {
@@ -5685,7 +5715,12 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 	uint16_t j;
 	uint16_t sp_reta_size;
 	uint32_t reta_reg;
-	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
+	struct rte_eth_rss_conf rss_conf = {
+		.rss_key = conf->conf.key_len ?
+			(void *)(uintptr_t)conf->conf.key : NULL,
+		.rss_key_len = conf->conf.key_len,
+		.rss_hf = conf->conf.types,
+	};
 	struct ixgbe_filter_info *filter_info =
 		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
@@ -5695,8 +5730,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 	sp_reta_size = ixgbe_reta_size_get(hw->mac.type);
 
 	if (!add) {
-		if (memcmp(conf, &filter_info->rss_info,
-			sizeof(struct ixgbe_rte_flow_rss_conf)) == 0) {
+		if (ixgbe_action_rss_same(&filter_info->rss_info.conf,
+					  &conf->conf)) {
 			ixgbe_rss_disable(dev);
 			memset(&filter_info->rss_info, 0,
 				sizeof(struct ixgbe_rte_flow_rss_conf));
@@ -5705,7 +5740,7 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (filter_info->rss_info.num)
+	if (filter_info->rss_info.conf.queue_num)
 		return -EINVAL;
 	/* Fill in redirection table
 	 * The byte-swap is needed because NIC registers are in
@@ -5715,9 +5750,9 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 	for (i = 0, j = 0; i < sp_reta_size; i++, j++) {
 		reta_reg = ixgbe_reta_reg_get(hw->mac.type, i);
 
-		if (j == conf->num)
+		if (j == conf->conf.queue_num)
 			j = 0;
-		reta = (reta << 8) | conf->queue[j];
+		reta = (reta << 8) | conf->conf.queue[j];
 		if ((i & 3) == 3)
 			IXGBE_WRITE_REG(hw, reta_reg,
 					rte_bswap32(reta));
@@ -5734,8 +5769,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
 		rss_conf.rss_key = rss_intel_key; /* Default hash key */
 	ixgbe_hw_rss_hash_set(hw, &rss_conf);
 
-	rte_memcpy(&filter_info->rss_info,
-		conf, sizeof(struct ixgbe_rte_flow_rss_conf));
+	if (ixgbe_rss_conf_init(&filter_info->rss_info, &conf->conf))
+		return -EINVAL;
 
 	return 0;
 }
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 937074a4f..3dd72dbf5 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -571,7 +571,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			     " for UDP RSS and inner VXLAN RSS");
 			/* Fake support for all possible RSS hash fields. */
 			priv->hw_rss_sup = ~UINT64_C(0);
-			priv->hw_rss_sup = mlx4_conv_rss_hf(priv, -1);
+			priv->hw_rss_sup = mlx4_conv_rss_types(priv, -1);
 			/* Filter out known unsupported fields. */
 			priv->hw_rss_sup &=
 				~(uint64_t)(IBV_RX_HASH_SRC_PORT_UDP |
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 8feb6ae31..dd86e4ce7 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -76,22 +76,22 @@ struct mlx4_drop {
 };
 
 /**
- * Convert DPDK RSS hash fields to their Verbs equivalent.
+ * Convert DPDK RSS hash types to their Verbs equivalent.
  *
- * This function returns the supported (default) set when @p rss_hf has
+ * This function returns the supported (default) set when @p types has
  * special value (uint64_t)-1.
  *
  * @param priv
  *   Pointer to private structure.
- * @param rss_hf
- *   Hash fields in DPDK format (see struct rte_eth_rss_conf).
+ * @param types
+ *   Hash types in DPDK format (see struct rte_eth_rss_conf).
  *
  * @return
  *   A valid Verbs RSS hash fields mask for mlx4 on success, (uint64_t)-1
  *   otherwise and rte_errno is set.
  */
 uint64_t
-mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
+mlx4_conv_rss_types(struct priv *priv, uint64_t types)
 {
 	enum { IPV4, IPV6, TCP, UDP, };
 	const uint64_t in[] = {
@@ -126,17 +126,17 @@ mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
 	unsigned int i;
 
 	for (i = 0; i != RTE_DIM(in); ++i)
-		if (rss_hf & in[i]) {
-			seen |= rss_hf & in[i];
+		if (types & in[i]) {
+			seen |= types & in[i];
 			conv |= out[i];
 		}
 	if ((conv & priv->hw_rss_sup) == conv) {
-		if (rss_hf == (uint64_t)-1) {
+		if (types == (uint64_t)-1) {
 			/* Include inner RSS by default if supported. */
 			conv |= priv->hw_rss_sup & IBV_RX_HASH_INNER;
 			return conv;
 		}
-		if (!(rss_hf & ~seen))
+		if (!(types & ~seen))
 			return conv;
 	}
 	rte_errno = ENOTSUP;
@@ -717,7 +717,8 @@ mlx4_flow_prepare(struct priv *priv,
 		switch (action->type) {
 			const struct rte_flow_action_queue *queue;
 			const struct rte_flow_action_rss *rss;
-			const struct rte_eth_rss_conf *rss_conf;
+			const uint8_t *rss_key;
+			uint32_t rss_key_len;
 			uint64_t fields;
 			unsigned int i;
 
@@ -747,58 +748,56 @@ mlx4_flow_prepare(struct priv *priv,
 				break;
 			rss = action->conf;
 			/* Default RSS configuration if none is provided. */
-			rss_conf =
-				rss->rss_conf ?
-				rss->rss_conf :
-				&(struct rte_eth_rss_conf){
-					.rss_key = mlx4_rss_hash_key_default,
-					.rss_key_len = MLX4_RSS_HASH_KEY_SIZE,
-					.rss_hf = -1,
-				};
+			if (rss->key_len) {
+				rss_key = rss->key;
+				rss_key_len = rss->key_len;
+			} else {
+				rss_key = mlx4_rss_hash_key_default;
+				rss_key_len = MLX4_RSS_HASH_KEY_SIZE;
+			}
 			/* Sanity checks. */
-			for (i = 0; i < rss->num; ++i)
+			for (i = 0; i < rss->queue_num; ++i)
 				if (rss->queue[i] >=
 				    priv->dev->data->nb_rx_queues)
 					break;
-			if (i != rss->num) {
+			if (i != rss->queue_num) {
 				msg = "queue index target beyond number of"
 					" configured Rx queues";
 				goto exit_action_not_supported;
 			}
-			if (!rte_is_power_of_2(rss->num)) {
+			if (!rte_is_power_of_2(rss->queue_num)) {
 				msg = "for RSS, mlx4 requires the number of"
 					" queues to be a power of two";
 				goto exit_action_not_supported;
 			}
-			if (rss_conf->rss_key_len !=
-			    sizeof(flow->rss->key)) {
+			if (rss_key_len != sizeof(flow->rss->key)) {
 				msg = "mlx4 supports exactly one RSS hash key"
 					" length: "
 					MLX4_STR_EXPAND(MLX4_RSS_HASH_KEY_SIZE);
 				goto exit_action_not_supported;
 			}
-			for (i = 1; i < rss->num; ++i)
+			for (i = 1; i < rss->queue_num; ++i)
 				if (rss->queue[i] - rss->queue[i - 1] != 1)
 					break;
-			if (i != rss->num) {
+			if (i != rss->queue_num) {
 				msg = "mlx4 requires RSS contexts to use"
 					" consecutive queue indices only";
 				goto exit_action_not_supported;
 			}
-			if (rss->queue[0] % rss->num) {
+			if (rss->queue[0] % rss->queue_num) {
 				msg = "mlx4 requires the first queue of a RSS"
 					" context to be aligned on a multiple"
 					" of the context size";
 				goto exit_action_not_supported;
 			}
 			rte_errno = 0;
-			fields = mlx4_conv_rss_hf(priv, rss_conf->rss_hf);
+			fields = mlx4_conv_rss_types(priv, rss->types);
 			if (fields == (uint64_t)-1 && rte_errno) {
 				msg = "unsupported RSS hash type requested";
 				goto exit_action_not_supported;
 			}
 			flow->rss = mlx4_rss_get
-				(priv, fields, rss_conf->rss_key, rss->num,
+				(priv, fields, rss_key, rss->queue_num,
 				 rss->queue);
 			if (!flow->rss) {
 				msg = "either invalid parameters or not enough"
@@ -1284,8 +1283,10 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
 	uint16_t queue[queues];
 	struct rte_flow_action_rss action_rss = {
-		.rss_conf = NULL, /* Rely on default fallback settings. */
-		.num = queues,
+		.types = -1,
+		.key_len = MLX4_RSS_HASH_KEY_SIZE,
+		.queue_num = queues,
+		.key = mlx4_rss_hash_key_default,
 		.queue = queue,
 	};
 	struct rte_flow_action actions[] = {
diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h
index 4e3889e67..7b83d74b0 100644
--- a/drivers/net/mlx4/mlx4_flow.h
+++ b/drivers/net/mlx4/mlx4_flow.h
@@ -47,7 +47,7 @@ struct rte_flow {
 
 /* mlx4_flow.c */
 
-uint64_t mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf);
+uint64_t mlx4_conv_rss_types(struct priv *priv, uint64_t rss_hf);
 int mlx4_flow_sync(struct priv *priv, struct rte_flow_error *error);
 void mlx4_flow_clean(struct priv *priv);
 int mlx4_filter_ctrl(struct rte_eth_dev *dev,
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index a7acc047b..65f099423 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -88,7 +88,7 @@ mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE] = {
  */
 struct mlx4_rss *
 mlx4_rss_get(struct priv *priv, uint64_t fields,
-	     uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
+	     const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
 	     uint16_t queues, const uint16_t queue_id[])
 {
 	struct mlx4_rss *rss;
diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
index b1af86110..2dfee957f 100644
--- a/drivers/net/mlx4/mlx4_rxtx.h
+++ b/drivers/net/mlx4/mlx4_rxtx.h
@@ -127,7 +127,7 @@ uint8_t mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE];
 int mlx4_rss_init(struct priv *priv);
 void mlx4_rss_deinit(struct priv *priv);
 struct mlx4_rss *mlx4_rss_get(struct priv *priv, uint64_t fields,
-			      uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
+			      const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
 			      uint16_t queues, const uint16_t queue_id[]);
 void mlx4_rss_put(struct mlx4_rss *rss);
 int mlx4_rss_attach(struct mlx4_rss *rss);
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 0c89bff45..af8853e09 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -214,9 +214,8 @@ struct rte_flow {
 	TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
 	uint32_t mark:1; /**< Set if the flow is marked. */
 	uint32_t drop:1; /**< Drop queue. */
-	uint16_t queues_n; /**< Number of entries in queue[]. */
+	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
 	uint16_t (*queues)[]; /**< Queues indexes to use. */
-	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
 	uint8_t rss_key[40]; /**< copy of the RSS key. */
 	struct ibv_counter_set *cs; /**< Holds the counters for the rule. */
 	struct mlx5_flow_counter_stats counter_stats;/**<The counter stats. */
@@ -406,9 +405,8 @@ struct mlx5_flow_parse {
 	uint32_t mark:1; /**< Mark is present in the flow. */
 	uint32_t count:1; /**< Count is present in the flow. */
 	uint32_t mark_id; /**< Mark identifier. */
+	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
 	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queues indexes to use. */
-	uint16_t queues_n; /**< Number of entries in queue[]. */
-	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
 	uint8_t rss_key[40]; /**< copy of the RSS key. */
 	enum hash_rxq_type layer; /**< Last pattern layer detected. */
 	struct ibv_counter_set *cs; /**< Holds the counter set for the rule */
@@ -540,47 +538,6 @@ mlx5_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Copy the RSS configuration from the user ones, of the rss_conf is null,
- * uses the driver one.
- *
- * @param parser
- *   Internal parser structure.
- * @param rss_conf
- *   User RSS configuration to save.
- *
- * @return
- *   0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_convert_rss_conf(struct mlx5_flow_parse *parser,
-			   const struct rte_eth_rss_conf *rss_conf)
-{
-	/*
-	 * This function is also called at the beginning of
-	 * mlx5_flow_convert_actions() to initialize the parser with the
-	 * device default RSS configuration.
-	 */
-	if (rss_conf) {
-		if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) {
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		if (rss_conf->rss_key_len != 40) {
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		if (rss_conf->rss_key_len && rss_conf->rss_key) {
-			parser->rss_conf.rss_key_len = rss_conf->rss_key_len;
-			memcpy(parser->rss_key, rss_conf->rss_key,
-			       rss_conf->rss_key_len);
-			parser->rss_conf.rss_key = parser->rss_key;
-		}
-		parser->rss_conf.rss_hf = rss_conf->rss_hf;
-	}
-	return 0;
-}
-
-/**
  * Extract attribute to the parser.
  *
  * @param[in] attr
@@ -650,17 +607,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 	enum { FATE = 1, MARK = 2, COUNT = 4, };
 	uint32_t overlap = 0;
 	struct priv *priv = dev->data->dev_private;
-	int ret;
 
-	/*
-	 * Add default RSS configuration necessary for Verbs to create QP even
-	 * if no RSS is necessary.
-	 */
-	ret = mlx5_flow_convert_rss_conf(parser,
-					 (const struct rte_eth_rss_conf *)
-					 &priv->rss_conf);
-	if (ret)
-		return ret;
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
 		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
 			continue;
@@ -679,25 +626,53 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 			overlap |= FATE;
 			if (!queue || (queue->index > (priv->rxqs_n - 1)))
 				goto exit_action_not_supported;
-			parser->queues_n = 1;
 			parser->queues[0] = queue->index;
+			parser->rss_conf = (struct rte_flow_action_rss){
+				.queue_num = 1,
+				.queue = parser->queues,
+			};
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
+			const uint8_t *rss_key;
+			uint32_t rss_key_len;
 			uint16_t n;
 
 			if (overlap & FATE)
 				goto exit_action_overlap;
 			overlap |= FATE;
-			if (!rss || !rss->num) {
+			if (rss->types & MLX5_RSS_HF_MASK) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION,
+						   actions,
+						   "unsupported RSS type"
+						   " requested");
+				return -rte_errno;
+			}
+			if (rss->key_len) {
+				rss_key_len = rss->key_len;
+				rss_key = rss->key;
+			} else {
+				rss_key_len = rss_hash_default_key_len;
+				rss_key = rss_hash_default_key;
+			}
+			if (rss_key_len != RTE_DIM(parser->rss_key)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION,
+						   actions,
+						   "RSS hash key must be"
+						   " exactly 40 bytes long");
+				return -rte_errno;
+			}
+			if (!rss->queue_num) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
 						   actions,
 						   "no valid queues");
 				return -rte_errno;
 			}
-			if (rss->num > RTE_DIM(parser->queues)) {
+			if (rss->queue_num > RTE_DIM(parser->queues)) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
 						   actions,
@@ -705,7 +680,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 						   " context");
 				return -rte_errno;
 			}
-			for (n = 0; n < rss->num; ++n) {
+			for (n = 0; n < rss->queue_num; ++n) {
 				if (rss->queue[n] >= priv->rxqs_n) {
 					rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -715,16 +690,16 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 					return -rte_errno;
 				}
 			}
-			for (n = 0; n < rss->num; ++n)
-				parser->queues[n] = rss->queue[n];
-			parser->queues_n = rss->num;
-			if (mlx5_flow_convert_rss_conf(parser, rss->rss_conf)) {
-				rte_flow_error_set(error, EINVAL,
-						   RTE_FLOW_ERROR_TYPE_ACTION,
-						   actions,
-						   "wrong RSS configuration");
-				return -rte_errno;
-			}
+			parser->rss_conf = (struct rte_flow_action_rss){
+				.types = rss->types,
+				.key_len = rss_key_len,
+				.queue_num = rss->queue_num,
+				.key = memcpy(parser->rss_key, rss_key,
+					      sizeof(*rss_key) * rss_key_len),
+				.queue = memcpy(parser->queues, rss->queue,
+						sizeof(*rss->queue) *
+						rss->queue_num),
+			};
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK) {
 			const struct rte_flow_action_mark *mark =
 				(const struct rte_flow_action_mark *)
@@ -769,7 +744,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 		parser->drop = 1;
 	if (parser->drop && parser->mark)
 		parser->mark = 0;
-	if (!parser->queues_n && !parser->drop) {
+	if (!parser->rss_conf.queue_num && !parser->drop) {
 		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
 				   NULL, "no valid action");
 		return -rte_errno;
@@ -951,7 +926,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse *parser)
 	unsigned int i;
 
 	/* Remove any other flow not matching the pattern. */
-	if (parser->queues_n == 1 && !parser->rss_conf.rss_hf) {
+	if (parser->rss_conf.queue_num == 1 && !parser->rss_conf.types) {
 		for (i = 0; i != hash_rxq_init_n; ++i) {
 			if (i == HASH_RXQ_ETH)
 				continue;
@@ -979,7 +954,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse *parser)
 	}
 	/* Remove impossible flow according to the RSS configuration. */
 	if (hash_rxq_init[parser->layer].dpdk_rss_hf &
-	    parser->rss_conf.rss_hf) {
+	    parser->rss_conf.types) {
 		/* Remove any other flow. */
 		for (i = hmin; i != (hmax + 1); ++i) {
 			if ((i == parser->layer) ||
@@ -990,7 +965,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse *parser)
 		}
 	} else  if (!parser->queue[ip].ibv_attr) {
 		/* no RSS possible with the current configuration. */
-		parser->queues_n = 1;
+		parser->rss_conf.queue_num = 1;
 		return;
 	}
 fill:
@@ -1119,7 +1094,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev,
 		for (i = 0; i != hash_rxq_init_n; ++i) {
 			unsigned int offset;
 
-			if (!(parser->rss_conf.rss_hf &
+			if (!(parser->rss_conf.types &
 			      hash_rxq_init[i].dpdk_rss_hf) &&
 			    (i != HASH_RXQ_ETH))
 				continue;
@@ -1787,20 +1762,20 @@ mlx5_flow_create_action_queue_rss(struct rte_eth_dev *dev,
 			continue;
 		flow->frxq[i].hrxq =
 			mlx5_hrxq_get(dev,
-				      parser->rss_conf.rss_key,
-				      parser->rss_conf.rss_key_len,
+				      parser->rss_conf.key,
+				      parser->rss_conf.key_len,
 				      hash_fields,
-				      parser->queues,
-				      parser->queues_n);
+				      parser->rss_conf.queue,
+				      parser->rss_conf.queue_num);
 		if (flow->frxq[i].hrxq)
 			continue;
 		flow->frxq[i].hrxq =
 			mlx5_hrxq_new(dev,
-				      parser->rss_conf.rss_key,
-				      parser->rss_conf.rss_key_len,
+				      parser->rss_conf.key,
+				      parser->rss_conf.key_len,
 				      hash_fields,
-				      parser->queues,
-				      parser->queues_n);
+				      parser->rss_conf.queue,
+				      parser->rss_conf.queue_num);
 		if (!flow->frxq[i].hrxq) {
 			return rte_flow_error_set(error, ENOMEM,
 						  RTE_FLOW_ERROR_TYPE_HANDLE,
@@ -1871,9 +1846,9 @@ mlx5_flow_create_action_queue(struct rte_eth_dev *dev,
 				   NULL, "internal error in flow creation");
 		goto error;
 	}
-	for (i = 0; i != parser->queues_n; ++i) {
+	for (i = 0; i != parser->rss_conf.queue_num; ++i) {
 		struct mlx5_rxq_data *q =
-			(*priv->rxqs)[parser->queues[i]];
+			(*priv->rxqs)[parser->rss_conf.queue[i]];
 
 		q->mark |= parser->mark;
 	}
@@ -1937,7 +1912,8 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
 	if (ret)
 		goto exit;
 	flow = rte_calloc(__func__, 1,
-			  sizeof(*flow) + parser.queues_n * sizeof(uint16_t),
+			  sizeof(*flow) +
+			  parser.rss_conf.queue_num * sizeof(uint16_t),
 			  0);
 	if (!flow) {
 		rte_flow_error_set(error, ENOMEM,
@@ -1946,15 +1922,20 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
 				   "cannot allocate flow memory");
 		return NULL;
 	}
-	/* Copy queues configuration. */
+	/* Copy configuration. */
 	flow->queues = (uint16_t (*)[])(flow + 1);
-	memcpy(flow->queues, parser.queues, parser.queues_n * sizeof(uint16_t));
-	flow->queues_n = parser.queues_n;
+	flow->rss_conf = (struct rte_flow_action_rss){
+		.types = parser.rss_conf.types,
+		.key_len = parser.rss_conf.key_len,
+		.queue_num = parser.rss_conf.queue_num,
+		.key = memcpy(flow->rss_key, parser.rss_conf.key,
+			      sizeof(*parser.rss_conf.key) *
+			      parser.rss_conf.key_len),
+		.queue = memcpy(flow->queues, parser.rss_conf.queue,
+				sizeof(*parser.rss_conf.queue) *
+				parser.rss_conf.queue_num),
+	};
 	flow->mark = parser.mark;
-	/* Copy RSS configuration. */
-	flow->rss_conf = parser.rss_conf;
-	flow->rss_conf.rss_key = flow->rss_key;
-	memcpy(flow->rss_key, parser.rss_key, parser.rss_conf.rss_key_len);
 	/* finalise the flow. */
 	if (parser.drop)
 		ret = mlx5_flow_create_action_queue_drop(dev, &parser, flow,
@@ -2034,7 +2015,7 @@ mlx5_flow_list_destroy(struct rte_eth_dev *dev, struct mlx5_flows *list,
 
 	if (flow->drop || !flow->mark)
 		goto free;
-	for (i = 0; i != flow->queues_n; ++i) {
+	for (i = 0; i != flow->rss_conf.queue_num; ++i) {
 		struct rte_flow *tmp;
 		int mark = 0;
 
@@ -2344,19 +2325,19 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct mlx5_flows *list)
 			if (!flow->frxq[i].ibv_attr)
 				continue;
 			flow->frxq[i].hrxq =
-				mlx5_hrxq_get(dev, flow->rss_conf.rss_key,
-					      flow->rss_conf.rss_key_len,
+				mlx5_hrxq_get(dev, flow->rss_conf.key,
+					      flow->rss_conf.key_len,
 					      hash_rxq_init[i].hash_fields,
-					      (*flow->queues),
-					      flow->queues_n);
+					      flow->rss_conf.queue,
+					      flow->rss_conf.queue_num);
 			if (flow->frxq[i].hrxq)
 				goto flow_create;
 			flow->frxq[i].hrxq =
-				mlx5_hrxq_new(dev, flow->rss_conf.rss_key,
-					      flow->rss_conf.rss_key_len,
+				mlx5_hrxq_new(dev, flow->rss_conf.key,
+					      flow->rss_conf.key_len,
 					      hash_rxq_init[i].hash_fields,
-					      (*flow->queues),
-					      flow->queues_n);
+					      flow->rss_conf.queue,
+					      flow->rss_conf.queue_num);
 			if (!flow->frxq[i].hrxq) {
 				DRV_LOG(DEBUG,
 					"port %u flow %p cannot be applied",
@@ -2380,8 +2361,8 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct mlx5_flows *list)
 		}
 		if (!flow->mark)
 			continue;
-		for (i = 0; i != flow->queues_n; ++i)
-			(*priv->rxqs)[(*flow->queues)[i]]->mark = 1;
+		for (i = 0; i != flow->rss_conf.queue_num; ++i)
+			(*priv->rxqs)[flow->rss_conf.queue[i]]->mark = 1;
 	}
 	return 0;
 }
@@ -2458,8 +2439,10 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
 	};
 	uint16_t queue[priv->reta_idx_n];
 	struct rte_flow_action_rss action_rss = {
-		.rss_conf = &priv->rss_conf,
-		.num = priv->reta_idx_n,
+		.types = priv->rss_conf.rss_hf,
+		.key_len = priv->rss_conf.rss_key_len,
+		.queue_num = priv->reta_idx_n,
+		.key = priv->rss_conf.rss_key,
 		.queue = queue,
 	};
 	struct rte_flow_action actions[] = {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index eda3ba3d5..d2b25e8e8 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -1218,8 +1218,8 @@ mlx5_rxq_verify(struct rte_eth_dev *dev)
  *   The Verbs object initialised, NULL otherwise and rte_errno is set.
  */
 struct mlx5_ind_table_ibv *
-mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, uint16_t queues[],
-		       uint16_t queues_n)
+mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, const uint16_t *queues,
+		       uint32_t queues_n)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct mlx5_ind_table_ibv *ind_tbl;
@@ -1286,8 +1286,8 @@ mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, uint16_t queues[],
  *   An indirection table if found.
  */
 struct mlx5_ind_table_ibv *
-mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, uint16_t queues[],
-		       uint16_t queues_n)
+mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, const uint16_t *queues,
+		       uint32_t queues_n)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct mlx5_ind_table_ibv *ind_tbl;
@@ -1391,8 +1391,10 @@ mlx5_ind_table_ibv_verify(struct rte_eth_dev *dev)
  *   The Verbs object initialised, NULL otherwise and rte_errno is set.
  */
 struct mlx5_hrxq *
-mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t rss_key_len,
-	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
+mlx5_hrxq_new(struct rte_eth_dev *dev,
+	      const uint8_t *rss_key, uint32_t rss_key_len,
+	      uint64_t hash_fields,
+	      const uint16_t *queues, uint32_t queues_n)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct mlx5_hrxq *hrxq;
@@ -1408,6 +1410,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t rss_key_len,
 		rte_errno = ENOMEM;
 		return NULL;
 	}
+	if (!rss_key_len) {
+		rss_key_len = rss_hash_default_key_len;
+		rss_key = rss_hash_default_key;
+	}
 	qp = mlx5_glue->create_qp_ex
 		(priv->ctx,
 		 &(struct ibv_qp_init_attr_ex){
@@ -1419,7 +1425,7 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t rss_key_len,
 			.rx_hash_conf = (struct ibv_rx_hash_conf){
 				.rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
 				.rx_hash_key_len = rss_key_len,
-				.rx_hash_key = rss_key,
+				.rx_hash_key = (void *)(uintptr_t)rss_key,
 				.rx_hash_fields_mask = hash_fields,
 			},
 			.rwq_ind_tbl = ind_tbl->ind_table,
@@ -1469,8 +1475,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t rss_key_len,
  *   An hash Rx queue on success.
  */
 struct mlx5_hrxq *
-mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t rss_key_len,
-	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
+mlx5_hrxq_get(struct rte_eth_dev *dev,
+	      const uint8_t *rss_key, uint32_t rss_key_len,
+	      uint64_t hash_fields,
+	      const uint16_t *queues, uint32_t queues_n)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct mlx5_hrxq *hrxq;
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index 14d4418d9..c3a1ae213 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -134,7 +134,7 @@ struct mlx5_ind_table_ibv {
 	LIST_ENTRY(mlx5_ind_table_ibv) next; /* Pointer to the next element. */
 	rte_atomic32_t refcnt; /* Reference counter. */
 	struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
-	uint16_t queues_n; /**< Number of queues in the list. */
+	uint32_t queues_n; /**< Number of queues in the list. */
 	uint16_t queues[]; /**< Queue list. */
 };
 
@@ -145,7 +145,7 @@ struct mlx5_hrxq {
 	struct mlx5_ind_table_ibv *ind_table; /* Indirection table. */
 	struct ibv_qp *qp; /* Verbs queue pair. */
 	uint64_t hash_fields; /* Verbs Hash fields. */
-	uint8_t rss_key_len; /* Hash key length in bytes. */
+	uint32_t rss_key_len; /* Hash key length in bytes. */
 	uint8_t rss_key[]; /* Hash key. */
 };
 
@@ -238,20 +238,22 @@ int mlx5_rxq_releasable(struct rte_eth_dev *dev, uint16_t idx);
 int mlx5_rxq_verify(struct rte_eth_dev *dev);
 int rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl);
 struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_new(struct rte_eth_dev *dev,
-						  uint16_t queues[],
-						  uint16_t queues_n);
+						  const uint16_t *queues,
+						  uint32_t queues_n);
 struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_get(struct rte_eth_dev *dev,
-						  uint16_t queues[],
-						  uint16_t queues_n);
+						  const uint16_t *queues,
+						  uint32_t queues_n);
 int mlx5_ind_table_ibv_release(struct rte_eth_dev *dev,
 			       struct mlx5_ind_table_ibv *ind_tbl);
 int mlx5_ind_table_ibv_verify(struct rte_eth_dev *dev);
-struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key,
-				uint8_t rss_key_len, uint64_t hash_fields,
-				uint16_t queues[], uint16_t queues_n);
-struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t *rss_key,
-				uint8_t rss_key_len, uint64_t hash_fields,
-				uint16_t queues[], uint16_t queues_n);
+struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev,
+				const uint8_t *rss_key, uint32_t rss_key_len,
+				uint64_t hash_fields,
+				const uint16_t *queues, uint32_t queues_n);
+struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev,
+				const uint8_t *rss_key, uint32_t rss_key_len,
+				uint64_t hash_fields,
+				const uint16_t *queues, uint32_t queues_n);
 int mlx5_hrxq_release(struct rte_eth_dev *dev, struct mlx5_hrxq *hxrq);
 int mlx5_hrxq_ibv_verify(struct rte_eth_dev *dev);
 uint64_t mlx5_get_rx_port_offloads(void);
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 056405515..1a2c0299c 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1234,13 +1234,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 	struct sfc_rxq *rxq;
 	unsigned int rxq_hw_index_min;
 	unsigned int rxq_hw_index_max;
-	const struct rte_eth_rss_conf *rss_conf = rss->rss_conf;
-	uint64_t rss_hf;
-	uint8_t *rss_key = NULL;
+	const uint8_t *rss_key;
 	struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf;
 	unsigned int i;
 
-	if (rss->num == 0)
+	if (rss->queue_num == 0)
 		return -EINVAL;
 
 	rxq_sw_index = sa->rxq_count - 1;
@@ -1248,7 +1246,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 	rxq_hw_index_min = rxq->hw_index;
 	rxq_hw_index_max = 0;
 
-	for (i = 0; i < rss->num; ++i) {
+	for (i = 0; i < rss->queue_num; ++i) {
 		rxq_sw_index = rss->queue[i];
 
 		if (rxq_sw_index >= sa->rxq_count)
@@ -1263,15 +1261,14 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 			rxq_hw_index_max = rxq->hw_index;
 	}
 
-	rss_hf = (rss_conf != NULL) ? rss_conf->rss_hf : SFC_RSS_OFFLOADS;
-	if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0)
+	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
 		return -EINVAL;
 
-	if (rss_conf != NULL) {
-		if (rss_conf->rss_key_len != sizeof(sa->rss_key))
+	if (rss->key_len) {
+		if (rss->key_len != sizeof(sa->rss_key))
 			return -EINVAL;
 
-		rss_key = rss_conf->rss_key;
+		rss_key = rss->key;
 	} else {
 		rss_key = sa->rss_key;
 	}
@@ -1280,11 +1277,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 
 	sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
 	sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
-	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf);
+	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss->types);
 	rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key));
 
 	for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
-		unsigned int rxq_sw_index = rss->queue[i % rss->num];
+		unsigned int rxq_sw_index = rss->queue[i % rss->queue_num];
 		struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq;
 
 		sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index fe2f94010..67146aaba 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1215,7 +1215,7 @@ priv_flow_process(struct pmd_internals *pmd,
 				if (err)
 					goto exit_action_not_supported;
 			}
-			if (flow && rss)
+			if (flow)
 				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
@@ -2050,7 +2050,7 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			   struct rte_flow_error *error)
 {
 	/* 4096 is the maximum number of instructions for a BPF program */
-	int i;
+	unsigned int i;
 	int err;
 	struct rss_key rss_entry = { .hash_fields = 0,
 				     .key_size = 0 };
@@ -2066,8 +2066,8 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 	}
 
 	/* Update RSS map entry with queues */
-	rss_entry.nb_queues = rss->num;
-	for (i = 0; i < rss->num; i++)
+	rss_entry.nb_queues = rss->queue_num;
+	for (i = 0; i < rss->queue_num; i++)
 		rss_entry.queues[i] = rss->queue[i];
 	rss_entry.hash_fields =
 		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 5971937cf..ee2497352 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -203,9 +203,13 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 				     i < eth_dev->data->nb_rx_queues; ++i)
 					if (eth_dev->data->rx_queues[i])
 						queue[j++] = i;
-				action_rss.rss_conf = &rss_conf;
-				action_rss.num = j;
-				action_rss.queue = queue;
+				action_rss = (struct rte_flow_action_rss){
+					.types = rss_conf.rss_hf,
+					.key_len = rss_conf.rss_key_len,
+					.queue_num = j,
+					.key = rss_key,
+					.queue = queue,
+				};
 				ret = rte_flow_validate(sa->portid, &sa->attr,
 							sa->pattern, sa->action,
 							&err);
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index bb19e28c6..cc7819b6a 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -330,40 +330,27 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		off = 0;
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
-				.num = src.rss->num,
+				.types = src.rss->types,
+				.key_len = src.rss->key_len,
+				.queue_num = src.rss->queue_num,
 			};
 		off += sizeof(*src.rss);
-		if (src.rss->num) {
+		if (src.rss->key_len) {
 			off = RTE_ALIGN_CEIL(off, sizeof(double));
-			size = sizeof(*src.rss->queue) * src.rss->num;
+			size = sizeof(*src.rss->key) * src.rss->key_len;
 			if (dst.rss)
-				dst.rss->queue = memcpy
+				dst.rss->key = memcpy
 					((void *)((uintptr_t)dst.rss + off),
-					 src.rss->queue, size);
+					 src.rss->key, size);
 			off += size;
 		}
-		off = RTE_ALIGN_CEIL(off, sizeof(double));
-		if (dst.rss) {
-			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
-			*(struct rte_eth_rss_conf *)(uintptr_t)
-				dst.rss->rss_conf = (struct rte_eth_rss_conf){
-				.rss_key_len = src.rss->rss_conf->rss_key_len,
-				.rss_hf = src.rss->rss_conf->rss_hf,
-			};
-		}
-		off += sizeof(*src.rss->rss_conf);
-		if (src.rss->rss_conf->rss_key_len) {
+		if (src.rss->queue_num) {
 			off = RTE_ALIGN_CEIL(off, sizeof(double));
-			size = sizeof(*src.rss->rss_conf->rss_key) *
-				src.rss->rss_conf->rss_key_len;
-			if (dst.rss) {
-				((struct rte_eth_rss_conf *)(uintptr_t)
-				 dst.rss->rss_conf)->rss_key =
-					(void *)((uintptr_t)dst.rss + off);
-				memcpy(dst.rss->rss_conf->rss_key,
-				       src.rss->rss_conf->rss_key,
-				       size);
-			}
+			size = sizeof(*src.rss->queue) * src.rss->queue_num;
+			if (dst.rss)
+				dst.rss->queue = memcpy
+					((void *)((uintptr_t)dst.rss + off),
+					 src.rss->queue, size);
 			off += size;
 		}
 		size = off;
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index ad2e55b8e..bbc408fa6 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -1033,13 +1033,21 @@ struct rte_flow_query_count {
  * Similar to QUEUE, except RSS is additionally performed on packets to
  * spread them among several queues according to the provided parameters.
  *
+ * Unlike global RSS settings used by other DPDK APIs, unsetting the
+ * @p types field does not disable RSS in a flow rule. Doing so instead
+ * requests safe unspecified "best-effort" settings from the underlying PMD,
+ * which depending on the flow rule, may result in anything ranging from
+ * empty (single queue) to all-inclusive RSS.
+ *
  * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps
  * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only,
  * both can be requested simultaneously.
  */
 struct rte_flow_action_rss {
-	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
-	uint16_t num; /**< Number of entries in @p queue. */
+	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
+	uint32_t key_len; /**< Hash key length in bytes. */
+	uint32_t queue_num; /**< Number of entries in @p queue. */
+	const uint8_t *key; /**< Hash key. */
 	const uint16_t *queue; /**< Queue indices to use. */
 };
 
-- 
2.11.0

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v6 08/16] ethdev: add hash function to RSS flow API action
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (4 preceding siblings ...)
  2018-04-25 15:27  3%   ` [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in " Adrien Mazarguil
@ 2018-04-25 15:27  5%   ` Adrien Mazarguil
  2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 09/16] ethdev: add encap level " Adrien Mazarguil
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Wenzhuo Lu, Jingjing Wu, Beilei Xing, Qi Zhang,
	Konstantin Ananyev, Nelio Laranjeiro, Yongseok Koh,
	Andrew Rybchenko, Pascal Mazon

By definition, RSS involves some kind of hash algorithm, usually Toeplitz.

Until now it could not be modified on a flow rule basis and PMDs had to
always assume RTE_ETH_HASH_FUNCTION_DEFAULT, which remains the default
behavior when unspecified (0).

This breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Thomas Monjalon <thomas@monjalon.net>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: Jingjing Wu <jingjing.wu@intel.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>

---

v6 changes:

Updated API changes section in release notes.

v3 changes:

- Although RTE_ETH_HASH_FUNCTION_DEFAULT is defined as 0, made comparisons
  more explicit where doing so would clarify the code.

- Updated sfc to include Toeplitz as the other allowed value.

Both according to Andrew's suggestions [1].

[1] http://dpdk.org/ml/archives/dev/2018-April/095840.html
---
 app/test-pmd/cmdline_flow.c                 | 72 ++++++++++++++++++++++++
 app/test-pmd/config.c                       |  1 +
 doc/guides/prog_guide/rte_flow.rst          |  2 +
 doc/guides/rel_notes/release_18_05.rst      |  3 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  3 +
 drivers/net/e1000/igb_flow.c                |  4 ++
 drivers/net/e1000/igb_rxtx.c                |  4 +-
 drivers/net/i40e/i40e_ethdev.c              |  4 +-
 drivers/net/i40e/i40e_flow.c                |  4 ++
 drivers/net/ixgbe/ixgbe_flow.c              |  4 ++
 drivers/net/ixgbe/ixgbe_rxtx.c              |  4 +-
 drivers/net/mlx4/mlx4_flow.c                |  7 +++
 drivers/net/mlx5/mlx5_flow.c                | 13 +++++
 drivers/net/sfc/sfc_flow.c                  |  8 +++
 drivers/net/tap/tap_flow.c                  |  6 ++
 lib/librte_ether/rte_flow.c                 |  1 +
 lib/librte_ether/rte_flow.h                 |  2 +
 17 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index c9c2c3ad9..7436e0356 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -14,6 +14,7 @@
 #include <sys/socket.h>
 
 #include <rte_common.h>
+#include <rte_eth_ctrl.h>
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
@@ -165,6 +166,10 @@ enum index {
 	ACTION_DROP,
 	ACTION_COUNT,
 	ACTION_RSS,
+	ACTION_RSS_FUNC,
+	ACTION_RSS_FUNC_DEFAULT,
+	ACTION_RSS_FUNC_TOEPLITZ,
+	ACTION_RSS_FUNC_SIMPLE_XOR,
 	ACTION_RSS_TYPES,
 	ACTION_RSS_TYPE,
 	ACTION_RSS_KEY,
@@ -632,6 +637,7 @@ static const enum index action_queue[] = {
 };
 
 static const enum index action_rss[] = {
+	ACTION_RSS_FUNC,
 	ACTION_RSS_TYPES,
 	ACTION_RSS_KEY,
 	ACTION_RSS_KEY_LEN,
@@ -666,6 +672,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_action_rss(struct context *, const struct token *,
 			       const char *, unsigned int, void *,
 			       unsigned int);
+static int parse_vc_action_rss_func(struct context *, const struct token *,
+				    const char *, unsigned int, void *,
+				    unsigned int);
 static int parse_vc_action_rss_type(struct context *, const struct token *,
 				    const char *, unsigned int, void *,
 				    unsigned int);
@@ -1584,6 +1593,29 @@ static const struct token token_list[] = {
 		.next = NEXT(action_rss),
 		.call = parse_vc_action_rss,
 	},
+	[ACTION_RSS_FUNC] = {
+		.name = "func",
+		.help = "RSS hash function to apply",
+		.next = NEXT(action_rss,
+			     NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT,
+					ACTION_RSS_FUNC_TOEPLITZ,
+					ACTION_RSS_FUNC_SIMPLE_XOR)),
+	},
+	[ACTION_RSS_FUNC_DEFAULT] = {
+		.name = "default",
+		.help = "default hash function",
+		.call = parse_vc_action_rss_func,
+	},
+	[ACTION_RSS_FUNC_TOEPLITZ] = {
+		.name = "toeplitz",
+		.help = "Toeplitz hash function",
+		.call = parse_vc_action_rss_func,
+	},
+	[ACTION_RSS_FUNC_SIMPLE_XOR] = {
+		.name = "simple_xor",
+		.help = "simple XOR hash function",
+		.call = parse_vc_action_rss_func,
+	},
 	[ACTION_RSS_TYPES] = {
 		.name = "types",
 		.help = "specific RSS hash types",
@@ -2074,6 +2106,7 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 	action_rss_data = ctx->object;
 	*action_rss_data = (struct action_rss_data){
 		.conf = (struct rte_flow_action_rss){
+			.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
 			.types = rss_hf,
 			.key_len = sizeof(action_rss_data->key),
 			.queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
@@ -2099,6 +2132,45 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 }
 
 /**
+ * Parse func field for RSS action.
+ *
+ * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the
+ * ACTION_RSS_FUNC_* index that called this function.
+ */
+static int
+parse_vc_action_rss_func(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct action_rss_data *action_rss_data;
+	enum rte_eth_hash_function func;
+
+	(void)buf;
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ACTION_RSS_FUNC_DEFAULT:
+		func = RTE_ETH_HASH_FUNCTION_DEFAULT;
+		break;
+	case ACTION_RSS_FUNC_TOEPLITZ:
+		func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+		break;
+	case ACTION_RSS_FUNC_SIMPLE_XOR:
+		func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	action_rss_data = ctx->object;
+	action_rss_data->conf.func = func;
+	return len;
+}
+
+/**
  * Parse type field for RSS action.
  *
  * Valid tokens are type field names and the "end" token.
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4700dd674..89dc3c9b7 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1117,6 +1117,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		off = 0;
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
+				.func = src.rss->func,
 				.types = src.rss->types,
 				.key_len = src.rss->key_len,
 				.queue_num = src.rss->queue_num,
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index cf252eeba..e0c68495c 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1318,6 +1318,8 @@ field only, both can be requested simultaneously.
    +---------------+---------------------------------------------+
    | Field         | Value                                       |
    +===============+=============================================+
+   | ``func``      | RSS hash function to apply                  |
+   +---------------+---------------------------------------------+
    | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
    +---------------+---------------------------------------------+
    | ``key_len``   | hash key length in bytes                    |
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index b702ac66a..edf53c031 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -260,7 +260,8 @@ API Changes
     (``rss_conf->rss_key`` => ``key``,
     ``rss_conf->rss_key_len`` => ``key_len``,
     ``rss_conf->rss_hf`` => ``types``,
-    ``num`` => ``queue_num``).
+    ``num`` => ``queue_num``), and the addition of missing RSS parameters
+    (``func`` for RSS hash function to apply).
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a12e0267a..12933ef1e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3422,6 +3422,9 @@ This section lists supported actions and their attributes, if any.
 
 - ``rss``: spread packets among several queues.
 
+  - ``func {hash function}``: RSS hash function to apply, allowed tokens are
+    the same as `set_hash_global_config`_.
+
   - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
     tokens are the same as `set_hash_input_set`_, except that an empty list
     does not disable RSS but instead requests unspecified "best-effort"
diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index 8dc5f75f2..82307ec5d 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -1310,6 +1310,10 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 		}
 	}
 
+	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "non-default RSS hash functions are not supported");
 	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 45bb3455c..d5c1cd3d3 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -2905,6 +2905,7 @@ igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
 	    in->queue_num > RTE_DIM(out->queue))
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
+		.func = in->func,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -2919,7 +2920,8 @@ int
 igb_action_rss_same(const struct rte_flow_action_rss *comp,
 		    const struct rte_flow_action_rss *with)
 {
-	return (comp->types == with->types &&
+	return (comp->func == with->func &&
+		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
 		!memcmp(comp->key, with->key, with->key_len) &&
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 50e77901c..cf19649dc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -12190,6 +12190,7 @@ i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
 	    in->queue_num > RTE_DIM(out->queue))
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
+		.func = in->func,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -12204,7 +12205,8 @@ int
 i40e_action_rss_same(const struct rte_flow_action_rss *comp,
 		     const struct rte_flow_action_rss *with)
 {
-	return (comp->types == with->types &&
+	return (comp->func == with->func &&
+		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
 		!memcmp(comp->key, with->key, with->key_len) &&
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index ec6231003..897989bbd 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -4376,6 +4376,10 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 	}
 
 	/* Parse RSS related parameters from configuration */
+	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "non-default RSS hash functions are not supported");
 	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
index 4e31c7c56..00d975b93 100644
--- a/drivers/net/ixgbe/ixgbe_flow.c
+++ b/drivers/net/ixgbe/ixgbe_flow.c
@@ -2779,6 +2779,10 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 		}
 	}
 
+	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "non-default RSS hash functions are not supported");
 	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 9fbd7dbd7..e91e7f746 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -5683,6 +5683,7 @@ ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
 	    in->queue_num > RTE_DIM(out->queue))
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
+		.func = in->func,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -5697,7 +5698,8 @@ int
 ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
 		      const struct rte_flow_action_rss *with)
 {
-	return (comp->types == with->types &&
+	return (comp->func == with->func &&
+		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
 		!memcmp(comp->key, with->key, with->key_len) &&
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index dd86e4ce7..002003235 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -790,6 +790,12 @@ mlx4_flow_prepare(struct priv *priv,
 					" of the context size";
 				goto exit_action_not_supported;
 			}
+			if (rss->func &&
+			    rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
+				msg = "the only supported RSS hash function"
+					" is Toeplitz";
+				goto exit_action_not_supported;
+			}
 			rte_errno = 0;
 			fields = mlx4_conv_rss_types(priv, rss->types);
 			if (fields == (uint64_t)-1 && rte_errno) {
@@ -1283,6 +1289,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
 	uint16_t queue[queues];
 	struct rte_flow_action_rss action_rss = {
+		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
 		.types = -1,
 		.key_len = MLX4_RSS_HASH_KEY_SIZE,
 		.queue_num = queues,
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index af8853e09..093e3a228 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -18,6 +18,7 @@
 #endif
 
 #include <rte_common.h>
+#include <rte_eth_ctrl.h>
 #include <rte_ethdev_driver.h>
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
@@ -642,6 +643,15 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 			if (overlap & FATE)
 				goto exit_action_overlap;
 			overlap |= FATE;
+			if (rss->func &&
+			    rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION,
+						   actions,
+						   "the only supported RSS hash"
+						   " function is Toeplitz");
+				return -rte_errno;
+			}
 			if (rss->types & MLX5_RSS_HF_MASK) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -691,6 +701,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 				}
 			}
 			parser->rss_conf = (struct rte_flow_action_rss){
+				.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
 				.types = rss->types,
 				.key_len = rss_key_len,
 				.queue_num = rss->queue_num,
@@ -1925,6 +1936,7 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
 	/* Copy configuration. */
 	flow->queues = (uint16_t (*)[])(flow + 1);
 	flow->rss_conf = (struct rte_flow_action_rss){
+		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
 		.types = parser.rss_conf.types,
 		.key_len = parser.rss_conf.key_len,
 		.queue_num = parser.rss_conf.queue_num,
@@ -2439,6 +2451,7 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
 	};
 	uint16_t queue[priv->reta_idx_n];
 	struct rte_flow_action_rss action_rss = {
+		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
 		.types = priv->rss_conf.rss_hf,
 		.key_len = priv->rss_conf.rss_key_len,
 		.queue_num = priv->reta_idx_n,
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 1a2c0299c..779edad0c 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1261,6 +1261,14 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 			rxq_hw_index_max = rxq->hw_index;
 	}
 
+	switch (rss->func) {
+	case RTE_ETH_HASH_FUNCTION_DEFAULT:
+	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
 		return -EINVAL;
 
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 67146aaba..845031a31 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -2055,6 +2055,12 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 	struct rss_key rss_entry = { .hash_fields = 0,
 				     .key_size = 0 };
 
+	/* Check supported hash functions */
+	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			 "non-default RSS hash functions are not supported");
+
 	/* Get a new map key for a new RSS rule */
 	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
 	if (err < 0) {
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index cc7819b6a..a2b51f1e0 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -330,6 +330,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		off = 0;
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
+				.func = src.rss->func,
 				.types = src.rss->types,
 				.key_len = src.rss->key_len,
 				.queue_num = src.rss->queue_num,
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index bbc408fa6..97d7d3594 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -19,6 +19,7 @@
 
 #include <rte_arp.h>
 #include <rte_ether.h>
+#include <rte_eth_ctrl.h>
 #include <rte_icmp.h>
 #include <rte_ip.h>
 #include <rte_sctp.h>
@@ -1044,6 +1045,7 @@ struct rte_flow_query_count {
  * both can be requested simultaneously.
  */
 struct rte_flow_action_rss {
+	enum rte_eth_hash_function func; /**< RSS hash function to apply. */
 	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
 	uint32_t key_len; /**< Hash key length in bytes. */
 	uint32_t queue_num; /**< Number of entries in @p queue. */
-- 
2.11.0

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH v6 09/16] ethdev: add encap level to RSS flow API action
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (5 preceding siblings ...)
  2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 08/16] ethdev: add hash function to RSS flow API action Adrien Mazarguil
@ 2018-04-25 15:27  5%   ` Adrien Mazarguil
  2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API Adrien Mazarguil
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Xueming Li, Wenzhuo Lu, Jingjing Wu, Beilei Xing, Qi Zhang,
	Konstantin Ananyev, Nelio Laranjeiro, Yongseok Koh,
	Andrew Rybchenko, Pascal Mazon

RSS hash types (ETH_RSS_* macros defined in rte_ethdev.h) describe the
protocol header fields of a packet that must be taken into account while
computing RSS.

When facing encapsulated (e.g. tunneled) packets, there is an ambiguity as
to whether these should apply to inner or outer packets. Applications need
the ability to tell exactly "where" RSS must be performed.

This is addressed by adding encapsulation level information to the RSS flow
action. Its default value is 0 and stands for the usual unspecified
behavior. Other values provide a specific encapsulation level.

Contrary to the change announced by commit 676b605182a5 ("doc: announce
ethdev API change for RSS configuration"), this patch does not affect
struct rte_eth_rss_conf but struct rte_flow_action_rss as the former is not
used anymore by the RSS flow action. ABI impact is therefore limited to
rte_flow.

This breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Xueming Li <xuemingl@mellanox.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Thomas Monjalon <thomas@monjalon.net>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: Jingjing Wu <jingjing.wu@intel.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>

---

v6 changes:

- Removed deprecation notice for RSS configuration structure in this patch
  instead of Xueming's series [1].
- Updated API changes section in release notes.

[1] http://dpdk.org/ml/archives/dev/2018-April/098670.html
---
 app/test-pmd/cmdline_flow.c                 | 13 ++++++++++++
 app/test-pmd/config.c                       |  1 +
 doc/guides/prog_guide/rte_flow.rst          | 24 ++++++++++++++++++++++
 doc/guides/rel_notes/deprecation.rst        |  4 ----
 doc/guides/rel_notes/release_18_05.rst      |  3 ++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 ++
 drivers/net/e1000/igb_flow.c                |  4 ++++
 drivers/net/e1000/igb_rxtx.c                |  2 ++
 drivers/net/i40e/i40e_ethdev.c              |  2 ++
 drivers/net/i40e/i40e_flow.c                |  4 ++++
 drivers/net/ixgbe/ixgbe_flow.c              |  4 ++++
 drivers/net/ixgbe/ixgbe_rxtx.c              |  2 ++
 drivers/net/mlx4/mlx4_flow.c                |  6 ++++++
 drivers/net/mlx5/mlx5_flow.c                | 11 ++++++++++
 drivers/net/sfc/sfc_flow.c                  |  3 +++
 drivers/net/tap/tap_flow.c                  |  6 +++++-
 lib/librte_ether/rte_flow.c                 |  1 +
 lib/librte_ether/rte_flow.h                 | 26 ++++++++++++++++++++++++
 18 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7436e0356..976fde7cd 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -167,6 +167,7 @@ enum index {
 	ACTION_COUNT,
 	ACTION_RSS,
 	ACTION_RSS_FUNC,
+	ACTION_RSS_LEVEL,
 	ACTION_RSS_FUNC_DEFAULT,
 	ACTION_RSS_FUNC_TOEPLITZ,
 	ACTION_RSS_FUNC_SIMPLE_XOR,
@@ -638,6 +639,7 @@ static const enum index action_queue[] = {
 
 static const enum index action_rss[] = {
 	ACTION_RSS_FUNC,
+	ACTION_RSS_LEVEL,
 	ACTION_RSS_TYPES,
 	ACTION_RSS_KEY,
 	ACTION_RSS_KEY_LEN,
@@ -1616,6 +1618,16 @@ static const struct token token_list[] = {
 		.help = "simple XOR hash function",
 		.call = parse_vc_action_rss_func,
 	},
+	[ACTION_RSS_LEVEL] = {
+		.name = "level",
+		.help = "encapsulation level for \"types\"",
+		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY_ARB
+			     (offsetof(struct action_rss_data, conf) +
+			      offsetof(struct rte_flow_action_rss, level),
+			      sizeof(((struct rte_flow_action_rss *)0)->
+				     level))),
+	},
 	[ACTION_RSS_TYPES] = {
 		.name = "types",
 		.help = "specific RSS hash types",
@@ -2107,6 +2119,7 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
 	*action_rss_data = (struct action_rss_data){
 		.conf = (struct rte_flow_action_rss){
 			.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
+			.level = 0,
 			.types = rss_hf,
 			.key_len = sizeof(action_rss_data->key),
 			.queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 89dc3c9b7..4b121aa79 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1118,6 +1118,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
 				.func = src.rss->func,
+				.level = src.rss->level,
 				.types = src.rss->types,
 				.key_len = src.rss->key_len,
 				.queue_num = src.rss->queue_num,
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index e0c68495c..1a09e8a0f 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1311,6 +1311,28 @@ Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
 overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
 field only, both can be requested simultaneously.
 
+Also, regarding packet encapsulation ``level``:
+
+- ``0`` requests the default behavior. Depending on the packet type, it can
+  mean outermost, innermost, anything in between or even no RSS.
+
+  It basically stands for the innermost encapsulation level RSS can be
+  performed on according to PMD and device capabilities.
+
+- ``1`` requests RSS to be performed on the outermost packet encapsulation
+  level.
+
+- ``2`` and subsequent values request RSS to be performed on the specified
+   inner packet encapsulation level, from outermost to innermost (lower to
+   higher values).
+
+Values other than ``0`` are not necessarily supported.
+
+Requesting a specific RSS level on unrecognized traffic results in undefined
+behavior. For predictable results, it is recommended to make the flow rule
+pattern match packet headers up to the requested encapsulation level so that
+only matching traffic goes through.
+
 .. _table_rte_flow_action_rss:
 
 .. table:: RSS
@@ -1320,6 +1342,8 @@ field only, both can be requested simultaneously.
    +===============+=============================================+
    | ``func``      | RSS hash function to apply                  |
    +---------------+---------------------------------------------+
+   | ``level``     | encapsulation level for ``types``           |
+   +---------------+---------------------------------------------+
    | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
    +---------------+---------------------------------------------+
    | ``key_len``   | hash key length in bytes                    |
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index bce97a2a9..7ed890871 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,10 +71,6 @@ Deprecation Notices
   Target release for removal of the legacy API will be defined once most
   PMDs have switched to rte_flow.
 
-* ethdev: A new rss level field planned in 18.05.
-  The new API add rss_level field to ``rte_eth_rss_conf`` to enable a choice
-  of RSS hash calculation on outer or inner header of tunneled packet.
-
 * ethdev: A work is being planned for 18.05 to expose VF port representors
   as a mean to perform control and data path operation on the different VFs.
   As VF representor is an ethdev port, new fields are needed in order to map
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index edf53c031..e1419f925 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -261,7 +261,8 @@ API Changes
     ``rss_conf->rss_key_len`` => ``key_len``,
     ``rss_conf->rss_hf`` => ``types``,
     ``num`` => ``queue_num``), and the addition of missing RSS parameters
-    (``func`` for RSS hash function to apply).
+    (``func`` for RSS hash function to apply and ``level`` for the
+    encapsulation level).
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 12933ef1e..c5e399f3b 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3425,6 +3425,8 @@ This section lists supported actions and their attributes, if any.
   - ``func {hash function}``: RSS hash function to apply, allowed tokens are
     the same as `set_hash_global_config`_.
 
+  - ``level {unsigned}``: encapsulation level for ``types``.
+
   - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
     tokens are the same as `set_hash_input_set`_, except that an empty list
     does not disable RSS but instead requests unspecified "best-effort"
diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index 82307ec5d..d1c0b4b8d 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -1314,6 +1314,10 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
 			 "non-default RSS hash functions are not supported");
+	if (rss->level)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "a nonzero RSS encapsulation level is not supported");
 	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index d5c1cd3d3..a3776a0d7 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -2906,6 +2906,7 @@ igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
 		.func = in->func,
+		.level = in->level,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -2921,6 +2922,7 @@ igb_action_rss_same(const struct rte_flow_action_rss *comp,
 		    const struct rte_flow_action_rss *with)
 {
 	return (comp->func == with->func &&
+		comp->level == with->level &&
 		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index cf19649dc..685b9ca25 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -12191,6 +12191,7 @@ i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
 		.func = in->func,
+		.level = in->level,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -12206,6 +12207,7 @@ i40e_action_rss_same(const struct rte_flow_action_rss *comp,
 		     const struct rte_flow_action_rss *with)
 {
 	return (comp->func == with->func &&
+		comp->level == with->level &&
 		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index 897989bbd..db668835d 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -4380,6 +4380,10 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev,
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
 			 "non-default RSS hash functions are not supported");
+	if (rss->level)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "a nonzero RSS encapsulation level is not supported");
 	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
index 00d975b93..438bfcdfb 100644
--- a/drivers/net/ixgbe/ixgbe_flow.c
+++ b/drivers/net/ixgbe/ixgbe_flow.c
@@ -2783,6 +2783,10 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
 			 "non-default RSS hash functions are not supported");
+	if (rss->level)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
+			 "a nonzero RSS encapsulation level is not supported");
 	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e91e7f746..2892436e9 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -5684,6 +5684,7 @@ ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
 		return -EINVAL;
 	out->conf = (struct rte_flow_action_rss){
 		.func = in->func,
+		.level = in->level,
 		.types = in->types,
 		.key_len = in->key_len,
 		.queue_num = in->queue_num,
@@ -5699,6 +5700,7 @@ ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
 		      const struct rte_flow_action_rss *with)
 {
 	return (comp->func == with->func &&
+		comp->level == with->level &&
 		comp->types == with->types &&
 		comp->key_len == with->key_len &&
 		comp->queue_num == with->queue_num &&
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 002003235..ce36ac715 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -796,6 +796,11 @@ mlx4_flow_prepare(struct priv *priv,
 					" is Toeplitz";
 				goto exit_action_not_supported;
 			}
+			if (rss->level) {
+				msg = "a nonzero RSS encapsulation level is"
+					" not supported";
+				goto exit_action_not_supported;
+			}
 			rte_errno = 0;
 			fields = mlx4_conv_rss_types(priv, rss->types);
 			if (fields == (uint64_t)-1 && rte_errno) {
@@ -1290,6 +1295,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
 	uint16_t queue[queues];
 	struct rte_flow_action_rss action_rss = {
 		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
+		.level = 0,
 		.types = -1,
 		.key_len = MLX4_RSS_HASH_KEY_SIZE,
 		.queue_num = queues,
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 093e3a228..cf38ceaa1 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -652,6 +652,14 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 						   " function is Toeplitz");
 				return -rte_errno;
 			}
+			if (rss->level) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION,
+						   actions,
+						   "a nonzero RSS encapsulation"
+						   " level is not supported");
+				return -rte_errno;
+			}
 			if (rss->types & MLX5_RSS_HF_MASK) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -702,6 +710,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
 			}
 			parser->rss_conf = (struct rte_flow_action_rss){
 				.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
+				.level = 0,
 				.types = rss->types,
 				.key_len = rss_key_len,
 				.queue_num = rss->queue_num,
@@ -1937,6 +1946,7 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
 	flow->queues = (uint16_t (*)[])(flow + 1);
 	flow->rss_conf = (struct rte_flow_action_rss){
 		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
+		.level = 0,
 		.types = parser.rss_conf.types,
 		.key_len = parser.rss_conf.key_len,
 		.queue_num = parser.rss_conf.queue_num,
@@ -2452,6 +2462,7 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
 	uint16_t queue[priv->reta_idx_n];
 	struct rte_flow_action_rss action_rss = {
 		.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
+		.level = 0,
 		.types = priv->rss_conf.rss_hf,
 		.key_len = priv->rss_conf.rss_key_len,
 		.queue_num = priv->reta_idx_n,
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 779edad0c..3028efbf9 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1269,6 +1269,9 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
 		return -EINVAL;
 	}
 
+	if (rss->level)
+		return -EINVAL;
+
 	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
 		return -EINVAL;
 
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 845031a31..7dfaf9ac5 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -2055,11 +2055,15 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 	struct rss_key rss_entry = { .hash_fields = 0,
 				     .key_size = 0 };
 
-	/* Check supported hash functions */
+	/* Check supported RSS features */
 	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 			 "non-default RSS hash functions are not supported");
+	if (rss->level)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			 "a nonzero RSS encapsulation level is not supported");
 
 	/* Get a new map key for a new RSS rule */
 	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index a2b51f1e0..83b733ff0 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -331,6 +331,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
 		if (dst.rss)
 			*dst.rss = (struct rte_flow_action_rss){
 				.func = src.rss->func,
+				.level = src.rss->level,
 				.types = src.rss->types,
 				.key_len = src.rss->key_len,
 				.queue_num = src.rss->queue_num,
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 97d7d3594..d0ff26aa3 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -1046,6 +1046,32 @@ struct rte_flow_query_count {
  */
 struct rte_flow_action_rss {
 	enum rte_eth_hash_function func; /**< RSS hash function to apply. */
+	/**
+	 * Packet encapsulation level RSS hash @p types apply to.
+	 *
+	 * - @p 0 requests the default behavior. Depending on the packet
+	 *   type, it can mean outermost, innermost, anything in between or
+	 *   even no RSS.
+	 *
+	 *   It basically stands for the innermost encapsulation level RSS
+	 *   can be performed on according to PMD and device capabilities.
+	 *
+	 * - @p 1 requests RSS to be performed on the outermost packet
+	 *   encapsulation level.
+	 *
+	 * - @p 2 and subsequent values request RSS to be performed on the
+	 *   specified inner packet encapsulation level, from outermost to
+	 *   innermost (lower to higher values).
+	 *
+	 * Values other than @p 0 are not necessarily supported.
+	 *
+	 * Requesting a specific RSS level on unrecognized traffic results
+	 * in undefined behavior. For predictable results, it is recommended
+	 * to make the flow rule pattern match packet headers up to the
+	 * requested encapsulation level so that only matching traffic goes
+	 * through.
+	 */
+	uint32_t level;
 	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
 	uint32_t key_len; /**< Hash key length in bytes. */
 	uint32_t queue_num; /**< Number of entries in @p queue. */
-- 
2.11.0

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (6 preceding siblings ...)
  2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 09/16] ethdev: add encap level " Adrien Mazarguil
@ 2018-04-25 15:27  7%   ` Adrien Mazarguil
  2018-04-25 16:10  0%     ` Adrien Mazarguil
  2018-04-25 15:27  4%   ` [dpdk-dev] [PATCH v6 11/16] ethdev: fix default VLAN TCI mask " Adrien Mazarguil
                     ` (6 subsequent siblings)
  14 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Wenzhuo Lu, Jingjing Wu, Ajit Khaparde, Somnath Kotur,
	John Daley, Hyong Youb Kim, Beilei Xing, Qi Zhang,
	Konstantin Ananyev, Nelio Laranjeiro, Yongseok Koh,
	Tomasz Duszynski, Dmitri Epshtein, Natalie Samsonov, Jianbo Liu,
	Andrew Rybchenko, Pascal Mazon

TPID handling in rte_flow VLAN and E_TAG pattern item definitions is not
consistent with the normal stacking order of pattern items, which is
confusing to applications.

Problem is that when followed by one of these layers, the EtherType field
of the preceding layer keeps its "inner" definition, and the "outer" TPID
is provided by the subsequent layer, the reverse of how a packet looks like
on the wire:

 Wire:     [ ETH TPID = A | VLAN EtherType = B | B DATA ]
 rte_flow: [ ETH EtherType = B | VLAN TPID = A | B DATA ]

Worse, when QinQ is involved, the stacking order of VLAN layers is
unspecified. It is unclear whether it should be reversed (innermost to
outermost) as well given TPID applies to the previous layer:

 Wire:       [ ETH TPID = A | VLAN TPID = B | VLAN EtherType = C | C DATA ]
 rte_flow 1: [ ETH EtherType = C | VLAN TPID = B | VLAN TPID = A | C DATA ]
 rte_flow 2: [ ETH EtherType = C | VLAN TPID = A | VLAN TPID = B | C DATA ]

While specifying EtherType/TPID is hopefully rarely necessary, the stacking
order in case of QinQ and the lack of documentation remain an issue.

This patch replaces TPID in the VLAN pattern item with an inner
EtherType/TPID as is usually done everywhere else (e.g. struct vlan_hdr),
clarifies documentation and updates all relevant code.

It breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Summary of changes for PMDs that implement ETH, VLAN or E_TAG pattern
items:

- bnxt: EtherType matching is supported with and without VLAN, but TPID
  matching is not and triggers an error.

- e1000: EtherType matching is only supported with the ETHERTYPE filter,
  which does not support VLAN matching, therefore no impact.

- enic: same as bnxt.

- i40e: same as bnxt with existing FDIR limitations on allowed EtherType
  values. The remaining filter types (VXLAN, NVGRE, QINQ) do not support
  EtherType matching.

- ixgbe: same as e1000, with additional minor change to rely on the new
  E-Tag macro definition.

- mlx4: EtherType/TPID matching is not supported, no impact.

- mlx5: same as bnxt.

- mvpp2: same as bnxt.

- sfc: same as bnxt.

- tap: same as bnxt.

Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API")
Fixes: 99e7003831c3 ("net/ixgbe: parse L2 tunnel filter")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Thomas Monjalon <thomas@monjalon.net>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: Jingjing Wu <jingjing.wu@intel.com>
Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
Cc: Somnath Kotur <somnath.kotur@broadcom.com>
Cc: John Daley <johndale@cisco.com>
Cc: Hyong Youb Kim <hyonkim@cisco.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Tomasz Duszynski <tdu@semihalf.com>
Cc: Dmitri Epshtein <dima@marvell.com>
Cc: Natalie Samsonov <nsamsono@marvell.com>
Cc: Jianbo Liu <jianbo.liu@arm.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>

---

v6 changes:

- Reworded patch title as a "fix" (not candidate for backports) since it
  addresses a flaw in the original API definition.
- Updated API and ABI changes sections in release notes.

v3 changes:

Updated mrvl to mvpp2.

Moved unrelated default TCI mask update to separate patch.

Fixed sfc according to Andrew's comments [1], which made so much sense that
I standardized on the same behavior for all other PMDs: matching outer TPID
is never supported when a VLAN pattern item is present.

This is done because many devices accept several TPIDs but do not provide
means to match a given one explicitly, it's all or nothing, and that makes
the resulting flow rule inaccurate.

[1] http://dpdk.org/ml/archives/dev/2018-April/095870.html
---
 app/test-pmd/cmdline_flow.c                 | 17 +++----
 doc/guides/nics/tap.rst                     |  2 +-
 doc/guides/prog_guide/rte_flow.rst          | 19 ++++++--
 doc/guides/rel_notes/release_18_05.rst      |  7 ++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +-
 drivers/net/bnxt/bnxt_filter.c              | 35 +++++++++++---
 drivers/net/enic/enic_flow.c                | 19 +++++---
 drivers/net/i40e/i40e_flow.c                | 60 ++++++++++++++++++++----
 drivers/net/ixgbe/ixgbe_ethdev.c            |  3 +-
 drivers/net/mlx5/mlx5_flow.c                | 13 ++++-
 drivers/net/mvpp2/mrvl_flow.c               | 26 +++++++---
 drivers/net/sfc/sfc_flow.c                  | 18 +++++++
 drivers/net/tap/tap_flow.c                  | 14 ++++--
 lib/librte_ether/rte_flow.h                 | 22 ++++++---
 lib/librte_net/rte_ether.h                  |  1 +
 15 files changed, 203 insertions(+), 57 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 976fde7cd..f8f2a559e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -99,11 +99,11 @@ enum index {
 	ITEM_ETH_SRC,
 	ITEM_ETH_TYPE,
 	ITEM_VLAN,
-	ITEM_VLAN_TPID,
 	ITEM_VLAN_TCI,
 	ITEM_VLAN_PCP,
 	ITEM_VLAN_DEI,
 	ITEM_VLAN_VID,
+	ITEM_VLAN_INNER_TYPE,
 	ITEM_IPV4,
 	ITEM_IPV4_TOS,
 	ITEM_IPV4_TTL,
@@ -505,11 +505,11 @@ static const enum index item_eth[] = {
 };
 
 static const enum index item_vlan[] = {
-	ITEM_VLAN_TPID,
 	ITEM_VLAN_TCI,
 	ITEM_VLAN_PCP,
 	ITEM_VLAN_DEI,
 	ITEM_VLAN_VID,
+	ITEM_VLAN_INNER_TYPE,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -1142,12 +1142,6 @@ static const struct token token_list[] = {
 		.next = NEXT(item_vlan),
 		.call = parse_vc,
 	},
-	[ITEM_VLAN_TPID] = {
-		.name = "tpid",
-		.help = "tag protocol identifier",
-		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
-		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tpid)),
-	},
 	[ITEM_VLAN_TCI] = {
 		.name = "tci",
 		.help = "tag control information",
@@ -1175,6 +1169,13 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
 						  tci, "\x0f\xff")),
 	},
+	[ITEM_VLAN_INNER_TYPE] = {
+		.name = "inner_type",
+		.help = "inner EtherType",
+		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan,
+					     inner_type)),
+	},
 	[ITEM_IPV4] = {
 		.name = "ipv4",
 		.help = "match IPv4 header",
diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
index 3e038cc5e..dca64c98d 100644
--- a/doc/guides/nics/tap.rst
+++ b/doc/guides/nics/tap.rst
@@ -108,7 +108,7 @@ The kernel support can be checked with this command::
 Supported items:
 
 - eth: src and dst (with variable masks), and eth_type (0xffff mask).
-- vlan: vid, pcp, tpid, but not eid. (requires kernel 4.9)
+- vlan: vid, pcp, but not eid. (requires kernel 4.9)
 - ipv4/6: src and dst (with variable masks), and ip_proto (0xffff mask).
 - udp/tcp: src and dst port (0xffff) mask.
 
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 1a09e8a0f..fd317b48c 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -784,9 +784,15 @@ Item: ``ETH``
 
 Matches an Ethernet header.
 
+The ``type`` field either stands for "EtherType" or "TPID" when followed by
+so-called layer 2.5 pattern items such as ``RTE_FLOW_ITEM_TYPE_VLAN``. In
+the latter case, ``type`` refers to that of the outer header, with the inner
+EtherType/TPID provided by the subsequent pattern item. This is the same
+order as on the wire.
+
 - ``dst``: destination MAC.
 - ``src``: source MAC.
-- ``type``: EtherType.
+- ``type``: EtherType or TPID.
 - Default ``mask`` matches destination and source addresses only.
 
 Item: ``VLAN``
@@ -794,8 +800,12 @@ Item: ``VLAN``
 
 Matches an 802.1Q/ad VLAN tag.
 
-- ``tpid``: tag protocol identifier.
+The corresponding standard outer EtherType (TPID) values are
+``ETHER_TYPE_VLAN`` or ``ETHER_TYPE_QINQ``. It can be overridden by the
+preceding pattern item.
+
 - ``tci``: tag control information.
+- ``inner_type``: inner EtherType or TPID.
 - Default ``mask`` matches TCI only.
 
 Item: ``IPV4``
@@ -866,12 +876,15 @@ Item: ``E_TAG``
 
 Matches an IEEE 802.1BR E-Tag header.
 
-- ``tpid``: tag protocol identifier (0x893F)
+The corresponding standard outer EtherType (TPID) value is
+``ETHER_TYPE_ETAG``. It can be overridden by the preceding pattern item.
+
 - ``epcp_edei_in_ecid_b``: E-Tag control information (E-TCI), E-PCP (3b),
   E-DEI (1b), ingress E-CID base (12b).
 - ``rsvd_grp_ecid_b``: reserved (2b), GRP (2b), E-CID base (12b).
 - ``in_ecid_e``: ingress E-CID ext.
 - ``ecid_e``: E-CID ext.
+- ``inner_type``: inner EtherType or TPID.
 - Default ``mask`` simultaneously matches GRP and E-CID base.
 
 Item: ``NVGRE``
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index e1419f925..a980a23ae 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -263,6 +263,8 @@ API Changes
     ``num`` => ``queue_num``), and the addition of missing RSS parameters
     (``func`` for RSS hash function to apply and ``level`` for the
     encapsulation level).
+  * The VLAN pattern item (``struct rte_flow_item_vlan``) was modified to
+    include inner EtherType instead of outer TPID.
 
 
 ABI Changes
@@ -312,8 +314,9 @@ ABI Changes
   changes in error type definitions (``enum rte_flow_error_type``), removal
   of the unused DUP action (``enum rte_flow_action_type``), modified
   behavior for flow rule actions (see API changes), removal of C99 flexible
-  array from RAW pattern item (``struct rte_flow_item_raw``) and complete
-  rework of the RSS action definition (``struct rte_flow_action_rss``).
+  array from RAW pattern item (``struct rte_flow_item_raw``), complete
+  rework of the RSS action definition (``struct rte_flow_action_rss``) and
+  sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``).
 
 
 Removed Items
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index c5e399f3b..007b24ff3 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3247,15 +3247,15 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``dst {MAC-48}``: destination MAC.
   - ``src {MAC-48}``: source MAC.
-  - ``type {unsigned}``: EtherType.
+  - ``type {unsigned}``: EtherType or TPID.
 
 - ``vlan``: match 802.1Q/ad VLAN tag.
 
-  - ``tpid {unsigned}``: tag protocol identifier.
   - ``tci {unsigned}``: tag control information.
   - ``pcp {unsigned}``: priority code point.
   - ``dei {unsigned}``: drop eligible indicator.
   - ``vid {unsigned}``: VLAN identifier.
+  - ``inner_type {unsigned}``: inner EtherType or TPID.
 
 - ``ipv4``: match IPv4 header.
 
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index fdd94bf02..25806bdc0 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -307,6 +307,7 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp,
 	uint32_t vf = 0;
 	int use_ntuple;
 	uint32_t en = 0;
+	uint32_t en_ethertype;
 	int dflt_vnic;
 
 	use_ntuple = bnxt_filter_type_check(pattern, error);
@@ -316,6 +317,9 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp,
 
 	filter->filter_type = use_ntuple ?
 		HWRM_CFA_NTUPLE_FILTER : HWRM_CFA_EM_FILTER;
+	en_ethertype = use_ntuple ?
+		NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE :
+		EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE;
 
 	while (item->type != RTE_FLOW_ITEM_TYPE_END) {
 		if (item->last) {
@@ -385,30 +389,49 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp,
 			if (eth_mask->type) {
 				filter->ethertype =
 					rte_be_to_cpu_16(eth_spec->type);
-				en |= use_ntuple ?
-					NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE :
-					EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE;
+				en |= en_ethertype;
 			}
 
 			break;
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
+			if (en & en_ethertype) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "VLAN TPID matching is not"
+						   " supported");
+				return -rte_errno;
+			}
 			if (vlan_mask->tci &&
-			    vlan_mask->tci == RTE_BE16(0x0fff) &&
-			    !vlan_mask->tpid) {
+			    vlan_mask->tci == RTE_BE16(0x0fff)) {
 				/* Only the VLAN ID can be matched. */
 				filter->l2_ovlan =
 					rte_be_to_cpu_16(vlan_spec->tci &
 							 RTE_BE16(0x0fff));
 				en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID;
-			} else if (vlan_mask->tci || vlan_mask->tpid) {
+			} else if (vlan_mask->tci) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ITEM,
 						   item,
 						   "VLAN mask is invalid");
 				return -rte_errno;
 			}
+			if (vlan_mask->inner_type &&
+			    vlan_mask->inner_type != RTE_BE16(0xffff)) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "inner ethertype mask not"
+						   " valid");
+				return -rte_errno;
+			}
+			if (vlan_mask->inner_type) {
+				filter->ethertype =
+					rte_be_to_cpu_16(vlan_spec->inner_type);
+				en |= en_ethertype;
+			}
 
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV4:
diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index c34ae84d1..eea14ee73 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -557,16 +557,21 @@ enic_copy_item_vlan_v2(const struct rte_flow_item *item,
 	if (!spec)
 		return 0;
 
-	/* Don't support filtering in tpid */
-	if (mask) {
-		if (mask->tpid != 0)
-			return ENOTSUP;
-	} else {
+	if (!mask)
 		mask = &rte_flow_item_vlan_mask;
-		RTE_ASSERT(mask->tpid == 0);
-	}
 
 	if (*inner_ofst == 0) {
+		struct ether_hdr *eth_mask =
+			(void *)gp->layer[FILTER_GENERIC_1_L2].mask;
+		struct ether_hdr *eth_val =
+			(void *)gp->layer[FILTER_GENERIC_1_L2].val;
+
+		/* Outer TPID cannot be matched */
+		if (eth_mask->ether_type)
+			return ENOTSUP;
+		eth_mask->ether_type = mask->inner_type;
+		eth_val->ether_type = spec->inner_type;
+
 		/* Outer header. Use the vlan mask/val fields */
 		gp->mask_vlan = mask->tci;
 		gp->val_vlan = spec->tci;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index db668835d..470ab93d6 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #include <stdarg.h>
 
+#include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev_driver.h>
 #include <rte_log.h>
@@ -2491,16 +2492,22 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 						      "Invalid MAC_addr mask.");
 					return -rte_errno;
 				}
+			}
+			if (eth_spec && eth_mask && eth_mask->type) {
+				enum rte_flow_item_type next = (item + 1)->type;
 
-				if ((eth_mask->type & UINT16_MAX) ==
-				    UINT16_MAX) {
-					input_set |= I40E_INSET_LAST_ETHER_TYPE;
-					filter->input.flow.l2_flow.ether_type =
-						eth_spec->type;
+				if (eth_mask->type != RTE_BE16(0xffff)) {
+					rte_flow_error_set(error, EINVAL,
+						      RTE_FLOW_ERROR_TYPE_ITEM,
+						      item,
+						      "Invalid type mask.");
+					return -rte_errno;
 				}
 
 				ether_type = rte_be_to_cpu_16(eth_spec->type);
-				if (ether_type == ETHER_TYPE_IPv4 ||
+
+				if (next == RTE_FLOW_ITEM_TYPE_VLAN ||
+				    ether_type == ETHER_TYPE_IPv4 ||
 				    ether_type == ETHER_TYPE_IPv6 ||
 				    ether_type == ETHER_TYPE_ARP ||
 				    ether_type == outer_tpid) {
@@ -2510,6 +2517,9 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 						     "Unsupported ether_type.");
 					return -rte_errno;
 				}
+				input_set |= I40E_INSET_LAST_ETHER_TYPE;
+				filter->input.flow.l2_flow.ether_type =
+					eth_spec->type;
 			}
 
 			pctype = I40E_FILTER_PCTYPE_L2_PAYLOAD;
@@ -2519,6 +2529,8 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
+
+			RTE_ASSERT(!(input_set & I40E_INSET_LAST_ETHER_TYPE));
 			if (vlan_spec && vlan_mask) {
 				if (vlan_mask->tci ==
 				    rte_cpu_to_be_16(I40E_TCI_MASK)) {
@@ -2527,6 +2539,33 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 						vlan_spec->tci;
 				}
 			}
+			if (vlan_spec && vlan_mask && vlan_mask->inner_type) {
+				if (vlan_mask->inner_type != RTE_BE16(0xffff)) {
+					rte_flow_error_set(error, EINVAL,
+						      RTE_FLOW_ERROR_TYPE_ITEM,
+						      item,
+						      "Invalid inner_type"
+						      " mask.");
+					return -rte_errno;
+				}
+
+				ether_type =
+					rte_be_to_cpu_16(vlan_spec->inner_type);
+
+				if (ether_type == ETHER_TYPE_IPv4 ||
+				    ether_type == ETHER_TYPE_IPv6 ||
+				    ether_type == ETHER_TYPE_ARP ||
+				    ether_type == outer_tpid) {
+					rte_flow_error_set(error, EINVAL,
+						     RTE_FLOW_ERROR_TYPE_ITEM,
+						     item,
+						     "Unsupported inner_type.");
+					return -rte_errno;
+				}
+				input_set |= I40E_INSET_LAST_ETHER_TYPE;
+				filter->input.flow.l2_flow.ether_type =
+					vlan_spec->inner_type;
+			}
 
 			pctype = I40E_FILTER_PCTYPE_L2_PAYLOAD;
 			layer_idx = I40E_FLXPLD_L2_IDX;
@@ -3285,7 +3324,8 @@ i40e_flow_parse_vxlan_pattern(__rte_unused struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
-			if (!(vlan_spec && vlan_mask)) {
+			if (!(vlan_spec && vlan_mask) ||
+			    vlan_mask->inner_type) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ITEM,
 						   item,
@@ -3515,7 +3555,8 @@ i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
-			if (!(vlan_spec && vlan_mask)) {
+			if (!(vlan_spec && vlan_mask) ||
+			    vlan_mask->inner_type) {
 				rte_flow_error_set(error, EINVAL,
 						   RTE_FLOW_ERROR_TYPE_ITEM,
 						   item,
@@ -4023,7 +4064,8 @@ i40e_flow_parse_qinq_pattern(__rte_unused struct rte_eth_dev *dev,
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
 
-			if (!(vlan_spec && vlan_mask)) {
+			if (!(vlan_spec && vlan_mask) ||
+			    vlan_mask->inner_type) {
 				rte_flow_error_set(error, EINVAL,
 					   RTE_FLOW_ERROR_TYPE_ITEM,
 					   item,
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index c00bdae3d..98a78755d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -115,7 +115,6 @@
 
 #define IXGBE_VT_CTL_POOLING_MODE_MASK         0x00030000
 #define IXGBE_VT_CTL_POOLING_MODE_ETAG         0x00010000
-#define DEFAULT_ETAG_ETYPE                     0x893f
 #define IXGBE_ETAG_ETYPE                       0x00005084
 #define IXGBE_ETAG_ETYPE_MASK                  0x0000ffff
 #define IXGBE_ETAG_ETYPE_VALID                 0x80000000
@@ -1488,7 +1487,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
 	}
 	l2_tn_info->e_tag_en = FALSE;
 	l2_tn_info->e_tag_fwd_en = FALSE;
-	l2_tn_info->e_tag_ether_type = DEFAULT_ETAG_ETYPE;
+	l2_tn_info->e_tag_ether_type = ETHER_TYPE_ETAG;
 
 	return 0;
 }
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index cf38ceaa1..d77598b2d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -18,6 +18,7 @@
 #endif
 
 #include <rte_common.h>
+#include <rte_ether.h>
 #include <rte_eth_ctrl.h>
 #include <rte_ethdev_driver.h>
 #include <rte_flow.h>
@@ -306,6 +307,7 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
 		.actions = valid_actions,
 		.mask = &(const struct rte_flow_item_vlan){
 			.tci = -1,
+			.inner_type = -1,
 		},
 		.default_mask = &rte_flow_item_vlan_mask,
 		.mask_sz = sizeof(struct rte_flow_item_vlan),
@@ -1295,6 +1297,7 @@ mlx5_flow_create_vlan(const struct rte_flow_item *item,
 	struct mlx5_flow_parse *parser = data->parser;
 	struct ibv_flow_spec_eth *eth;
 	const unsigned int eth_size = sizeof(struct ibv_flow_spec_eth);
+	const char *msg = "VLAN cannot be empty";
 
 	if (spec) {
 		unsigned int i;
@@ -1316,12 +1319,20 @@ mlx5_flow_create_vlan(const struct rte_flow_item *item,
 			 */
 			if (!eth->mask.vlan_tag)
 				goto error;
+			/* Outer TPID cannot be matched. */
+			if (eth->mask.ether_type) {
+				msg = "VLAN TPID matching is not supported";
+				goto error;
+			}
+			eth->val.ether_type = spec->inner_type;
+			eth->mask.ether_type = mask->inner_type;
+			eth->val.ether_type &= eth->mask.ether_type;
 		}
 		return 0;
 	}
 error:
 	return rte_flow_error_set(data->error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
-				  item, "VLAN cannot be empty");
+				  item, msg);
 }
 
 /**
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
index 8fd4dbfb1..6478eb2fe 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -1091,12 +1091,6 @@ mrvl_parse_vlan(const struct rte_flow_item *item,
 	if (ret)
 		return ret;
 
-	if (mask->tpid) {
-		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
-				   NULL, "Not supported by classifier\n");
-		return -rte_errno;
-	}
-
 	m = rte_be_to_cpu_16(mask->tci);
 	if (m & MRVL_VLAN_ID_MASK) {
 		RTE_LOG(WARNING, PMD, "vlan id mask is ignored\n");
@@ -1112,6 +1106,26 @@ mrvl_parse_vlan(const struct rte_flow_item *item,
 			goto out;
 	}
 
+	if (flow->pattern & F_TYPE) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ITEM, item,
+				   "VLAN TPID matching is not supported\n");
+		return -rte_errno;
+	}
+	if (mask->inner_type) {
+		struct rte_flow_item_eth spec_eth = {
+			.type = spec->inner_type,
+		};
+		struct rte_flow_item_eth mask_eth = {
+			.type = mask->inner_type,
+		};
+
+		RTE_LOG(WARNING, PMD, "inner eth type mask is ignored\n");
+		ret = mrvl_parse_type(spec_eth, mask_eth, flow);
+		if (ret)
+			goto out;
+	}
+
 	return 0;
 out:
 	rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 3028efbf9..cd6a61b39 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -7,6 +7,7 @@
  * for Solarflare) and Solarflare Communications, Inc.
  */
 
+#include <rte_byteorder.h>
 #include <rte_tailq.h>
 #include <rte_common.h>
 #include <rte_ethdev_driver.h>
@@ -351,6 +352,7 @@ sfc_flow_parse_vlan(const struct rte_flow_item *item,
 	const struct rte_flow_item_vlan *mask = NULL;
 	const struct rte_flow_item_vlan supp_mask = {
 		.tci = rte_cpu_to_be_16(ETH_VLAN_ID_MAX),
+		.inner_type = RTE_BE16(0xffff),
 	};
 
 	rc = sfc_flow_parse_init(item,
@@ -393,6 +395,22 @@ sfc_flow_parse_vlan(const struct rte_flow_item *item,
 		return -rte_errno;
 	}
 
+	if (efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM, item,
+				   "VLAN TPID matching is not supported");
+		return -rte_errno;
+	}
+	if (mask->inner_type == supp_mask.inner_type) {
+		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
+		efx_spec->efs_ether_type = rte_bswap16(spec->inner_type);
+	} else if (mask->inner_type) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM, item,
+				   "Bad mask for VLAN inner_type");
+		return -rte_errno;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 7dfaf9ac5..dff09313a 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -270,13 +270,13 @@ static const struct tap_flow_items tap_flow_items[] = {
 		.items = ITEMS(RTE_FLOW_ITEM_TYPE_IPV4,
 			       RTE_FLOW_ITEM_TYPE_IPV6),
 		.mask = &(const struct rte_flow_item_vlan){
-			.tpid = -1,
 			/* DEI matching is not supported */
 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
 			.tci = 0xffef,
 #else
 			.tci = 0xefff,
 #endif
+			.inner_type = -1,
 		},
 		.mask_sz = sizeof(struct rte_flow_item_vlan),
 		.default_mask = &rte_flow_item_vlan_mask,
@@ -578,13 +578,19 @@ tap_flow_create_vlan(const struct rte_flow_item *item, void *data)
 	/* use default mask if none provided */
 	if (!mask)
 		mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_VLAN].default_mask;
-	/* TC does not support tpid masking. Only accept if exact match. */
-	if (mask->tpid && mask->tpid != 0xffff)
+	/* Outer TPID cannot be matched. */
+	if (info->eth_type)
 		return -1;
 	/* Double-tagging not supported. */
-	if (spec && mask->tpid && spec->tpid != htons(ETH_P_8021Q))
+	if (info->vlan)
 		return -1;
 	info->vlan = 1;
+	if (mask->inner_type) {
+		/* TC does not support partial eth_type masking */
+		if (mask->inner_type != RTE_BE16(0xffff))
+			return -1;
+		info->eth_type = spec->inner_type;
+	}
 	if (!flow)
 		return 0;
 	msg = &flow->msg;
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index d0ff26aa3..8e50384d0 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -454,11 +454,17 @@ static const struct rte_flow_item_raw rte_flow_item_raw_mask = {
  * RTE_FLOW_ITEM_TYPE_ETH
  *
  * Matches an Ethernet header.
+ *
+ * The @p type field either stands for "EtherType" or "TPID" when followed
+ * by so-called layer 2.5 pattern items such as RTE_FLOW_ITEM_TYPE_VLAN. In
+ * the latter case, @p type refers to that of the outer header, with the
+ * inner EtherType/TPID provided by the subsequent pattern item. This is the
+ * same order as on the wire.
  */
 struct rte_flow_item_eth {
 	struct ether_addr dst; /**< Destination MAC. */
 	struct ether_addr src; /**< Source MAC. */
-	rte_be16_t type; /**< EtherType. */
+	rte_be16_t type; /**< EtherType or TPID. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */
@@ -475,19 +481,20 @@ static const struct rte_flow_item_eth rte_flow_item_eth_mask = {
  *
  * Matches an 802.1Q/ad VLAN tag.
  *
- * This type normally follows either RTE_FLOW_ITEM_TYPE_ETH or
- * RTE_FLOW_ITEM_TYPE_VLAN.
+ * The corresponding standard outer EtherType (TPID) values are
+ * ETHER_TYPE_VLAN or ETHER_TYPE_QINQ. It can be overridden by the preceding
+ * pattern item.
  */
 struct rte_flow_item_vlan {
-	rte_be16_t tpid; /**< Tag protocol identifier. */
 	rte_be16_t tci; /**< Tag control information. */
+	rte_be16_t inner_type; /**< Inner EtherType or TPID. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */
 #ifndef __cplusplus
 static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = {
-	.tpid = RTE_BE16(0x0000),
 	.tci = RTE_BE16(0xffff),
+	.inner_type = RTE_BE16(0x0000),
 };
 #endif
 
@@ -636,9 +643,11 @@ static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = {
  * RTE_FLOW_ITEM_TYPE_E_TAG.
  *
  * Matches a E-tag header.
+ *
+ * The corresponding standard outer EtherType (TPID) value is
+ * ETHER_TYPE_ETAG. It can be overridden by the preceding pattern item.
  */
 struct rte_flow_item_e_tag {
-	rte_be16_t tpid; /**< Tag protocol identifier (0x893F). */
 	/**
 	 * E-Tag control information (E-TCI).
 	 * E-PCP (3b), E-DEI (1b), ingress E-CID base (12b).
@@ -648,6 +657,7 @@ struct rte_flow_item_e_tag {
 	rte_be16_t rsvd_grp_ecid_b;
 	uint8_t in_ecid_e; /**< Ingress E-CID ext. */
 	uint8_t ecid_e; /**< E-CID ext. */
+	rte_be16_t inner_type; /**< Inner EtherType or TPID. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_E_TAG. */
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 45daa911a..a271d1c86 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -301,6 +301,7 @@ struct vxlan_hdr {
 #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */
 #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
 #define ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */
+#define ETHER_TYPE_ETAG 0x893F /**< IEEE 802.1BR E-Tag. */
 #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */
 #define ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */
 #define ETHER_TYPE_TEB  0x6558 /**< Transparent Ethernet Bridging. */
-- 
2.11.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v6 11/16] ethdev: fix default VLAN TCI mask in flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (7 preceding siblings ...)
  2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API Adrien Mazarguil
@ 2018-04-25 15:27  4%   ` Adrien Mazarguil
  2018-04-25 15:28  8%   ` [dpdk-dev] [PATCH v6 12/16] ethdev: add transfer attribute to " Adrien Mazarguil
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:27 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Wenzhuo Lu, Jingjing Wu, Ajit Khaparde, Somnath Kotur,
	John Daley, Hyong Youb Kim, Beilei Xing, Qi Zhang,
	Konstantin Ananyev, Nelio Laranjeiro, Yongseok Koh,
	Tomasz Duszynski, Dmitri Epshtein, Natalie Samsonov, Jianbo Liu,
	Andrew Rybchenko, Pascal Mazon

VLAN TCI is a 16-bit field broken down as PCP (3b), DEI (1b) and VID (12b).

The default mask used by PMDs for the VLAN pattern when one isn't provided
by the application comprises the entire TCI, which is problematic because
most devices only support VID matching.

This forces applications to always provide a mask limited to the VID part
in order to successfully apply a flow rule with a VLAN pattern item.
Moreover, applications rarely want to match PCP and DEI intentionally.

Given the above and since VID is what is commonly referred to when talking
about VLAN, this commit excludes PCP and DEI from the default mask.

Fixes: 6de5c0f1302c ("ethdev: define default item masks in flow API")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Thomas Monjalon <thomas@monjalon.net>
Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
Cc: Jingjing Wu <jingjing.wu@intel.com>
Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
Cc: Somnath Kotur <somnath.kotur@broadcom.com>
Cc: John Daley <johndale@cisco.com>
Cc: Hyong Youb Kim <hyonkim@cisco.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>
Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Tomasz Duszynski <tdu@semihalf.com>
Cc: Dmitri Epshtein <dima@marvell.com>
Cc: Natalie Samsonov <nsamsono@marvell.com>
Cc: Jianbo Liu <jianbo.liu@arm.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: Pascal Mazon <pascal.mazon@6wind.com>

---

v6 changes:

- Reworded patch title as a "fix" (not candidate for backports) since it
  addresses a flaw in the original API definition.
- Updated API changes section in release notes.

v3 changes:

These changes were previously mistakenly made part of the previous patch
("ethdev: refine TPID handling in flow API") from which they were split
following Andrew's rightful comment [1].

[1] http://dpdk.org/ml/archives/dev/2018-April/095870.html
---
 doc/guides/prog_guide/rte_flow.rst     | 2 +-
 doc/guides/rel_notes/release_18_05.rst | 3 ++-
 lib/librte_ether/rte_flow.h            | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index fd317b48c..c62a80566 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -806,7 +806,7 @@ preceding pattern item.
 
 - ``tci``: tag control information.
 - ``inner_type``: inner EtherType or TPID.
-- Default ``mask`` matches TCI only.
+- Default ``mask`` matches the VID part of TCI only (lower 12 bits).
 
 Item: ``IPV4``
 ^^^^^^^^^^^^^^
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index a980a23ae..9aca8b4c8 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -264,7 +264,8 @@ API Changes
     (``func`` for RSS hash function to apply and ``level`` for the
     encapsulation level).
   * The VLAN pattern item (``struct rte_flow_item_vlan``) was modified to
-    include inner EtherType instead of outer TPID.
+    include inner EtherType instead of outer TPID. Its default mask was also
+    modified to cover the VID part (lower 12 bits) of TCI only.
 
 
 ABI Changes
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 8e50384d0..513734dce 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -493,7 +493,7 @@ struct rte_flow_item_vlan {
 /** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */
 #ifndef __cplusplus
 static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = {
-	.tci = RTE_BE16(0xffff),
+	.tci = RTE_BE16(0x0fff),
 	.inner_type = RTE_BE16(0x0000),
 };
 #endif
-- 
2.11.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v6 12/16] ethdev: add transfer attribute to flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (8 preceding siblings ...)
  2018-04-25 15:27  4%   ` [dpdk-dev] [PATCH v6 11/16] ethdev: fix default VLAN TCI mask " Adrien Mazarguil
@ 2018-04-25 15:28  8%   ` Adrien Mazarguil
  2018-04-25 15:28  4%   ` [dpdk-dev] [PATCH v6 13/16] ethdev: fix behavior of VF/PF in " Adrien Mazarguil
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:28 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev; +Cc: Andrew Rybchenko

This new attribute enables applications to create flow rules that do not
simply match traffic whose origin is specified in the pattern (e.g. some
non-default physical port or VF), but actively affect it by applying the
flow rule at the lowest possible level in the underlying device.

It breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Cc: Andrew Rybchenko <arybchenko@solarflare.com>

---

v6 changes:

Updated API and ABI changes sections in release notes.

v3 changes:

Clarified definition for ingress and egress following Andrew's comment on
subsequent patch.

[1] http://dpdk.org/ml/archives/dev/2018-April/095961.html
---
 app/test-pmd/cmdline_flow.c                 | 11 +++++
 app/test-pmd/config.c                       |  6 ++-
 doc/guides/prog_guide/rte_flow.rst          | 26 +++++++++++-
 doc/guides/rel_notes/release_18_05.rst      |  7 +++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 ++---
 drivers/net/bnxt/bnxt_filter.c              |  8 ++++
 drivers/net/e1000/igb_flow.c                | 44 ++++++++++++++++++++
 drivers/net/enic/enic_flow.c                |  6 +++
 drivers/net/i40e/i40e_flow.c                |  8 ++++
 drivers/net/ixgbe/ixgbe_flow.c              | 53 ++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_flow.c                |  4 ++
 drivers/net/mlx5/mlx5_flow.c                |  7 ++++
 drivers/net/mvpp2/mrvl_flow.c               |  6 +++
 drivers/net/sfc/sfc_flow.c                  |  6 +++
 drivers/net/tap/tap_flow.c                  |  6 +++
 lib/librte_ether/rte_flow.h                 | 22 +++++++++-
 16 files changed, 220 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f8f2a559e..1c6b5a112 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -69,6 +69,7 @@ enum index {
 	PRIORITY,
 	INGRESS,
 	EGRESS,
+	TRANSFER,
 
 	/* Validate/create pattern. */
 	PATTERN,
@@ -407,6 +408,7 @@ static const enum index next_vc_attr[] = {
 	PRIORITY,
 	INGRESS,
 	EGRESS,
+	TRANSFER,
 	PATTERN,
 	ZERO,
 };
@@ -960,6 +962,12 @@ static const struct token token_list[] = {
 		.next = NEXT(next_vc_attr),
 		.call = parse_vc,
 	},
+	[TRANSFER] = {
+		.name = "transfer",
+		.help = "apply rule directly to endpoints found in pattern",
+		.next = NEXT(next_vc_attr),
+		.call = parse_vc,
+	},
 	/* Validate/create pattern. */
 	[PATTERN] = {
 		.name = "pattern",
@@ -1945,6 +1953,9 @@ parse_vc(struct context *ctx, const struct token *token,
 	case EGRESS:
 		out->args.vc.attr.egress = 1;
 		return len;
+	case TRANSFER:
+		out->args.vc.attr.transfer = 1;
+		return len;
 	case PATTERN:
 		out->args.vc.pattern =
 			(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4b121aa79..a06514acc 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1256,6 +1256,7 @@ port_flow_complain(struct rte_flow_error *error)
 		[RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
 		[RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
 		[RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
+		[RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER] = "transfer field",
 		[RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
 		[RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
 		[RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification",
@@ -1521,12 +1522,13 @@ port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])
 		const struct rte_flow_item *item = pf->pattern;
 		const struct rte_flow_action *action = pf->actions;
 
-		printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c\t",
+		printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t",
 		       pf->id,
 		       pf->attr.group,
 		       pf->attr.priority,
 		       pf->attr.ingress ? 'i' : '-',
-		       pf->attr.egress ? 'e' : '-');
+		       pf->attr.egress ? 'e' : '-',
+		       pf->attr.transfer ? 't' : '-');
 		while (item->type != RTE_FLOW_ITEM_TYPE_END) {
 			if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
 				printf("%s ", flow_item[item->type].name);
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index c62a80566..550a4c95b 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -170,7 +170,13 @@ Note that support for more than a single priority level is not guaranteed.
 Attribute: Traffic direction
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Flow rules can apply to inbound and/or outbound traffic (ingress/egress).
+Flow rule patterns apply to inbound and/or outbound traffic.
+
+In the context of this API, **ingress** and **egress** respectively stand
+for **inbound** and **outbound** based on the standpoint of the application
+creating a flow rule.
+
+There are no exceptions to this definition.
 
 Several pattern items and actions are valid and can be used in both
 directions. At least one direction must be specified.
@@ -178,6 +184,24 @@ directions. At least one direction must be specified.
 Specifying both directions at once for a given rule is not recommended but
 may be valid in a few cases (e.g. shared counters).
 
+Attribute: Transfer
+^^^^^^^^^^^^^^^^^^^
+
+Instead of simply matching the properties of traffic as it would appear on a
+given DPDK port ID, enabling this attribute transfers a flow rule to the
+lowest possible level of any device endpoints found in the pattern.
+
+When supported, this effectively enables an application to reroute traffic
+not necessarily intended for it (e.g. coming from or addressed to different
+physical ports, VFs or applications) at the device level.
+
+It complements the behavior of some pattern items such as `Item: PORT`_ and
+is meaningless without them.
+
+When transferring flow rules, **ingress** and **egress** attributes
+(`Attribute: Traffic direction`_) keep their original meaning, as if
+processing traffic emitted or received by the application.
+
 Pattern item
 ~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 9aca8b4c8..635b69aa1 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -266,6 +266,8 @@ API Changes
   * The VLAN pattern item (``struct rte_flow_item_vlan``) was modified to
     include inner EtherType instead of outer TPID. Its default mask was also
     modified to cover the VID part (lower 12 bits) of TCI only.
+  * A new transfer attribute was added to ``struct rte_flow_attr`` in order
+    to clarify the behavior of some pattern items.
 
 
 ABI Changes
@@ -316,8 +318,9 @@ ABI Changes
   of the unused DUP action (``enum rte_flow_action_type``), modified
   behavior for flow rule actions (see API changes), removal of C99 flexible
   array from RAW pattern item (``struct rte_flow_item_raw``), complete
-  rework of the RSS action definition (``struct rte_flow_action_rss``) and
-  sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``).
+  rework of the RSS action definition (``struct rte_flow_action_rss``),
+  sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``) and
+  new transfer attribute (``struct rte_flow_attr``).
 
 
 Removed Items
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 007b24ff3..454157dd4 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2994,14 +2994,14 @@ following sections.
 - Check whether a flow rule can be created::
 
    flow validate {port_id}
-       [group {group_id}] [priority {level}] [ingress] [egress]
+       [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
        pattern {item} [/ {item} [...]] / end
        actions {action} [/ {action} [...]] / end
 
 - Create a flow rule::
 
    flow create {port_id}
-       [group {group_id}] [priority {level}] [ingress] [egress]
+       [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
        pattern {item} [/ {item} [...]] / end
        actions {action} [/ {action} [...]] / end
 
@@ -3034,7 +3034,7 @@ underlying device in its current state but stops short of creating it. It is
 bound to ``rte_flow_validate()``::
 
    flow validate {port_id}
-      [group {group_id}] [priority {level}] [ingress] [egress]
+      [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
       pattern {item} [/ {item} [...]] / end
       actions {action} [/ {action} [...]] / end
 
@@ -3071,7 +3071,7 @@ Creating flow rules
 to ``rte_flow_create()``::
 
    flow create {port_id}
-      [group {group_id}] [priority {level}] [ingress] [egress]
+      [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
       pattern {item} [/ {item} [...]] / end
       actions {action} [/ {action} [...]] / end
 
@@ -3085,7 +3085,7 @@ Otherwise it will show an error message of the form::
 
 Parameters describe in the following order:
 
-- Attributes (*group*, *priority*, *ingress*, *egress* tokens).
+- Attributes (*group*, *priority*, *ingress*, *egress*, *transfer* tokens).
 - A matching pattern, starting with the *pattern* token and terminated by an
   *end* pattern item.
 - Actions, starting with the *actions* token and terminated by an *end*
@@ -3113,6 +3113,7 @@ specified before the ``pattern`` token.
 - ``priority {level}``: priority level within group.
 - ``ingress``: rule applies to ingress traffic.
 - ``egress``: rule applies to egress traffic.
+- ``transfer``: apply rule directly to endpoints found in pattern.
 
 Each instance of an attribute specified several times overrides the previous
 value as shown below (group 4 is used)::
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 25806bdc0..68deb3445 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -754,6 +754,14 @@ bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
+	if (attr->transfer) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index d1c0b4b8d..073852913 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -379,6 +379,15 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	if (attr->priority > 0xFFFF) {
 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
 		rte_flow_error_set(error, EINVAL,
@@ -624,6 +633,14 @@ cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
+	if (attr->transfer) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -923,6 +940,15 @@ cons_parse_syn_filter(const struct rte_flow_attr *attr,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
+		rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	/* Support 2 priorities, the lowest or highest. */
 	if (!attr->priority) {
 		filter->hig_pri = 0;
@@ -1211,6 +1237,15 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
+		rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	if (attr->priority > 0xFFFF) {
 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
 		rte_flow_error_set(error, EINVAL,
@@ -1361,6 +1396,15 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	if (attr->priority > 0xFFFF) {
 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
 		rte_flow_error_set(error, EINVAL,
diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index eea14ee73..525f3dd7c 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -1318,6 +1318,12 @@ enic_flow_parse(struct rte_eth_dev *dev,
 					   NULL,
 					   "egress is not supported");
 			return -rte_errno;
+		} else if (attrs->transfer) {
+			rte_flow_error_set(error, ENOTSUP,
+					   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+					   NULL,
+					   "transfer is not supported");
+			return -rte_errno;
 		} else if (!attrs->ingress) {
 			rte_flow_error_set(error, ENOTSUP,
 					   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index 470ab93d6..f416b6a00 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -1918,6 +1918,14 @@ i40e_flow_parse_attr(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
+	if (attr->transfer) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
index 438bfcdfb..eb0644c82 100644
--- a/drivers/net/ixgbe/ixgbe_flow.c
+++ b/drivers/net/ixgbe/ixgbe_flow.c
@@ -557,6 +557,15 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	if (attr->priority > 0xFFFF) {
 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
 		rte_flow_error_set(error, EINVAL,
@@ -787,6 +796,14 @@ cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
+	if (attr->transfer) {
+		rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -1078,6 +1095,15 @@ cons_parse_syn_filter(const struct rte_flow_attr *attr,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
+		rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	/* Support 2 priorities, the lowest or highest. */
 	if (!attr->priority) {
 		filter->hig_pri = 0;
@@ -1250,6 +1276,15 @@ cons_parse_l2_tn_filter(struct rte_eth_dev *dev,
 	}
 
 	/* not supported */
+	if (attr->transfer) {
+		memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
+		rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* not supported */
 	if (attr->priority) {
 		memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
 		rte_flow_error_set(error, EINVAL,
@@ -1354,6 +1389,15 @@ ixgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr,
 	}
 
 	/* not supported */
+	if (attr->transfer) {
+		memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
+		rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
+	/* not supported */
 	if (attr->priority) {
 		memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
 		rte_flow_error_set(error, EINVAL,
@@ -2829,6 +2873,15 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
 		return -rte_errno;
 	}
 
+	/* not supported */
+	if (attr->transfer) {
+		memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   attr, "No support for transfer.");
+		return -rte_errno;
+	}
+
 	if (attr->priority > 0xFFFF) {
 		memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
 		rte_flow_error_set(error, EINVAL,
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index ce36ac715..e3d7aa8ef 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -652,6 +652,10 @@ mlx4_flow_prepare(struct priv *priv,
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
 			 NULL, "egress is not supported");
+	if (attr->transfer)
+		return rte_flow_error_set
+			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			 NULL, "transfer is not supported");
 	if (!attr->ingress)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index d77598b2d..41a7c6477 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -576,6 +576,13 @@ mlx5_flow_convert_attributes(const struct rte_flow_attr *attr,
 				   "egress is not supported");
 		return -rte_errno;
 	}
+	if (attr->transfer) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+				   NULL,
+				   "transfer is not supported");
+		return -rte_errno;
+	}
 	if (!attr->ingress) {
 		rte_flow_error_set(error, ENOTSUP,
 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
index 6478eb2fe..a2e2129cc 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -2187,6 +2187,12 @@ mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused,
 				   "Egress is not supported");
 		return -rte_errno;
 	}
+	if (attr->transfer) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
+				   "Transfer is not supported");
+		return -rte_errno;
+	}
 
 	return 0;
 }
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index cd6a61b39..bcde2c2f7 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1116,6 +1116,12 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr,
 				   "Egress is not supported");
 		return -rte_errno;
 	}
+	if (attr->transfer != 0) {
+		rte_flow_error_set(error, ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
+				   "Transfer is not supported");
+		return -rte_errno;
+	}
 	if (attr->ingress == 0) {
 		rte_flow_error_set(error, ENOTSUP,
 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr,
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index dff09313a..ad2ba9f4e 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1039,6 +1039,12 @@ priv_flow_process(struct pmd_internals *pmd,
 	};
 	int action = 0; /* Only one action authorized for now */
 
+	if (attr->transfer) {
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+			NULL, "transfer is not supported");
+		return -rte_errno;
+	}
 	if (attr->group > MAX_GROUP) {
 		rte_flow_error_set(
 			error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 513734dce..ab2bf2dce 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -72,7 +72,26 @@ struct rte_flow_attr {
 	uint32_t priority; /**< Priority level within group. */
 	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
 	uint32_t egress:1; /**< Rule applies to egress traffic. */
-	uint32_t reserved:30; /**< Reserved, must be zero. */
+	/**
+	 * Instead of simply matching the properties of traffic as it would
+	 * appear on a given DPDK port ID, enabling this attribute transfers
+	 * a flow rule to the lowest possible level of any device endpoints
+	 * found in the pattern.
+	 *
+	 * When supported, this effectively enables an application to
+	 * re-route traffic not necessarily intended for it (e.g. coming
+	 * from or addressed to different physical ports, VFs or
+	 * applications) at the device level.
+	 *
+	 * It complements the behavior of some pattern items such as
+	 * RTE_FLOW_ITEM_TYPE_PORT and is meaningless without them.
+	 *
+	 * When transferring flow rules, ingress and egress attributes keep
+	 * their original meaning, as if processing traffic emitted or
+	 * received by the application.
+	 */
+	uint32_t transfer:1;
+	uint32_t reserved:29; /**< Reserved, must be zero. */
 };
 
 /**
@@ -1181,6 +1200,7 @@ enum rte_flow_error_type {
 	RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */
 	RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */
 	RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */
+	RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, /**< Transfer field. */
 	RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */
 	RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */
 	RTE_FLOW_ERROR_TYPE_ITEM_SPEC, /**< Item specification. */
-- 
2.11.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v6 13/16] ethdev: fix behavior of VF/PF in flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (9 preceding siblings ...)
  2018-04-25 15:28  8%   ` [dpdk-dev] [PATCH v6 12/16] ethdev: add transfer attribute to " Adrien Mazarguil
@ 2018-04-25 15:28  4%   ` Adrien Mazarguil
  2018-04-25 15:28  6%   ` [dpdk-dev] [PATCH v6 14/16] ethdev: rename physical port item " Adrien Mazarguil
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:28 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev
  Cc: Ajit Khaparde, Somnath Kotur, Beilei Xing, Qi Zhang

Contrary to all other pattern items, these are inconsistently documented as
affecting traffic instead of simply matching its origin, without provision
for the latter.

This commit clarifies documentation and updates PMDs since the original
behavior now has to be explicitly requested using the new transfer
attribute.

It breaks ABI compatibility for the following public functions:

- rte_flow_create()
- rte_flow_validate()

Impacted PMDs are bnxt and i40e, for which the VF pattern item is now only
supported when a transfer attribute is also present.

Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
Cc: Somnath Kotur <somnath.kotur@broadcom.com>
Cc: Beilei Xing <beilei.xing@intel.com>
Cc: Qi Zhang <qi.z.zhang@intel.com>

---

v6 changes:

- Reworded patch title as a "fix" (not candidate for backports) since it
  addresses a flaw in the original API definition.
- Updated API changes section in release notes.
---
 app/test-pmd/cmdline_flow.c                 | 12 +++---
 doc/guides/prog_guide/rte_flow.rst          | 36 +++++++++---------
 doc/guides/rel_notes/release_18_05.rst      |  3 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 +++---
 drivers/net/bnxt/bnxt_filter.c              | 22 ++++++-----
 drivers/net/i40e/i40e_flow.c                | 23 +++++++-----
 lib/librte_ether/rte_flow.h                 | 47 ++++++++++--------------
 7 files changed, 80 insertions(+), 75 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1c6b5a112..41103de67 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -1041,21 +1041,21 @@ static const struct token token_list[] = {
 	},
 	[ITEM_PF] = {
 		.name = "pf",
-		.help = "match packets addressed to the physical function",
+		.help = "match traffic from/to the physical function",
 		.priv = PRIV_ITEM(PF, 0),
 		.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
 		.call = parse_vc,
 	},
 	[ITEM_VF] = {
 		.name = "vf",
-		.help = "match packets addressed to a virtual function ID",
+		.help = "match traffic from/to a virtual function ID",
 		.priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
 		.next = NEXT(item_vf),
 		.call = parse_vc,
 	},
 	[ITEM_VF_ID] = {
 		.name = "id",
-		.help = "destination VF ID",
+		.help = "VF ID",
 		.next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
 	},
@@ -1686,14 +1686,14 @@ static const struct token token_list[] = {
 	},
 	[ACTION_PF] = {
 		.name = "pf",
-		.help = "redirect packets to physical device function",
+		.help = "direct traffic to physical function",
 		.priv = PRIV_ACTION(PF, 0),
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
 	[ACTION_VF] = {
 		.name = "vf",
-		.help = "redirect packets to virtual device function",
+		.help = "direct traffic to a virtual function ID",
 		.priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
 		.next = NEXT(action_vf),
 		.call = parse_vc,
@@ -1708,7 +1708,7 @@ static const struct token token_list[] = {
 	},
 	[ACTION_VF_ID] = {
 		.name = "id",
-		.help = "VF ID to redirect packets to",
+		.help = "VF ID",
 		.next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
 		.call = parse_vc_conf,
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 550a4c95b..a0a124aa2 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -528,15 +528,12 @@ Usage example, matching non-TCPv4 packets only:
 Item: ``PF``
 ^^^^^^^^^^^^
 
-Matches packets addressed to the physical function of the device.
+Matches traffic originating from (ingress) or going to (egress) the physical
+function of the current device.
 
-If the underlying device function differs from the one that would normally
-receive the matched traffic, specifying this item prevents it from reaching
-that device unless the flow rule contains a `Action: PF`_. Packets are not
-duplicated between device instances by default.
+If supported, should work even if the physical function is not managed by
+the application and thus not associated with a DPDK port ID.
 
-- Likely to return an error or never match any traffic if applied to a VF
-  device.
 - Can be combined with any number of `Item: VF`_ to match both PF and VF
   traffic.
 - ``spec``, ``last`` and ``mask`` must not be set.
@@ -558,15 +555,15 @@ duplicated between device instances by default.
 Item: ``VF``
 ^^^^^^^^^^^^
 
-Matches packets addressed to a virtual function ID of the device.
+Matches traffic originating from (ingress) or going to (egress) a given
+virtual function of the current device.
 
-If the underlying device function differs from the one that would normally
-receive the matched traffic, specifying this item prevents it from reaching
-that device unless the flow rule contains a `Action: VF`_. Packets are not
-duplicated between device instances by default.
+If supported, should work even if the virtual function is not managed by the
+application and thus not associated with a DPDK port ID.
+
+Note this pattern item does not match VF representors traffic which, as
+separate entities, should be addressed through their own DPDK port IDs.
 
-- Likely to return an error or never match any traffic if this causes a VF
-  device to match traffic addressed to a different VF.
 - Can be specified multiple times to match traffic addressed to several VF
   IDs.
 - Can be combined with a PF item to match both PF and VF traffic.
@@ -1395,7 +1392,10 @@ only matching traffic goes through.
 Action: ``PF``
 ^^^^^^^^^^^^^^
 
-Redirects packets to the physical function (PF) of the current device.
+Directs matching traffic to the physical function (PF) of the current
+device.
+
+See `Item: PF`_.
 
 - No configurable properties.
 
@@ -1412,13 +1412,15 @@ Redirects packets to the physical function (PF) of the current device.
 Action: ``VF``
 ^^^^^^^^^^^^^^
 
-Redirects packets to a virtual function (VF) of the current device.
+Directs matching traffic to a given virtual function of the current device.
 
 Packets matched by a VF pattern item can be redirected to their original VF
 ID instead of the specified one. This parameter may not be available and is
 not guaranteed to work properly if the VF part is matched by a prior flow
 rule or if packets are not addressed to a VF in the first place.
 
+See `Item: VF`_.
+
 .. _table_rte_flow_action_vf:
 
 .. table:: VF
@@ -1428,7 +1430,7 @@ rule or if packets are not addressed to a VF in the first place.
    +==============+================================+
    | ``original`` | use original VF ID if possible |
    +--------------+--------------------------------+
-   | ``vf``       | VF ID to redirect packets to   |
+   | ``id``       | VF ID                          |
    +--------------+--------------------------------+
 
 Action: ``METER``
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 635b69aa1..ea133971f 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -268,6 +268,9 @@ API Changes
     modified to cover the VID part (lower 12 bits) of TCI only.
   * A new transfer attribute was added to ``struct rte_flow_attr`` in order
     to clarify the behavior of some pattern items.
+  * PF and VF pattern items are now only accepted by PMDs that implement
+    them (bnxt and i40e) when the transfer attribute is also present for
+    consistency.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 454157dd4..396a0599a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3226,11 +3226,11 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``num {unsigned}``: number of layers covered.
 
-- ``pf``: match packets addressed to the physical function.
+- ``pf``: match traffic from/to the physical function.
 
-- ``vf``: match packets addressed to a virtual function ID.
+- ``vf``: match traffic from/to a virtual function ID.
 
-  - ``id {unsigned}``: destination VF ID.
+  - ``id {unsigned}``: VF ID.
 
 - ``port``: device-specific physical port index to use.
 
@@ -3440,12 +3440,12 @@ This section lists supported actions and their attributes, if any.
 
   - ``queues [{unsigned} [...]] end``: queue indices to use.
 
-- ``pf``: redirect packets to physical device function.
+- ``pf``: direct traffic to physical function.
 
-- ``vf``: redirect packets to virtual device function.
+- ``vf``: direct traffic to a virtual function ID.
 
   - ``original {boolean}``: use original VF ID if possible.
-  - ``id {unsigned}``: VF ID to redirect packets to.
+  - ``id {unsigned}``: VF ID.
 
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 68deb3445..dadd1e32f 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -283,6 +283,7 @@ bnxt_filter_type_check(const struct rte_flow_item pattern[],
 
 static int
 bnxt_validate_and_parse_flow_type(struct bnxt *bp,
+				  const struct rte_flow_attr *attr,
 				  const struct rte_flow_item pattern[],
 				  struct rte_flow_error *error,
 				  struct bnxt_filter_info *filter)
@@ -707,6 +708,16 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp,
 				return -rte_errno;
 			}
 
+			if (!attr->transfer) {
+				rte_flow_error_set(error, ENOTSUP,
+					   RTE_FLOW_ERROR_TYPE_ITEM,
+					   item,
+					   "Matching VF traffic without"
+					   " affecting it (transfer attribute)"
+					   " is unsupported");
+				return -rte_errno;
+			}
+
 			filter->mirror_vnic_id =
 			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
 			if (dflt_vnic < 0) {
@@ -754,14 +765,6 @@ bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
-	if (attr->transfer) {
-		rte_flow_error_set(error, EINVAL,
-				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
-				   attr, "No support for transfer.");
-		return -rte_errno;
-	}
-
-	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -841,7 +844,8 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
 		goto ret;
 	}
 
-	rc = bnxt_validate_and_parse_flow_type(bp, pattern, error, filter);
+	rc = bnxt_validate_and_parse_flow_type(bp, attr, pattern, error,
+					       filter);
 	if (rc != 0)
 		goto ret;
 
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index f416b6a00..057e4f96d 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -54,6 +54,7 @@ static int i40e_flow_parse_ethertype_action(struct rte_eth_dev *dev,
 				    struct rte_flow_error *error,
 				    struct rte_eth_ethertype_filter *filter);
 static int i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
+					const struct rte_flow_attr *attr,
 					const struct rte_flow_item *pattern,
 					struct rte_flow_error *error,
 					struct i40e_fdir_filter_conf *filter);
@@ -1918,14 +1919,6 @@ i40e_flow_parse_attr(const struct rte_flow_attr *attr,
 	}
 
 	/* Not supported */
-	if (attr->transfer) {
-		rte_flow_error_set(error, EINVAL,
-				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
-				   attr, "No support for transfer.");
-		return -rte_errno;
-	}
-
-	/* Not supported */
 	if (attr->priority) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -2429,6 +2422,7 @@ i40e_flow_fdir_get_pctype_value(struct i40e_pf *pf,
  */
 static int
 i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
+			     const struct rte_flow_attr *attr,
 			     const struct rte_flow_item *pattern,
 			     struct rte_flow_error *error,
 			     struct i40e_fdir_filter_conf *filter)
@@ -2966,6 +2960,16 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 			break;
 		case RTE_FLOW_ITEM_TYPE_VF:
 			vf_spec = item->spec;
+			if (!attr->transfer) {
+				rte_flow_error_set(error, ENOTSUP,
+						   RTE_FLOW_ERROR_TYPE_ITEM,
+						   item,
+						   "Matching VF traffic"
+						   " without affecting it"
+						   " (transfer attribute)"
+						   " is unsupported");
+				return -rte_errno;
+			}
 			filter->input.flow_ext.is_vf = 1;
 			filter->input.flow_ext.dst_id = vf_spec->id;
 			if (filter->input.flow_ext.is_vf &&
@@ -3128,7 +3132,8 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 		&filter->fdir_filter;
 	int ret;
 
-	ret = i40e_flow_parse_fdir_pattern(dev, pattern, error, fdir_filter);
+	ret = i40e_flow_parse_fdir_pattern(dev, attr, pattern, error,
+					   fdir_filter);
 	if (ret)
 		return ret;
 
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index ab2bf2dce..f1c7a664e 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -152,13 +152,8 @@ enum rte_flow_item_type {
 	/**
 	 * [META]
 	 *
-	 * Matches packets addressed to the physical function of the device.
-	 *
-	 * If the underlying device function differs from the one that would
-	 * normally receive the matched traffic, specifying this item
-	 * prevents it from reaching that device unless the flow rule
-	 * contains a PF action. Packets are not duplicated between device
-	 * instances by default.
+	 * Matches traffic originating from (ingress) or going to (egress)
+	 * the physical function of the current device.
 	 *
 	 * No associated specification structure.
 	 */
@@ -167,13 +162,8 @@ enum rte_flow_item_type {
 	/**
 	 * [META]
 	 *
-	 * Matches packets addressed to a virtual function ID of the device.
-	 *
-	 * If the underlying device function differs from the one that would
-	 * normally receive the matched traffic, specifying this item
-	 * prevents it from reaching that device unless the flow rule
-	 * contains a VF action. Packets are not duplicated between device
-	 * instances by default.
+	 * Matches traffic originating from (ingress) or going to (egress) a
+	 * given virtual function of the current device.
 	 *
 	 * See struct rte_flow_item_vf.
 	 */
@@ -371,15 +361,15 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
 /**
  * RTE_FLOW_ITEM_TYPE_VF
  *
- * Matches packets addressed to a virtual function ID of the device.
+ * Matches traffic originating from (ingress) or going to (egress) a given
+ * virtual function of the current device.
  *
- * If the underlying device function differs from the one that would
- * normally receive the matched traffic, specifying this item prevents it
- * from reaching that device unless the flow rule contains a VF
- * action. Packets are not duplicated between device instances by default.
+ * If supported, should work even if the virtual function is not managed by
+ * the application and thus not associated with a DPDK port ID.
+ *
+ * Note this pattern item does not match VF representors traffic which, as
+ * separate entities, should be addressed through their own DPDK port IDs.
  *
- * - Likely to return an error or never match any traffic if this causes a
- *   VF device to match traffic addressed to a different VF.
  * - Can be specified multiple times to match traffic addressed to several
  *   VF IDs.
  * - Can be combined with a PF item to match both PF and VF traffic.
@@ -387,7 +377,7 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
  * A zeroed mask can be used to match any VF ID.
  */
 struct rte_flow_item_vf {
-	uint32_t id; /**< Destination VF ID. */
+	uint32_t id; /**< VF ID. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_VF. */
@@ -988,16 +978,16 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_RSS,
 
 	/**
-	 * Redirects packets to the physical function (PF) of the current
-	 * device.
+	 * Directs matching traffic to the physical function (PF) of the
+	 * current device.
 	 *
 	 * No associated configuration structure.
 	 */
 	RTE_FLOW_ACTION_TYPE_PF,
 
 	/**
-	 * Redirects packets to the virtual function (VF) of the current
-	 * device with the specified ID.
+	 * Directs matching traffic to a given virtual function of the
+	 * current device.
 	 *
 	 * See struct rte_flow_action_vf.
 	 */
@@ -1111,7 +1101,8 @@ struct rte_flow_action_rss {
 /**
  * RTE_FLOW_ACTION_TYPE_VF
  *
- * Redirects packets to a virtual function (VF) of the current device.
+ * Directs matching traffic to a given virtual function of the current
+ * device.
  *
  * Packets matched by a VF pattern item can be redirected to their original
  * VF ID instead of the specified one. This parameter may not be available
@@ -1122,7 +1113,7 @@ struct rte_flow_action_rss {
 struct rte_flow_action_vf {
 	uint32_t original:1; /**< Use original VF ID if possible. */
 	uint32_t reserved:31; /**< Reserved, must be zero. */
-	uint32_t id; /**< VF ID to redirect packets to. */
+	uint32_t id; /**< VF ID. */
 };
 
 /**
-- 
2.11.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v6 14/16] ethdev: rename physical port item in flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (10 preceding siblings ...)
  2018-04-25 15:28  4%   ` [dpdk-dev] [PATCH v6 13/16] ethdev: fix behavior of VF/PF in " Adrien Mazarguil
@ 2018-04-25 15:28  6%   ` Adrien Mazarguil
  2018-04-25 15:28  7%   ` [dpdk-dev] [PATCH v6 15/16] ethdev: add physical port action to " Adrien Mazarguil
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:28 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev

While RTE_FLOW_ITEM_TYPE_PORT refers to physical ports of the underlying
device using specific identifiers, these are often confused with DPDK port
IDs exposed to applications in the global name space.

Since this pattern item is seldom used, rename it RTE_FLOW_ITEM_PHY_PORT
for better clarity.

No ABI impact.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

---

v6 changes:

Updated API changes section in release notes.
---
 app/test-pmd/cmdline_flow.c                 | 27 +++++++++++----------
 app/test-pmd/config.c                       |  2 +-
 doc/guides/prog_guide/rte_flow.rst          | 22 ++++++++---------
 doc/guides/rel_notes/release_18_05.rst      |  2 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 lib/librte_ether/rte_flow.c                 |  2 +-
 lib/librte_ether/rte_flow.h                 | 31 ++++++++++--------------
 7 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 41103de67..f9f937277 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -87,8 +87,8 @@ enum index {
 	ITEM_PF,
 	ITEM_VF,
 	ITEM_VF_ID,
-	ITEM_PORT,
-	ITEM_PORT_INDEX,
+	ITEM_PHY_PORT,
+	ITEM_PHY_PORT_INDEX,
 	ITEM_RAW,
 	ITEM_RAW_RELATIVE,
 	ITEM_RAW_SEARCH,
@@ -441,7 +441,7 @@ static const enum index next_item[] = {
 	ITEM_ANY,
 	ITEM_PF,
 	ITEM_VF,
-	ITEM_PORT,
+	ITEM_PHY_PORT,
 	ITEM_RAW,
 	ITEM_ETH,
 	ITEM_VLAN,
@@ -482,8 +482,8 @@ static const enum index item_vf[] = {
 	ZERO,
 };
 
-static const enum index item_port[] = {
-	ITEM_PORT_INDEX,
+static const enum index item_phy_port[] = {
+	ITEM_PHY_PORT_INDEX,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -1059,18 +1059,19 @@ static const struct token token_list[] = {
 		.next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
 	},
-	[ITEM_PORT] = {
-		.name = "port",
-		.help = "device-specific physical port index to use",
-		.priv = PRIV_ITEM(PORT, sizeof(struct rte_flow_item_port)),
-		.next = NEXT(item_port),
+	[ITEM_PHY_PORT] = {
+		.name = "phy_port",
+		.help = "match traffic from/to a specific physical port",
+		.priv = PRIV_ITEM(PHY_PORT,
+				  sizeof(struct rte_flow_item_phy_port)),
+		.next = NEXT(item_phy_port),
 		.call = parse_vc,
 	},
-	[ITEM_PORT_INDEX] = {
+	[ITEM_PHY_PORT_INDEX] = {
 		.name = "index",
 		.help = "physical port index",
-		.next = NEXT(item_port, NEXT_ENTRY(UNSIGNED), item_param),
-		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port, index)),
+		.next = NEXT(item_phy_port, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
 	},
 	[ITEM_RAW] = {
 		.name = "raw",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index a06514acc..d168e515d 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -993,7 +993,7 @@ static const struct {
 	MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
-	MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
+	MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
 	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a0a124aa2..4e053c24b 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -195,8 +195,8 @@ When supported, this effectively enables an application to reroute traffic
 not necessarily intended for it (e.g. coming from or addressed to different
 physical ports, VFs or applications) at the device level.
 
-It complements the behavior of some pattern items such as `Item: PORT`_ and
-is meaningless without them.
+It complements the behavior of some pattern items such as `Item: PHY_PORT`_
+and is meaningless without them.
 
 When transferring flow rules, **ingress** and **egress** attributes
 (`Attribute: Traffic direction`_) keep their original meaning, as if
@@ -583,15 +583,15 @@ separate entities, should be addressed through their own DPDK port IDs.
    | ``mask`` | ``id``   | zeroed to match any VF ID |
    +----------+----------+---------------------------+
 
-Item: ``PORT``
-^^^^^^^^^^^^^^
+Item: ``PHY_PORT``
+^^^^^^^^^^^^^^^^^^
 
-Matches packets coming from the specified physical port of the underlying
-device.
+Matches traffic originating from (ingress) or going to (egress) a physical
+port of the underlying device.
 
-The first PORT item overrides the physical port normally associated with the
-specified DPDK input port (port_id). This item can be provided several times
-to match additional physical ports.
+The first PHY_PORT item overrides the physical port normally associated with
+the specified DPDK input port (port_id). This item can be provided several
+times to match additional physical ports.
 
 Note that physical ports are not necessarily tied to DPDK input ports
 (port_id) when those are not under DPDK control. Possible values are
@@ -603,9 +603,9 @@ associated with a port_id should be retrieved by other means.
 
 - Default ``mask`` matches any port index.
 
-.. _table_rte_flow_item_port:
+.. _table_rte_flow_item_phy_port:
 
-.. table:: PORT
+.. table:: PHY_PORT
 
    +----------+-----------+--------------------------------+
    | Field    | Subfield  | Value                          |
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index ea133971f..86dd710d2 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -271,6 +271,8 @@ API Changes
   * PF and VF pattern items are now only accepted by PMDs that implement
     them (bnxt and i40e) when the transfer attribute is also present for
     consistency.
+  * Pattern item PORT was renamed PHY_PORT to avoid confusion with DPDK port
+    IDs.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 396a0599a..51d36d346 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3232,7 +3232,7 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``id {unsigned}``: VF ID.
 
-- ``port``: device-specific physical port index to use.
+- ``phy_port``: match traffic from/to a specific physical port.
 
   - ``index {unsigned}``: physical port index.
 
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 83b733ff0..36e277a4f 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -38,7 +38,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
-	MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
+	MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
 	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index f1c7a664e..2c7c4d009 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -84,7 +84,7 @@ struct rte_flow_attr {
 	 * applications) at the device level.
 	 *
 	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PORT and is meaningless without them.
+	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
 	 *
 	 * When transferring flow rules, ingress and egress attributes keep
 	 * their original meaning, as if processing traffic emitted or
@@ -172,17 +172,12 @@ enum rte_flow_item_type {
 	/**
 	 * [META]
 	 *
-	 * Matches packets coming from the specified physical port of the
-	 * underlying device.
-	 *
-	 * The first PORT item overrides the physical port normally
-	 * associated with the specified DPDK input port (port_id). This
-	 * item can be provided several times to match additional physical
-	 * ports.
+	 * Matches traffic originating from (ingress) or going to (egress) a
+	 * physical port of the underlying device.
 	 *
-	 * See struct rte_flow_item_port.
+	 * See struct rte_flow_item_phy_port.
 	 */
-	RTE_FLOW_ITEM_TYPE_PORT,
+	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
 	 * Matches a byte string of a given length at a given offset.
@@ -388,13 +383,13 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
 #endif
 
 /**
- * RTE_FLOW_ITEM_TYPE_PORT
+ * RTE_FLOW_ITEM_TYPE_PHY_PORT
  *
- * Matches packets coming from the specified physical port of the underlying
- * device.
+ * Matches traffic originating from (ingress) or going to (egress) a
+ * physical port of the underlying device.
  *
- * The first PORT item overrides the physical port normally associated with
- * the specified DPDK input port (port_id). This item can be provided
+ * The first PHY_PORT item overrides the physical port normally associated
+ * with the specified DPDK input port (port_id). This item can be provided
  * several times to match additional physical ports.
  *
  * Note that physical ports are not necessarily tied to DPDK input ports
@@ -407,13 +402,13 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
  *
  * A zeroed mask can be used to match any port index.
  */
-struct rte_flow_item_port {
+struct rte_flow_item_phy_port {
 	uint32_t index; /**< Physical port index. */
 };
 
-/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */
+/** Default mask for RTE_FLOW_ITEM_TYPE_PHY_PORT. */
 #ifndef __cplusplus
-static const struct rte_flow_item_port rte_flow_item_port_mask = {
+static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 	.index = 0x00000000,
 };
 #endif
-- 
2.11.0

^ permalink raw reply	[relevance 6%]

* [dpdk-dev] [PATCH v6 15/16] ethdev: add physical port action to flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (11 preceding siblings ...)
  2018-04-25 15:28  6%   ` [dpdk-dev] [PATCH v6 14/16] ethdev: rename physical port item " Adrien Mazarguil
@ 2018-04-25 15:28  7%   ` Adrien Mazarguil
  2018-04-25 15:28  5%   ` [dpdk-dev] [PATCH v6 16/16] ethdev: add port ID item and " Adrien Mazarguil
  2018-04-25 17:34  0%   ` [dpdk-dev] [PATCH v6 00/16] Flow API overhaul for switch offloads Ferruh Yigit
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:28 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev; +Cc: Zhang, Qi Z

This patch adds the missing action counterpart to the PHY_PORT pattern
item, that is, the ability to directly inject matching traffic into a
physical port of the underlying device.

It breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Cc: "Zhang, Qi Z" <qi.z.zhang@intel.com>

---

v6 changes:

Updated API changes section in release notes.
---
 app/test-pmd/cmdline_flow.c                 | 35 ++++++++++++++++++++++++
 app/test-pmd/config.c                       |  1 +
 doc/guides/prog_guide/rte_flow.rst          | 20 ++++++++++++++
 doc/guides/rel_notes/release_18_05.rst      |  2 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 ++++
 lib/librte_ether/rte_flow.c                 |  1 +
 lib/librte_ether/rte_flow.h                 | 22 +++++++++++++++
 7 files changed, 86 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f9f937277..356714801 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -182,6 +182,9 @@ enum index {
 	ACTION_VF,
 	ACTION_VF_ORIGINAL,
 	ACTION_VF_ID,
+	ACTION_PHY_PORT,
+	ACTION_PHY_PORT_ORIGINAL,
+	ACTION_PHY_PORT_INDEX,
 	ACTION_METER,
 	ACTION_METER_ID,
 };
@@ -623,6 +626,7 @@ static const enum index next_action[] = {
 	ACTION_RSS,
 	ACTION_PF,
 	ACTION_VF,
+	ACTION_PHY_PORT,
 	ACTION_METER,
 	ZERO,
 };
@@ -657,6 +661,13 @@ static const enum index action_vf[] = {
 	ZERO,
 };
 
+static const enum index action_phy_port[] = {
+	ACTION_PHY_PORT_ORIGINAL,
+	ACTION_PHY_PORT_INDEX,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_meter[] = {
 	ACTION_METER_ID,
 	ACTION_NEXT,
@@ -1714,6 +1725,30 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_PHY_PORT] = {
+		.name = "phy_port",
+		.help = "direct packets to physical port index",
+		.priv = PRIV_ACTION(PHY_PORT,
+				    sizeof(struct rte_flow_action_phy_port)),
+		.next = NEXT(action_phy_port),
+		.call = parse_vc,
+	},
+	[ACTION_PHY_PORT_ORIGINAL] = {
+		.name = "original",
+		.help = "use original port index if possible",
+		.next = NEXT(action_phy_port, NEXT_ENTRY(BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_phy_port,
+					   original, 1)),
+		.call = parse_vc_conf,
+	},
+	[ACTION_PHY_PORT_INDEX] = {
+		.name = "index",
+		.help = "physical port index",
+		.next = NEXT(action_phy_port, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_phy_port,
+					index)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_METER] = {
 		.name = "meter",
 		.help = "meter the directed packets at given id",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index d168e515d..869c6663b 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1091,6 +1091,7 @@ static const struct {
 	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+	MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
 	MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
 };
 
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 4e053c24b..a39c1e1b0 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1433,6 +1433,26 @@ See `Item: VF`_.
    | ``id``       | VF ID                          |
    +--------------+--------------------------------+
 
+Action: ``PHY_PORT``
+^^^^^^^^^^^^^^^^^^^^
+
+Directs matching traffic to a given physical port index of the underlying
+device.
+
+See `Item: PHY_PORT`_.
+
+.. _table_rte_flow_action_phy_port:
+
+.. table:: PHY_PORT
+
+   +--------------+-------------------------------------+
+   | Field        | Value                               |
+   +==============+=====================================+
+   | ``original`` | use original port index if possible |
+   +--------------+-------------------------------------+
+   | ``index``    | physical port index                 |
+   +--------------+-------------------------------------+
+
 Action: ``METER``
 ^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 86dd710d2..211f68da1 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -273,6 +273,8 @@ API Changes
     consistency.
   * Pattern item PORT was renamed PHY_PORT to avoid confusion with DPDK port
     IDs.
+  * An action counterpart to the PHY_PORT pattern item was added in order to
+    redirect matching traffic to a specific physical port.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 51d36d346..9733a7262 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3447,6 +3447,11 @@ This section lists supported actions and their attributes, if any.
   - ``original {boolean}``: use original VF ID if possible.
   - ``id {unsigned}``: VF ID.
 
+- ``phy_port``: direct packets to physical port index.
+
+  - ``original {boolean}``: use original port index if possible.
+  - ``index {unsigned}``: physical port index.
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 36e277a4f..00989c73b 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -76,6 +76,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+	MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
 };
 
 static int
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 2c7c4d009..58b75e934 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -989,6 +989,14 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VF,
 
 	/**
+	 * Directs packets to a given physical port index of the underlying
+	 * device.
+	 *
+	 * See struct rte_flow_action_phy_port.
+	 */
+	RTE_FLOW_ACTION_TYPE_PHY_PORT,
+
+	/**
 	 * Traffic metering and policing (MTR).
 	 *
 	 * See struct rte_flow_action_meter.
@@ -1112,6 +1120,20 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * RTE_FLOW_ACTION_TYPE_PHY_PORT
+ *
+ * Directs packets to a given physical port index of the underlying
+ * device.
+ *
+ * @see RTE_FLOW_ITEM_TYPE_PHY_PORT
+ */
+struct rte_flow_action_phy_port {
+	uint32_t original:1; /**< Use original port index if possible. */
+	uint32_t reserved:31; /**< Reserved, must be zero. */
+	uint32_t index; /**< Physical port index. */
+};
+
+/**
  * RTE_FLOW_ACTION_TYPE_METER
  *
  * Traffic metering and policing (MTR).
-- 
2.11.0

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v6 16/16] ethdev: add port ID item and action to flow API
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (12 preceding siblings ...)
  2018-04-25 15:28  7%   ` [dpdk-dev] [PATCH v6 15/16] ethdev: add physical port action to " Adrien Mazarguil
@ 2018-04-25 15:28  5%   ` Adrien Mazarguil
  2018-04-25 17:34  0%   ` [dpdk-dev] [PATCH v6 00/16] Flow API overhaul for switch offloads Ferruh Yigit
  14 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-04-25 15:28 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, dev; +Cc: Zhang, Qi Z, Declan Doherty

RTE_FLOW_ACTION_TYPE_PORT_ID brings the ability to inject matching traffic
into a different device, as identified by its DPDK port ID.

This is normally only supported when the target port ID has some kind of
relationship with the port ID the flow rule is created against, such as
being exposed by a common physical device (e.g. a different port of an
Ethernet switch).

The converse pattern item, RTE_FLOW_ITEM_TYPE_PORT_ID, makes the resulting
flow rule match traffic whose origin is the specified port ID. Note that
specifying a port ID that differs from the one the flow rule is created
against is normally meaningless (if even accepted), but can make sense if
combined with the transfer attribute.

These must not be confused with their PHY_PORT counterparts, which refer to
physical ports using device-specific indices, but unlike PORT_ID are not
necessarily tied to DPDK port IDs.

This breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Cc: "Zhang, Qi Z" <qi.z.zhang@intel.com>
Cc: Declan Doherty <declan.doherty@intel.com>

---

v6 changes:

Updated API changes section in release notes.

v1:

This patch provides the same functionality and supersedes Qi Zhang's
"ether: add flow action to redirect packet to a port" [1].

The main differences are:

- Action is named PORT_ID instead of PORT.
- Addition of a PORT_ID pattern item.
- More extensive documentation.
- Testpmd support.
- rte_flow_copy() support.

[1] http://dpdk.org/ml/archives/dev/2018-April/094648.html
---
 app/test-pmd/cmdline_flow.c                 | 57 ++++++++++++++++++++++++
 app/test-pmd/config.c                       |  2 +
 doc/guides/prog_guide/rte_flow.rst          | 48 ++++++++++++++++++++
 doc/guides/rel_notes/release_18_05.rst      |  2 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  9 ++++
 lib/librte_ether/rte_flow.c                 |  2 +
 lib/librte_ether/rte_flow.h                 | 56 +++++++++++++++++++++++
 7 files changed, 176 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 356714801..32fe6645a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -89,6 +89,8 @@ enum index {
 	ITEM_VF_ID,
 	ITEM_PHY_PORT,
 	ITEM_PHY_PORT_INDEX,
+	ITEM_PORT_ID,
+	ITEM_PORT_ID_ID,
 	ITEM_RAW,
 	ITEM_RAW_RELATIVE,
 	ITEM_RAW_SEARCH,
@@ -185,6 +187,9 @@ enum index {
 	ACTION_PHY_PORT,
 	ACTION_PHY_PORT_ORIGINAL,
 	ACTION_PHY_PORT_INDEX,
+	ACTION_PORT_ID,
+	ACTION_PORT_ID_ORIGINAL,
+	ACTION_PORT_ID_ID,
 	ACTION_METER,
 	ACTION_METER_ID,
 };
@@ -445,6 +450,7 @@ static const enum index next_item[] = {
 	ITEM_PF,
 	ITEM_VF,
 	ITEM_PHY_PORT,
+	ITEM_PORT_ID,
 	ITEM_RAW,
 	ITEM_ETH,
 	ITEM_VLAN,
@@ -491,6 +497,12 @@ static const enum index item_phy_port[] = {
 	ZERO,
 };
 
+static const enum index item_port_id[] = {
+	ITEM_PORT_ID_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index item_raw[] = {
 	ITEM_RAW_RELATIVE,
 	ITEM_RAW_SEARCH,
@@ -627,6 +639,7 @@ static const enum index next_action[] = {
 	ACTION_PF,
 	ACTION_VF,
 	ACTION_PHY_PORT,
+	ACTION_PORT_ID,
 	ACTION_METER,
 	ZERO,
 };
@@ -668,6 +681,13 @@ static const enum index action_phy_port[] = {
 	ZERO,
 };
 
+static const enum index action_port_id[] = {
+	ACTION_PORT_ID_ORIGINAL,
+	ACTION_PORT_ID_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_meter[] = {
 	ACTION_METER_ID,
 	ACTION_NEXT,
@@ -1084,6 +1104,20 @@ static const struct token token_list[] = {
 		.next = NEXT(item_phy_port, NEXT_ENTRY(UNSIGNED), item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
 	},
+	[ITEM_PORT_ID] = {
+		.name = "port_id",
+		.help = "match traffic from/to a given DPDK port ID",
+		.priv = PRIV_ITEM(PORT_ID,
+				  sizeof(struct rte_flow_item_port_id)),
+		.next = NEXT(item_port_id),
+		.call = parse_vc,
+	},
+	[ITEM_PORT_ID_ID] = {
+		.name = "id",
+		.help = "DPDK port ID",
+		.next = NEXT(item_port_id, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)),
+	},
 	[ITEM_RAW] = {
 		.name = "raw",
 		.help = "match an arbitrary byte string",
@@ -1749,6 +1783,29 @@ static const struct token token_list[] = {
 					index)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_PORT_ID] = {
+		.name = "port_id",
+		.help = "direct matching traffic to a given DPDK port ID",
+		.priv = PRIV_ACTION(PORT_ID,
+				    sizeof(struct rte_flow_action_port_id)),
+		.next = NEXT(action_port_id),
+		.call = parse_vc,
+	},
+	[ACTION_PORT_ID_ORIGINAL] = {
+		.name = "original",
+		.help = "use original DPDK port ID if possible",
+		.next = NEXT(action_port_id, NEXT_ENTRY(BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id,
+					   original, 1)),
+		.call = parse_vc_conf,
+	},
+	[ACTION_PORT_ID_ID] = {
+		.name = "id",
+		.help = "DPDK port ID",
+		.next = NEXT(action_port_id, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_METER] = {
 		.name = "meter",
 		.help = "meter the directed packets at given id",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 869c6663b..8e56c0668 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -994,6 +994,7 @@ static const struct {
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
 	MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
+	MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
 	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
@@ -1092,6 +1093,7 @@ static const struct {
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
 	MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
+	MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
 	MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
 };
 
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a39c1e1b0..2fb8e9c3f 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -617,6 +617,36 @@ associated with a port_id should be retrieved by other means.
    | ``mask`` | ``index`` | zeroed to match any port index |
    +----------+-----------+--------------------------------+
 
+Item: ``PORT_ID``
+^^^^^^^^^^^^^^^^^
+
+Matches traffic originating from (ingress) or going to (egress) a given DPDK
+port ID.
+
+Normally only supported if the port ID in question is known by the
+underlying PMD and related to the device the flow rule is created against.
+
+This must not be confused with `Item: PHY_PORT`_ which refers to the
+physical port of a device, whereas `Item: PORT_ID`_ refers to a ``struct
+rte_eth_dev`` object on the application side (also known as "port
+representor" depending on the kind of underlying device).
+
+- Default ``mask`` matches the specified DPDK port ID.
+
+.. _table_rte_flow_item_port_id:
+
+.. table:: PORT_ID
+
+   +----------+----------+-----------------------------+
+   | Field    | Subfield | Value                       |
+   +==========+==========+=============================+
+   | ``spec`` | ``id``   | DPDK port ID                |
+   +----------+----------+-----------------------------+
+   | ``last`` | ``id``   | upper range value           |
+   +----------+----------+-----------------------------+
+   | ``mask`` | ``id``   | zeroed to match any port ID |
+   +----------+----------+-----------------------------+
+
 Data matching item types
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1453,6 +1483,24 @@ See `Item: PHY_PORT`_.
    | ``index``    | physical port index                 |
    +--------------+-------------------------------------+
 
+Action: ``PORT_ID``
+^^^^^^^^^^^^^^^^^^^
+Directs matching traffic to a given DPDK port ID.
+
+See `Item: PORT_ID`_.
+
+.. _table_rte_flow_action_port_id:
+
+.. table:: PORT_ID
+
+   +--------------+---------------------------------------+
+   | Field        | Value                                 |
+   +==============+=======================================+
+   | ``original`` | use original DPDK port ID if possible |
+   +--------------+---------------------------------------+
+   | ``id``       | DPDK port ID                          |
+   +--------------+---------------------------------------+
+
 Action: ``METER``
 ^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 211f68da1..b1b2fd00e 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -275,6 +275,8 @@ API Changes
     IDs.
   * An action counterpart to the PHY_PORT pattern item was added in order to
     redirect matching traffic to a specific physical port.
+  * PORT_ID pattern item and actions were added to match and target DPDK
+    port IDs at a higher level than PHY_PORT.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 9733a7262..f5565db29 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3236,6 +3236,10 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``index {unsigned}``: physical port index.
 
+- ``port_id``: match traffic from/to a given DPDK port ID.
+
+  - ``id {unsigned}``: DPDK port ID.
+
 - ``raw``: match an arbitrary byte string.
 
   - ``relative {boolean}``: look for pattern after the previous item.
@@ -3452,6 +3456,11 @@ This section lists supported actions and their attributes, if any.
   - ``original {boolean}``: use original port index if possible.
   - ``index {unsigned}``: physical port index.
 
+- ``port_id``: direct matching traffic to a given DPDK port ID.
+
+  - ``original {boolean}``: use original DPDK port ID if possible.
+  - ``id {unsigned}``: DPDK port ID.
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 00989c73b..cecab59f6 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -39,6 +39,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(PF, 0),
 	MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
 	MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
+	MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
 	MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
 	MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
 	MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
@@ -77,6 +78,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(PF, 0),
 	MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
 	MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
+	MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
 };
 
 static int
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 58b75e934..09a21e531 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -180,6 +180,16 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
+	 * [META]
+	 *
+	 * Matches traffic originating from (ingress) or going to (egress) a
+	 * given DPDK port ID.
+	 *
+	 * See struct rte_flow_item_port_id.
+	 */
+	RTE_FLOW_ITEM_TYPE_PORT_ID,
+
+	/**
 	 * Matches a byte string of a given length at a given offset.
 	 *
 	 * See struct rte_flow_item_raw.
@@ -414,6 +424,32 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 #endif
 
 /**
+ * RTE_FLOW_ITEM_TYPE_PORT_ID
+ *
+ * Matches traffic originating from (ingress) or going to (egress) a given
+ * DPDK port ID.
+ *
+ * Normally only supported if the port ID in question is known by the
+ * underlying PMD and related to the device the flow rule is created
+ * against.
+ *
+ * This must not be confused with @p PHY_PORT which refers to the physical
+ * port of a device, whereas @p PORT_ID refers to a struct rte_eth_dev
+ * object on the application side (also known as "port representor"
+ * depending on the kind of underlying device).
+ */
+struct rte_flow_item_port_id {
+	uint32_t id; /**< DPDK port ID. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PORT_ID. */
+#ifndef __cplusplus
+static const struct rte_flow_item_port_id rte_flow_item_port_id_mask = {
+	.id = 0xffffffff,
+};
+#endif
+
+/**
  * RTE_FLOW_ITEM_TYPE_RAW
  *
  * Matches a byte string of a given length at a given offset.
@@ -997,6 +1033,13 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
+	 * Directs matching traffic to a given DPDK port ID.
+	 *
+	 * See struct rte_flow_action_port_id.
+	 */
+	RTE_FLOW_ACTION_TYPE_PORT_ID,
+
+	/**
 	 * Traffic metering and policing (MTR).
 	 *
 	 * See struct rte_flow_action_meter.
@@ -1134,6 +1177,19 @@ struct rte_flow_action_phy_port {
 };
 
 /**
+ * RTE_FLOW_ACTION_TYPE_PORT_ID
+ *
+ * Directs matching traffic to a given DPDK port ID.
+ *
+ * @see RTE_FLOW_ITEM_TYPE_PORT_ID
+ */
+struct rte_flow_action_port_id {
+	uint32_t original:1; /**< Use original DPDK port ID if possible. */
+	uint32_t reserved:31; /**< Reserved, must be zero. */
+	uint32_t id; /**< DPDK port ID. */
+};
+
+/**
  * RTE_FLOW_ACTION_TYPE_METER
  *
  * Traffic metering and policing (MTR).
-- 
2.11.0

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API
  2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API Adrien Mazarguil
@ 2018-04-25 16:10  0%     ` Adrien Mazarguil
  2018-04-25 16:15  0%       ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2018-04-25 16:10 UTC (permalink / raw)
  To: Ferruh Yigit, dev
  Cc: Jacek Siuda, Tomasz Duszynski, Dmitri Epshtein, Natalie Samsonov,
	Jianbo Liu

On Wed, Apr 25, 2018 at 05:27:56PM +0200, Adrien Mazarguil wrote:
> TPID handling in rte_flow VLAN and E_TAG pattern item definitions is not
> consistent with the normal stacking order of pattern items, which is
> confusing to applications.
> 
> Problem is that when followed by one of these layers, the EtherType field
> of the preceding layer keeps its "inner" definition, and the "outer" TPID
> is provided by the subsequent layer, the reverse of how a packet looks like
> on the wire:
> 
>  Wire:     [ ETH TPID = A | VLAN EtherType = B | B DATA ]
>  rte_flow: [ ETH EtherType = B | VLAN TPID = A | B DATA ]
> 
> Worse, when QinQ is involved, the stacking order of VLAN layers is
> unspecified. It is unclear whether it should be reversed (innermost to
> outermost) as well given TPID applies to the previous layer:
> 
>  Wire:       [ ETH TPID = A | VLAN TPID = B | VLAN EtherType = C | C DATA ]
>  rte_flow 1: [ ETH EtherType = C | VLAN TPID = B | VLAN TPID = A | C DATA ]
>  rte_flow 2: [ ETH EtherType = C | VLAN TPID = A | VLAN TPID = B | C DATA ]
> 
> While specifying EtherType/TPID is hopefully rarely necessary, the stacking
> order in case of QinQ and the lack of documentation remain an issue.
> 
> This patch replaces TPID in the VLAN pattern item with an inner
> EtherType/TPID as is usually done everywhere else (e.g. struct vlan_hdr),
> clarifies documentation and updates all relevant code.
> 
> It breaks ABI compatibility for the following public functions:
> 
> - rte_flow_copy()
> - rte_flow_create()
> - rte_flow_query()
> - rte_flow_validate()
> 
> Summary of changes for PMDs that implement ETH, VLAN or E_TAG pattern
> items:
> 
> - bnxt: EtherType matching is supported with and without VLAN, but TPID
>   matching is not and triggers an error.
> 
> - e1000: EtherType matching is only supported with the ETHERTYPE filter,
>   which does not support VLAN matching, therefore no impact.
> 
> - enic: same as bnxt.
> 
> - i40e: same as bnxt with existing FDIR limitations on allowed EtherType
>   values. The remaining filter types (VXLAN, NVGRE, QINQ) do not support
>   EtherType matching.
> 
> - ixgbe: same as e1000, with additional minor change to rely on the new
>   E-Tag macro definition.
> 
> - mlx4: EtherType/TPID matching is not supported, no impact.
> 
> - mlx5: same as bnxt.
> 
> - mvpp2: same as bnxt.
> 
> - sfc: same as bnxt.
> 
> - tap: same as bnxt.
> 
> Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API")
> Fixes: 99e7003831c3 ("net/ixgbe: parse L2 tunnel filter")
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>
> Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>
> Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
> Cc: Somnath Kotur <somnath.kotur@broadcom.com>
> Cc: John Daley <johndale@cisco.com>
> Cc: Hyong Youb Kim <hyonkim@cisco.com>
> Cc: Beilei Xing <beilei.xing@intel.com>
> Cc: Qi Zhang <qi.z.zhang@intel.com>
> Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Tomasz Duszynski <tdu@semihalf.com>
> Cc: Dmitri Epshtein <dima@marvell.com>
> Cc: Natalie Samsonov <nsamsono@marvell.com>
> Cc: Jianbo Liu <jianbo.liu@arm.com>
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Pascal Mazon <pascal.mazon@6wind.com>
> 
> ---
> 
> v6 changes:
> 
> - Reworded patch title as a "fix" (not candidate for backports) since it
>   addresses a flaw in the original API definition.
> - Updated API and ABI changes sections in release notes.
> 
> v3 changes:
> 
> Updated mrvl to mvpp2.
> 
> Moved unrelated default TCI mask update to separate patch.
> 
> Fixed sfc according to Andrew's comments [1], which made so much sense that
> I standardized on the same behavior for all other PMDs: matching outer TPID
> is never supported when a VLAN pattern item is present.
> 
> This is done because many devices accept several TPIDs but do not provide
> means to match a given one explicitly, it's all or nothing, and that makes
> the resulting flow rule inaccurate.
> 
> [1] http://dpdk.org/ml/archives/dev/2018-April/095870.html
<snip>
> diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
<snip>
> +	if (mask->inner_type) {
> +		struct rte_flow_item_eth spec_eth = {
> +			.type = spec->inner_type,
> +		};
> +		struct rte_flow_item_eth mask_eth = {
> +			.type = mask->inner_type,
> +		};
> +
> +		RTE_LOG(WARNING, PMD, "inner eth type mask is ignored\n");
> +		ret = mrvl_parse_type(spec_eth, mask_eth, flow);

Looks like there's a compilation issue left on the above line, which should
obviously read:

 ret = mrvl_parse_type(&spec_eth, &mask_eth, flow);

Ferruh, can you update it while applying?
I'd hate to spam the world with v7 :)

Thanks.

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API
  2018-04-25 16:10  0%     ` Adrien Mazarguil
@ 2018-04-25 16:15  0%       ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-04-25 16:15 UTC (permalink / raw)
  To: Adrien Mazarguil, dev
  Cc: Jacek Siuda, Tomasz Duszynski, Dmitri Epshtein, Natalie Samsonov,
	Jianbo Liu

On 4/25/2018 5:10 PM, Adrien Mazarguil wrote:
> On Wed, Apr 25, 2018 at 05:27:56PM +0200, Adrien Mazarguil wrote:
>> TPID handling in rte_flow VLAN and E_TAG pattern item definitions is not
>> consistent with the normal stacking order of pattern items, which is
>> confusing to applications.
>>
>> Problem is that when followed by one of these layers, the EtherType field
>> of the preceding layer keeps its "inner" definition, and the "outer" TPID
>> is provided by the subsequent layer, the reverse of how a packet looks like
>> on the wire:
>>
>>  Wire:     [ ETH TPID = A | VLAN EtherType = B | B DATA ]
>>  rte_flow: [ ETH EtherType = B | VLAN TPID = A | B DATA ]
>>
>> Worse, when QinQ is involved, the stacking order of VLAN layers is
>> unspecified. It is unclear whether it should be reversed (innermost to
>> outermost) as well given TPID applies to the previous layer:
>>
>>  Wire:       [ ETH TPID = A | VLAN TPID = B | VLAN EtherType = C | C DATA ]
>>  rte_flow 1: [ ETH EtherType = C | VLAN TPID = B | VLAN TPID = A | C DATA ]
>>  rte_flow 2: [ ETH EtherType = C | VLAN TPID = A | VLAN TPID = B | C DATA ]
>>
>> While specifying EtherType/TPID is hopefully rarely necessary, the stacking
>> order in case of QinQ and the lack of documentation remain an issue.
>>
>> This patch replaces TPID in the VLAN pattern item with an inner
>> EtherType/TPID as is usually done everywhere else (e.g. struct vlan_hdr),
>> clarifies documentation and updates all relevant code.
>>
>> It breaks ABI compatibility for the following public functions:
>>
>> - rte_flow_copy()
>> - rte_flow_create()
>> - rte_flow_query()
>> - rte_flow_validate()
>>
>> Summary of changes for PMDs that implement ETH, VLAN or E_TAG pattern
>> items:
>>
>> - bnxt: EtherType matching is supported with and without VLAN, but TPID
>>   matching is not and triggers an error.
>>
>> - e1000: EtherType matching is only supported with the ETHERTYPE filter,
>>   which does not support VLAN matching, therefore no impact.
>>
>> - enic: same as bnxt.
>>
>> - i40e: same as bnxt with existing FDIR limitations on allowed EtherType
>>   values. The remaining filter types (VXLAN, NVGRE, QINQ) do not support
>>   EtherType matching.
>>
>> - ixgbe: same as e1000, with additional minor change to rely on the new
>>   E-Tag macro definition.
>>
>> - mlx4: EtherType/TPID matching is not supported, no impact.
>>
>> - mlx5: same as bnxt.
>>
>> - mvpp2: same as bnxt.
>>
>> - sfc: same as bnxt.
>>
>> - tap: same as bnxt.
>>
>> Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API")
>> Fixes: 99e7003831c3 ("net/ixgbe: parse L2 tunnel filter")
>>
>> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
>> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
>> Cc: Thomas Monjalon <thomas@monjalon.net>
>> Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
>> Cc: Jingjing Wu <jingjing.wu@intel.com>
>> Cc: Ajit Khaparde <ajit.khaparde@broadcom.com>
>> Cc: Somnath Kotur <somnath.kotur@broadcom.com>
>> Cc: John Daley <johndale@cisco.com>
>> Cc: Hyong Youb Kim <hyonkim@cisco.com>
>> Cc: Beilei Xing <beilei.xing@intel.com>
>> Cc: Qi Zhang <qi.z.zhang@intel.com>
>> Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
>> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
>> Cc: Yongseok Koh <yskoh@mellanox.com>
>> Cc: Tomasz Duszynski <tdu@semihalf.com>
>> Cc: Dmitri Epshtein <dima@marvell.com>
>> Cc: Natalie Samsonov <nsamsono@marvell.com>
>> Cc: Jianbo Liu <jianbo.liu@arm.com>
>> Cc: Andrew Rybchenko <arybchenko@solarflare.com>
>> Cc: Pascal Mazon <pascal.mazon@6wind.com>
>>
>> ---
>>
>> v6 changes:
>>
>> - Reworded patch title as a "fix" (not candidate for backports) since it
>>   addresses a flaw in the original API definition.
>> - Updated API and ABI changes sections in release notes.
>>
>> v3 changes:
>>
>> Updated mrvl to mvpp2.
>>
>> Moved unrelated default TCI mask update to separate patch.
>>
>> Fixed sfc according to Andrew's comments [1], which made so much sense that
>> I standardized on the same behavior for all other PMDs: matching outer TPID
>> is never supported when a VLAN pattern item is present.
>>
>> This is done because many devices accept several TPIDs but do not provide
>> means to match a given one explicitly, it's all or nothing, and that makes
>> the resulting flow rule inaccurate.
>>
>> [1] http://dpdk.org/ml/archives/dev/2018-April/095870.html
> <snip>
>> diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
> <snip>
>> +	if (mask->inner_type) {
>> +		struct rte_flow_item_eth spec_eth = {
>> +			.type = spec->inner_type,
>> +		};
>> +		struct rte_flow_item_eth mask_eth = {
>> +			.type = mask->inner_type,
>> +		};
>> +
>> +		RTE_LOG(WARNING, PMD, "inner eth type mask is ignored\n");
>> +		ret = mrvl_parse_type(spec_eth, mask_eth, flow);
> 
> Looks like there's a compilation issue left on the above line, which should
> obviously read:
> 
>  ret = mrvl_parse_type(&spec_eth, &mask_eth, flow);
> 
> Ferruh, can you update it while applying?
> I'd hate to spam the world with v7 :)

OK, will update while applying.

> 
> Thanks.
> 

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3 0/6] mempool: add bucket driver
  @ 2018-04-25 16:32  4% ` Andrew Rybchenko
  2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 2/6] mempool: implement abstract mempool info API Andrew Rybchenko
  2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 3/6] mempool: support block dequeue operation Andrew Rybchenko
  2018-04-26 10:59  4% ` [dpdk-dev] [PATCH v4 0/5] mempool: add bucket driver Andrew Rybchenko
  1 sibling, 2 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-25 16:32 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ

The initial patch series [1] (RFCv1 is [2]) is split into two to simplify
processing.  It is the second part which relies on the first one [3]
which is already applied.

The patch series adds bucket mempool driver which allows to allocate
(both physically and virtually) contiguous blocks of objects and adds
mempool API to do it. It is still capable to provide separate objects,
but it is definitely more heavy-weight than ring/stack drivers.
The driver will be used by the future Solarflare driver enhancements
which allow to utilize physical contiguous blocks in the NIC firmware.

The target usecase is dequeue in blocks and enqueue separate objects
back (which are collected in buckets to be dequeued). So, the memory
pool with bucket driver is created by an application and provided to
networking PMD receive queue. The choice of bucket driver is done using
rte_eth_dev_pool_ops_supported(). A PMD that relies upon contiguous
block allocation should report the bucket driver as the only supported
and preferred one.

Introduction of the contiguous block dequeue operation is proven by
performance measurements using autotest with minor enhancements:
 - in the original test bulks are powers of two, which is unacceptable
   for us, so they are changed to multiple of contig_block_size;
 - the test code is duplicated to support plain dequeue and
   dequeue_contig_blocks;
 - all the extra test variations (with/without cache etc) are eliminated;
 - a fake read from the dequeued buffer is added (in both cases) to
   simulate mbufs access.

start performance test for bucket (without cache)
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   111935488
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   115290931
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=   353055539
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=   353330790
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   224657407
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   230411468
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=   706700902
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=   703673139
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   425236887
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   437295512
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=  1343409356
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=  1336567397
start performance test for bucket (without cache + contiguous dequeue)
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   122945536
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   126458265
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=   374262988
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=   377316966
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   244842496
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   251618917
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=   751226060
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=   756233010
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   462068120
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   476997221
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=  1432171313
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=  1438829771

The number of objects in the contiguous block is a function of bucket
memory size (.config option) and total element size. In the future
additional API with possibility to pass parameters on mempool allocation
may be added.

It breaks ABI since changes rte_mempool_ops. The ABI version is already
bumped in [4].

I've double-checked that mempool_autotest and mempool_perf_autotest
work fine if EAL argument --mbuf-pool-ops-name=bucket is used.

mempool_perf_autotest as is for bucket shows less rate than ring_mp_mc
since test dequeue bulk sizes are not aligned to contintiguous block size
and bucket driver is optimized for contiguous blocks allocation (or at
least allocation in bulks multiple by contiguous block size).

However, real usage of the bucket driver even without contiguous block
dequeue (transmit only benchmark which simply generates traffic) shows
better packet rate. It looks like it is because the driver is
stack-based (per lcore without locks/barriers) and it improves cache
hit (working memory is smaller since it is a subset of the mempool
instead of entire mempool when some objects do not fit into mempool cache).

Unfortunately I've not finalized yet patches which allow to repeat above
measurements (done using hacks).

The driver is required for [5].


[1] https://dpdk.org/ml/archives/dev/2018-January/088698.html
[2] https://dpdk.org/ml/archives/dev/2017-November/082335.html
[3] https://dpdk.org/ml/archives/dev/2018-April/097354.html
[4] https://dpdk.org/ml/archives/dev/2018-April/097352.html
[5] https://dpdk.org/ml/archives/dev/2018-April/098089.html

v2 -> v3:
 - rebase
 - align rte_mempool_info structure size to avoid ABI breakages in a
   number of cases when something relative small added
 - fix bug in get_count because of not counted objects in the
   adaptation rings
 - squash __mempool_generic_get_contig_blocks() into
   rte_mempool_get_contig_blocks()
 - fix typo in documentation

v1 -> v2:
  - just rebase

RFCv2 -> v1:
  - rebased on top of [3]
  - cleanup deprecation notice when it is done
  - mark a new API experimental
  - move contig blocks dequeue debug checks/processing to the library function
  - add contig blocks get stats
  - add release notes

RFCv1 -> RFCv2:
  - change info API to get information from driver required to
    API user to know contiguous block size
  - use SPDX tags
  - avoid all objects affinity to single lcore
  - fix bucket get_count
  - fix NO_CACHE_ALIGN case in bucket mempool


Andrew Rybchenko (1):
  doc: advertise bucket mempool driver

Artem V. Andreev (5):
  mempool/bucket: implement bucket mempool manager
  mempool: implement abstract mempool info API
  mempool: support block dequeue operation
  mempool/bucket: implement block dequeue operation
  mempool/bucket: do not allow one lcore to grab all buckets

 MAINTAINERS                                        |   9 +
 config/common_base                                 |   2 +
 doc/guides/rel_notes/deprecation.rst               |   7 -
 doc/guides/rel_notes/release_18_05.rst             |  10 +-
 drivers/mempool/Makefile                           |   1 +
 drivers/mempool/bucket/Makefile                    |  27 +
 drivers/mempool/bucket/meson.build                 |   9 +
 drivers/mempool/bucket/rte_mempool_bucket.c        | 628 +++++++++++++++++++++
 .../mempool/bucket/rte_mempool_bucket_version.map  |   4 +
 lib/librte_mempool/Makefile                        |   1 +
 lib/librte_mempool/meson.build                     |   2 +
 lib/librte_mempool/rte_mempool.c                   |  39 ++
 lib/librte_mempool/rte_mempool.h                   | 171 ++++++
 lib/librte_mempool/rte_mempool_ops.c               |  16 +
 lib/librte_mempool/rte_mempool_version.map         |   8 +
 mk/rte.app.mk                                      |   1 +
 16 files changed, 927 insertions(+), 8 deletions(-)
 create mode 100644 drivers/mempool/bucket/Makefile
 create mode 100644 drivers/mempool/bucket/meson.build
 create mode 100644 drivers/mempool/bucket/rte_mempool_bucket.c
 create mode 100644 drivers/mempool/bucket/rte_mempool_bucket_version.map

-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 3/6] mempool: support block dequeue operation
  2018-04-25 16:32  4% ` [dpdk-dev] [PATCH v3 0/6] mempool: add bucket driver Andrew Rybchenko
  2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 2/6] mempool: implement abstract mempool info API Andrew Rybchenko
@ 2018-04-25 16:32  4%   ` Andrew Rybchenko
  1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-25 16:32 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ, Artem V. Andreev

From: "Artem V. Andreev" <Artem.Andreev@oktetlabs.ru>

If mempool manager supports object blocks (physically and virtual
contiguous set of objects), it is sufficient to get the first
object only and the function allows to avoid filling in of
information about each block member.

Signed-off-by: Artem V. Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst       |   7 --
 lib/librte_mempool/Makefile                |   1 +
 lib/librte_mempool/meson.build             |   2 +
 lib/librte_mempool/rte_mempool.c           |  39 +++++++++
 lib/librte_mempool/rte_mempool.h           | 131 +++++++++++++++++++++++++++--
 lib/librte_mempool/rte_mempool_ops.c       |   1 +
 lib/librte_mempool/rte_mempool_version.map |   1 +
 7 files changed, 170 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index bce97a2a9..faf1e527e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -42,13 +42,6 @@ Deprecation Notices
 
   - ``rte_eal_mbuf_default_mempool_ops``
 
-* mempool: several API and ABI changes are planned in v18.05.
-
-  The following changes are planned:
-
-  - addition of new op to allocate contiguous
-    block of objects if underlying driver supports it.
-
 * mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
   definition in line with the ethdev TM and MTR APIs. Currently, this field
   is defined in librte_sched in a non-generic way. The new generic format
diff --git a/lib/librte_mempool/Makefile b/lib/librte_mempool/Makefile
index 7f19f005a..e3c32b14f 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -10,6 +10,7 @@ CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
 # Allow deprecated symbol to use deprecated rte_mempool_populate_iova_tab()
 # from earlier deprecated rte_mempool_populate_phys_tab()
 CFLAGS += -Wno-deprecated-declarations
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_ring
 
 EXPORT_MAP := rte_mempool_version.map
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index baf2d24d5..d507e5511 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
+
 extra_flags = []
 
 # Allow deprecated symbol to use deprecated rte_mempool_populate_iova_tab()
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 84b3d640f..cf5d124ec 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -1255,6 +1255,36 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp,
 #endif
 }
 
+void
+rte_mempool_contig_blocks_check_cookies(const struct rte_mempool *mp,
+	void * const *first_obj_table_const, unsigned int n, int free)
+{
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	struct rte_mempool_info info;
+	const size_t total_elt_sz =
+		mp->header_size + mp->elt_size + mp->trailer_size;
+	unsigned int i, j;
+
+	rte_mempool_ops_get_info(mp, &info);
+
+	for (i = 0; i < n; ++i) {
+		void *first_obj = first_obj_table_const[i];
+
+		for (j = 0; j < info.contig_block_size; ++j) {
+			void *obj;
+
+			obj = (void *)((uintptr_t)first_obj + j * total_elt_sz);
+			rte_mempool_check_cookies(mp, &obj, 1, free);
+		}
+	}
+#else
+	RTE_SET_USED(mp);
+	RTE_SET_USED(first_obj_table_const);
+	RTE_SET_USED(n);
+	RTE_SET_USED(free);
+#endif
+}
+
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 static void
 mempool_obj_audit(struct rte_mempool *mp, __rte_unused void *opaque,
@@ -1320,6 +1350,7 @@ void
 rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 {
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	struct rte_mempool_info info;
 	struct rte_mempool_debug_stats sum;
 	unsigned lcore_id;
 #endif
@@ -1361,6 +1392,7 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 
 	/* sum and dump statistics */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	rte_mempool_ops_get_info(mp, &info);
 	memset(&sum, 0, sizeof(sum));
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		sum.put_bulk += mp->stats[lcore_id].put_bulk;
@@ -1369,6 +1401,8 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 		sum.get_success_objs += mp->stats[lcore_id].get_success_objs;
 		sum.get_fail_bulk += mp->stats[lcore_id].get_fail_bulk;
 		sum.get_fail_objs += mp->stats[lcore_id].get_fail_objs;
+		sum.get_success_blks += mp->stats[lcore_id].get_success_blks;
+		sum.get_fail_blks += mp->stats[lcore_id].get_fail_blks;
 	}
 	fprintf(f, "  stats:\n");
 	fprintf(f, "    put_bulk=%"PRIu64"\n", sum.put_bulk);
@@ -1377,6 +1411,11 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 	fprintf(f, "    get_success_objs=%"PRIu64"\n", sum.get_success_objs);
 	fprintf(f, "    get_fail_bulk=%"PRIu64"\n", sum.get_fail_bulk);
 	fprintf(f, "    get_fail_objs=%"PRIu64"\n", sum.get_fail_objs);
+	if (info.contig_block_size > 0) {
+		fprintf(f, "    get_success_blks=%"PRIu64"\n",
+			sum.get_success_blks);
+		fprintf(f, "    get_fail_blks=%"PRIu64"\n", sum.get_fail_blks);
+	}
 #else
 	fprintf(f, "  no statistics available\n");
 #endif
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 853f2da4d..1f59553b3 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -70,6 +70,10 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_objs; /**< Objects successfully allocated. */
 	uint64_t get_fail_bulk;    /**< Failed allocation number. */
 	uint64_t get_fail_objs;    /**< Objects that failed to be allocated. */
+	/** Successful allocation number of contiguous blocks. */
+	uint64_t get_success_blks;
+	/** Failed allocation number of contiguous blocks. */
+	uint64_t get_fail_blks;
 } __rte_cache_aligned;
 #endif
 
@@ -199,11 +203,8 @@ struct rte_mempool_memhdr {
  * a number of cases when something small is added.
  */
 struct rte_mempool_info {
-	/*
-	 * Dummy structure member to make it non emtpy until the first
-	 * real member is added.
-	 */
-	unsigned int dummy;
+	/** Number of objects in the contiguous block */
+	unsigned int contig_block_size;
 } __rte_cache_aligned;
 
 /**
@@ -282,8 +283,16 @@ struct rte_mempool {
 			mp->stats[__lcore_id].name##_bulk += 1;	\
 		}                                               \
 	} while(0)
+#define __MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, name, n) do {                    \
+		unsigned int __lcore_id = rte_lcore_id();       \
+		if (__lcore_id < RTE_MAX_LCORE) {               \
+			mp->stats[__lcore_id].name##_blks += n;	\
+			mp->stats[__lcore_id].name##_bulk += 1;	\
+		}                                               \
+	} while (0)
 #else
 #define __MEMPOOL_STAT_ADD(mp, name, n) do {} while(0)
+#define __MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, name, n) do {} while (0)
 #endif
 
 /**
@@ -351,6 +360,38 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp,
 #define __mempool_check_cookies(mp, obj_table_const, n, free) do {} while(0)
 #endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * @internal Check contiguous object blocks and update cookies or panic.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ * @param first_obj_table_const
+ *   Pointer to a table of void * pointers (first object of the contiguous
+ *   object blocks).
+ * @param n
+ *   Number of contiguous object blocks.
+ * @param free
+ *   - 0: object is supposed to be allocated, mark it as free
+ *   - 1: object is supposed to be free, mark it as allocated
+ *   - 2: just check that cookie is valid (free or allocated)
+ */
+void rte_mempool_contig_blocks_check_cookies(const struct rte_mempool *mp,
+	void * const *first_obj_table_const, unsigned int n, int free);
+
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+#define __mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+					      free) \
+	rte_mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+						free)
+#else
+#define __mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+					      free) \
+	do {} while (0)
+#endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
+
 #define RTE_MEMPOOL_OPS_NAMESIZE 32 /**< Max length of ops struct name. */
 
 /**
@@ -382,6 +423,15 @@ typedef int (*rte_mempool_enqueue_t)(struct rte_mempool *mp,
 typedef int (*rte_mempool_dequeue_t)(struct rte_mempool *mp,
 		void **obj_table, unsigned int n);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Dequeue a number of contiquous object blocks from the external pool.
+ */
+typedef int (*rte_mempool_dequeue_contig_blocks_t)(struct rte_mempool *mp,
+		 void **first_obj_table, unsigned int n);
+
 /**
  * Return the number of available objects in the external pool.
  */
@@ -548,6 +598,10 @@ struct rte_mempool_ops {
 	 * Get mempool info
 	 */
 	rte_mempool_get_info_t get_info;
+	/**
+	 * Dequeue a number of contiguous object blocks.
+	 */
+	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
 } __rte_cache_aligned;
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
@@ -625,6 +679,30 @@ rte_mempool_ops_dequeue_bulk(struct rte_mempool *mp,
 	return ops->dequeue(mp, obj_table, n);
 }
 
+/**
+ * @internal Wrapper for mempool_ops dequeue_contig_blocks callback.
+ *
+ * @param[in] mp
+ *   Pointer to the memory pool.
+ * @param[out] first_obj_table
+ *   Pointer to a table of void * pointers (first objects).
+ * @param[in] n
+ *   Number of blocks to get.
+ * @return
+ *   - 0: Success; got n objects.
+ *   - <0: Error; code of dequeue function.
+ */
+static inline int
+rte_mempool_ops_dequeue_contig_blocks(struct rte_mempool *mp,
+		void **first_obj_table, unsigned int n)
+{
+	struct rte_mempool_ops *ops;
+
+	ops = rte_mempool_get_ops(mp->ops_index);
+	RTE_ASSERT(ops->dequeue_contig_blocks != NULL);
+	return ops->dequeue_contig_blocks(mp, first_obj_table, n);
+}
+
 /**
  * @internal wrapper for mempool_ops enqueue callback.
  *
@@ -1539,6 +1617,49 @@ rte_mempool_get(struct rte_mempool *mp, void **obj_p)
 	return rte_mempool_get_bulk(mp, obj_p, 1);
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get a contiguous blocks of objects from the mempool.
+ *
+ * If cache is enabled, consider to flush it first, to reuse objects
+ * as soon as possible.
+ *
+ * The application should check that the driver supports the operation
+ * by calling rte_mempool_ops_get_info() and checking that `contig_block_size`
+ * is not zero.
+ *
+ * @param mp
+ *   A pointer to the mempool structure.
+ * @param first_obj_table
+ *   A pointer to a pointer to the first object in each block.
+ * @param n
+ *   The number of blocks to get from mempool.
+ * @return
+ *   - 0: Success; blocks taken.
+ *   - -ENOBUFS: Not enough entries in the mempool; no object is retrieved.
+ *   - -EOPNOTSUPP: The mempool driver does not support block dequeue
+ */
+static __rte_always_inline int
+__rte_experimental
+rte_mempool_get_contig_blocks(struct rte_mempool *mp,
+			      void **first_obj_table, unsigned int n)
+{
+	int ret;
+
+	ret = rte_mempool_ops_dequeue_contig_blocks(mp, first_obj_table, n);
+	if (ret == 0) {
+		__MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, get_success, n);
+		__mempool_contig_blocks_check_cookies(mp, first_obj_table, n,
+						      1);
+	} else {
+		__MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, get_fail, n);
+	}
+
+	return ret;
+}
+
 /**
  * Return the number of entries in the mempool.
  *
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index efc1c084c..a27e1fa51 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -60,6 +60,7 @@ rte_mempool_register_ops(const struct rte_mempool_ops *h)
 	ops->calc_mem_size = h->calc_mem_size;
 	ops->populate = h->populate;
 	ops->get_info = h->get_info;
+	ops->dequeue_contig_blocks = h->dequeue_contig_blocks;
 
 	rte_spinlock_unlock(&rte_mempool_ops_table.sl);
 
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index c9d16ecc4..1c406b5b0 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -53,6 +53,7 @@ DPDK_17.11 {
 DPDK_18.05 {
 	global:
 
+	rte_mempool_contig_blocks_check_cookies;
 	rte_mempool_op_calc_mem_size_default;
 	rte_mempool_op_populate_default;
 
-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 2/6] mempool: implement abstract mempool info API
  2018-04-25 16:32  4% ` [dpdk-dev] [PATCH v3 0/6] mempool: add bucket driver Andrew Rybchenko
@ 2018-04-25 16:32  4%   ` Andrew Rybchenko
  2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 3/6] mempool: support block dequeue operation Andrew Rybchenko
  1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-25 16:32 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ, Artem V. Andreev

From: "Artem V. Andreev" <Artem.Andreev@oktetlabs.ru>

Primarily, it is intended as a way for the mempool driver to provide
additional information on how it lays up objects inside the mempool.

Signed-off-by: Artem V. Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mempool/rte_mempool.h           | 50 ++++++++++++++++++++++++++++++
 lib/librte_mempool/rte_mempool_ops.c       | 15 +++++++++
 lib/librte_mempool/rte_mempool_version.map |  7 +++++
 3 files changed, 72 insertions(+)

diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 3e06ae051..853f2da4d 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -189,6 +189,23 @@ struct rte_mempool_memhdr {
 	void *opaque;            /**< Argument passed to the free callback */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Additional information about the mempool
+ *
+ * The structure is cache-line aligned to avoid ABI breakages in
+ * a number of cases when something small is added.
+ */
+struct rte_mempool_info {
+	/*
+	 * Dummy structure member to make it non emtpy until the first
+	 * real member is added.
+	 */
+	unsigned int dummy;
+} __rte_cache_aligned;
+
 /**
  * The RTE mempool structure.
  */
@@ -499,6 +516,16 @@ int rte_mempool_op_populate_default(struct rte_mempool *mp,
 		void *vaddr, rte_iova_t iova, size_t len,
 		rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get some additional information about a mempool.
+ */
+typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
+		struct rte_mempool_info *info);
+
+
 /** Structure defining mempool operations structure */
 struct rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
@@ -517,6 +544,10 @@ struct rte_mempool_ops {
 	 * provided memory chunk.
 	 */
 	rte_mempool_populate_t populate;
+	/**
+	 * Get mempool info
+	 */
+	rte_mempool_get_info_t get_info;
 } __rte_cache_aligned;
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
@@ -679,6 +710,25 @@ int rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
 			     rte_mempool_populate_obj_cb_t *obj_cb,
 			     void *obj_cb_arg);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Wrapper for mempool_ops get_info callback.
+ *
+ * @param[in] mp
+ *   Pointer to the memory pool.
+ * @param[out] info
+ *   Pointer to the rte_mempool_info structure
+ * @return
+ *   - 0: Success; The mempool driver supports retrieving supplementary
+ *        mempool information
+ *   - -ENOTSUP - doesn't support get_info ops (valid case).
+ */
+__rte_experimental
+int rte_mempool_ops_get_info(const struct rte_mempool *mp,
+			 struct rte_mempool_info *info);
+
 /**
  * @internal wrapper for mempool_ops free callback.
  *
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index ea9be1eb2..efc1c084c 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -59,6 +59,7 @@ rte_mempool_register_ops(const struct rte_mempool_ops *h)
 	ops->get_count = h->get_count;
 	ops->calc_mem_size = h->calc_mem_size;
 	ops->populate = h->populate;
+	ops->get_info = h->get_info;
 
 	rte_spinlock_unlock(&rte_mempool_ops_table.sl);
 
@@ -134,6 +135,20 @@ rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
 			     obj_cb_arg);
 }
 
+/* wrapper to get additional mempool info */
+int
+rte_mempool_ops_get_info(const struct rte_mempool *mp,
+			 struct rte_mempool_info *info)
+{
+	struct rte_mempool_ops *ops;
+
+	ops = rte_mempool_get_ops(mp->ops_index);
+
+	RTE_FUNC_PTR_OR_ERR_RET(ops->get_info, -ENOTSUP);
+	return ops->get_info(mp, info);
+}
+
+
 /* sets mempool ops previously registered by rte_mempool_register_ops. */
 int
 rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index cf375dbe6..c9d16ecc4 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -57,3 +57,10 @@ DPDK_18.05 {
 	rte_mempool_op_populate_default;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_mempool_ops_get_info;
+
+} DPDK_18.05;
-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 00/16] Flow API overhaul for switch offloads
  2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
                     ` (13 preceding siblings ...)
  2018-04-25 15:28  5%   ` [dpdk-dev] [PATCH v6 16/16] ethdev: add port ID item and " Adrien Mazarguil
@ 2018-04-25 17:34  0%   ` Ferruh Yigit
  14 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-04-25 17:34 UTC (permalink / raw)
  To: Adrien Mazarguil, Thomas Monjalon, dev

On 4/25/2018 4:27 PM, Adrien Mazarguil wrote:
> As summarized in a prior RFC [1], the flow API (rte_flow) was chosen as a
> means to manage switch offloads supported by many devices (usually going by
> names such as E-Switch or vSwitch) through user-specified flow rules.
> 
> Combined with the need to support encap/decap actions, this requires a
> change in the way flow actions are processed (in order and possibly
> repeated) which modifies the behavior of some of the existing actions, thus
> warranting a major ABI breakage.
> 
> Given this ABI breakage is also required by other work submitted for the
> current release [2][3], this series addresses various longstanding issues
> with the flow API and makes minor improvements in preparation for upcoming
> features.
> 
> Changes summary:
> 
> - Additional error types.
> - Clearer documentation.
> - Improved C++ compatibility.
> - Exhaustive RSS action.
> - Consistent behavior of VLAN pattern item.
> - New "transfer" attribute bringing consistency to VF/PF pattern items.
> - Confusing "PORT" pattern item renamed "PHY_PORT", with new action
>   counterpart.
> - New "PORT_ID" pattern item and action to be used with port representors.
> 
> This series piggybacks on the major ABI update introduced by a prior
> commit [4] for DPDK 18.05 and depends on several fixes [5] which must be
> applied first.
> 
> [1] "[RFC] Switch device offload with DPDK"
>     http://dpdk.org/ml/archives/dev/2018-March/092513.html
> 
> [2] commit 676b605182a5 ("doc: announce ethdev API change for RSS
>     configuration")
> 
> [3] "[PATCH v1 00/21] MLX5 tunnel Rx offloading"
>     http://dpdk.org/ml/archives/dev/2018-March/092264.html
> 
> [4] commit 653e038efc9b ("ethdev: remove versioning of filter control
>     function")
> 
> [5] "[PATCH v6 00/11] Bunch of flow API-related fixes"
>     http://dpdk.org/ml/archives/dev/2018-April/098035.html
> 
> v6 changes:
> 
> - Fixed mlx5 issue raised by Nelio in "ethdev: flatten RSS configuration in
>   flow API".
> - Updated release notes (API update / ABI breakage) in relevant patches.
> - Removed Xueming's deprecation notice in "ethdev: add encap level to RSS
>   flow API action" since it's covered by this series.
> - Reworded a few patches as fixes since they address API flaws.
> - Rebased series once again.
> 
> v5 changes:
> 
> - Fixed errors reported by GCC and Clang in patch 05/16 ("ethdev: alter
>   behavior of flow API actions").
> - Rebased series once again.
> 
> v4 changes:
> 
> - No change besides new acked-by lines, rebased series to address conflicts.
> 
> v3 changes:
> 
> - Rebased series, fixed latest conflicts.
> - Addressed Andrew's comments, see affected patches for details:
>   - Empty RSS types in flow rule means PMD-specific RSS instead of no RSS.
>   - RSS hash function now explicitly compared against
>     RTE_ETH_HASH_FUNCTION_DEFAULT instead of 0 in all PMDs.
>   - sfc PMD updated to also accept Toeplitz.
>   - Implicit VLAN TPID matching now removed from all PMDs.
>   - Default mask upate for VLAN TCI now split as separate patch #11.
>   - Ingress/egress definition clarified in patch #12.
> 
> v2 changes:
> 
> - Squashed "ethdev: update ABI for flow API functions" in subsequent
>   patches.
> - Emphasized ABI impact in relevant commit logs.
> - Modified documentation in "ethdev: alter behavior of flow API actions" to
>   describe how terminating flow rules without any action of the fate kind
>   result in undefined behavior instead of dropping traffic.
> - Fixed other minor documentation formatting issues.
> - Modified "ethdev: refine TPID handling in flow API" as follows:
>   - Using standard macro definitions for VLAN, QinQ and E-Tag EtherTypes.
>   - Fixed endian conversion in sfc.
>   - Replaced a condition in VLAN pattern item processing with an assertion
>     check for i40e.
> 
> Adrien Mazarguil (16):
>   ethdev: add error types to flow API
>   ethdev: clarify flow API pattern items and actions
>   doc: remove flow API migration section
>   ethdev: remove DUP action from flow API
>   ethdev: alter behavior of flow API actions
>   ethdev: fix C99 flexible arrays from flow API
>   ethdev: flatten RSS configuration in flow API
>   ethdev: add hash function to RSS flow API action
>   ethdev: add encap level to RSS flow API action
>   ethdev: fix TPID handling in flow API
>   ethdev: fix default VLAN TCI mask in flow API
>   ethdev: add transfer attribute to flow API
>   ethdev: fix behavior of VF/PF in flow API
>   ethdev: rename physical port item in flow API
>   ethdev: add physical port action to flow API
>   ethdev: add port ID item and action to flow API

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 0/5] introduce new tunnel types
  @ 2018-04-25 21:31  0%   ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-04-25 21:31 UTC (permalink / raw)
  To: Xueming Li, Wenzhuo Lu, Jingjing Wu, Thomas Monjalon, Adrien Mazarguil
  Cc: Nelio Laranjeiro, Shahaf Shuler, dev, Olivier Matz

On 4/23/2018 1:16 PM, Xueming Li wrote:
> v7:
> - Fixed display name of MPLS-in-GRE and MPLS-in-UDP
> v6:
> - Add MPLS-in-GRE and MPLS-in-UDP back
> - UPdate comment alignment
> v5:
> - Fixed VXLAN-GPE comment alignment
> - Removed MPLS-in-GRE and MPLS-in-UDP patch
> v4:
> - Update testpmd doc for flow VXLAN-GPE paramter.
> v3:
> - Change VXLAN-GPE definition order to avoid ABI compatibility issue.
> v2:
> - Split patch set into public and mlx5 two series, this one is the first.
> v1:
> - Support new tunnel type MPLS-in-GRE and MPLS-in-UDP
> - Remove deprecation notes of rss level
> 
> This patchset introduced new tunnel type and related testpmd code:
> - New tunnel type VXLAN-GPE
>   https://datatracker.ietf.org/doc/draft-ietf-nvo3-vxlan-gpe/
> - New tunnel type MPLS-in-GRE
>   https://tools.ietf.org/html/rfc4023
> - New tunnel type MPLS-in-UDP
>   https://tools.ietf.org/html/rfc7510
> - Support GRE extension in testpmd csum forwarding engine
> 
> 
> Xueming Li (5):
>   doc: remove RSS configuration change announcement
>   ethdev: introduce new tunnel VXLAN-GPE
>   ethdev: introduce tunnel type MPLS-in-GRE and MPLS-in-UDP
>   app/testpmd: introduce new tunnel VXLAN-GPE
>   app/testpmd: add more GRE extension support to csum engine

Series applied to dpdk-next-net/master, thanks.

(Except 1/5)

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver
  @ 2018-04-26  6:20  3%   ` Arnon Warshavsky
  2018-04-26 16:06  0%     ` Kevin Traynor
  2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:20 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Replace panic calls with log and return value.
Local functions to this file,
changing from void to int are non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/bonding/rte_eth_bond_8023ad.c         | 29 ++++++++++++++---------
 drivers/net/bonding/rte_eth_bond_8023ad_private.h |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c            | 22 ++++++++++++-----
 drivers/net/bonding/rte_eth_bond_pmd.c            |  9 ++++---
 drivers/net/bonding/rte_eth_bond_private.h        |  2 +-
 5 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index c452318..308e623 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -893,7 +893,7 @@
 			bond_mode_8023ad_periodic_cb, arg);
 }
 
-void
+int
 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
 				uint16_t slave_id)
 {
@@ -939,7 +939,7 @@
 	timer_cancel(&port->warning_timer);
 
 	if (port->mbuf_pool != NULL)
-		return;
+		return 0;
 
 	RTE_ASSERT(port->rx_ring == NULL);
 	RTE_ASSERT(port->tx_ring == NULL);
@@ -968,8 +968,9 @@
 	/* Any memory allocation failure in initialization is critical because
 	 * resources can't be free, so reinitialization is impossible. */
 	if (port->mbuf_pool == NULL) {
-		rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
-			slave_id, mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
 
 	snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
@@ -977,8 +978,9 @@
 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
 
 	if (port->rx_ring == NULL) {
-		rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
-			mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create rx ring '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
 
 	/* TX ring is at least one pkt longer to make room for marker packet. */
@@ -987,9 +989,12 @@
 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
 
 	if (port->tx_ring == NULL) {
-		rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
-			mem_name, rte_strerror(rte_errno));
+		RTE_BOND_LOG(ERR, "%s() Slave %u: Fail to create tx ring '%s': %s\n",
+			__func__, slave_id, mem_name, rte_strerror(rte_errno));
+		return -1;
 	}
+
+	return 0;
 }
 
 int
@@ -1143,9 +1148,11 @@
 	struct bond_dev_private *internals = bond_dev->data->dev_private;
 	uint8_t i;
 
-	for (i = 0; i < internals->active_slave_count; i++)
-		bond_mode_8023ad_activate_slave(bond_dev,
-				internals->active_slaves[i]);
+	for (i = 0; i < internals->active_slave_count; i++) {
+		if (!bond_mode_8023ad_activate_slave(bond_dev,
+						internals->active_slaves[i]))
+			return -1;
+	}
 
 	return 0;
 }
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad_private.h b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
index 0f490a5..96a42f2 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
@@ -263,7 +263,7 @@ struct mode8023ad_private {
  * @return
  *  0 on success, negative value otherwise.
  */
-void
+int
 bond_mode_8023ad_activate_slave(struct rte_eth_dev *dev, uint16_t port_id);
 
 /**
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index aa89425..657fd74 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -69,14 +69,15 @@
 	return 0;
 }
 
-void
+int
 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id)
 {
 	struct bond_dev_private *internals = eth_dev->data->dev_private;
 	uint8_t active_count = internals->active_slave_count;
 
 	if (internals->mode == BONDING_MODE_8023AD)
-		bond_mode_8023ad_activate_slave(eth_dev, port_id);
+		if (bond_mode_8023ad_activate_slave(eth_dev, port_id) != 0)
+			return -1;
 
 	if (internals->mode == BONDING_MODE_TLB
 			|| internals->mode == BONDING_MODE_ALB) {
@@ -94,6 +95,8 @@
 		bond_tlb_activate_slave(internals);
 	if (internals->mode == BONDING_MODE_ALB)
 		bond_mode_alb_client_list_upd(eth_dev);
+
+	return 0;
 }
 
 void
@@ -357,10 +360,17 @@
 				bond_ethdev_primary_set(internals,
 							slave_port_id);
 
-			if (find_slave_by_id(internals->active_slaves,
-					     internals->active_slave_count,
-					     slave_port_id) == internals->active_slave_count)
-				activate_slave(bonded_eth_dev, slave_port_id);
+			int rc =
+				find_slave_by_id(internals->active_slaves,
+					internals->active_slave_count,
+					slave_port_id);
+
+			if (rc == internals->active_slave_count) {
+				int rc = activate_slave(bonded_eth_dev,
+							slave_port_id);
+				if (rc != 0)
+					return -1;
+			}
 		}
 	}
 
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 09696ea..d2dbe4a 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1741,8 +1741,10 @@ struct bwg_slave {
 		/* Any memory allocation failure in initialization is critical because
 		 * resources can't be free, so reinitialization is impossible. */
 		if (port->slow_pool == NULL) {
-			rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
-				slave_id, mem_name, rte_strerror(rte_errno));
+			RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
+				__func__, slave_id,
+				mem_name, rte_strerror(rte_errno));
+			return -1;
 		}
 	}
 
@@ -2673,7 +2675,8 @@ struct bwg_slave {
 			mac_address_slaves_update(bonded_eth_dev);
 		}
 
-		activate_slave(bonded_eth_dev, port_id);
+		if (activate_slave(bonded_eth_dev, port_id) != 0)
+			return -1;
 
 		/* If user has defined the primary port then default to using it */
 		if (internals->user_defined_primary_port &&
diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h
index 94eca88..d99d42c 100644
--- a/drivers/net/bonding/rte_eth_bond_private.h
+++ b/drivers/net/bonding/rte_eth_bond_private.h
@@ -187,7 +187,7 @@ struct bond_dev_private {
 void
 deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
 
-void
+int
 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
 
 void
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 03/10] e1000: replace rte_panic instances in e1000 driver
    2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
@ 2018-04-26  6:20  3%   ` Arnon Warshavsky
  2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:20 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/e1000/e1000_ethdev.h |  2 +-
 drivers/net/e1000/igb_ethdev.c   |  4 +++-
 drivers/net/e1000/igb_pf.c       | 15 +++++++++------
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h
index 6354b89..2e527de 100644
--- a/drivers/net/e1000/e1000_ethdev.h
+++ b/drivers/net/e1000/e1000_ethdev.h
@@ -411,7 +411,7 @@ int eth_igb_rss_hash_conf_get(struct rte_eth_dev *dev,
 /*
  * misc function prototypes
  */
-void igb_pf_host_init(struct rte_eth_dev *eth_dev);
+int igb_pf_host_init(struct rte_eth_dev *eth_dev);
 
 void igb_pf_mbx_process(struct rte_eth_dev *eth_dev);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 9b808a9..67a32a2 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -833,7 +833,9 @@ static int igb_flex_filter_uninit(struct rte_eth_dev *eth_dev)
 	}
 
 	/* initialize PF if max_vfs not zero */
-	igb_pf_host_init(eth_dev);
+	error = igb_pf_host_init(eth_dev);
+	if (error != 0)
+		goto err_late;
 
 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
 	/* Set PF Reset Done bit so PF/VF Mail Ops can work */
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index b9f2e53..6e511a9 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -63,7 +63,7 @@ int igb_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num)
 	return 0;
 }
 
-void igb_pf_host_init(struct rte_eth_dev *eth_dev)
+int igb_pf_host_init(struct rte_eth_dev *eth_dev)
 {
 	struct e1000_vf_info **vfinfo =
 		E1000_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
@@ -74,7 +74,7 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 
 	RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
 	if (0 == (vf_num = dev_num_vf(eth_dev)))
-		return;
+		return 0;
 
 	if (hw->mac.type == e1000_i350)
 		nb_queue = 1;
@@ -82,11 +82,14 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 		/* per datasheet, it should be 2, but 1 seems correct */
 		nb_queue = 1;
 	else
-		return;
+		return 0;
 
 	*vfinfo = rte_zmalloc("vf_info", sizeof(struct e1000_vf_info) * vf_num, 0);
-	if (*vfinfo == NULL)
-		rte_panic("Cannot allocate memory for private VF data\n");
+	if (*vfinfo == NULL) {
+		PMD_DRV_LOG(CRIT, "%s(): Cannot allocate memory for private VF data\n",
+			__func__);
+		return -ENOMEM;
+	}
 
 	RTE_ETH_DEV_SRIOV(eth_dev).active = ETH_8_POOLS;
 	RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = nb_queue;
@@ -98,7 +101,7 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev)
 	/* set mb interrupt mask */
 	igb_mb_intr_setup(eth_dev);
 
-	return;
+	return 0;
 }
 
 void igb_pf_host_uninit(struct rte_eth_dev *dev)
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 04/10] ixgbe: replace rte_panic instances in ixgbe driver
    2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
  2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
@ 2018-04-26  6:20  3%   ` Arnon Warshavsky
  2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:20 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c |  6 ++++--
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 +-
 drivers/net/ixgbe/ixgbe_pf.c     | 15 ++++++++++-----
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a5e2fc0..fb95cc7 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1061,7 +1061,7 @@ struct rte_ixgbe_xstats_name_off {
 		IXGBE_DEV_PRIVATE_TO_BW_CONF(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 	uint16_t csum;
-	int diag, i;
+	int diag, i, error;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1224,7 +1224,9 @@ struct rte_ixgbe_xstats_name_off {
 	memset(hwstrip, 0, sizeof(*hwstrip));
 
 	/* initialize PF if max_vfs not zero */
-	ixgbe_pf_host_init(eth_dev);
+	error = ixgbe_pf_host_init(eth_dev);
+	if (error != 0)
+		return error;
 
 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
 	/* let hardware know driver is loaded */
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 6550777..8bb41ec 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -661,7 +661,7 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev);
 
-void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);
+int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);
 
 void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev);
 
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 4e61310..81a9910 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -66,7 +66,7 @@ int ixgbe_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num)
 	return 0;
 }
 
-void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
+int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 {
 	struct ixgbe_vf_info **vfinfo =
 		IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
@@ -84,11 +84,14 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 	RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
-		return;
+		return 0;
 
 	*vfinfo = rte_zmalloc("vf_info", sizeof(struct ixgbe_vf_info) * vf_num, 0);
-	if (*vfinfo == NULL)
-		rte_panic("Cannot allocate memory for private VF data\n");
+	if (*vfinfo == NULL) {
+		PMD_DRV_LOG(ERR, "%s() Cannot allocate memory for private VF data\n",
+				__func__);
+		return -ENOMEM;
+	}
 
 	memset(mirror_info, 0, sizeof(struct ixgbe_mirror_info));
 	memset(uta_info, 0, sizeof(struct ixgbe_uta_info));
@@ -116,6 +119,8 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 
 	/* set mb interrupt mask */
 	ixgbe_mb_intr_setup(eth_dev);
+
+	return 0;
 }
 
 void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
@@ -203,7 +208,7 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
-		return -1;
+		return -ENOMEM;
 
 	/* enable VMDq and set the default pool for PF */
 	vtctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 06/10] kni: replace rte_panic instances in kni
                       ` (2 preceding siblings ...)
  2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
@ 2018-04-26  6:21  3%   ` Arnon Warshavsky
  2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
  2018-04-26  6:21  2%   ` [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
  5 siblings, 0 replies; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:21 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

replace panic calls with log and return value.
Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 lib/librte_kni/rte_kni.c      | 18 ++++++++++++------
 lib/librte_kni/rte_kni_fifo.h | 11 ++++++++---
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 8a8f6c1..4dac407 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -353,37 +353,43 @@ struct rte_kni *
 	/* TX RING */
 	mz = slot->m_tx_q;
 	ctx->tx_q = mz->addr;
-	kni_fifo_init(ctx->tx_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->tx_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.tx_phys = mz->phys_addr;
 
 	/* RX RING */
 	mz = slot->m_rx_q;
 	ctx->rx_q = mz->addr;
-	kni_fifo_init(ctx->rx_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->rx_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.rx_phys = mz->phys_addr;
 
 	/* ALLOC RING */
 	mz = slot->m_alloc_q;
 	ctx->alloc_q = mz->addr;
-	kni_fifo_init(ctx->alloc_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->alloc_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.alloc_phys = mz->phys_addr;
 
 	/* FREE RING */
 	mz = slot->m_free_q;
 	ctx->free_q = mz->addr;
-	kni_fifo_init(ctx->free_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->free_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.free_phys = mz->phys_addr;
 
 	/* Request RING */
 	mz = slot->m_req_q;
 	ctx->req_q = mz->addr;
-	kni_fifo_init(ctx->req_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->req_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.req_phys = mz->phys_addr;
 
 	/* Response RING */
 	mz = slot->m_resp_q;
 	ctx->resp_q = mz->addr;
-	kni_fifo_init(ctx->resp_q, KNI_FIFO_COUNT_MAX);
+	if (kni_fifo_init(ctx->resp_q, KNI_FIFO_COUNT_MAX))
+		return NULL;
 	dev_info.resp_phys = mz->phys_addr;
 
 	/* Req/Resp sync mem area */
diff --git a/lib/librte_kni/rte_kni_fifo.h b/lib/librte_kni/rte_kni_fifo.h
index ac26a8c..5052015 100644
--- a/lib/librte_kni/rte_kni_fifo.h
+++ b/lib/librte_kni/rte_kni_fifo.h
@@ -7,17 +7,22 @@
 /**
  * Initializes the kni fifo structure
  */
-static void
+static int
 kni_fifo_init(struct rte_kni_fifo *fifo, unsigned size)
 {
 	/* Ensure size is power of 2 */
-	if (size & (size - 1))
-		rte_panic("KNI fifo size must be power of 2\n");
+	if (size & (size - 1)) {
+		RTE_LOG(CRIT, EAL, "%s(): KNI fifo size must be power of 2\n",
+				__func__);
+		return -1;
+	}
 
 	fifo->write = 0;
 	fifo->read = 0;
 	fifo->len = size;
 	fifo->elem_size = sizeof(void *);
+
+	return 0;
 }
 
 /**
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev
                       ` (3 preceding siblings ...)
  2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
@ 2018-04-26  6:21  3%   ` Arnon Warshavsky
  2018-04-26 16:07  0%     ` Kevin Traynor
  2018-04-26  6:21  2%   ` [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
  5 siblings, 1 reply; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:21 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Local function to this file,
changing from void to int is non-abi-breaking

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
---
 lib/librte_ether/rte_ethdev.c | 42 ++++++++++++++++++++++++++++++------------
 lib/librte_ether/rte_ethdev.h |  4 +++-
 2 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f0f53d4..940de15 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -194,7 +194,7 @@ enum {
 	return port_id;
 }
 
-static void
+static int
 rte_eth_dev_shared_data_prepare(void)
 {
 	const unsigned flags = 0;
@@ -210,8 +210,12 @@ enum {
 					rte_socket_id(), flags);
 		} else
 			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
-		if (mz == NULL)
-			rte_panic("Cannot allocate ethdev shared data\n");
+		if (mz == NULL) {
+			rte_spinlock_unlock(&rte_eth_shared_data_lock);
+			RTE_LOG(CRIT, EAL, "%s(): Cannot allocate ethdev shared data\n",
+					__func__);
+			return -1;
+		}
 
 		rte_eth_dev_shared_data = mz->addr;
 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
@@ -224,6 +228,8 @@ enum {
 	}
 
 	rte_spinlock_unlock(&rte_eth_shared_data_lock);
+
+	return 0;
 }
 
 struct rte_eth_dev *
@@ -274,7 +280,8 @@ struct rte_eth_dev *
 	uint16_t port_id;
 	struct rte_eth_dev *eth_dev = NULL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return NULL;
 
 	/* Synchronize port creation between primary and secondary threads. */
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
@@ -317,7 +324,8 @@ struct rte_eth_dev *
 	uint16_t i;
 	struct rte_eth_dev *eth_dev = NULL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return NULL;
 
 	/* Synchronize port attachment to primary port creation and release. */
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
@@ -345,7 +353,8 @@ struct rte_eth_dev *
 	if (eth_dev == NULL)
 		return -EINVAL;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -399,7 +408,8 @@ struct rte_eth_dev *
 int __rte_experimental
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -450,7 +460,8 @@ struct rte_eth_dev *
 {
 	int ret;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -467,7 +478,8 @@ struct rte_eth_dev *
 			{.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
 	int ret;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -477,12 +489,15 @@ struct rte_eth_dev *
 	return ret;
 }
 
-void __rte_experimental
+int __rte_experimental
 rte_eth_dev_owner_delete(const uint64_t owner_id)
 {
 	uint16_t port_id;
+	int error;
 
-	rte_eth_dev_shared_data_prepare();
+	error = rte_eth_dev_shared_data_prepare();
+	if (error != 0)
+		return error;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
@@ -495,6 +510,8 @@ struct rte_eth_dev *
 	}
 
 	rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+	return 0;
 }
 
 int __rte_experimental
@@ -502,7 +519,8 @@ struct rte_eth_dev *
 {
 	int ret = 0;
 
-	rte_eth_dev_shared_data_prepare();
+	if (rte_eth_dev_shared_data_prepare() != 0)
+		return -1;
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b9eb8ae..46e5947 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1354,8 +1354,10 @@ int __rte_experimental rte_eth_dev_owner_unset(const uint16_t port_id,
  *
  * @param	owner_id
  *  The owner identifier.
+ *  @return
+ *  0 on success, negative errno value on error.
  */
-void __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
+int __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
 
 /**
  * @warning
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence
                       ` (4 preceding siblings ...)
  2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
@ 2018-04-26  6:21  2%   ` Arnon Warshavsky
  2018-04-26 16:07  0%     ` Kevin Traynor
  5 siblings, 1 reply; 200+ results
From: Arnon Warshavsky @ 2018-04-26  6:21 UTC (permalink / raw)
  To: thomas, anatoly.burakov, wenzhuo.lu, declan.doherty, jerin.jacob,
	bruce.richardson, ferruh.yigit
  Cc: dev, arnon

Change some local functions return type from void to int.
This change does not break ABI as the functions are internal.
Panic thrown from threads was not handled in this patch

Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/librte_eal/bsdapp/eal/eal.c   |  71 ++++++++++++++++++++-------
 lib/librte_eal/linuxapp/eal/eal.c | 101 ++++++++++++++++++++++++++------------
 2 files changed, 121 insertions(+), 51 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 10d8dc0..c958ed9 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -151,7 +151,7 @@ enum rte_iova_mode
  * We also don't lock the whole file, so that in future we can use read-locks
  * on other parts, e.g. memzones, to detect if there are running secondary
  * processes. */
-static void
+static int
 rte_eal_config_create(void)
 {
 	void *rte_mem_cfg_addr;
@@ -160,60 +160,83 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	if (mem_cfg_fd < 0){
 		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+					__func__, pathname);
+			return -1;
+		}
 	}
 
 	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
 	if (retval < 0){
 		close(mem_cfg_fd);
-		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
 	if (retval < 0){
 		close(mem_cfg_fd);
-		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
-				"process running?\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'. Is another primary process running?\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 
 	if (rte_mem_cfg_addr == MAP_FAILED){
-		rte_panic("Cannot mmap memory for rte_config\n");
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+				__func__);
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		return -1;
 	}
 	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
 	rte_config.mem_config = rte_mem_cfg_addr;
+
+	return 0;
 }
 
 /* attach to an existing shared memory config */
-static void
+static int
 rte_eal_config_attach(void)
 {
 	void *rte_mem_cfg_addr;
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	if (mem_cfg_fd < 0){
 		mem_cfg_fd = open(pathname, O_RDWR);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+					__func__, pathname);
+			return -1;
+		}
 	}
 
 	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 	close(mem_cfg_fd);
-	if (rte_mem_cfg_addr == MAP_FAILED)
-		rte_panic("Cannot mmap memory for rte_config\n");
+	if (rte_mem_cfg_addr == MAP_FAILED) {
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+				__func__);
+		return -1;
+	}
 
 	rte_config.mem_config = rte_mem_cfg_addr;
+
+	return 0;
 }
 
 /* Detect if we are a primary or a secondary process */
@@ -237,23 +260,29 @@ enum rte_proc_type_t
 }
 
 /* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
 rte_config_init(void)
 {
 	rte_config.process_type = internal_config.process_type;
 
 	switch (rte_config.process_type){
 	case RTE_PROC_PRIMARY:
-		rte_eal_config_create();
+		if (rte_eal_config_create())
+			return -1;
 		break;
 	case RTE_PROC_SECONDARY:
-		rte_eal_config_attach();
+		if (rte_eal_config_attach())
+			return -1;
 		rte_eal_mcfg_wait_complete(rte_config.mem_config);
 		break;
 	case RTE_PROC_AUTO:
 	case RTE_PROC_INVALID:
-		rte_panic("Invalid process type\n");
+	default:
+		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
+				__func__, rte_config.process_type);
+		return -1;
 	}
+	return 0;
 }
 
 /* display usage */
@@ -552,7 +581,11 @@ static void rte_eal_init_alert(const char *msg)
 		return -1;
 	}
 
-	rte_config_init();
+	if (rte_config_init() != 0) {
+		rte_eal_init_alert("Failed to init configuration");
+		rte_errno = EFAULT;
+		return -1;
+	}
 
 	/* Put mp channel init before bus scan so that we can init the vdev
 	 * bus through mp channel in the secondary process before the bus scan.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 200e879..c0d704b 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -160,7 +160,7 @@ enum rte_iova_mode
  * We also don't lock the whole file, so that in future we can use read-locks
  * on other parts, e.g. memzones, to detect if there are running secondary
  * processes. */
-static void
+static int
 rte_eal_config_create(void)
 {
 	void *rte_mem_cfg_addr;
@@ -169,7 +169,7 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	/* map the config before hugepage address so that we don't waste a page */
 	if (internal_config.base_virtaddr != 0)
@@ -179,30 +179,42 @@ enum rte_iova_mode
 	else
 		rte_mem_cfg_addr = NULL;
 
-	if (mem_cfg_fd < 0){
+	if (mem_cfg_fd < 0) {
 		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+				__func__, pathname);
+			return -1;
+		}
 	}
 
 	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
-	if (retval < 0){
+	if (retval < 0) {
 		close(mem_cfg_fd);
-		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
+				__func__, pathname);
+		return -1;
 	}
 
 	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
-	if (retval < 0){
+	if (retval < 0) {
 		close(mem_cfg_fd);
-		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
-				"process running?\n", pathname);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'.Is another primary process running?\n",
+			__func__, pathname);
+		return -1;
 	}
 
 	rte_mem_cfg_addr = mmap(rte_mem_cfg_addr, sizeof(*rte_config.mem_config),
 				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
 
-	if (rte_mem_cfg_addr == MAP_FAILED){
-		rte_panic("Cannot mmap memory for rte_config\n");
+	if (rte_mem_cfg_addr == MAP_FAILED) {
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
+			__func__);
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		return -1;
 	}
 	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
 	rte_config.mem_config = rte_mem_cfg_addr;
@@ -211,10 +223,11 @@ enum rte_iova_mode
 	 * processes could later map the config into this exact location */
 	rte_config.mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;
 
+	return 0;
 }
 
 /* attach to an existing shared memory config */
-static void
+static int
 rte_eal_config_attach(void)
 {
 	struct rte_mem_config *mem_config;
@@ -222,33 +235,42 @@ enum rte_iova_mode
 	const char *pathname = eal_runtime_config_path();
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
-	if (mem_cfg_fd < 0){
+	if (mem_cfg_fd < 0) {
 		mem_cfg_fd = open(pathname, O_RDWR);
-		if (mem_cfg_fd < 0)
-			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+		if (mem_cfg_fd < 0) {
+			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
+						__func__, pathname);
+			return -1;
+		}
 	}
 
 	/* map it as read-only first */
 	mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config),
 			PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
-	if (mem_config == MAP_FAILED)
-		rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
-			  errno, strerror(errno));
+	if (mem_config == MAP_FAILED) {
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
+				__func__, errno, strerror(errno));
+		return -1;
+	}
 
 	rte_config.mem_config = mem_config;
+
+	return 0;
 }
 
 /* reattach the shared config at exact memory location primary process has it */
-static void
+static int
 rte_eal_config_reattach(void)
 {
 	struct rte_mem_config *mem_config;
 	void *rte_mem_cfg_addr;
 
 	if (internal_config.no_shconf)
-		return;
+		return 0;
 
 	/* save the address primary process has mapped shared config to */
 	rte_mem_cfg_addr = (void *) (uintptr_t) rte_config.mem_config->mem_cfg_addr;
@@ -263,16 +285,20 @@ enum rte_iova_mode
 	if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
 		if (mem_config != MAP_FAILED)
 			/* errno is stale, don't use */
-			rte_panic("Cannot mmap memory for rte_config at [%p], got [%p]"
-				  " - please use '--base-virtaddr' option\n",
-				  rte_mem_cfg_addr, mem_config);
+			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config at [%p], got [%p] - please use '--base-virtaddr' option\n",
+					__func__, rte_mem_cfg_addr, mem_config);
 		else
-			rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
-				  errno, strerror(errno));
+			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
+					__func__, errno, strerror(errno));
+		close(mem_cfg_fd);
+		mem_cfg_fd = -1;
+		return -1;
 	}
 	close(mem_cfg_fd);
 
 	rte_config.mem_config = mem_config;
+
+	return 0;
 }
 
 /* Detect if we are a primary or a secondary process */
@@ -296,24 +322,32 @@ enum rte_proc_type_t
 }
 
 /* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
 rte_config_init(void)
 {
 	rte_config.process_type = internal_config.process_type;
 
 	switch (rte_config.process_type){
 	case RTE_PROC_PRIMARY:
-		rte_eal_config_create();
+		if (rte_eal_config_create())
+			return -1;
 		break;
 	case RTE_PROC_SECONDARY:
-		rte_eal_config_attach();
+		if (rte_eal_config_attach())
+			return -1;
 		rte_eal_mcfg_wait_complete(rte_config.mem_config);
-		rte_eal_config_reattach();
+		if (rte_eal_config_reattach())
+			return -1;
 		break;
 	case RTE_PROC_AUTO:
 	case RTE_PROC_INVALID:
-		rte_panic("Invalid process type\n");
+	default:
+		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
+				__func__, rte_config.process_type);
+		return -1;
 	}
+
+	return 0;
 }
 
 /* Unlocks hugepage directories that were locked by eal_hugepage_info_init */
@@ -833,6 +867,9 @@ static void rte_eal_init_alert(const char *msg)
 
 	rte_srand(rte_rdtsc());
 
+	if (rte_config_init() != 0)
+		return -1;
+
 	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) {
 		rte_eal_init_alert("Cannot init logging.");
 		rte_errno = ENOMEM;
-- 
1.8.3.1

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v4 2/5] mempool: implement abstract mempool info API
  2018-04-26 10:59  4% ` [dpdk-dev] [PATCH v4 0/5] mempool: add bucket driver Andrew Rybchenko
@ 2018-04-26 10:59  4%   ` Andrew Rybchenko
  2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 3/5] mempool: support block dequeue operation Andrew Rybchenko
  1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-26 10:59 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ, Artem V. Andreev

From: "Artem V. Andreev" <Artem.Andreev@oktetlabs.ru>

Primarily, it is intended as a way for the mempool driver to provide
additional information on how it lays up objects inside the mempool.

Signed-off-by: Artem V. Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_mempool/rte_mempool.h           | 50 ++++++++++++++++++++++++++++++
 lib/librte_mempool/rte_mempool_ops.c       | 15 +++++++++
 lib/librte_mempool/rte_mempool_version.map |  7 +++++
 3 files changed, 72 insertions(+)

diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 3e06ae051..853f2da4d 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -189,6 +189,23 @@ struct rte_mempool_memhdr {
 	void *opaque;            /**< Argument passed to the free callback */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Additional information about the mempool
+ *
+ * The structure is cache-line aligned to avoid ABI breakages in
+ * a number of cases when something small is added.
+ */
+struct rte_mempool_info {
+	/*
+	 * Dummy structure member to make it non emtpy until the first
+	 * real member is added.
+	 */
+	unsigned int dummy;
+} __rte_cache_aligned;
+
 /**
  * The RTE mempool structure.
  */
@@ -499,6 +516,16 @@ int rte_mempool_op_populate_default(struct rte_mempool *mp,
 		void *vaddr, rte_iova_t iova, size_t len,
 		rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get some additional information about a mempool.
+ */
+typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
+		struct rte_mempool_info *info);
+
+
 /** Structure defining mempool operations structure */
 struct rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
@@ -517,6 +544,10 @@ struct rte_mempool_ops {
 	 * provided memory chunk.
 	 */
 	rte_mempool_populate_t populate;
+	/**
+	 * Get mempool info
+	 */
+	rte_mempool_get_info_t get_info;
 } __rte_cache_aligned;
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
@@ -679,6 +710,25 @@ int rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
 			     rte_mempool_populate_obj_cb_t *obj_cb,
 			     void *obj_cb_arg);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Wrapper for mempool_ops get_info callback.
+ *
+ * @param[in] mp
+ *   Pointer to the memory pool.
+ * @param[out] info
+ *   Pointer to the rte_mempool_info structure
+ * @return
+ *   - 0: Success; The mempool driver supports retrieving supplementary
+ *        mempool information
+ *   - -ENOTSUP - doesn't support get_info ops (valid case).
+ */
+__rte_experimental
+int rte_mempool_ops_get_info(const struct rte_mempool *mp,
+			 struct rte_mempool_info *info);
+
 /**
  * @internal wrapper for mempool_ops free callback.
  *
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index ea9be1eb2..efc1c084c 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -59,6 +59,7 @@ rte_mempool_register_ops(const struct rte_mempool_ops *h)
 	ops->get_count = h->get_count;
 	ops->calc_mem_size = h->calc_mem_size;
 	ops->populate = h->populate;
+	ops->get_info = h->get_info;
 
 	rte_spinlock_unlock(&rte_mempool_ops_table.sl);
 
@@ -134,6 +135,20 @@ rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
 			     obj_cb_arg);
 }
 
+/* wrapper to get additional mempool info */
+int
+rte_mempool_ops_get_info(const struct rte_mempool *mp,
+			 struct rte_mempool_info *info)
+{
+	struct rte_mempool_ops *ops;
+
+	ops = rte_mempool_get_ops(mp->ops_index);
+
+	RTE_FUNC_PTR_OR_ERR_RET(ops->get_info, -ENOTSUP);
+	return ops->get_info(mp, info);
+}
+
+
 /* sets mempool ops previously registered by rte_mempool_register_ops. */
 int
 rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index cf375dbe6..c9d16ecc4 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -57,3 +57,10 @@ DPDK_18.05 {
 	rte_mempool_op_populate_default;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_mempool_ops_get_info;
+
+} DPDK_18.05;
-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 3/5] mempool: support block dequeue operation
  2018-04-26 10:59  4% ` [dpdk-dev] [PATCH v4 0/5] mempool: add bucket driver Andrew Rybchenko
  2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 2/5] mempool: implement abstract mempool info API Andrew Rybchenko
@ 2018-04-26 10:59  4%   ` Andrew Rybchenko
  1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-26 10:59 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ, Artem V. Andreev

From: "Artem V. Andreev" <Artem.Andreev@oktetlabs.ru>

If mempool manager supports object blocks (physically and virtual
contiguous set of objects), it is sufficient to get the first
object only and the function allows to avoid filling in of
information about each block member.

Signed-off-by: Artem V. Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst       |   7 --
 lib/librte_mempool/Makefile                |   1 +
 lib/librte_mempool/meson.build             |   2 +
 lib/librte_mempool/rte_mempool.c           |  39 +++++++++
 lib/librte_mempool/rte_mempool.h           | 131 +++++++++++++++++++++++++++--
 lib/librte_mempool/rte_mempool_ops.c       |   1 +
 lib/librte_mempool/rte_mempool_version.map |   1 +
 7 files changed, 170 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 72ab33cb7..da156c3cc 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -42,13 +42,6 @@ Deprecation Notices
 
   - ``rte_eal_mbuf_default_mempool_ops``
 
-* mempool: several API and ABI changes are planned in v18.05.
-
-  The following changes are planned:
-
-  - addition of new op to allocate contiguous
-    block of objects if underlying driver supports it.
-
 * mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
   definition in line with the ethdev TM and MTR APIs. Currently, this field
   is defined in librte_sched in a non-generic way. The new generic format
diff --git a/lib/librte_mempool/Makefile b/lib/librte_mempool/Makefile
index 7f19f005a..e3c32b14f 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -10,6 +10,7 @@ CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
 # Allow deprecated symbol to use deprecated rte_mempool_populate_iova_tab()
 # from earlier deprecated rte_mempool_populate_phys_tab()
 CFLAGS += -Wno-deprecated-declarations
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_ring
 
 EXPORT_MAP := rte_mempool_version.map
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index baf2d24d5..d507e5511 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
+
 extra_flags = []
 
 # Allow deprecated symbol to use deprecated rte_mempool_populate_iova_tab()
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 84b3d640f..cf5d124ec 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -1255,6 +1255,36 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp,
 #endif
 }
 
+void
+rte_mempool_contig_blocks_check_cookies(const struct rte_mempool *mp,
+	void * const *first_obj_table_const, unsigned int n, int free)
+{
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	struct rte_mempool_info info;
+	const size_t total_elt_sz =
+		mp->header_size + mp->elt_size + mp->trailer_size;
+	unsigned int i, j;
+
+	rte_mempool_ops_get_info(mp, &info);
+
+	for (i = 0; i < n; ++i) {
+		void *first_obj = first_obj_table_const[i];
+
+		for (j = 0; j < info.contig_block_size; ++j) {
+			void *obj;
+
+			obj = (void *)((uintptr_t)first_obj + j * total_elt_sz);
+			rte_mempool_check_cookies(mp, &obj, 1, free);
+		}
+	}
+#else
+	RTE_SET_USED(mp);
+	RTE_SET_USED(first_obj_table_const);
+	RTE_SET_USED(n);
+	RTE_SET_USED(free);
+#endif
+}
+
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
 static void
 mempool_obj_audit(struct rte_mempool *mp, __rte_unused void *opaque,
@@ -1320,6 +1350,7 @@ void
 rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 {
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	struct rte_mempool_info info;
 	struct rte_mempool_debug_stats sum;
 	unsigned lcore_id;
 #endif
@@ -1361,6 +1392,7 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 
 	/* sum and dump statistics */
 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	rte_mempool_ops_get_info(mp, &info);
 	memset(&sum, 0, sizeof(sum));
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		sum.put_bulk += mp->stats[lcore_id].put_bulk;
@@ -1369,6 +1401,8 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 		sum.get_success_objs += mp->stats[lcore_id].get_success_objs;
 		sum.get_fail_bulk += mp->stats[lcore_id].get_fail_bulk;
 		sum.get_fail_objs += mp->stats[lcore_id].get_fail_objs;
+		sum.get_success_blks += mp->stats[lcore_id].get_success_blks;
+		sum.get_fail_blks += mp->stats[lcore_id].get_fail_blks;
 	}
 	fprintf(f, "  stats:\n");
 	fprintf(f, "    put_bulk=%"PRIu64"\n", sum.put_bulk);
@@ -1377,6 +1411,11 @@ rte_mempool_dump(FILE *f, struct rte_mempool *mp)
 	fprintf(f, "    get_success_objs=%"PRIu64"\n", sum.get_success_objs);
 	fprintf(f, "    get_fail_bulk=%"PRIu64"\n", sum.get_fail_bulk);
 	fprintf(f, "    get_fail_objs=%"PRIu64"\n", sum.get_fail_objs);
+	if (info.contig_block_size > 0) {
+		fprintf(f, "    get_success_blks=%"PRIu64"\n",
+			sum.get_success_blks);
+		fprintf(f, "    get_fail_blks=%"PRIu64"\n", sum.get_fail_blks);
+	}
 #else
 	fprintf(f, "  no statistics available\n");
 #endif
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 853f2da4d..1f59553b3 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -70,6 +70,10 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_objs; /**< Objects successfully allocated. */
 	uint64_t get_fail_bulk;    /**< Failed allocation number. */
 	uint64_t get_fail_objs;    /**< Objects that failed to be allocated. */
+	/** Successful allocation number of contiguous blocks. */
+	uint64_t get_success_blks;
+	/** Failed allocation number of contiguous blocks. */
+	uint64_t get_fail_blks;
 } __rte_cache_aligned;
 #endif
 
@@ -199,11 +203,8 @@ struct rte_mempool_memhdr {
  * a number of cases when something small is added.
  */
 struct rte_mempool_info {
-	/*
-	 * Dummy structure member to make it non emtpy until the first
-	 * real member is added.
-	 */
-	unsigned int dummy;
+	/** Number of objects in the contiguous block */
+	unsigned int contig_block_size;
 } __rte_cache_aligned;
 
 /**
@@ -282,8 +283,16 @@ struct rte_mempool {
 			mp->stats[__lcore_id].name##_bulk += 1;	\
 		}                                               \
 	} while(0)
+#define __MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, name, n) do {                    \
+		unsigned int __lcore_id = rte_lcore_id();       \
+		if (__lcore_id < RTE_MAX_LCORE) {               \
+			mp->stats[__lcore_id].name##_blks += n;	\
+			mp->stats[__lcore_id].name##_bulk += 1;	\
+		}                                               \
+	} while (0)
 #else
 #define __MEMPOOL_STAT_ADD(mp, name, n) do {} while(0)
+#define __MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, name, n) do {} while (0)
 #endif
 
 /**
@@ -351,6 +360,38 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp,
 #define __mempool_check_cookies(mp, obj_table_const, n, free) do {} while(0)
 #endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * @internal Check contiguous object blocks and update cookies or panic.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ * @param first_obj_table_const
+ *   Pointer to a table of void * pointers (first object of the contiguous
+ *   object blocks).
+ * @param n
+ *   Number of contiguous object blocks.
+ * @param free
+ *   - 0: object is supposed to be allocated, mark it as free
+ *   - 1: object is supposed to be free, mark it as allocated
+ *   - 2: just check that cookie is valid (free or allocated)
+ */
+void rte_mempool_contig_blocks_check_cookies(const struct rte_mempool *mp,
+	void * const *first_obj_table_const, unsigned int n, int free);
+
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+#define __mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+					      free) \
+	rte_mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+						free)
+#else
+#define __mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
+					      free) \
+	do {} while (0)
+#endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
+
 #define RTE_MEMPOOL_OPS_NAMESIZE 32 /**< Max length of ops struct name. */
 
 /**
@@ -382,6 +423,15 @@ typedef int (*rte_mempool_enqueue_t)(struct rte_mempool *mp,
 typedef int (*rte_mempool_dequeue_t)(struct rte_mempool *mp,
 		void **obj_table, unsigned int n);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Dequeue a number of contiquous object blocks from the external pool.
+ */
+typedef int (*rte_mempool_dequeue_contig_blocks_t)(struct rte_mempool *mp,
+		 void **first_obj_table, unsigned int n);
+
 /**
  * Return the number of available objects in the external pool.
  */
@@ -548,6 +598,10 @@ struct rte_mempool_ops {
 	 * Get mempool info
 	 */
 	rte_mempool_get_info_t get_info;
+	/**
+	 * Dequeue a number of contiguous object blocks.
+	 */
+	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
 } __rte_cache_aligned;
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
@@ -625,6 +679,30 @@ rte_mempool_ops_dequeue_bulk(struct rte_mempool *mp,
 	return ops->dequeue(mp, obj_table, n);
 }
 
+/**
+ * @internal Wrapper for mempool_ops dequeue_contig_blocks callback.
+ *
+ * @param[in] mp
+ *   Pointer to the memory pool.
+ * @param[out] first_obj_table
+ *   Pointer to a table of void * pointers (first objects).
+ * @param[in] n
+ *   Number of blocks to get.
+ * @return
+ *   - 0: Success; got n objects.
+ *   - <0: Error; code of dequeue function.
+ */
+static inline int
+rte_mempool_ops_dequeue_contig_blocks(struct rte_mempool *mp,
+		void **first_obj_table, unsigned int n)
+{
+	struct rte_mempool_ops *ops;
+
+	ops = rte_mempool_get_ops(mp->ops_index);
+	RTE_ASSERT(ops->dequeue_contig_blocks != NULL);
+	return ops->dequeue_contig_blocks(mp, first_obj_table, n);
+}
+
 /**
  * @internal wrapper for mempool_ops enqueue callback.
  *
@@ -1539,6 +1617,49 @@ rte_mempool_get(struct rte_mempool *mp, void **obj_p)
 	return rte_mempool_get_bulk(mp, obj_p, 1);
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get a contiguous blocks of objects from the mempool.
+ *
+ * If cache is enabled, consider to flush it first, to reuse objects
+ * as soon as possible.
+ *
+ * The application should check that the driver supports the operation
+ * by calling rte_mempool_ops_get_info() and checking that `contig_block_size`
+ * is not zero.
+ *
+ * @param mp
+ *   A pointer to the mempool structure.
+ * @param first_obj_table
+ *   A pointer to a pointer to the first object in each block.
+ * @param n
+ *   The number of blocks to get from mempool.
+ * @return
+ *   - 0: Success; blocks taken.
+ *   - -ENOBUFS: Not enough entries in the mempool; no object is retrieved.
+ *   - -EOPNOTSUPP: The mempool driver does not support block dequeue
+ */
+static __rte_always_inline int
+__rte_experimental
+rte_mempool_get_contig_blocks(struct rte_mempool *mp,
+			      void **first_obj_table, unsigned int n)
+{
+	int ret;
+
+	ret = rte_mempool_ops_dequeue_contig_blocks(mp, first_obj_table, n);
+	if (ret == 0) {
+		__MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, get_success, n);
+		__mempool_contig_blocks_check_cookies(mp, first_obj_table, n,
+						      1);
+	} else {
+		__MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, get_fail, n);
+	}
+
+	return ret;
+}
+
 /**
  * Return the number of entries in the mempool.
  *
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index efc1c084c..a27e1fa51 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -60,6 +60,7 @@ rte_mempool_register_ops(const struct rte_mempool_ops *h)
 	ops->calc_mem_size = h->calc_mem_size;
 	ops->populate = h->populate;
 	ops->get_info = h->get_info;
+	ops->dequeue_contig_blocks = h->dequeue_contig_blocks;
 
 	rte_spinlock_unlock(&rte_mempool_ops_table.sl);
 
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index c9d16ecc4..1c406b5b0 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -53,6 +53,7 @@ DPDK_17.11 {
 DPDK_18.05 {
 	global:
 
+	rte_mempool_contig_blocks_check_cookies;
 	rte_mempool_op_calc_mem_size_default;
 	rte_mempool_op_populate_default;
 
-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 0/5] mempool: add bucket driver
    2018-04-25 16:32  4% ` [dpdk-dev] [PATCH v3 0/6] mempool: add bucket driver Andrew Rybchenko
@ 2018-04-26 10:59  4% ` Andrew Rybchenko
  2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 2/5] mempool: implement abstract mempool info API Andrew Rybchenko
  2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 3/5] mempool: support block dequeue operation Andrew Rybchenko
  1 sibling, 2 replies; 200+ results
From: Andrew Rybchenko @ 2018-04-26 10:59 UTC (permalink / raw)
  To: dev; +Cc: Olivier MATZ

The initial patch series [1] (RFCv1 is [2]) is split into two to simplify
processing.  It is the second part which relies on the first one [3]
which is already applied.

The patch series adds bucket mempool driver which allows to allocate
(both physically and virtually) contiguous blocks of objects and adds
mempool API to do it. It is still capable to provide separate objects,
but it is definitely more heavy-weight than ring/stack drivers.
The driver will be used by the future Solarflare driver enhancements
which allow to utilize physical contiguous blocks in the NIC firmware.

The target usecase is dequeue in blocks and enqueue separate objects
back (which are collected in buckets to be dequeued). So, the memory
pool with bucket driver is created by an application and provided to
networking PMD receive queue. The choice of bucket driver is done using
rte_eth_dev_pool_ops_supported(). A PMD that relies upon contiguous
block allocation should report the bucket driver as the only supported
and preferred one.

Introduction of the contiguous block dequeue operation is proven by
performance measurements using autotest with minor enhancements:
 - in the original test bulks are powers of two, which is unacceptable
   for us, so they are changed to multiple of contig_block_size;
 - the test code is duplicated to support plain dequeue and
   dequeue_contig_blocks;
 - all the extra test variations (with/without cache etc) are eliminated;
 - a fake read from the dequeued buffer is added (in both cases) to
   simulate mbufs access.

start performance test for bucket (without cache)
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   111935488
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   115290931
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=   353055539
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=   353330790
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   224657407
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   230411468
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=   706700902
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=   703673139
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Srate_persec=   425236887
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Srate_persec=   437295512
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Srate_persec=  1343409356
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Srate_persec=  1336567397
start performance test for bucket (without cache + contiguous dequeue)
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   122945536
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   126458265
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=   374262988
mempool_autotest cache=   0 cores= 1 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=   377316966
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   244842496
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   251618917
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=   751226060
mempool_autotest cache=   0 cores= 2 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=   756233010
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  30 Crate_persec=   462068120
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=   1 n_keep=  60 Crate_persec=   476997221
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  30 Crate_persec=  1432171313
mempool_autotest cache=   0 cores= 4 n_get_bulk=  15 n_put_bulk=  15 n_keep=  60 Crate_persec=  1438829771

The number of objects in the contiguous block is a function of bucket
memory size (.config option) and total element size. In the future
additional API with possibility to pass parameters on mempool allocation
may be added.

It breaks ABI since changes rte_mempool_ops. The ABI version is already
bumped in [4].

I've double-checked that mempool_autotest and mempool_perf_autotest
work fine if EAL argument --mbuf-pool-ops-name=bucket is used.

mempool_perf_autotest as is for bucket shows less rate than ring_mp_mc
since test dequeue bulk sizes are not aligned to contintiguous block size
and bucket driver is optimized for contiguous blocks allocation (or at
least allocation in bulks multiple by contiguous block size).

However, real usage of the bucket driver even without contiguous block
dequeue (transmit only benchmark which simply generates traffic) shows
better packet rate. It looks like it is because the driver is
stack-based (per lcore without locks/barriers) and it improves cache
hit (working memory is smaller since it is a subset of the mempool
instead of entire mempool when some objects do not fit into mempool cache).

Unfortunately I've not finalized yet patches which allow to repeat above
measurements (done using hacks).

The driver is required for [5].


[1] https://dpdk.org/ml/archives/dev/2018-January/088698.html
[2] https://dpdk.org/ml/archives/dev/2017-November/082335.html
[3] https://dpdk.org/ml/archives/dev/2018-April/097354.html
[4] https://dpdk.org/ml/archives/dev/2018-April/097352.html
[5] https://dpdk.org/ml/archives/dev/2018-April/098089.html

v3 -> v4:
 - squash documentation into corresponding patches
 - move the feature release notes to top of features
 - rebase on top of the mainline instead of next-net

v2 -> v3:
 - rebase
 - align rte_mempool_info structure size to avoid ABI breakages in a
   number of cases when something relative small added
 - fix bug in get_count because of not counted objects in the
   adaptation rings
 - squash __mempool_generic_get_contig_blocks() into
   rte_mempool_get_contig_blocks()
 - fix typo in documentation

v1 -> v2:
  - just rebase

RFCv2 -> v1:
  - rebased on top of [3]
  - cleanup deprecation notice when it is done
  - mark a new API experimental
  - move contig blocks dequeue debug checks/processing to the library function
  - add contig blocks get stats
  - add release notes

RFCv1 -> RFCv2:
  - change info API to get information from driver required to
    API user to know contiguous block size
  - use SPDX tags
  - avoid all objects affinity to single lcore
  - fix bucket get_count
  - fix NO_CACHE_ALIGN case in bucket mempool

Artem V. Andreev (5):
  mempool/bucket: implement bucket mempool manager
  mempool: implement abstract mempool info API
  mempool: support block dequeue operation
  mempool/bucket: implement block dequeue operation
  mempool/bucket: do not allow one lcore to grab all buckets

 MAINTAINERS                                        |   9 +
 config/common_base                                 |   2 +
 doc/guides/rel_notes/deprecation.rst               |   7 -
 doc/guides/rel_notes/release_18_05.rst             |   9 +
 drivers/mempool/Makefile                           |   1 +
 drivers/mempool/bucket/Makefile                    |  27 +
 drivers/mempool/bucket/meson.build                 |   9 +
 drivers/mempool/bucket/rte_mempool_bucket.c        | 628 +++++++++++++++++++++
 .../mempool/bucket/rte_mempool_bucket_version.map  |   4 +
 lib/librte_mempool/Makefile                        |   1 +
 lib/librte_mempool/meson.build                     |   2 +
 lib/librte_mempool/rte_mempool.c                   |  39 ++
 lib/librte_mempool/rte_mempool.h                   | 171 ++++++
 lib/librte_mempool/rte_mempool_ops.c               |  16 +
 lib/librte_mempool/rte_mempool_version.map         |   8 +
 mk/rte.app.mk                                      |   1 +
 16 files changed, 927 insertions(+), 7 deletions(-)
 create mode 100644 drivers/mempool/bucket/Makefile
 create mode 100644 drivers/mempool/bucket/meson.build
 create mode 100644 drivers/mempool/bucket/rte_mempool_bucket.c
 create mode 100644 drivers/mempool/bucket/rte_mempool_bucket_version.map

-- 
2.14.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v6 2/4] ethdev: Add group JUMP action
  @ 2018-04-26 12:08  2% ` Declan Doherty
    1 sibling, 0 replies; 200+ results
From: Declan Doherty @ 2018-04-26 12:08 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Declan Doherty

Add jump action type which defines an action which allows a matched
flow to be redirect to the specified group. This allows physical and
logical flow table/group hierarchies to be defined through rte_flow.

This breaks ABI compatibility for the following public functions (as it
modifes the ordering of the rte_flow_action_type enumeration):

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Add support for specification of new JUMP action to testpmd's flow
cli, and update the testpmd documentation to describe this new
action.

Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 23 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 61 ++++++++++++++++++++++++-----
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
 lib/librte_ether/rte_flow.h                 | 41 +++++++++++++++----
 4 files changed, 112 insertions(+), 17 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4239602b6..6e9fa5d7c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -183,6 +183,8 @@ enum index {
 	ACTION_END,
 	ACTION_VOID,
 	ACTION_PASSTHRU,
+	ACTION_JUMP,
+	ACTION_JUMP_GROUP,
 	ACTION_MARK,
 	ACTION_MARK_ID,
 	ACTION_FLAG,
@@ -738,6 +740,7 @@ static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
 	ACTION_PASSTHRU,
+	ACTION_JUMP,
 	ACTION_MARK,
 	ACTION_FLAG,
 	ACTION_QUEUE,
@@ -856,6 +859,12 @@ static const enum index action_of_push_mpls[] = {
 	ZERO,
 };
 
+static const enum index action_jump[] = {
+	ACTION_JUMP_GROUP,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_init(struct context *, const struct token *,
 		      const char *, unsigned int,
 		      void *, unsigned int);
@@ -1931,6 +1940,20 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
+	[ACTION_JUMP] = {
+		.name = "jump",
+		.help = "redirect traffic to a given group",
+		.priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
+		.next = NEXT(action_jump),
+		.call = parse_vc,
+	},
+	[ACTION_JUMP_GROUP] = {
+		.name = "group",
+		.help = "group to redirect traffic to",
+		.next = NEXT(action_jump, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_MARK] = {
 		.name = "mark",
 		.help = "attach 32 bit value to packets",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a7197cb7e..1102fae09 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -90,8 +90,12 @@ Thus predictable results for a given priority level can only be achieved
 with non-overlapping rules, using perfect matching on all protocol layers.
 
 Flow rules can also be grouped, the flow rule priority is specific to the
-group they belong to. All flow rules in a given group are thus processed
-either before or after another group.
+group they belong to. All flow rules in a given group are thus processed within
+the context of that group. Groups are not linked by default, so the logical
+hierarchy of groups must be explicitly defined by flow rules themselves in each
+group using the JUMP action to define the next group to redirect too. Only flow
+rules defined in the default group 0 are guarantee to be matched against, this
+makes group 0 the origin of any group hierarchy defined by an application.
 
 Support for multiple actions per rule may be implemented internally on top
 of non-default hardware priorities, as a result both features may not be
@@ -138,29 +142,34 @@ Attributes
 Attribute: Group
 ^^^^^^^^^^^^^^^^
 
-Flow rules can be grouped by assigning them a common group number. Lower
-values have higher priority. Group 0 has the highest priority.
+Flow rules can be grouped by assigning them a common group number. Groups
+allow a logical hierarchy of flow rule groups (tables) to be defined. These
+groups can be supported virtually in the PMD or in the physical device.
+Group 0 is the default group and this is the only group which flows are
+guarantee to matched against, all subsequent groups can only be reached by
+way of the JUMP action from a matched flow rule.
 
 Although optional, applications are encouraged to group similar rules as
 much as possible to fully take advantage of hardware capabilities
 (e.g. optimized matching) and work around limitations (e.g. a single pattern
-type possibly allowed in a given group).
+type possibly allowed in a given group), while being aware that the groups
+hierarchies must be programmed explicitly.
 
 Note that support for more than a single group is not guaranteed.
 
 Attribute: Priority
 ^^^^^^^^^^^^^^^^^^^
 
-A priority level can be assigned to a flow rule. Like groups, lower values
+A priority level can be assigned to a flow rule, lower values
 denote higher priority, with 0 as the maximum.
 
-A rule with priority 0 in group 8 is always matched after a rule with
-priority 8 in group 0.
-
-Group and priority levels are arbitrary and up to the application, they do
+Priority levels are arbitrary and up to the application, they do
 not need to be contiguous nor start from 0, however the maximum number
 varies between devices and may be affected by existing flow rules.
 
+A flow which matches multiple rules in the same group will always matched by
+the rule with the highest priority in that group.
+
 If a packet is matched by several rules of a given group for a given
 priority level, the outcome is undefined. It can take any path, may be
 duplicated or even cause unrecoverable errors.
@@ -1372,6 +1381,38 @@ flow rules:
    | 2     | END                        |
    +-------+----------------------------+
 
+Action: ``JUMP``
+^^^^^^^^^^^^^^^^
+
+Redirects packets to a group on the current device.
+
+In a hierarchy of groups, which can be used to represent physical or logical
+flow group/tables on the device, this action redirects the matched flow to
+the specified group on that device.
+
+If a matched flow is redirected to a table which doesn't contain a matching
+rule for that flow then the behavior is undefined and the resulting behavior
+is up to the specific device. Best practice when using groups would be define
+a default flow rule for each group which a defines the default actions in that
+group so a consistent behavior is defined.
+
+Defining an action for matched flow in a group to jump to a group which is
+higher in the group hierarchy may not be supported by physical devices,
+depending on how groups are mapped to the physical devices. In the
+definitions of jump actions, applications should be aware that it may be
+possible to define flow rules which trigger an undefined behavior causing
+flows to loop between groups.
+
+.. _table_rte_flow_action_jump:
+
+.. table:: JUMP
+
+   +-----------+------------------------------+
+   | Field     | Value                        |
+   +===========+==============================+
+   | ``group`` | Group to redirect packets to |
+   +-----------+------------------------------+
+
 Action: ``MARK``
 ^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2edf96dd6..260d044d5 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3453,6 +3453,10 @@ This section lists supported actions and their attributes, if any.
 
 - ``passthru``: let subsequent rule process matched packets.
 
+- ``jump``: redirect traffic to group on device.
+
+  - ``group {unsigned}``: group to redirect to.
+
 - ``mark``: attach 32 bit value to packets.
 
   - ``id {unsigned}``: 32 bit value to return with packets.
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 657cb9a99..17c1c4a89 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -35,18 +35,20 @@ extern "C" {
 /**
  * Flow rule attributes.
  *
- * Priorities are set on two levels: per group and per rule within groups.
+ * Priorities are set on a per rule based within groups.
  *
- * Lower values denote higher priority, the highest priority for both levels
- * is 0, so that a rule with priority 0 in group 8 is always matched after a
- * rule with priority 8 in group 0.
+ * Lower values denote higher priority, the highest priority for a flow rule
+ * is 0, so that a flow that matches for than one rule, the rule with the
+ * lowest priority value will always be matched.
  *
  * Although optional, applications are encouraged to group similar rules as
  * much as possible to fully take advantage of hardware capabilities
  * (e.g. optimized matching) and work around limitations (e.g. a single
- * pattern type possibly allowed in a given group).
+ * pattern type possibly allowed in a given group). Applications should be
+ * aware that groups are not linked by default, and that they must be
+ * explicitly linked by the application using the JUMP action.
  *
- * Group and priority levels are arbitrary and up to the application, they
+ * Priority levels are arbitrary and up to the application, they
  * do not need to be contiguous nor start from 0, however the maximum number
  * varies between devices and may be affected by existing flow rules.
  *
@@ -69,7 +71,7 @@ extern "C" {
  */
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
-	uint32_t priority; /**< Priority level within group. */
+	uint32_t priority; /**< Rule priority level within group. */
 	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
 	uint32_t egress:1; /**< Rule applies to egress traffic. */
 	/**
@@ -1236,6 +1238,15 @@ enum rte_flow_action_type {
 	 */
 	RTE_FLOW_ACTION_TYPE_PASSTHRU,
 
+	/**
+	 * RTE_FLOW_ACTION_TYPE_JUMP
+	 *
+	 * Redirects packets to a group on the current device.
+	 *
+	 * See struct rte_flow_action_jump.
+	 */
+	RTE_FLOW_ACTION_TYPE_JUMP,
+
 	/**
 	 * Attaches an integer value to packets and sets PKT_RX_FDIR and
 	 * PKT_RX_FDIR_ID mbuf flags.
@@ -1481,6 +1492,22 @@ struct rte_flow_action_mark {
 	uint32_t id; /**< Integer value to return with packets. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_JUMP
+ *
+ * Redirects packets to a group on the current device.
+ *
+ * In a hierarchy of groups, which can be used to represent physical or logical
+ * flow tables on the device, this action allows the action to be a redirect to
+ * a group on that device.
+ */
+struct rte_flow_action_jump {
+	uint32_t group;
+};
+
 /**
  * RTE_FLOW_ACTION_TYPE_QUEUE
  *
-- 
2.14.3

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH 12/13] bbdev: split queue groups
    @ 2018-04-26 13:30  5% ` Kamil Chalupnik
  2018-05-09 14:35  5%   ` [dpdk-dev] [PATCH v2 08/14] " Kamil Chalupnik
  1 sibling, 1 reply; 200+ results
From: Kamil Chalupnik @ 2018-04-26 13:30 UTC (permalink / raw)
  To: dev; +Cc: amr.mokhtar, pablo.de.lara.guarch, KamilX Chalupnik

From: KamilX Chalupnik <kamilx.chalupnik@intel.com>

Splitting Queue Groups into UL/DL Groups in Turbo Software
Driver. They are independent for Decode/Encode.
Release note updated accordingly.

Signed-off-by: Kamil Chalupnik <kamilx.chalupnik@intel.com>
---
 app/test-bbdev/test_bbdev.c                      | 11 ++---------
 doc/guides/rel_notes/release_18_05.rst           |  5 +++++
 drivers/baseband/null/bbdev_null.c               |  3 ++-
 drivers/baseband/turbo_sw/bbdev_turbo_software.c |  3 ++-
 lib/librte_bbdev/rte_bbdev.c                     | 13 +++++++++++--
 lib/librte_bbdev/rte_bbdev.h                     |  6 ++++--
 6 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/app/test-bbdev/test_bbdev.c b/app/test-bbdev/test_bbdev.c
index 10579ea..5d325b6 100644
--- a/app/test-bbdev/test_bbdev.c
+++ b/app/test-bbdev/test_bbdev.c
@@ -273,7 +273,7 @@ test_bbdev_configure_stop_queue(void)
 
 	/* Valid queue configuration */
 	ts_params->qconf.queue_size = info.drv.queue_size_lim;
-	ts_params->qconf.priority = info.drv.max_queue_priority;
+	ts_params->qconf.priority = info.drv.max_ul_queue_priority;
 
 	/* Device - started; queue - started */
 	rte_bbdev_start(dev_id);
@@ -413,14 +413,7 @@ test_bbdev_configure_invalid_queue_configure(void)
 			ts_params->qconf.queue_size);
 
 	ts_params->qconf.queue_size = info.drv.queue_size_lim;
-	ts_params->qconf.priority = info.drv.max_queue_priority + 1;
-	TEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,
-			&ts_params->qconf),
-			"Failed test for rte_bbdev_queue_configure: "
-			"invalid value qconf.queue_size: %u",
-			ts_params->qconf.queue_size);
-
-	ts_params->qconf.priority = info.drv.max_queue_priority;
+	ts_params->qconf.priority = info.drv.max_ul_queue_priority;
 	queue_id = info.num_queues;
 	TEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,
 			&ts_params->qconf),
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 3923dc2..116c3d4 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -69,6 +69,11 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* **Queue Groups split into UL/DL Groups**
+
+  Queue Groups have been split into UL/DL Groups in Turbo Software Driver.
+  They are independent for Decode/Encode. ``rte_bbdev_driver_info`` reflects
+  introduced changes.
 
 Removed Items
 -------------
diff --git a/drivers/baseband/null/bbdev_null.c b/drivers/baseband/null/bbdev_null.c
index 6bc8491..e8e541f 100644
--- a/drivers/baseband/null/bbdev_null.c
+++ b/drivers/baseband/null/bbdev_null.c
@@ -71,7 +71,8 @@ info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
 	dev_info->max_num_queues = internals->max_nb_queues;
 	dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT;
 	dev_info->hardware_accelerated = false;
-	dev_info->max_queue_priority = 0;
+	dev_info->max_dl_queue_priority = 0;
+	dev_info->max_ul_queue_priority = 0;
 	dev_info->default_queue_conf = default_queue_conf;
 	dev_info->capabilities = bbdev_capabilities;
 	dev_info->cpu_flag_reqs = NULL;
diff --git a/drivers/baseband/turbo_sw/bbdev_turbo_software.c b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
index af484fc..39b597b 100644
--- a/drivers/baseband/turbo_sw/bbdev_turbo_software.c
+++ b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
@@ -175,7 +175,8 @@ info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
 	dev_info->max_num_queues = internals->max_nb_queues;
 	dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT;
 	dev_info->hardware_accelerated = false;
-	dev_info->max_queue_priority = 0;
+	dev_info->max_dl_queue_priority = 0;
+	dev_info->max_ul_queue_priority = 0;
 	dev_info->default_queue_conf = default_queue_conf;
 	dev_info->capabilities = bbdev_capabilities;
 	dev_info->cpu_flag_reqs = &cpu_flag;
diff --git a/lib/librte_bbdev/rte_bbdev.c b/lib/librte_bbdev/rte_bbdev.c
index 74ecc49..28434e0 100644
--- a/lib/librte_bbdev/rte_bbdev.c
+++ b/lib/librte_bbdev/rte_bbdev.c
@@ -495,11 +495,20 @@ rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,
 					conf->queue_size, queue_id, dev_id);
 			return -EINVAL;
 		}
-		if (conf->priority > dev_info.max_queue_priority) {
+		if (conf->op_type == RTE_BBDEV_OP_TURBO_DEC &&
+			conf->priority > dev_info.max_ul_queue_priority) {
 			rte_bbdev_log(ERR,
 					"Priority (%u) of queue %u of bdev %u must be <= %u",
 					conf->priority, queue_id, dev_id,
-					dev_info.max_queue_priority);
+					dev_info.max_ul_queue_priority);
+			return -EINVAL;
+		}
+		if (conf->op_type == RTE_BBDEV_OP_TURBO_ENC &&
+			conf->priority > dev_info.max_dl_queue_priority) {
+			rte_bbdev_log(ERR,
+					"Priority (%u) of queue %u of bdev %u must be <= %u",
+					conf->priority, queue_id, dev_id,
+					dev_info.max_dl_queue_priority);
 			return -EINVAL;
 		}
 	}
diff --git a/lib/librte_bbdev/rte_bbdev.h b/lib/librte_bbdev/rte_bbdev.h
index bd0ec24..9906488 100644
--- a/lib/librte_bbdev/rte_bbdev.h
+++ b/lib/librte_bbdev/rte_bbdev.h
@@ -283,8 +283,10 @@ struct rte_bbdev_driver_info {
 	uint32_t queue_size_lim;
 	/** Set if device off-loads operation to hardware  */
 	bool hardware_accelerated;
-	/** Max value supported by queue priority */
-	uint8_t max_queue_priority;
+	/** Max value supported by queue priority for DL */
+	uint8_t max_dl_queue_priority;
+	/** Max value supported by queue priority for UL */
+	uint8_t max_ul_queue_priority;
 	/** Set if device supports per-queue interrupts */
 	bool queue_intr_supported;
 	/** Minimum alignment of buffers, in bytes */
-- 
2.5.5

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function more intuitive
  @ 2018-04-26 14:44  4%   ` Carrillo, Erik G
  2018-04-26 14:54  5%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Carrillo, Erik G @ 2018-04-26 14:44 UTC (permalink / raw)
  To: Thomas Monjalon, Burakov, Anatoly
  Cc: dev, Neil Horman, Mcnamara, John, Kovacevic, Marko,
	Robert Sanford, olivier.matz, shreyansh.jain

Thanks,  Anatoly and Thomas.  I had also considered the following chunk for the release notes:

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 04ff4fe..127a7e2 100644                                                   
--- a/doc/guides/rel_notes/release_18_05.rst                                    
+++ b/doc/guides/rel_notes/release_18_05.rst                                    
@@ -72,6 +72,11 @@ API Changes                                                  
    Also, make sure to start the actual text at the margin.                     
    =========================================================                   
                                                                                
+* **rte_lcore_has_role() return values changed**                               
+                                                                               
+  This function now returns 1 or 0 for true or false, respectively, rather        
+  than 0 or <0 for success or failure to make use of the function more         
+  intuitive.                                                                   
                                                                                
 ABI Changes                                                                    
 -----------

Do we want this note?  Also, it looks like the Doxygen documentation of the function in the header file didn't get updated.

Regards,
Erik

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, April 26, 2018 9:31 AM
> To: Burakov, Anatoly <anatoly.burakov@intel.com>
> Cc: dev@dpdk.org; Neil Horman <nhorman@tuxdriver.com>; Mcnamara,
> John <john.mcnamara@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>; Robert Sanford <rsanford@akamai.com>;
> Carrillo, Erik G <erik.g.carrillo@intel.com>; olivier.matz@6wind.com;
> shreyansh.jain@nxp.com
> Subject: Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function
> more intuitive
> 
> 26/04/2018 15:42, Anatoly Burakov:
> > rte_lcore_has_role() returns 0 if role of lcore matches requested
> > role. The return value of the API is confusing, and this is a known
> > problem with a deprecation notice announcing the change to more
> > intuitive semantics:
> >
> > Commit 064518f68d48 ("doc: announce EAL API change to lcore role
> > function")
> > Cc: erik.g.carrillo@intel.com
> >
> > Implement changes announced in the deprecation notice, and remove it.
> > Also, fix usages of this API to reflect the change. Control thread
> > patches expected new behavior and were broken before, now they are
> fixed as well.
> >
> > Fixes: d651ee4919cd ("eal: set affinity for control threads")
> > Cc: olivier.matz@6wind.com
> >
> > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> 
> Applied, thanks
> 
> 

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function more intuitive
  2018-04-26 14:44  4%   ` Carrillo, Erik G
@ 2018-04-26 14:54  5%     ` Thomas Monjalon
  2018-04-26 14:56  0%       ` Carrillo, Erik G
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-04-26 14:54 UTC (permalink / raw)
  To: Carrillo, Erik G
  Cc: Burakov, Anatoly, dev, Neil Horman, Mcnamara, John, Kovacevic,
	Marko, Robert Sanford, olivier.matz, shreyansh.jain

26/04/2018 16:44, Carrillo, Erik G:
> Thanks,  Anatoly and Thomas.  I had also considered the following chunk for the release notes:
> 
> diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
> index 04ff4fe..127a7e2 100644                                                   
> --- a/doc/guides/rel_notes/release_18_05.rst                                    
> +++ b/doc/guides/rel_notes/release_18_05.rst                                    
> @@ -72,6 +72,11 @@ API Changes                                                  
>     Also, make sure to start the actual text at the margin.                     
>     =========================================================                   
>                                                                                 
> +* **rte_lcore_has_role() return values changed**                               
> +                                                                               
> +  This function now returns 1 or 0 for true or false, respectively, rather        
> +  than 0 or <0 for success or failure to make use of the function more         
> +  intuitive.                                                                   
>                                                                                 
>  ABI Changes                                                                    
>  -----------
> 
> Do we want this note?  Also, it looks like the Doxygen documentation of the function in the header file didn't get updated.


Oh, you are right, this patch is not complete.
I've fixed it:

--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -161,6 +161,12 @@ API Changes
   announced at least one release before the ABI change is made. There are no
   ABI breaking changes planned.
 
+* eal: ``rte_lcore_has_role()`` return value changed.
+
+  This function now returns true or false, respectively, rather
+  than 0 or <0 for success or failure.
+  It makes use of the function more intuitive.
+
 * mempool: capability flags and related functions have been removed.
 
   Flags ``MEMPOOL_F_CAPA_PHYS_CONTIG`` and
diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index 334a0629e..1a2f37eaa 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -311,7 +311,7 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name,
  * @param role
  *   The role to be checked against.
  * @return
- *   On success, return 0; otherwise return a negative value.
+ *   Boolean value: positive if test is true; otherwise returns 0.
  */

Thanks Erik!

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function more intuitive
  2018-04-26 14:54  5%     ` Thomas Monjalon
@ 2018-04-26 14:56  0%       ` Carrillo, Erik G
  2018-04-26 15:37  0%         ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Carrillo, Erik G @ 2018-04-26 14:56 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Burakov, Anatoly, dev, Neil Horman, Mcnamara, John, Kovacevic,
	Marko, Robert Sanford, olivier.matz, shreyansh.jain

Great, thanks Thomas.

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, April 26, 2018 9:55 AM
> To: Carrillo, Erik G <erik.g.carrillo@intel.com>
> Cc: Burakov, Anatoly <anatoly.burakov@intel.com>; dev@dpdk.org; Neil
> Horman <nhorman@tuxdriver.com>; Mcnamara, John
> <john.mcnamara@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>; Robert Sanford <rsanford@akamai.com>;
> olivier.matz@6wind.com; shreyansh.jain@nxp.com
> Subject: Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function
> more intuitive
> 
> 26/04/2018 16:44, Carrillo, Erik G:
> > Thanks,  Anatoly and Thomas.  I had also considered the following chunk for
> the release notes:
> >
> > diff --git a/doc/guides/rel_notes/release_18_05.rst
> b/doc/guides/rel_notes/release_18_05.rst
> > index 04ff4fe..127a7e2 100644
> > --- a/doc/guides/rel_notes/release_18_05.rst
> > +++ b/doc/guides/rel_notes/release_18_05.rst
> > @@ -72,6 +72,11 @@ API Changes
> >     Also, make sure to start the actual text at the margin.
> >
> =========================================================
> >
> > +* **rte_lcore_has_role() return values changed**
> > +
> > +  This function now returns 1 or 0 for true or false, respectively, rather
> > +  than 0 or <0 for success or failure to make use of the function more
> > +  intuitive.
> >
> >  ABI Changes
> >  -----------
> >
> > Do we want this note?  Also, it looks like the Doxygen documentation of
> the function in the header file didn't get updated.
> 
> 
> Oh, you are right, this patch is not complete.
> I've fixed it:
> 
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> @@ -161,6 +161,12 @@ API Changes
>    announced at least one release before the ABI change is made. There are
> no
>    ABI breaking changes planned.
> 
> +* eal: ``rte_lcore_has_role()`` return value changed.
> +
> +  This function now returns true or false, respectively, rather  than 0
> + or <0 for success or failure.
> +  It makes use of the function more intuitive.
> +
>  * mempool: capability flags and related functions have been removed.
> 
>    Flags ``MEMPOOL_F_CAPA_PHYS_CONTIG`` and diff --git
> a/lib/librte_eal/common/include/rte_lcore.h
> b/lib/librte_eal/common/include/rte_lcore.h
> index 334a0629e..1a2f37eaa 100644
> --- a/lib/librte_eal/common/include/rte_lcore.h
> +++ b/lib/librte_eal/common/include/rte_lcore.h
> @@ -311,7 +311,7 @@ rte_ctrl_thread_create(pthread_t *thread, const char
> *name,
>   * @param role
>   *   The role to be checked against.
>   * @return
> - *   On success, return 0; otherwise return a negative value.
> + *   Boolean value: positive if test is true; otherwise returns 0.
>   */
> 
> Thanks Erik!
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function more intuitive
  2018-04-26 14:56  0%       ` Carrillo, Erik G
@ 2018-04-26 15:37  0%         ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-04-26 15:37 UTC (permalink / raw)
  To: Carrillo, Erik G
  Cc: Thomas Monjalon, Burakov, Anatoly, dev, Neil Horman, Mcnamara,
	John, Kovacevic, Marko, Robert Sanford, olivier.matz,
	shreyansh.jain

On Thu, 26 Apr 2018 14:56:19 +0000
"Carrillo, Erik G" <erik.g.carrillo@intel.com> wrote:

> Great, thanks Thomas.
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > Sent: Thursday, April 26, 2018 9:55 AM
> > To: Carrillo, Erik G <erik.g.carrillo@intel.com>
> > Cc: Burakov, Anatoly <anatoly.burakov@intel.com>; dev@dpdk.org; Neil
> > Horman <nhorman@tuxdriver.com>; Mcnamara, John
> > <john.mcnamara@intel.com>; Kovacevic, Marko
> > <marko.kovacevic@intel.com>; Robert Sanford <rsanford@akamai.com>;
> > olivier.matz@6wind.com; shreyansh.jain@nxp.com
> > Subject: Re: [dpdk-dev] [PATCH] lcore: make semantics of lcore role function
> > more intuitive
> > 
> > 26/04/2018 16:44, Carrillo, Erik G:  
> > > Thanks,  Anatoly and Thomas.  I had also considered the following chunk for  
> > the release notes:  
> > >
> > > diff --git a/doc/guides/rel_notes/release_18_05.rst  
> > b/doc/guides/rel_notes/release_18_05.rst  
> > > index 04ff4fe..127a7e2 100644
> > > --- a/doc/guides/rel_notes/release_18_05.rst
> > > +++ b/doc/guides/rel_notes/release_18_05.rst
> > > @@ -72,6 +72,11 @@ API Changes
> > >     Also, make sure to start the actual text at the margin.
> > >  
> > =========================================================  
> > >
> > > +* **rte_lcore_has_role() return values changed**
> > > +
> > > +  This function now returns 1 or 0 for true or false, respectively, rather
> > > +  than 0 or <0 for success or failure to make use of the function more
> > > +  intuitive.
> > >
> > >  ABI Changes
> > >  -----------
> > >
> > > Do we want this note?  Also, it looks like the Doxygen documentation of  
> > the function in the header file didn't get updated.
> > 
> > 
> > Oh, you are right, this patch is not complete.
> > I've fixed it:
> > 
> > --- a/doc/guides/rel_notes/release_18_05.rst
> > +++ b/doc/guides/rel_notes/release_18_05.rst
> > @@ -161,6 +161,12 @@ API Changes
> >    announced at least one release before the ABI change is made. There are
> > no
> >    ABI breaking changes planned.
> > 
> > +* eal: ``rte_lcore_has_role()`` return value changed.
> > +
> > +  This function now returns true or false, respectively, rather  than 0
> > + or <0 for success or failure.
> > +  It makes use of the function more intuitive.
> > +
> >  * mempool: capability flags and related functions have been removed.
> > 
> >    Flags ``MEMPOOL_F_CAPA_PHYS_CONTIG`` and diff --git
> > a/lib/librte_eal/common/include/rte_lcore.h
> > b/lib/librte_eal/common/include/rte_lcore.h
> > index 334a0629e..1a2f37eaa 100644
> > --- a/lib/librte_eal/common/include/rte_lcore.h
> > +++ b/lib/librte_eal/common/include/rte_lcore.h
> > @@ -311,7 +311,7 @@ rte_ctrl_thread_create(pthread_t *thread, const char
> > *name,
> >   * @param role
> >   *   The role to be checked against.
> >   * @return
> > - *   On success, return 0; otherwise return a negative value.
> > + *   Boolean value: positive if test is true; otherwise returns 0.
> >   */
> > 
> > Thanks Erik!
> >   
> 

Usually the  safest way to introduce this is introduce a new function
with a different name. Then retire the old one. 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver
  2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
@ 2018-04-26 16:06  0%     ` Kevin Traynor
  0 siblings, 0 replies; 200+ results
From: Kevin Traynor @ 2018-04-26 16:06 UTC (permalink / raw)
  To: Arnon Warshavsky, thomas, anatoly.burakov, wenzhuo.lu,
	declan.doherty, jerin.jacob, bruce.richardson, ferruh.yigit
  Cc: dev

On 04/26/2018 07:20 AM, Arnon Warshavsky wrote:
> Replace panic calls with log and return value.
> Local functions to this file,
> changing from void to int are non-abi-breaking
> 
> Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
> ---
>  drivers/net/bonding/rte_eth_bond_8023ad.c         | 29 ++++++++++++++---------
>  drivers/net/bonding/rte_eth_bond_8023ad_private.h |  2 +-
>  drivers/net/bonding/rte_eth_bond_api.c            | 22 ++++++++++++-----
>  drivers/net/bonding/rte_eth_bond_pmd.c            |  9 ++++---
>  drivers/net/bonding/rte_eth_bond_private.h        |  2 +-
>  5 files changed, 42 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index c452318..308e623 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -893,7 +893,7 @@
>  			bond_mode_8023ad_periodic_cb, arg);
>  }
>  
> -void
> +int
>  bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
>  				uint16_t slave_id)
>  {
> @@ -939,7 +939,7 @@
>  	timer_cancel(&port->warning_timer);
>  
>  	if (port->mbuf_pool != NULL)
> -		return;
> +		return 0;
>  
>  	RTE_ASSERT(port->rx_ring == NULL);
>  	RTE_ASSERT(port->tx_ring == NULL);
> @@ -968,8 +968,9 @@
>  	/* Any memory allocation failure in initialization is critical because
>  	 * resources can't be free, so reinitialization is impossible. */

What about this comment? Not sure if it is just stale or if there is
something else you need to do.

>  	if (port->mbuf_pool == NULL) {
> -		rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
> -			slave_id, mem_name, rte_strerror(rte_errno));
> +		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
> +			__func__, slave_id, mem_name, rte_strerror(rte_errno));
> +		return -1;
>  	}
>  
>  	snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
> @@ -977,8 +978,9 @@
>  			rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
>  
>  	if (port->rx_ring == NULL) {
> -		rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
> -			mem_name, rte_strerror(rte_errno));
> +		RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create rx ring '%s': %s\n",
> +			__func__, slave_id, mem_name, rte_strerror(rte_errno));
> +		return -1;
>  	}
>  
>  	/* TX ring is at least one pkt longer to make room for marker packet. */
> @@ -987,9 +989,12 @@
>  			rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
>  
>  	if (port->tx_ring == NULL) {
> -		rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
> -			mem_name, rte_strerror(rte_errno));
> +		RTE_BOND_LOG(ERR, "%s() Slave %u: Fail to create tx ring '%s': %s\n",
> +			__func__, slave_id, mem_name, rte_strerror(rte_errno));
> +		return -1;
>  	}
> +
> +	return 0;
>  }
>  
>  int
> @@ -1143,9 +1148,11 @@
>  	struct bond_dev_private *internals = bond_dev->data->dev_private;
>  	uint8_t i;
>  
> -	for (i = 0; i < internals->active_slave_count; i++)
> -		bond_mode_8023ad_activate_slave(bond_dev,
> -				internals->active_slaves[i]);
> +	for (i = 0; i < internals->active_slave_count; i++) {
> +		if (!bond_mode_8023ad_activate_slave(bond_dev,
> +						internals->active_slaves[i]))
> +			return -1;
> +	}
>  
>  	return 0;
>  }
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad_private.h b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
> index 0f490a5..96a42f2 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad_private.h
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad_private.h
> @@ -263,7 +263,7 @@ struct mode8023ad_private {
>   * @return
>   *  0 on success, negative value otherwise.

      ^^^ you inadvertently fixed a doxygen bug :-)

>   */
> -void
> +int
>  bond_mode_8023ad_activate_slave(struct rte_eth_dev *dev, uint16_t port_id);
>  
>  /**
> diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
> index aa89425..657fd74 100644
> --- a/drivers/net/bonding/rte_eth_bond_api.c
> +++ b/drivers/net/bonding/rte_eth_bond_api.c
> @@ -69,14 +69,15 @@
>  	return 0;
>  }
>  
> -void
> +int
>  activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id)
>  {
>  	struct bond_dev_private *internals = eth_dev->data->dev_private;
>  	uint8_t active_count = internals->active_slave_count;
>  
>  	if (internals->mode == BONDING_MODE_8023AD)
> -		bond_mode_8023ad_activate_slave(eth_dev, port_id);
> +		if (bond_mode_8023ad_activate_slave(eth_dev, port_id) != 0)
> +			return -1;
>  
>  	if (internals->mode == BONDING_MODE_TLB
>  			|| internals->mode == BONDING_MODE_ALB) {
> @@ -94,6 +95,8 @@
>  		bond_tlb_activate_slave(internals);
>  	if (internals->mode == BONDING_MODE_ALB)
>  		bond_mode_alb_client_list_upd(eth_dev);
> +
> +	return 0;
>  }
>  
>  void
> @@ -357,10 +360,17 @@
>  				bond_ethdev_primary_set(internals,
>  							slave_port_id);
>  
> -			if (find_slave_by_id(internals->active_slaves,
> -					     internals->active_slave_count,
> -					     slave_port_id) == internals->active_slave_count)
> -				activate_slave(bonded_eth_dev, slave_port_id);
> +			int rc =
> +				find_slave_by_id(internals->active_slaves,
> +					internals->active_slave_count,
> +					slave_port_id);
> +
> +			if (rc == internals->active_slave_count) {
> +				int rc = activate_slave(bonded_eth_dev,
> +							slave_port_id);
> +				if (rc != 0)
> +					return -1;
> +			}

Not functionally wrong, but commented about no need for variables here
in v4 and seems to have been missed

>  		}
>  	}
>  
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 09696ea..d2dbe4a 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -1741,8 +1741,10 @@ struct bwg_slave {
>  		/* Any memory allocation failure in initialization is critical because
>  		 * resources can't be free, so reinitialization is impossible. */
>  		if (port->slow_pool == NULL) {
> -			rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
> -				slave_id, mem_name, rte_strerror(rte_errno));
> +			RTE_BOND_LOG(ERR, "%s() Slave %u: Failed to create memory pool '%s': %s\n",
> +				__func__, slave_id,
> +				mem_name, rte_strerror(rte_errno));
> +			return -1;
>  		}
>  	}
>  
> @@ -2673,7 +2675,8 @@ struct bwg_slave {
>  			mac_address_slaves_update(bonded_eth_dev);
>  		}
>  
> -		activate_slave(bonded_eth_dev, port_id);
> +		if (activate_slave(bonded_eth_dev, port_id) != 0)
> +			return -1;
>  
>  		/* If user has defined the primary port then default to using it */
>  		if (internals->user_defined_primary_port &&
> diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h
> index 94eca88..d99d42c 100644
> --- a/drivers/net/bonding/rte_eth_bond_private.h
> +++ b/drivers/net/bonding/rte_eth_bond_private.h
> @@ -187,7 +187,7 @@ struct bond_dev_private {
>  void
>  deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
>  
> -void
> +int
>  activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id);
>  
>  void
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev
  2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
@ 2018-04-26 16:07  0%     ` Kevin Traynor
  0 siblings, 0 replies; 200+ results
From: Kevin Traynor @ 2018-04-26 16:07 UTC (permalink / raw)
  To: Arnon Warshavsky, thomas, anatoly.burakov, wenzhuo.lu,
	declan.doherty, jerin.jacob, bruce.richardson, ferruh.yigit
  Cc: dev

On 04/26/2018 07:21 AM, Arnon Warshavsky wrote:
> Local function to this file,
> changing from void to int is non-abi-breaking
> 
> Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 42 ++++++++++++++++++++++++++++++------------
>  lib/librte_ether/rte_ethdev.h |  4 +++-
>  2 files changed, 33 insertions(+), 13 deletions(-)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f0f53d4..940de15 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -194,7 +194,7 @@ enum {
>  	return port_id;
>  }
>  
> -static void
> +static int
>  rte_eth_dev_shared_data_prepare(void)
>  {
>  	const unsigned flags = 0;
> @@ -210,8 +210,12 @@ enum {
>  					rte_socket_id(), flags);
>  		} else
>  			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
> -		if (mz == NULL)
> -			rte_panic("Cannot allocate ethdev shared data\n");
> +		if (mz == NULL) {
> +			rte_spinlock_unlock(&rte_eth_shared_data_lock);
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot allocate ethdev shared data\n",
> +					__func__);
> +			return -1;
> +		}
>  
>  		rte_eth_dev_shared_data = mz->addr;
>  		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> @@ -224,6 +228,8 @@ enum {
>  	}
>  
>  	rte_spinlock_unlock(&rte_eth_shared_data_lock);
> +
> +	return 0;
>  }
>  
>  struct rte_eth_dev *
> @@ -274,7 +280,8 @@ struct rte_eth_dev *
>  	uint16_t port_id;
>  	struct rte_eth_dev *eth_dev = NULL;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return NULL;
>  
>  	/* Synchronize port creation between primary and secondary threads. */
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
> @@ -317,7 +324,8 @@ struct rte_eth_dev *
>  	uint16_t i;
>  	struct rte_eth_dev *eth_dev = NULL;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return NULL;
>  
>  	/* Synchronize port attachment to primary port creation and release. */
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
> @@ -345,7 +353,8 @@ struct rte_eth_dev *
>  	if (eth_dev == NULL)
>  		return -EINVAL;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return -1;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> @@ -399,7 +408,8 @@ struct rte_eth_dev *
>  int __rte_experimental
>  rte_eth_dev_owner_new(uint64_t *owner_id)
>  {
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return -1;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> @@ -450,7 +460,8 @@ struct rte_eth_dev *
>  {
>  	int ret;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return -1;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> @@ -467,7 +478,8 @@ struct rte_eth_dev *
>  			{.id = RTE_ETH_DEV_NO_OWNER, .name = ""};
>  	int ret;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return -1;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> @@ -477,12 +489,15 @@ struct rte_eth_dev *
>  	return ret;
>  }
>  
> -void __rte_experimental
> +int __rte_experimental
>  rte_eth_dev_owner_delete(const uint64_t owner_id)
>  {
>  	uint16_t port_id;
> +	int error;

it's inconsistent that this function returns the error code from
rte_eth_dev_shared_data_prepare() and all these other functions return -1

>  
> -	rte_eth_dev_shared_data_prepare();
> +	error = rte_eth_dev_shared_data_prepare();
> +	if (error != 0)
> +		return error;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> @@ -495,6 +510,8 @@ struct rte_eth_dev *
>  	}
>  
>  	rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
> +
> +	return 0;
>  }
>  
>  int __rte_experimental
> @@ -502,7 +519,8 @@ struct rte_eth_dev *
>  {
>  	int ret = 0;
>  
> -	rte_eth_dev_shared_data_prepare();
> +	if (rte_eth_dev_shared_data_prepare() != 0)
> +		return -1;
>  
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
>  
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index b9eb8ae..46e5947 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1354,8 +1354,10 @@ int __rte_experimental rte_eth_dev_owner_unset(const uint16_t port_id,
>   *
>   * @param	owner_id
>   *  The owner identifier.
> + *  @return
> + *  0 on success, negative errno value on error.
>   */
> -void __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
> +int __rte_experimental rte_eth_dev_owner_delete(const uint64_t owner_id);
>  
>  /**
>   * @warning
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence
  2018-04-26  6:21  2%   ` [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
@ 2018-04-26 16:07  0%     ` Kevin Traynor
  0 siblings, 0 replies; 200+ results
From: Kevin Traynor @ 2018-04-26 16:07 UTC (permalink / raw)
  To: Arnon Warshavsky, thomas, anatoly.burakov, wenzhuo.lu,
	declan.doherty, jerin.jacob, bruce.richardson, ferruh.yigit
  Cc: dev

On 04/26/2018 07:21 AM, Arnon Warshavsky wrote:
> Change some local functions return type from void to int.
> This change does not break ABI as the functions are internal.
> Panic thrown from threads was not handled in this patch
> 
> Signed-off-by: Arnon Warshavsky <arnon@qwilt.com>
> Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>  lib/librte_eal/bsdapp/eal/eal.c   |  71 ++++++++++++++++++++-------
>  lib/librte_eal/linuxapp/eal/eal.c | 101 ++++++++++++++++++++++++++------------
>  2 files changed, 121 insertions(+), 51 deletions(-)
> 
> diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
> index 10d8dc0..c958ed9 100644
> --- a/lib/librte_eal/bsdapp/eal/eal.c
> +++ b/lib/librte_eal/bsdapp/eal/eal.c
> @@ -151,7 +151,7 @@ enum rte_iova_mode
>   * We also don't lock the whole file, so that in future we can use read-locks
>   * on other parts, e.g. memzones, to detect if there are running secondary
>   * processes. */
> -static void
> +static int
>  rte_eal_config_create(void)
>  {
>  	void *rte_mem_cfg_addr;
> @@ -160,60 +160,83 @@ enum rte_iova_mode
>  	const char *pathname = eal_runtime_config_path();
>  
>  	if (internal_config.no_shconf)
> -		return;
> +		return 0;
>  
>  	if (mem_cfg_fd < 0){
>  		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
> -		if (mem_cfg_fd < 0)
> -			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
> +		if (mem_cfg_fd < 0) {
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
> +					__func__, pathname);
> +			return -1;
> +		}
>  	}
>  
>  	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
>  	if (retval < 0){
>  		close(mem_cfg_fd);
> -		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
> +				__func__, pathname);
> +		return -1;
>  	}
>  
>  	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
>  	if (retval < 0){
>  		close(mem_cfg_fd);
> -		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
> -				"process running?\n", pathname);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'. Is another primary process running?\n",
> +				__func__, pathname);
> +		return -1;
>  	}
>  
>  	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
>  				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
>  
>  	if (rte_mem_cfg_addr == MAP_FAILED){
> -		rte_panic("Cannot mmap memory for rte_config\n");
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
> +				__func__);
> +		close(mem_cfg_fd);
> +		mem_cfg_fd = -1;
> +		return -1;
>  	}
>  	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
>  	rte_config.mem_config = rte_mem_cfg_addr;
> +
> +	return 0;
>  }
>  
>  /* attach to an existing shared memory config */
> -static void
> +static int
>  rte_eal_config_attach(void)
>  {
>  	void *rte_mem_cfg_addr;
>  	const char *pathname = eal_runtime_config_path();
>  
>  	if (internal_config.no_shconf)
> -		return;
> +		return 0;
>  
>  	if (mem_cfg_fd < 0){
>  		mem_cfg_fd = open(pathname, O_RDWR);
> -		if (mem_cfg_fd < 0)
> -			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
> +		if (mem_cfg_fd < 0) {
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
> +					__func__, pathname);
> +			return -1;
> +		}
>  	}
>  
>  	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
>  				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
>  	close(mem_cfg_fd);
> -	if (rte_mem_cfg_addr == MAP_FAILED)
> -		rte_panic("Cannot mmap memory for rte_config\n");
> +	if (rte_mem_cfg_addr == MAP_FAILED) {
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
> +				__func__);
> +		return -1;
> +	}
>  
>  	rte_config.mem_config = rte_mem_cfg_addr;
> +
> +	return 0;
>  }
>  
>  /* Detect if we are a primary or a secondary process */
> @@ -237,23 +260,29 @@ enum rte_proc_type_t
>  }
>  
>  /* Sets up rte_config structure with the pointer to shared memory config.*/
> -static void
> +static int
>  rte_config_init(void)
>  {
>  	rte_config.process_type = internal_config.process_type;
>  
>  	switch (rte_config.process_type){
>  	case RTE_PROC_PRIMARY:
> -		rte_eal_config_create();
> +		if (rte_eal_config_create())
> +			return -1;
>  		break;
>  	case RTE_PROC_SECONDARY:
> -		rte_eal_config_attach();
> +		if (rte_eal_config_attach())
> +			return -1;
>  		rte_eal_mcfg_wait_complete(rte_config.mem_config);
>  		break;
>  	case RTE_PROC_AUTO:
>  	case RTE_PROC_INVALID:
> -		rte_panic("Invalid process type\n");
> +	default:
> +		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
> +				__func__, rte_config.process_type);
> +		return -1;
>  	}
> +	return 0;
>  }
>  
>  /* display usage */
> @@ -552,7 +581,11 @@ static void rte_eal_init_alert(const char *msg)
>  		return -1;
>  	}
>  
> -	rte_config_init();
> +	if (rte_config_init() != 0) {
> +		rte_eal_init_alert("Failed to init configuration");
> +		rte_errno = EFAULT;
> +		return -1;
> +	}
>  
>  	/* Put mp channel init before bus scan so that we can init the vdev
>  	 * bus through mp channel in the secondary process before the bus scan.
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 200e879..c0d704b 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -160,7 +160,7 @@ enum rte_iova_mode
>   * We also don't lock the whole file, so that in future we can use read-locks
>   * on other parts, e.g. memzones, to detect if there are running secondary
>   * processes. */
> -static void
> +static int
>  rte_eal_config_create(void)
>  {
>  	void *rte_mem_cfg_addr;
> @@ -169,7 +169,7 @@ enum rte_iova_mode
>  	const char *pathname = eal_runtime_config_path();
>  
>  	if (internal_config.no_shconf)
> -		return;
> +		return 0;
>  
>  	/* map the config before hugepage address so that we don't waste a page */
>  	if (internal_config.base_virtaddr != 0)
> @@ -179,30 +179,42 @@ enum rte_iova_mode
>  	else
>  		rte_mem_cfg_addr = NULL;
>  
> -	if (mem_cfg_fd < 0){
> +	if (mem_cfg_fd < 0) {
>  		mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
> -		if (mem_cfg_fd < 0)
> -			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
> +		if (mem_cfg_fd < 0) {
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
> +				__func__, pathname);
> +			return -1;
> +		}
>  	}
>  
>  	retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
> -	if (retval < 0){
> +	if (retval < 0) {
>  		close(mem_cfg_fd);
> -		rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot resize '%s' for rte_mem_config\n",
> +				__func__, pathname);
> +		return -1;
>  	}
>  
>  	retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
> -	if (retval < 0){
> +	if (retval < 0) {
>  		close(mem_cfg_fd);
> -		rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
> -				"process running?\n", pathname);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot create lock on '%s'.Is another primary process running?\n",
> +			__func__, pathname);
> +		return -1;
>  	}
>  
>  	rte_mem_cfg_addr = mmap(rte_mem_cfg_addr, sizeof(*rte_config.mem_config),
>  				PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
>  
> -	if (rte_mem_cfg_addr == MAP_FAILED){
> -		rte_panic("Cannot mmap memory for rte_config\n");
> +	if (rte_mem_cfg_addr == MAP_FAILED) {
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config\n",
> +			__func__);
> +		close(mem_cfg_fd);
> +		mem_cfg_fd = -1;
> +		return -1;
>  	}
>  	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
>  	rte_config.mem_config = rte_mem_cfg_addr;
> @@ -211,10 +223,11 @@ enum rte_iova_mode
>  	 * processes could later map the config into this exact location */
>  	rte_config.mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;
>  
> +	return 0;
>  }
>  
>  /* attach to an existing shared memory config */
> -static void
> +static int
>  rte_eal_config_attach(void)
>  {
>  	struct rte_mem_config *mem_config;
> @@ -222,33 +235,42 @@ enum rte_iova_mode
>  	const char *pathname = eal_runtime_config_path();
>  
>  	if (internal_config.no_shconf)
> -		return;
> +		return 0;
>  
> -	if (mem_cfg_fd < 0){
> +	if (mem_cfg_fd < 0) {
>  		mem_cfg_fd = open(pathname, O_RDWR);
> -		if (mem_cfg_fd < 0)
> -			rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
> +		if (mem_cfg_fd < 0) {
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot open '%s' for rte_mem_config\n",
> +						__func__, pathname);
> +			return -1;
> +		}
>  	}
>  
>  	/* map it as read-only first */
>  	mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config),
>  			PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
> -	if (mem_config == MAP_FAILED)
> -		rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
> -			  errno, strerror(errno));
> +	if (mem_config == MAP_FAILED) {
> +		close(mem_cfg_fd);
> +		mem_cfg_fd = -1;
> +		RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
> +				__func__, errno, strerror(errno));
> +		return -1;
> +	}
>  
>  	rte_config.mem_config = mem_config;
> +
> +	return 0;
>  }
>  
>  /* reattach the shared config at exact memory location primary process has it */
> -static void
> +static int
>  rte_eal_config_reattach(void)
>  {
>  	struct rte_mem_config *mem_config;
>  	void *rte_mem_cfg_addr;
>  
>  	if (internal_config.no_shconf)
> -		return;
> +		return 0;
>  
>  	/* save the address primary process has mapped shared config to */
>  	rte_mem_cfg_addr = (void *) (uintptr_t) rte_config.mem_config->mem_cfg_addr;
> @@ -263,16 +285,20 @@ enum rte_iova_mode
>  	if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
>  		if (mem_config != MAP_FAILED)
>  			/* errno is stale, don't use */
> -			rte_panic("Cannot mmap memory for rte_config at [%p], got [%p]"
> -				  " - please use '--base-virtaddr' option\n",
> -				  rte_mem_cfg_addr, mem_config);
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config at [%p], got [%p] - please use '--base-virtaddr' option\n",
> +					__func__, rte_mem_cfg_addr, mem_config);
>  		else
> -			rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
> -				  errno, strerror(errno));
> +			RTE_LOG(CRIT, EAL, "%s(): Cannot mmap memory for rte_config! error %i (%s)\n",
> +					__func__, errno, strerror(errno));
> +		close(mem_cfg_fd);
> +		mem_cfg_fd = -1;
> +		return -1;
>  	}
>  	close(mem_cfg_fd);
>  
>  	rte_config.mem_config = mem_config;
> +
> +	return 0;
>  }
>  
>  /* Detect if we are a primary or a secondary process */
> @@ -296,24 +322,32 @@ enum rte_proc_type_t
>  }
>  
>  /* Sets up rte_config structure with the pointer to shared memory config.*/
> -static void
> +static int
>  rte_config_init(void)
>  {
>  	rte_config.process_type = internal_config.process_type;
>  
>  	switch (rte_config.process_type){
>  	case RTE_PROC_PRIMARY:
> -		rte_eal_config_create();
> +		if (rte_eal_config_create())
> +			return -1;
>  		break;
>  	case RTE_PROC_SECONDARY:
> -		rte_eal_config_attach();
> +		if (rte_eal_config_attach())
> +			return -1;
>  		rte_eal_mcfg_wait_complete(rte_config.mem_config);
> -		rte_eal_config_reattach();
> +		if (rte_eal_config_reattach())
> +			return -1;
>  		break;
>  	case RTE_PROC_AUTO:
>  	case RTE_PROC_INVALID:
> -		rte_panic("Invalid process type\n");
> +	default:
> +		RTE_LOG(CRIT, EAL, "%s(): Invalid process type %d\n",
> +				__func__, rte_config.process_type);
> +		return -1;
>  	}
> +
> +	return 0;
>  }
>  
>  /* Unlocks hugepage directories that were locked by eal_hugepage_info_init */
> @@ -833,6 +867,9 @@ static void rte_eal_init_alert(const char *msg)
>  
>  	rte_srand(rte_rdtsc());
>  
> +	if (rte_config_init() != 0)
> +		return -1;
> +

I'm confused, is this deliberate? there is now two rte_config_init()
calls. Aaron's comments on v4 about rte_eal_init_alert() are missed? and
it's missing the clear once and error number like the other returns.

>  	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) {
>  		rte_eal_init_alert("Cannot init logging.");
>  		rte_errno = ENOMEM;
> 

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v7 2/4] ethdev: Add group JUMP action
  @ 2018-04-26 17:29  2%   ` Declan Doherty
  0 siblings, 0 replies; 200+ results
From: Declan Doherty @ 2018-04-26 17:29 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Declan Doherty

Add jump action type which defines an action which allows a matched
flow to be redirect to the specified group. This allows physical and
logical flow table/group hierarchies to be defined through rte_flow.

This breaks ABI compatibility for the following public functions (as it
modifes the ordering of the rte_flow_action_type enumeration):

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

Add support for specification of new JUMP action to testpmd's flow
cli, and update the testpmd documentation to describe this new
action.

Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 23 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 61 ++++++++++++++++++++++++-----
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
 lib/librte_ether/rte_flow.h                 | 41 +++++++++++++++----
 4 files changed, 112 insertions(+), 17 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4239602b6..6e9fa5d7c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -183,6 +183,8 @@ enum index {
 	ACTION_END,
 	ACTION_VOID,
 	ACTION_PASSTHRU,
+	ACTION_JUMP,
+	ACTION_JUMP_GROUP,
 	ACTION_MARK,
 	ACTION_MARK_ID,
 	ACTION_FLAG,
@@ -738,6 +740,7 @@ static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
 	ACTION_PASSTHRU,
+	ACTION_JUMP,
 	ACTION_MARK,
 	ACTION_FLAG,
 	ACTION_QUEUE,
@@ -856,6 +859,12 @@ static const enum index action_of_push_mpls[] = {
 	ZERO,
 };
 
+static const enum index action_jump[] = {
+	ACTION_JUMP_GROUP,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_init(struct context *, const struct token *,
 		      const char *, unsigned int,
 		      void *, unsigned int);
@@ -1931,6 +1940,20 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
+	[ACTION_JUMP] = {
+		.name = "jump",
+		.help = "redirect traffic to a given group",
+		.priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
+		.next = NEXT(action_jump),
+		.call = parse_vc,
+	},
+	[ACTION_JUMP_GROUP] = {
+		.name = "group",
+		.help = "group to redirect traffic to",
+		.next = NEXT(action_jump, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_MARK] = {
 		.name = "mark",
 		.help = "attach 32 bit value to packets",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index e92969757..92e0f89ad 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -90,8 +90,12 @@ Thus predictable results for a given priority level can only be achieved
 with non-overlapping rules, using perfect matching on all protocol layers.
 
 Flow rules can also be grouped, the flow rule priority is specific to the
-group they belong to. All flow rules in a given group are thus processed
-either before or after another group.
+group they belong to. All flow rules in a given group are thus processed within
+the context of that group. Groups are not linked by default, so the logical
+hierarchy of groups must be explicitly defined by flow rules themselves in each
+group using the JUMP action to define the next group to redirect too. Only flow
+rules defined in the default group 0 are guarantee to be matched against, this
+makes group 0 the origin of any group hierarchy defined by an application.
 
 Support for multiple actions per rule may be implemented internally on top
 of non-default hardware priorities, as a result both features may not be
@@ -138,29 +142,34 @@ Attributes
 Attribute: Group
 ^^^^^^^^^^^^^^^^
 
-Flow rules can be grouped by assigning them a common group number. Lower
-values have higher priority. Group 0 has the highest priority.
+Flow rules can be grouped by assigning them a common group number. Groups
+allow a logical hierarchy of flow rule groups (tables) to be defined. These
+groups can be supported virtually in the PMD or in the physical device.
+Group 0 is the default group and this is the only group which flows are
+guarantee to matched against, all subsequent groups can only be reached by
+way of the JUMP action from a matched flow rule.
 
 Although optional, applications are encouraged to group similar rules as
 much as possible to fully take advantage of hardware capabilities
 (e.g. optimized matching) and work around limitations (e.g. a single pattern
-type possibly allowed in a given group).
+type possibly allowed in a given group), while being aware that the groups
+hierarchies must be programmed explicitly.
 
 Note that support for more than a single group is not guaranteed.
 
 Attribute: Priority
 ^^^^^^^^^^^^^^^^^^^
 
-A priority level can be assigned to a flow rule. Like groups, lower values
+A priority level can be assigned to a flow rule, lower values
 denote higher priority, with 0 as the maximum.
 
-A rule with priority 0 in group 8 is always matched after a rule with
-priority 8 in group 0.
-
-Group and priority levels are arbitrary and up to the application, they do
+Priority levels are arbitrary and up to the application, they do
 not need to be contiguous nor start from 0, however the maximum number
 varies between devices and may be affected by existing flow rules.
 
+A flow which matches multiple rules in the same group will always matched by
+the rule with the highest priority in that group.
+
 If a packet is matched by several rules of a given group for a given
 priority level, the outcome is undefined. It can take any path, may be
 duplicated or even cause unrecoverable errors.
@@ -1372,6 +1381,38 @@ flow rules:
    | 2     | END                        |
    +-------+----------------------------+
 
+Action: ``JUMP``
+^^^^^^^^^^^^^^^^
+
+Redirects packets to a group on the current device.
+
+In a hierarchy of groups, which can be used to represent physical or logical
+flow group/tables on the device, this action redirects the matched flow to
+the specified group on that device.
+
+If a matched flow is redirected to a table which doesn't contain a matching
+rule for that flow then the behavior is undefined and the resulting behavior
+is up to the specific device. Best practice when using groups would be define
+a default flow rule for each group which a defines the default actions in that
+group so a consistent behavior is defined.
+
+Defining an action for matched flow in a group to jump to a group which is
+higher in the group hierarchy may not be supported by physical devices,
+depending on how groups are mapped to the physical devices. In the
+definitions of jump actions, applications should be aware that it may be
+possible to define flow rules which trigger an undefined behavior causing
+flows to loop between groups.
+
+.. _table_rte_flow_action_jump:
+
+.. table:: JUMP
+
+   +-----------+------------------------------+
+   | Field     | Value                        |
+   +===========+==============================+
+   | ``group`` | Group to redirect packets to |
+   +-----------+------------------------------+
+
 Action: ``MARK``
 ^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2edf96dd6..260d044d5 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3453,6 +3453,10 @@ This section lists supported actions and their attributes, if any.
 
 - ``passthru``: let subsequent rule process matched packets.
 
+- ``jump``: redirect traffic to group on device.
+
+  - ``group {unsigned}``: group to redirect to.
+
 - ``mark``: attach 32 bit value to packets.
 
   - ``id {unsigned}``: 32 bit value to return with packets.
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 657cb9a99..17c1c4a89 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -35,18 +35,20 @@ extern "C" {
 /**
  * Flow rule attributes.
  *
- * Priorities are set on two levels: per group and per rule within groups.
+ * Priorities are set on a per rule based within groups.
  *
- * Lower values denote higher priority, the highest priority for both levels
- * is 0, so that a rule with priority 0 in group 8 is always matched after a
- * rule with priority 8 in group 0.
+ * Lower values denote higher priority, the highest priority for a flow rule
+ * is 0, so that a flow that matches for than one rule, the rule with the
+ * lowest priority value will always be matched.
  *
  * Although optional, applications are encouraged to group similar rules as
  * much as possible to fully take advantage of hardware capabilities
  * (e.g. optimized matching) and work around limitations (e.g. a single
- * pattern type possibly allowed in a given group).
+ * pattern type possibly allowed in a given group). Applications should be
+ * aware that groups are not linked by default, and that they must be
+ * explicitly linked by the application using the JUMP action.
  *
- * Group and priority levels are arbitrary and up to the application, they
+ * Priority levels are arbitrary and up to the application, they
  * do not need to be contiguous nor start from 0, however the maximum number
  * varies between devices and may be affected by existing flow rules.
  *
@@ -69,7 +71,7 @@ extern "C" {
  */
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
-	uint32_t priority; /**< Priority level within group. */
+	uint32_t priority; /**< Rule priority level within group. */
 	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
 	uint32_t egress:1; /**< Rule applies to egress traffic. */
 	/**
@@ -1236,6 +1238,15 @@ enum rte_flow_action_type {
 	 */
 	RTE_FLOW_ACTION_TYPE_PASSTHRU,
 
+	/**
+	 * RTE_FLOW_ACTION_TYPE_JUMP
+	 *
+	 * Redirects packets to a group on the current device.
+	 *
+	 * See struct rte_flow_action_jump.
+	 */
+	RTE_FLOW_ACTION_TYPE_JUMP,
+
 	/**
 	 * Attaches an integer value to packets and sets PKT_RX_FDIR and
 	 * PKT_RX_FDIR_ID mbuf flags.
@@ -1481,6 +1492,22 @@ struct rte_flow_action_mark {
 	uint32_t id; /**< Integer value to return with packets. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_JUMP
+ *
+ * Redirects packets to a group on the current device.
+ *
+ * In a hierarchy of groups, which can be used to represent physical or logical
+ * flow tables on the device, this action allows the action to be a redirect to
+ * a group on that device.
+ */
+struct rte_flow_action_jump {
+	uint32_t group;
+};
+
 /**
  * RTE_FLOW_ACTION_TYPE_QUEUE
  *
-- 
2.14.3

^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer after freeing
  @ 2018-04-27 12:37  3%       ` Van Haaren, Harry
  2018-04-27 13:09  0%         ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Van Haaren, Harry @ 2018-04-27 12:37 UTC (permalink / raw)
  To: Akhil Goyal, De Lara Guarch, Pablo, Zhang, Roy Fan; +Cc: dev, stable

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
> Sent: Friday, April 27, 2018 12:59 PM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Zhang, Roy Fan <roy.fan.zhang@intel.com>
> Cc: dev@dpdk.org; stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer after
> freeing
> 
> Hi Pablo,
> 
> On 4/27/2018 5:06 PM, De Lara Guarch, Pablo wrote:
> > Hi Akhil,
> >
> >> -----Original Message-----
> >> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> >> Sent: Friday, April 27, 2018 9:47 AM
> >> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Zhang, Roy Fan
> >> <roy.fan.zhang@intel.com>
> >> Cc: dev@dpdk.org; stable@dpdk.org
> >> Subject: Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer
> after
> >> freeing
> >>
> >> Hi Pablo,
> >>
> >> On 4/26/2018 8:39 PM, Pablo de Lara wrote:
> >>> When freeing memory, pointers should be set to NULL, to avoid memory
> >>> corruption/segmentation faults.
> >>
> >> Shouldn't this be handled in the rte_free itself. A lot of other driver are
> also not
> >> setting null after rte_free.
> >> This would require change at a lot of places if this is not handled in
> rte_free.
> >>
> >
> > The glibc function "free" works the same way. Users are responsible for
> > setting to NULL these pointers (because sometimes, it is not necessary to do
> such thing).
> Yes it is correct but rte_free is custom free API in DPDK which can be
> modified or we can have a safer API rte_free_safe which can set the
> pointer to null.
> >
> > Anyway, in case we still wanted to change it, we would need to pass a
> pointer
> > to a pointer in rte_free, which would imply an API breakage.


Actually there is an alternative solution, by creating a macro like so;

#define rte_free(x) do {
     rte_free_(x); /* call the real implementation, now with _ */
     x = NULL;
} while (0)

This is not an ABI break if symbol versioning is used for rte_free().

It is an API change however - not that the calling code has to change,
but rather that the effect of rte_free() changes transparently.

I'm not sure what the correct thing to do is in this case - just pointing
out that this is another possible solution.


> I think if the community agrees, we can add this change may be in next
> releases.

+1 to discuss this with the community, regardless of the implementation :)


> > Thanks,
> > Pablo
> >
> >> Thanks,
> >> Akhil

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer after freeing
  2018-04-27 12:37  3%       ` Van Haaren, Harry
@ 2018-04-27 13:09  0%         ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2018-04-27 13:09 UTC (permalink / raw)
  To: Van Haaren, Harry
  Cc: Akhil Goyal, De Lara Guarch, Pablo, Zhang, Roy Fan, dev, stable

On Fri, Apr 27, 2018 at 12:37:08PM +0000, Van Haaren, Harry wrote:
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
> > Sent: Friday, April 27, 2018 12:59 PM
> > To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Akhil Goyal
> > <akhil.goyal@nxp.com>; Zhang, Roy Fan <roy.fan.zhang@intel.com>
> > Cc: dev@dpdk.org; stable@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer after
> > freeing
> > 
> > Hi Pablo,
> > 
> > On 4/27/2018 5:06 PM, De Lara Guarch, Pablo wrote:
> > > Hi Akhil,
> > >
> > >> -----Original Message-----
> > >> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > >> Sent: Friday, April 27, 2018 9:47 AM
> > >> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Zhang, Roy Fan
> > >> <roy.fan.zhang@intel.com>
> > >> Cc: dev@dpdk.org; stable@dpdk.org
> > >> Subject: Re: [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer
> > after
> > >> freeing
> > >>
> > >> Hi Pablo,
> > >>
> > >> On 4/26/2018 8:39 PM, Pablo de Lara wrote:
> > >>> When freeing memory, pointers should be set to NULL, to avoid memory
> > >>> corruption/segmentation faults.
> > >>
> > >> Shouldn't this be handled in the rte_free itself. A lot of other driver are
> > also not
> > >> setting null after rte_free.
> > >> This would require change at a lot of places if this is not handled in
> > rte_free.
> > >>
> > >
> > > The glibc function "free" works the same way. Users are responsible for
> > > setting to NULL these pointers (because sometimes, it is not necessary to do
> > such thing).
> > Yes it is correct but rte_free is custom free API in DPDK which can be
> > modified or we can have a safer API rte_free_safe which can set the
> > pointer to null.
> > >
> > > Anyway, in case we still wanted to change it, we would need to pass a
> > pointer
> > > to a pointer in rte_free, which would imply an API breakage.
> 
> 
> Actually there is an alternative solution, by creating a macro like so;
> 
> #define rte_free(x) do {
>      rte_free_(x); /* call the real implementation, now with _ */
>      x = NULL;
> } while (0)
> 
> This is not an ABI break if symbol versioning is used for rte_free().
> 
> It is an API change however - not that the calling code has to change,
> but rather that the effect of rte_free() changes transparently.
> 
> I'm not sure what the correct thing to do is in this case - just pointing
> out that this is another possible solution.
> 
> 
> > I think if the community agrees, we can add this change may be in next
> > releases.
> 
> +1 to discuss this with the community, regardless of the implementation :)
> 
> 
I really don't think this change is necessary. I think having rte_free
behave as libc free is fine.

However, if we want to add a new API called rte_free_and_null(void **x),
I could be ok with that, though I'd be somewhat dubious of its necessity.
Static analysis tools should be able to pick up use-after-free errors,
though we may need to provide metadata to the tools in some form indicating
that rte_free is a free-ing function.

/Bruce

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API
  2018-04-25 15:27  3%   ` [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in " Adrien Mazarguil
@ 2018-04-28  3:46  0%     ` Zhao1, Wei
  2018-04-28  5:28  0%       ` Peng, Yuan
  0 siblings, 1 reply; 200+ results
From: Zhao1, Wei @ 2018-04-28  3:46 UTC (permalink / raw)
  To: Adrien Mazarguil, dev
  Cc: Peng, Yuan, Xu, Qian Q, Liu, Yu Y, Lu, Wenzhuo, Wu, Jingjing

Hi,Adrien Mazarguil

       We have just use new RC.1 code on the feature of flow RSS API, but we find some abnormal phenomenon.
After that I check code again, I find that it is  introduced in this patch:

SHA-1: ac8d22de2394e03ba4a77d8fd24381147aafb1d3
* ethdev: flatten RSS configuration in flow API
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>


This abnormal phenomenon include i40e and ixgbe 2 NIC, it do not has these 2 bug before merge this patch.
It is first find out by yuan.peng@intel.com,  she can tell you how to reappear these abnormal phenomenon on RSS flow API.

Thank you.


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Wednesday, April 25, 2018 11:28 PM
> To: Thomas Monjalon <thomas@monjalon.net>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; dev@dpdk.org
> Cc: Xueming Li <xuemingl@mellanox.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; Nelio Laranjeiro
> <nelio.laranjeiro@6wind.com>; Yongseok Koh <yskoh@mellanox.com>;
> Andrew Rybchenko <arybchenko@solarflare.com>; Pascal Mazon
> <pascal.mazon@6wind.com>; Nicolau, Radu <radu.nicolau@intel.com>; Akhil
> Goyal <akhil.goyal@nxp.com>
> Subject: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in
> flow API
> 
> Since its inception, the rte_flow RSS action has been relying in part on
> external struct rte_eth_rss_conf for compatibility with the legacy RSS API.
> This structure lacks parameters such as the hash algorithm to use, and more
> recently, a method to tell which layer RSS should be performed on [1].
> 
> Given struct rte_eth_rss_conf will never be flexible enough to represent a
> complete RSS configuration (e.g. RETA table), this patch supersedes it by
> extending the rte_flow RSS action directly.
> 
> A subsequent patch will add a field to use a non-default RSS hash
> algorithm. To that end, a field named "types" replaces the field formerly
> known as "rss_hf" and standing for "RSS hash functions" as it was
> confusing. Actual RSS hash function types are defined by enum
> rte_eth_hash_function.
> 
> This patch updates all PMDs and example applications accordingly.
> 
> It breaks ABI compatibility for the following public functions:
> 
> - rte_flow_copy()
> - rte_flow_create()
> - rte_flow_query()
> - rte_flow_validate()
> 
> [1] commit 676b605182a5 ("doc: announce ethdev API change for RSS
>     configuration")
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Xueming Li <xuemingl@mellanox.com>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>
> Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>
> Cc: Beilei Xing <beilei.xing@intel.com>
> Cc: Qi Zhang <qi.z.zhang@intel.com>
> Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Pascal Mazon <pascal.mazon@6wind.com>
> Cc: Radu Nicolau <radu.nicolau@intel.com>
> Cc: Akhil Goyal <akhil.goyal@nxp.com>
> 
> ---
> 
> v6 changes:
> 
> - Fixed QUEUE action support in mlx5 according to Nelio's comment [1].
>   This action relies on RSS to work and even though it targets a single Rx
>   queue, a non-NULL hash key is required.
> - Updated API and ABI changes sections in release notes.
> 
> [1] http://dpdk.org/ml/archives/dev/2018-April/098635.html
> 
> v3 changes:
> 
> Documentation update regarding the meaning of a 0 value for RSS types in
> flow rules.
> 
> It used to implicitly mean "no RSS" but is redefined as requesting a kind
> of "best-effort" mode from PMDs, i.e. anything ranging from empty to
> all-inclusive RSS; what matters is it provides safe defaults that will work
> regardless of PMD capabilities.
> ---
>  app/test-pmd/cmdline_flow.c                 |  48 +++---
>  app/test-pmd/config.c                       |  39 ++---
>  doc/guides/prog_guide/rte_flow.rst          |  28 ++--
>  doc/guides/rel_notes/release_18_05.rst      |  13 +-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   6 +-
>  drivers/net/e1000/e1000_ethdev.h            |  13 +-
>  drivers/net/e1000/igb_ethdev.c              |   4 +-
>  drivers/net/e1000/igb_flow.c                |  31 ++--
>  drivers/net/e1000/igb_rxtx.c                |  51 +++++-
>  drivers/net/i40e/i40e_ethdev.c              |  53 +++++--
>  drivers/net/i40e/i40e_ethdev.h              |  15 +-
>  drivers/net/i40e/i40e_flow.c                |  47 +++---
>  drivers/net/ixgbe/ixgbe_ethdev.c            |   4 +-
>  drivers/net/ixgbe/ixgbe_ethdev.h            |  13 +-
>  drivers/net/ixgbe/ixgbe_flow.c              |  30 ++--
>  drivers/net/ixgbe/ixgbe_rxtx.c              |  51 +++++-
>  drivers/net/mlx4/mlx4.c                     |   2 +-
>  drivers/net/mlx4/mlx4_flow.c                |  61 +++----
>  drivers/net/mlx4/mlx4_flow.h                |   2 +-
>  drivers/net/mlx4/mlx4_rxq.c                 |   2 +-
>  drivers/net/mlx4/mlx4_rxtx.h                |   2 +-
>  drivers/net/mlx5/mlx5_flow.c                | 193 +++++++++++------------
>  drivers/net/mlx5/mlx5_rxq.c                 |  26 +--
>  drivers/net/mlx5/mlx5_rxtx.h                |  26 +--
>  drivers/net/sfc/sfc_flow.c                  |  21 ++-
>  drivers/net/tap/tap_flow.c                  |   8 +-
>  examples/ipsec-secgw/ipsec.c                |  10 +-
>  lib/librte_ether/rte_flow.c                 |  39 ++---
>  lib/librte_ether/rte_flow.h                 |  12 +-
>  29 files changed, 492 insertions(+), 358 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 798b7948d..c9c2c3ad9 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -192,9 +192,8 @@ enum index {
>  /** Storage for struct rte_flow_action_rss including external data. */
>  struct action_rss_data {
>  	struct rte_flow_action_rss conf;
> +	uint8_t key[RSS_HASH_KEY_LENGTH];
>  	uint16_t queue[ACTION_RSS_QUEUE_NUM];
> -	struct rte_eth_rss_conf rss_conf;
> -	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
>  };
> 
>  /** Maximum number of subsequent tokens and arguments on the stack.
> */
> @@ -1587,7 +1586,7 @@ static const struct token token_list[] = {
>  	},
>  	[ACTION_RSS_TYPES] = {
>  		.name = "types",
> -		.help = "RSS hash types",
> +		.help = "specific RSS hash types",
>  		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
>  	},
>  	[ACTION_RSS_TYPE] = {
> @@ -1602,21 +1601,21 @@ static const struct token token_list[] = {
>  		.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
>  		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
>  			     ARGS_ENTRY_ARB
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len)),
> -			     ARGS_ENTRY(struct action_rss_data, rss_key)),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len)),
> +			     ARGS_ENTRY(struct action_rss_data, key)),
>  	},
>  	[ACTION_RSS_KEY_LEN] = {
>  		.name = "key_len",
>  		.help = "RSS hash key length in bytes",
>  		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
>  		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len),
>  			      0,
>  			      RSS_HASH_KEY_LENGTH)),
>  	},
> @@ -2075,27 +2074,24 @@ parse_vc_action_rss(struct context *ctx, const
> struct token *token,
>  	action_rss_data = ctx->object;
>  	*action_rss_data = (struct action_rss_data){
>  		.conf = (struct rte_flow_action_rss){
> -			.rss_conf = &action_rss_data->rss_conf,
> -			.num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.types = rss_hf,
> +			.key_len = sizeof(action_rss_data->key),
> +			.queue_num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.key = action_rss_data->key,
>  			.queue = action_rss_data->queue,
>  		},
> +		.key = "testpmd's default RSS hash key",
>  		.queue = { 0 },
> -		.rss_conf = (struct rte_eth_rss_conf){
> -			.rss_key = action_rss_data->rss_key,
> -			.rss_key_len = sizeof(action_rss_data->rss_key),
> -			.rss_hf = rss_hf,
> -		},
> -		.rss_key = "testpmd's default RSS hash key",
>  	};
> -	for (i = 0; i < action_rss_data->conf.num; ++i)
> +	for (i = 0; i < action_rss_data->conf.queue_num; ++i)
>  		action_rss_data->queue[i] = i;
>  	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
>  	    ctx->port != (portid_t)RTE_PORT_ALL) {
>  		struct rte_eth_dev_info info;
> 
>  		rte_eth_dev_info_get(ctx->port, &info);
> -		action_rss_data->rss_conf.rss_key_len =
> -			RTE_MIN(sizeof(action_rss_data->rss_key),
> +		action_rss_data->conf.key_len =
> +			RTE_MIN(sizeof(action_rss_data->key),
>  				info.hash_key_size);
>  	}
>  	action->conf = &action_rss_data->conf;
> @@ -2123,7 +2119,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  		return -1;
>  	if (!(ctx->objdata >> 16) && ctx->object) {
>  		action_rss_data = ctx->object;
> -		action_rss_data->rss_conf.rss_hf = 0;
> +		action_rss_data->conf.types = 0;
>  	}
>  	if (!strcmp_partial("end", str, len)) {
>  		ctx->objdata &= 0xffff;
> @@ -2142,7 +2138,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
> +	action_rss_data->conf.types |= rss_type_table[i].rss_type;
>  	return len;
>  }
> 
> @@ -2192,7 +2188,7 @@ parse_vc_action_rss_queue(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->conf.num = i;
> +	action_rss_data->conf.queue_num = i;
>  	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
>  	return len;
>  }
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index eb7ac315e..4700dd674 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1117,40 +1117,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index acbeaacbd..cf252eeba 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1301,6 +1301,12 @@ Action: ``RSS``
>  Similar to QUEUE, except RSS is additionally performed on packets to spread
>  them among several queues according to the provided parameters.
> 
> +Unlike global RSS settings used by other DPDK APIs, unsetting the ``types``
> +field does not disable RSS in a flow rule. Doing so instead requests safe
> +unspecified "best-effort" settings from the underlying PMD, which
> depending
> +on the flow rule, may result in anything ranging from empty (single queue)
> +to all-inclusive RSS.
> +
>  Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
>  overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
>  field only, both can be requested simultaneously.
> @@ -1309,15 +1315,19 @@ field only, both can be requested simultaneously.
> 
>  .. table:: RSS
> 
> -   +--------------+--------------------------------+
> -   | Field        | Value                          |
> -   +==============+================================+
> -   | ``rss_conf`` | RSS parameters                 |
> -   +--------------+--------------------------------+
> -   | ``num``      | number of entries in ``queue`` |
> -   +--------------+--------------------------------+
> -   | ``queue``    | queue indices to use           |
> -   +--------------+--------------------------------+
> +   +---------------+---------------------------------------------+
> +   | Field         | Value                                       |
> +
> +===============+=========================================
> ====+
> +   | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
> +   +---------------+---------------------------------------------+
> +   | ``key_len``   | hash key length in bytes                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue_num`` | number of entries in ``queue``              |
> +   +---------------+---------------------------------------------+
> +   | ``key``       | hash key                                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue``     | queue indices to use                        |
> +   +---------------+---------------------------------------------+
> 
>  Action: ``PF``
>  ^^^^^^^^^^^^^^
> diff --git a/doc/guides/rel_notes/release_18_05.rst
> b/doc/guides/rel_notes/release_18_05.rst
> index ca173450c..b702ac66a 100644
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> @@ -254,6 +254,13 @@ API Changes
>      present.
>    * C99-style flexible arrays were replaced with standard pointers in RSS
>      action and in RAW pattern item structures due to compatibility issues.
> +  * The RSS action was modified to not rely on external
> +    ``struct rte_eth_rss_conf`` anymore to instead expose its own and more
> +    appropriately named configuration fields directly
> +    (``rss_conf->rss_key`` => ``key``,
> +    ``rss_conf->rss_key_len`` => ``key_len``,
> +    ``rss_conf->rss_hf`` => ``types``,
> +    ``num`` => ``queue_num``).
> 
> 
>  ABI Changes
> @@ -302,9 +309,9 @@ ABI Changes
>    ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
>    changes in error type definitions (``enum rte_flow_error_type``), removal
>    of the unused DUP action (``enum rte_flow_action_type``), modified
> -  behavior for flow rule actions (see API changes) and removal of C99
> -  flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
> -  pattern item (``struct rte_flow_item_raw``).
> +  behavior for flow rule actions (see API changes), removal of C99 flexible
> +  array from RAW pattern item (``struct rte_flow_item_raw``) and complete
> +  rework of the RSS action definition (``struct rte_flow_action_rss``).
> 
> 
>  Removed Items
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 68c286bd4..a12e0267a 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3422,8 +3422,10 @@ This section lists supported actions and their
> attributes, if any.
> 
>  - ``rss``: spread packets among several queues.
> 
> -  - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
> -    are the same as `set_hash_input_set`_, an empty list means none (0).
> +  - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
> +    tokens are the same as `set_hash_input_set`_, except that an empty list
> +    does not disable RSS but instead requests unspecified "best-effort"
> +    settings.
> 
>    - ``key {string}``: RSS hash key, overrides ``key_len``.
> 
> diff --git a/drivers/net/e1000/e1000_ethdev.h
> b/drivers/net/e1000/e1000_ethdev.h
> index 6354b894a..902001f36 100644
> --- a/drivers/net/e1000/e1000_ethdev.h
> +++ b/drivers/net/e1000/e1000_ethdev.h
> @@ -4,6 +4,10 @@
> 
>  #ifndef _E1000_ETHDEV_H_
>  #define _E1000_ETHDEV_H_
> +
> +#include <stdint.h>
> +
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_pci.h>
> 
> @@ -27,6 +31,7 @@
>  #define E1000_CTRL_EXT_EXTEND_VLAN  (1<<26)    /* EXTENDED VLAN */
>  #define IGB_VFTA_SIZE 128
> 
> +#define IGB_HKEY_MAX_INDEX             10
>  #define IGB_MAX_RX_QUEUE_NUM           8
>  #define IGB_MAX_RX_QUEUE_NUM_82576     16
> 
> @@ -229,8 +234,8 @@ struct igb_ethertype_filter {
>  };
> 
>  struct igb_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IGB_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key.
> */
>  	uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices
> to use. */
>  };
> 
> @@ -501,6 +506,10 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev,
>  int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
>  			struct rte_eth_flex_filter *filter,
>  			bool add);
> +int igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		      const struct rte_flow_action_rss *in);
> +int igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +			const struct rte_flow_action_rss *with);
>  int igb_config_rss_filter(struct rte_eth_dev *dev,
>  			struct igb_rte_flow_rss_conf *conf,
>  			bool add);
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c
> index c35c9352a..140334772 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -41,8 +41,6 @@
>  #define IGB_DEFAULT_TX_HTHRESH      1
>  #define IGB_DEFAULT_TX_WTHRESH      ((hw->mac.type == e1000_82576) ?
> 1 : 16)
> 
> -#define IGB_HKEY_MAX_INDEX 10
> -
>  /* Bit shift and mask */
>  #define IGB_4_BIT_WIDTH  (CHAR_BIT / 2)
>  #define IGB_4_BIT_MASK   RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)
> @@ -5662,7 +5660,7 @@ igb_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter_info->rss_info, TRUE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
> index c0f5b5190..8dc5f75f2 100644
> --- a/drivers/net/e1000/igb_flow.c
> +++ b/drivers/net/e1000/igb_flow.c
> @@ -1292,7 +1292,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -1300,7 +1300,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1310,14 +1310,18 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		}
>  	}
> 
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
> -
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (igb_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	index++;
> @@ -1518,9 +1522,8 @@ igb_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct igb_rte_flow_rss_conf));
> +			igb_rss_conf_init(&rss_filter_ptr->filter_info,
> +					  &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> @@ -1757,7 +1760,7 @@ igb_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter->rss_info.num)
> +	if (filter->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
> index 323913f0d..45bb3455c 100644
> --- a/drivers/net/e1000/igb_rxtx.c
> +++ b/drivers/net/e1000/igb_rxtx.c
> @@ -2898,12 +2898,47 @@ igb_txq_info_get(struct rte_eth_dev *dev,
> uint16_t queue_id,
>  }
> 
>  int
> +igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		  const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +		    const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  igb_config_rss_filter(struct rte_eth_dev *dev,
>  		struct igb_rte_flow_rss_conf *conf, bool add)
>  {
>  	uint32_t shift;
>  	uint16_t i, j;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
>  	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> @@ -2911,8 +2946,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct igb_rte_flow_rss_conf)) == 0) {
> +		if (igb_action_rss_same(&filter_info->rss_info.conf,
> +					&conf->conf)) {
>  			igb_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct igb_rte_flow_rss_conf));
> @@ -2921,7 +2956,7 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
> 
>  	/* Fill in redirection table. */
> @@ -2933,9 +2968,9 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		} reta;
>  		uint8_t q_idx;
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		q_idx = conf->queue[j];
> +		q_idx = conf->conf.queue[j];
>  		reta.bytes[i & 3] = (uint8_t)(q_idx << shift);
>  		if ((i & 3) == 3)
>  			E1000_WRITE_REG(hw, E1000_RETA(i >> 2),
> reta.dword);
> @@ -2952,8 +2987,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	igb_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct igb_rte_flow_rss_conf));
> +	if (igb_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 78f2be7da..50e77901c 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -11,6 +11,7 @@
>  #include <inttypes.h>
>  #include <assert.h>
> 
> +#include <rte_common.h>
>  #include <rte_eal.h>
>  #include <rte_string_fns.h>
>  #include <rte_pci.h>
> @@ -11650,7 +11651,7 @@ i40e_rss_filter_restore(struct i40e_pf *pf)
>  {
>  	struct i40e_rte_flow_rss_conf *conf =
>  					&pf->rss_info;
> -	if (conf->num)
> +	if (conf->conf.queue_num)
>  		i40e_config_rss_filter(pf, conf, TRUE);
>  }
> 
> @@ -12182,18 +12183,52 @@ i40e_cloud_filter_qinq_create(struct i40e_pf
> *pf)
>  }
> 
>  int
> +i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		   const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +		     const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
>  	uint32_t i, lut = 0;
>  	uint16_t j, num;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info;
> 
>  	if (!add) {
> -		if (memcmp(conf, rss_info,
> -			sizeof(struct i40e_rte_flow_rss_conf)) == 0) {
> +		if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) {
>  			i40e_pf_disable_rss(pf);
>  			memset(rss_info, 0,
>  				sizeof(struct i40e_rte_flow_rss_conf));
> @@ -12202,7 +12237,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  		return -EINVAL;
>  	}
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		return -EINVAL;
> 
>  	/* If both VMDQ and RSS enabled, not all of PF queues are
> configured.
> @@ -12213,7 +12248,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	else
>  		num = pf->dev_data->nb_rx_queues;
> 
> -	num = RTE_MIN(num, conf->num);
> +	num = RTE_MIN(num, conf->conf.queue_num);
>  	PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are
> configured",
>  			num);
> 
> @@ -12226,7 +12261,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
>  		if (j == num)
>  			j = 0;
> -		lut = (lut << 8) | (conf->queue[j] & ((0x1 <<
> +		lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 <<
>  			hw->func_caps.rss_table_entry_width) - 1));
>  		if ((i & 3) == 3)
>  			I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
> @@ -12251,8 +12286,8 @@ i40e_config_rss_filter(struct i40e_pf *pf,
> 
>  	i40e_hw_rss_hash_set(pf, &rss_conf);
> 
> -	rte_memcpy(rss_info,
> -		conf, sizeof(struct i40e_rte_flow_rss_conf));
> +	if (i40e_rss_conf_init(rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h
> index d33b255e7..a0569d4ae 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -5,14 +5,19 @@
>  #ifndef _I40E_ETHDEV_H_
>  #define _I40E_ETHDEV_H_
> 
> +#include <stdint.h>
> +
>  #include <rte_eth_ctrl.h>
>  #include <rte_time.h>
>  #include <rte_kvargs.h>
>  #include <rte_hash.h>
> +#include <rte_flow.h>
>  #include <rte_flow_driver.h>
>  #include <rte_tm_driver.h>
>  #include "rte_pmd_i40e.h"
> 
> +#include "base/i40e_register.h"
> +
>  #define I40E_VLAN_TAG_SIZE        4
> 
>  #define I40E_AQ_LEN               32
> @@ -878,9 +883,11 @@ struct i40e_customized_pctype {
>  };
> 
>  struct i40e_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
>  	uint16_t queue_region_conf; /**< Queue region config flag */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	uint8_t key[(I40E_VFQF_HKEY_MAX_INDEX >
> I40E_PFQF_HKEY_MAX_INDEX ?
> +		     I40E_VFQF_HKEY_MAX_INDEX :
> I40E_PFQF_HKEY_MAX_INDEX) + 1 *
> +		    sizeof(uint32_t)]; /* Hash key. */
>  	uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use.
> */
>  };
> 
> @@ -1219,6 +1226,10 @@ void i40e_init_queue_region_conf(struct
> rte_eth_dev *dev);
>  void i40e_flex_payload_reg_set_default(struct i40e_hw *hw);
>  int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
>  int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
> +int i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		       const struct rte_flow_action_rss *in);
> +int i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +			 const struct rte_flow_action_rss *with);
>  int i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index d6f5e9923..ec6231003 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -4220,7 +4220,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
> 
>  	if (action_flag) {
>  		for (n = 0; n < 64; n++) {
> -			if (rss->rss_conf->rss_hf & (hf_bit << n)) {
> +			if (rss->types & (hf_bit << n)) {
>  				conf_info->region[0].hw_flowtype[0] = n;
>  				conf_info->region[0].flowtype_num = 1;
>  				conf_info->queue_region_number = 1;
> @@ -4236,12 +4236,12 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	 * queue index for this port.
>  	 */
>  	if (conf_info->queue_region_number) {
> -		for (i = 0; i < rss->num; i++) {
> -			for (j = 0; j < rss_info->num; j++) {
> -				if (rss->queue[i] == rss_info->queue[j])
> +		for (i = 0; i < rss->queue_num; i++) {
> +			for (j = 0; j < rss_info->conf.queue_num; j++) {
> +				if (rss->queue[i] == rss_info->conf.queue[j])
>  					break;
>  			}
> -			if (j == rss_info->num) {
> +			if (j == rss_info->conf.queue_num) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4250,7 +4250,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
>  		}
> 
> -		for (i = 0; i < rss->num - 1; i++) {
> +		for (i = 0; i < rss->queue_num - 1; i++) {
>  			if (rss->queue[i + 1] != rss->queue[i] + 1) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4265,8 +4265,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	for (n = 0; n < conf_info->queue_region_number; n++) {
>  		if (conf_info->region[n].user_priority_num ||
>  				conf_info->region[n].flowtype_num) {
> -			if (!((rte_is_power_of_2(rss->num)) &&
> -					rss->num <= 64)) {
> +			if (!((rte_is_power_of_2(rss->queue_num)) &&
> +					rss->queue_num <= 64)) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4294,7 +4294,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
> 
>  			for (i = 0; i < info->queue_region_number; i++) {
> -				if (info->region[i].queue_num == rss->num
> &&
> +				if (info->region[i].queue_num ==
> +				    rss->queue_num &&
>  					info->region[i].queue_start_index ==
>  						rss->queue[0])
>  					break;
> @@ -4310,7 +4311,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  				}
> 
>  				info->region[i].queue_num =
> -					rss->num;
> +					rss->queue_num;
>  				info->region[i].queue_start_index =
>  					rss->queue[0];
>  				info->region[i].region_id =
> @@ -4356,7 +4357,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	if (rss_config->queue_region_conf)
>  		return 0;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -4364,7 +4365,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4375,15 +4376,19 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	}
> 
>  	/* Parse RSS related parameters from configuration */
> -	if (rss->rss_conf)
> -		rss_config->rss_conf = *rss->rss_conf;
> -	else
> -		rss_config->rss_conf.rss_hf =
> -			pf->adapter->flow_types_mask;
> +	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key too large");
> +	if (rss->queue_num > RTE_DIM(rss_config->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (i40e_rss_conf_init(rss_config, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_config->queue[n] = rss->queue[n];
> -	rss_config->num = rss->num;
>  	index++;
> 
>  	/* check if the next not void action is END */
> @@ -4903,7 +4908,7 @@ i40e_flow_flush_rss_filter(struct rte_eth_dev *dev)
> 
>  	ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		ret = i40e_config_rss_filter(pf, rss_info, FALSE);
>  	return ret;
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 92434809c..c00bdae3d 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -100,8 +100,6 @@
> 
>  #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) /
> sizeof(hw_stats->qprc[0]))
> 
> -#define IXGBE_HKEY_MAX_INDEX 10
> -
>  /* Additional timesync values. */
>  #define NSEC_PER_SEC             1000000000L
>  #define IXGBE_INCVAL_10GB        0x66666666
> @@ -8371,7 +8369,7 @@ ixgbe_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev,
>  			&filter_info->rss_info, TRUE);
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h
> b/drivers/net/ixgbe/ixgbe_ethdev.h
> index 655077700..9491b03f4 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -4,6 +4,9 @@
> 
>  #ifndef _IXGBE_ETHDEV_H_
>  #define _IXGBE_ETHDEV_H_
> +
> +#include <stdint.h>
> +
>  #include "base/ixgbe_type.h"
>  #include "base/ixgbe_dcb.h"
>  #include "base/ixgbe_dcb_82599.h"
> @@ -12,6 +15,7 @@
>  #ifdef RTE_LIBRTE_SECURITY
>  #include "ixgbe_ipsec.h"
>  #endif
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_hash.h>
>  #include <rte_pci.h>
> @@ -39,6 +43,7 @@
>  #define IXGBE_EXTENDED_VLAN	  (uint32_t)(1 << 26) /* EXTENDED
> VLAN ENABLE */
>  #define IXGBE_VFTA_SIZE 128
>  #define IXGBE_VLAN_TAG_SIZE 4
> +#define IXGBE_HKEY_MAX_INDEX 10
>  #define IXGBE_MAX_RX_QUEUE_NUM	128
>  #define IXGBE_MAX_INTR_QUEUE_NUM	15
>  #define IXGBE_VMDQ_DCB_NB_QUEUES     IXGBE_MAX_RX_QUEUE_NUM
> @@ -196,8 +201,8 @@ struct ixgbe_hw_fdir_info {
>  };
> 
>  struct ixgbe_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash
> key. */
>  	uint16_t queue[IXGBE_MAX_RX_QUEUE_NUM]; /**< Queues
> indices to use. */
>  };
> 
> @@ -696,6 +701,10 @@ void ixgbe_tm_conf_init(struct rte_eth_dev *dev);
>  void ixgbe_tm_conf_uninit(struct rte_eth_dev *dev);
>  int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t
> queue_idx,
>  			       uint16_t tx_rate);
> +int ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +			const struct rte_flow_action_rss *in);
> +int ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +			  const struct rte_flow_action_rss *with);
>  int ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
> index abdeac28b..4e31c7c56 100644
> --- a/drivers/net/ixgbe/ixgbe_flow.c
> +++ b/drivers/net/ixgbe/ixgbe_flow.c
> @@ -2761,7 +2761,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -2769,7 +2769,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -2778,14 +2778,19 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  			return -rte_errno;
>  		}
>  	}
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IXGBE_RSS_OFFLOAD_ALL;
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (ixgbe_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	act = next_no_void_action(actions, act);
> @@ -2834,7 +2839,7 @@ ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
>  }
> 
> @@ -3153,9 +3158,8 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct ixgbe_rte_flow_rss_conf));
> +			ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
> +					    &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index aed3f5a9a..9fbd7dbd7 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -5676,6 +5676,36 @@ ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev)
>  }
> 
>  int
> +ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +		    const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +		      const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add)
>  {
> @@ -5685,7 +5715,12 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	uint16_t j;
>  	uint16_t sp_reta_size;
>  	uint32_t reta_reg;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> @@ -5695,8 +5730,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	sp_reta_size = ixgbe_reta_size_get(hw->mac.type);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct ixgbe_rte_flow_rss_conf)) == 0) {
> +		if (ixgbe_action_rss_same(&filter_info->rss_info.conf,
> +					  &conf->conf)) {
>  			ixgbe_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct ixgbe_rte_flow_rss_conf));
> @@ -5705,7 +5740,7 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
>  	/* Fill in redirection table
>  	 * The byte-swap is needed because NIC registers are in
> @@ -5715,9 +5750,9 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	for (i = 0, j = 0; i < sp_reta_size; i++, j++) {
>  		reta_reg = ixgbe_reta_reg_get(hw->mac.type, i);
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		reta = (reta << 8) | conf->queue[j];
> +		reta = (reta << 8) | conf->conf.queue[j];
>  		if ((i & 3) == 3)
>  			IXGBE_WRITE_REG(hw, reta_reg,
>  					rte_bswap32(reta));
> @@ -5734,8 +5769,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	ixgbe_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct ixgbe_rte_flow_rss_conf));
> +	if (ixgbe_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 937074a4f..3dd72dbf5 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -571,7 +571,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct
> rte_pci_device *pci_dev)
>  			     " for UDP RSS and inner VXLAN RSS");
>  			/* Fake support for all possible RSS hash fields. */
>  			priv->hw_rss_sup = ~UINT64_C(0);
> -			priv->hw_rss_sup = mlx4_conv_rss_hf(priv, -1);
> +			priv->hw_rss_sup = mlx4_conv_rss_types(priv, -1);
>  			/* Filter out known unsupported fields. */
>  			priv->hw_rss_sup &=
>  				~(uint64_t)(IBV_RX_HASH_SRC_PORT_UDP |
> diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
> index 8feb6ae31..dd86e4ce7 100644
> --- a/drivers/net/mlx4/mlx4_flow.c
> +++ b/drivers/net/mlx4/mlx4_flow.c
> @@ -76,22 +76,22 @@ struct mlx4_drop {
>  };
> 
>  /**
> - * Convert DPDK RSS hash fields to their Verbs equivalent.
> + * Convert DPDK RSS hash types to their Verbs equivalent.
>   *
> - * This function returns the supported (default) set when @p rss_hf has
> + * This function returns the supported (default) set when @p types has
>   * special value (uint64_t)-1.
>   *
>   * @param priv
>   *   Pointer to private structure.
> - * @param rss_hf
> - *   Hash fields in DPDK format (see struct rte_eth_rss_conf).
> + * @param types
> + *   Hash types in DPDK format (see struct rte_eth_rss_conf).
>   *
>   * @return
>   *   A valid Verbs RSS hash fields mask for mlx4 on success, (uint64_t)-1
>   *   otherwise and rte_errno is set.
>   */
>  uint64_t
> -mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
> +mlx4_conv_rss_types(struct priv *priv, uint64_t types)
>  {
>  	enum { IPV4, IPV6, TCP, UDP, };
>  	const uint64_t in[] = {
> @@ -126,17 +126,17 @@ mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
>  	unsigned int i;
> 
>  	for (i = 0; i != RTE_DIM(in); ++i)
> -		if (rss_hf & in[i]) {
> -			seen |= rss_hf & in[i];
> +		if (types & in[i]) {
> +			seen |= types & in[i];
>  			conv |= out[i];
>  		}
>  	if ((conv & priv->hw_rss_sup) == conv) {
> -		if (rss_hf == (uint64_t)-1) {
> +		if (types == (uint64_t)-1) {
>  			/* Include inner RSS by default if supported. */
>  			conv |= priv->hw_rss_sup & IBV_RX_HASH_INNER;
>  			return conv;
>  		}
> -		if (!(rss_hf & ~seen))
> +		if (!(types & ~seen))
>  			return conv;
>  	}
>  	rte_errno = ENOTSUP;
> @@ -717,7 +717,8 @@ mlx4_flow_prepare(struct priv *priv,
>  		switch (action->type) {
>  			const struct rte_flow_action_queue *queue;
>  			const struct rte_flow_action_rss *rss;
> -			const struct rte_eth_rss_conf *rss_conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint64_t fields;
>  			unsigned int i;
> 
> @@ -747,58 +748,56 @@ mlx4_flow_prepare(struct priv *priv,
>  				break;
>  			rss = action->conf;
>  			/* Default RSS configuration if none is provided. */
> -			rss_conf =
> -				rss->rss_conf ?
> -				rss->rss_conf :
> -				&(struct rte_eth_rss_conf){
> -					.rss_key =
> mlx4_rss_hash_key_default,
> -					.rss_key_len =
> MLX4_RSS_HASH_KEY_SIZE,
> -					.rss_hf = -1,
> -				};
> +			if (rss->key_len) {
> +				rss_key = rss->key;
> +				rss_key_len = rss->key_len;
> +			} else {
> +				rss_key = mlx4_rss_hash_key_default;
> +				rss_key_len = MLX4_RSS_HASH_KEY_SIZE;
> +			}
>  			/* Sanity checks. */
> -			for (i = 0; i < rss->num; ++i)
> +			for (i = 0; i < rss->queue_num; ++i)
>  				if (rss->queue[i] >=
>  				    priv->dev->data->nb_rx_queues)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "queue index target beyond number
> of"
>  					" configured Rx queues";
>  				goto exit_action_not_supported;
>  			}
> -			if (!rte_is_power_of_2(rss->num)) {
> +			if (!rte_is_power_of_2(rss->queue_num)) {
>  				msg = "for RSS, mlx4 requires the number of"
>  					" queues to be a power of two";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss_conf->rss_key_len !=
> -			    sizeof(flow->rss->key)) {
> +			if (rss_key_len != sizeof(flow->rss->key)) {
>  				msg = "mlx4 supports exactly one RSS hash
> key"
>  					" length: "
> 
> 	MLX4_STR_EXPAND(MLX4_RSS_HASH_KEY_SIZE);
>  				goto exit_action_not_supported;
>  			}
> -			for (i = 1; i < rss->num; ++i)
> +			for (i = 1; i < rss->queue_num; ++i)
>  				if (rss->queue[i] - rss->queue[i - 1] != 1)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "mlx4 requires RSS contexts to use"
>  					" consecutive queue indices only";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss->queue[0] % rss->num) {
> +			if (rss->queue[0] % rss->queue_num) {
>  				msg = "mlx4 requires the first queue of a
> RSS"
>  					" context to be aligned on a multiple"
>  					" of the context size";
>  				goto exit_action_not_supported;
>  			}
>  			rte_errno = 0;
> -			fields = mlx4_conv_rss_hf(priv, rss_conf->rss_hf);
> +			fields = mlx4_conv_rss_types(priv, rss->types);
>  			if (fields == (uint64_t)-1 && rte_errno) {
>  				msg = "unsupported RSS hash type
> requested";
>  				goto exit_action_not_supported;
>  			}
>  			flow->rss = mlx4_rss_get
> -				(priv, fields, rss_conf->rss_key, rss->num,
> +				(priv, fields, rss_key, rss->queue_num,
>  				 rss->queue);
>  			if (!flow->rss) {
>  				msg = "either invalid parameters or not
> enough"
> @@ -1284,8 +1283,10 @@ mlx4_flow_internal(struct priv *priv, struct
> rte_flow_error *error)
>  		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
>  	uint16_t queue[queues];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = NULL, /* Rely on default fallback settings. */
> -		.num = queues,
> +		.types = -1,
> +		.key_len = MLX4_RSS_HASH_KEY_SIZE,
> +		.queue_num = queues,
> +		.key = mlx4_rss_hash_key_default,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h
> index 4e3889e67..7b83d74b0 100644
> --- a/drivers/net/mlx4/mlx4_flow.h
> +++ b/drivers/net/mlx4/mlx4_flow.h
> @@ -47,7 +47,7 @@ struct rte_flow {
> 
>  /* mlx4_flow.c */
> 
> -uint64_t mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf);
> +uint64_t mlx4_conv_rss_types(struct priv *priv, uint64_t rss_hf);
>  int mlx4_flow_sync(struct priv *priv, struct rte_flow_error *error);
>  void mlx4_flow_clean(struct priv *priv);
>  int mlx4_filter_ctrl(struct rte_eth_dev *dev,
> diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
> index a7acc047b..65f099423 100644
> --- a/drivers/net/mlx4/mlx4_rxq.c
> +++ b/drivers/net/mlx4/mlx4_rxq.c
> @@ -88,7 +88,7 @@
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE] = {
>   */
>  struct mlx4_rss *
>  mlx4_rss_get(struct priv *priv, uint64_t fields,
> -	     uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +	     const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  	     uint16_t queues, const uint16_t queue_id[])
>  {
>  	struct mlx4_rss *rss;
> diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
> index b1af86110..2dfee957f 100644
> --- a/drivers/net/mlx4/mlx4_rxtx.h
> +++ b/drivers/net/mlx4/mlx4_rxtx.h
> @@ -127,7 +127,7 @@ uint8_t
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE];
>  int mlx4_rss_init(struct priv *priv);
>  void mlx4_rss_deinit(struct priv *priv);
>  struct mlx4_rss *mlx4_rss_get(struct priv *priv, uint64_t fields,
> -			      uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +			      const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  			      uint16_t queues, const uint16_t queue_id[]);
>  void mlx4_rss_put(struct mlx4_rss *rss);
>  int mlx4_rss_attach(struct mlx4_rss *rss);
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 0c89bff45..af8853e09 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -214,9 +214,8 @@ struct rte_flow {
>  	TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure.
> */
>  	uint32_t mark:1; /**< Set if the flow is marked. */
>  	uint32_t drop:1; /**< Drop queue. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t (*queues)[]; /**< Queues indexes to use. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	struct ibv_counter_set *cs; /**< Holds the counters for the rule. */
>  	struct mlx5_flow_counter_stats counter_stats;/**<The counter
> stats. */
> @@ -406,9 +405,8 @@ struct mlx5_flow_parse {
>  	uint32_t mark:1; /**< Mark is present in the flow. */
>  	uint32_t count:1; /**< Count is present in the flow. */
>  	uint32_t mark_id; /**< Mark identifier. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queues
> indexes to use. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	enum hash_rxq_type layer; /**< Last pattern layer detected. */
>  	struct ibv_counter_set *cs; /**< Holds the counter set for the rule */
> @@ -540,47 +538,6 @@ mlx5_flow_item_validate(const struct
> rte_flow_item *item,
>  }
> 
>  /**
> - * Copy the RSS configuration from the user ones, of the rss_conf is null,
> - * uses the driver one.
> - *
> - * @param parser
> - *   Internal parser structure.
> - * @param rss_conf
> - *   User RSS configuration to save.
> - *
> - * @return
> - *   0 on success, a negative errno value otherwise and rte_errno is set.
> - */
> -static int
> -mlx5_flow_convert_rss_conf(struct mlx5_flow_parse *parser,
> -			   const struct rte_eth_rss_conf *rss_conf)
> -{
> -	/*
> -	 * This function is also called at the beginning of
> -	 * mlx5_flow_convert_actions() to initialize the parser with the
> -	 * device default RSS configuration.
> -	 */
> -	if (rss_conf) {
> -		if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len != 40) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len && rss_conf->rss_key) {
> -			parser->rss_conf.rss_key_len = rss_conf-
> >rss_key_len;
> -			memcpy(parser->rss_key, rss_conf->rss_key,
> -			       rss_conf->rss_key_len);
> -			parser->rss_conf.rss_key = parser->rss_key;
> -		}
> -		parser->rss_conf.rss_hf = rss_conf->rss_hf;
> -	}
> -	return 0;
> -}
> -
> -/**
>   * Extract attribute to the parser.
>   *
>   * @param[in] attr
> @@ -650,17 +607,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  	enum { FATE = 1, MARK = 2, COUNT = 4, };
>  	uint32_t overlap = 0;
>  	struct priv *priv = dev->data->dev_private;
> -	int ret;
> 
> -	/*
> -	 * Add default RSS configuration necessary for Verbs to create QP
> even
> -	 * if no RSS is necessary.
> -	 */
> -	ret = mlx5_flow_convert_rss_conf(parser,
> -					 (const struct rte_eth_rss_conf *)
> -					 &priv->rss_conf);
> -	if (ret)
> -		return ret;
>  	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
>  		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
>  			continue;
> @@ -679,25 +626,53 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  			overlap |= FATE;
>  			if (!queue || (queue->index > (priv->rxqs_n - 1)))
>  				goto exit_action_not_supported;
> -			parser->queues_n = 1;
>  			parser->queues[0] = queue->index;
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.queue_num = 1,
> +				.queue = parser->queues,
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
>  			const struct rte_flow_action_rss *rss =
>  				(const struct rte_flow_action_rss *)
>  				actions->conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint16_t n;
> 
>  			if (overlap & FATE)
>  				goto exit_action_overlap;
>  			overlap |= FATE;
> -			if (!rss || !rss->num) {
> +			if (rss->types & MLX5_RSS_HF_MASK) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "unsupported RSS type"
> +						   " requested");
> +				return -rte_errno;
> +			}
> +			if (rss->key_len) {
> +				rss_key_len = rss->key_len;
> +				rss_key = rss->key;
> +			} else {
> +				rss_key_len = rss_hash_default_key_len;
> +				rss_key = rss_hash_default_key;
> +			}
> +			if (rss_key_len != RTE_DIM(parser->rss_key)) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "RSS hash key must be"
> +						   " exactly 40 bytes long");
> +				return -rte_errno;
> +			}
> +			if (!rss->queue_num) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
>  						   "no valid queues");
>  				return -rte_errno;
>  			}
> -			if (rss->num > RTE_DIM(parser->queues)) {
> +			if (rss->queue_num > RTE_DIM(parser->queues)) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
> @@ -705,7 +680,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  						   " context");
>  				return -rte_errno;
>  			}
> -			for (n = 0; n < rss->num; ++n) {
> +			for (n = 0; n < rss->queue_num; ++n) {
>  				if (rss->queue[n] >= priv->rxqs_n) {
>  					rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -715,16 +690,16 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  					return -rte_errno;
>  				}
>  			}
> -			for (n = 0; n < rss->num; ++n)
> -				parser->queues[n] = rss->queue[n];
> -			parser->queues_n = rss->num;
> -			if (mlx5_flow_convert_rss_conf(parser, rss-
> >rss_conf)) {
> -				rte_flow_error_set(error, EINVAL,
> -
> RTE_FLOW_ERROR_TYPE_ACTION,
> -						   actions,
> -						   "wrong RSS configuration");
> -				return -rte_errno;
> -			}
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.types = rss->types,
> +				.key_len = rss_key_len,
> +				.queue_num = rss->queue_num,
> +				.key = memcpy(parser->rss_key, rss_key,
> +					      sizeof(*rss_key) * rss_key_len),
> +				.queue = memcpy(parser->queues, rss-
> >queue,
> +						sizeof(*rss->queue) *
> +						rss->queue_num),
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK)
> {
>  			const struct rte_flow_action_mark *mark =
>  				(const struct rte_flow_action_mark *)
> @@ -769,7 +744,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  		parser->drop = 1;
>  	if (parser->drop && parser->mark)
>  		parser->mark = 0;
> -	if (!parser->queues_n && !parser->drop) {
> +	if (!parser->rss_conf.queue_num && !parser->drop) {
>  		rte_flow_error_set(error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_HANDLE,
>  				   NULL, "no valid action");
>  		return -rte_errno;
> @@ -951,7 +926,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	unsigned int i;
> 
>  	/* Remove any other flow not matching the pattern. */
> -	if (parser->queues_n == 1 && !parser->rss_conf.rss_hf) {
> +	if (parser->rss_conf.queue_num == 1 && !parser->rss_conf.types) {
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			if (i == HASH_RXQ_ETH)
>  				continue;
> @@ -979,7 +954,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	}
>  	/* Remove impossible flow according to the RSS configuration. */
>  	if (hash_rxq_init[parser->layer].dpdk_rss_hf &
> -	    parser->rss_conf.rss_hf) {
> +	    parser->rss_conf.types) {
>  		/* Remove any other flow. */
>  		for (i = hmin; i != (hmax + 1); ++i) {
>  			if ((i == parser->layer) ||
> @@ -990,7 +965,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  		}
>  	} else  if (!parser->queue[ip].ibv_attr) {
>  		/* no RSS possible with the current configuration. */
> -		parser->queues_n = 1;
> +		parser->rss_conf.queue_num = 1;
>  		return;
>  	}
>  fill:
> @@ -1119,7 +1094,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev,
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			unsigned int offset;
> 
> -			if (!(parser->rss_conf.rss_hf &
> +			if (!(parser->rss_conf.types &
>  			      hash_rxq_init[i].dpdk_rss_hf) &&
>  			    (i != HASH_RXQ_ETH))
>  				continue;
> @@ -1787,20 +1762,20 @@ mlx5_flow_create_action_queue_rss(struct
> rte_eth_dev *dev,
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_get(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (flow->frxq[i].hrxq)
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_new(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (!flow->frxq[i].hrxq) {
>  			return rte_flow_error_set(error, ENOMEM,
> 
> RTE_FLOW_ERROR_TYPE_HANDLE,
> @@ -1871,9 +1846,9 @@ mlx5_flow_create_action_queue(struct
> rte_eth_dev *dev,
>  				   NULL, "internal error in flow creation");
>  		goto error;
>  	}
> -	for (i = 0; i != parser->queues_n; ++i) {
> +	for (i = 0; i != parser->rss_conf.queue_num; ++i) {
>  		struct mlx5_rxq_data *q =
> -			(*priv->rxqs)[parser->queues[i]];
> +			(*priv->rxqs)[parser->rss_conf.queue[i]];
> 
>  		q->mark |= parser->mark;
>  	}
> @@ -1937,7 +1912,8 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  	if (ret)
>  		goto exit;
>  	flow = rte_calloc(__func__, 1,
> -			  sizeof(*flow) + parser.queues_n * sizeof(uint16_t),
> +			  sizeof(*flow) +
> +			  parser.rss_conf.queue_num * sizeof(uint16_t),
>  			  0);
>  	if (!flow) {
>  		rte_flow_error_set(error, ENOMEM,
> @@ -1946,15 +1922,20 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  				   "cannot allocate flow memory");
>  		return NULL;
>  	}
> -	/* Copy queues configuration. */
> +	/* Copy configuration. */
>  	flow->queues = (uint16_t (*)[])(flow + 1);
> -	memcpy(flow->queues, parser.queues, parser.queues_n *
> sizeof(uint16_t));
> -	flow->queues_n = parser.queues_n;
> +	flow->rss_conf = (struct rte_flow_action_rss){
> +		.types = parser.rss_conf.types,
> +		.key_len = parser.rss_conf.key_len,
> +		.queue_num = parser.rss_conf.queue_num,
> +		.key = memcpy(flow->rss_key, parser.rss_conf.key,
> +			      sizeof(*parser.rss_conf.key) *
> +			      parser.rss_conf.key_len),
> +		.queue = memcpy(flow->queues, parser.rss_conf.queue,
> +				sizeof(*parser.rss_conf.queue) *
> +				parser.rss_conf.queue_num),
> +	};
>  	flow->mark = parser.mark;
> -	/* Copy RSS configuration. */
> -	flow->rss_conf = parser.rss_conf;
> -	flow->rss_conf.rss_key = flow->rss_key;
> -	memcpy(flow->rss_key, parser.rss_key,
> parser.rss_conf.rss_key_len);
>  	/* finalise the flow. */
>  	if (parser.drop)
>  		ret = mlx5_flow_create_action_queue_drop(dev, &parser,
> flow,
> @@ -2034,7 +2015,7 @@ mlx5_flow_list_destroy(struct rte_eth_dev *dev,
> struct mlx5_flows *list,
> 
>  	if (flow->drop || !flow->mark)
>  		goto free;
> -	for (i = 0; i != flow->queues_n; ++i) {
> +	for (i = 0; i != flow->rss_conf.queue_num; ++i) {
>  		struct rte_flow *tmp;
>  		int mark = 0;
> 
> @@ -2344,19 +2325,19 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  			if (!flow->frxq[i].ibv_attr)
>  				continue;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_get(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_get(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (flow->frxq[i].hrxq)
>  				goto flow_create;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_new(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_new(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (!flow->frxq[i].hrxq) {
>  				DRV_LOG(DEBUG,
>  					"port %u flow %p cannot be applied",
> @@ -2380,8 +2361,8 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  		}
>  		if (!flow->mark)
>  			continue;
> -		for (i = 0; i != flow->queues_n; ++i)
> -			(*priv->rxqs)[(*flow->queues)[i]]->mark = 1;
> +		for (i = 0; i != flow->rss_conf.queue_num; ++i)
> +			(*priv->rxqs)[flow->rss_conf.queue[i]]->mark = 1;
>  	}
>  	return 0;
>  }
> @@ -2458,8 +2439,10 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
>  	};
>  	uint16_t queue[priv->reta_idx_n];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = &priv->rss_conf,
> -		.num = priv->reta_idx_n,
> +		.types = priv->rss_conf.rss_hf,
> +		.key_len = priv->rss_conf.rss_key_len,
> +		.queue_num = priv->reta_idx_n,
> +		.key = priv->rss_conf.rss_key,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
> index eda3ba3d5..d2b25e8e8 100644
> --- a/drivers/net/mlx5/mlx5_rxq.c
> +++ b/drivers/net/mlx5/mlx5_rxq.c
> @@ -1218,8 +1218,8 @@ mlx5_rxq_verify(struct rte_eth_dev *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1286,8 +1286,8 @@ mlx5_ind_table_ibv_new(struct rte_eth_dev *dev,
> uint16_t queues[],
>   *   An indirection table if found.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1391,8 +1391,10 @@ mlx5_ind_table_ibv_verify(struct rte_eth_dev
> *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_new(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> @@ -1408,6 +1410,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  		rte_errno = ENOMEM;
>  		return NULL;
>  	}
> +	if (!rss_key_len) {
> +		rss_key_len = rss_hash_default_key_len;
> +		rss_key = rss_hash_default_key;
> +	}
>  	qp = mlx5_glue->create_qp_ex
>  		(priv->ctx,
>  		 &(struct ibv_qp_init_attr_ex){
> @@ -1419,7 +1425,7 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  			.rx_hash_conf = (struct ibv_rx_hash_conf){
>  				.rx_hash_function =
> IBV_RX_HASH_FUNC_TOEPLITZ,
>  				.rx_hash_key_len = rss_key_len,
> -				.rx_hash_key = rss_key,
> +				.rx_hash_key = (void *)(uintptr_t)rss_key,
>  				.rx_hash_fields_mask = hash_fields,
>  			},
>  			.rwq_ind_tbl = ind_tbl->ind_table,
> @@ -1469,8 +1475,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>   *   An hash Rx queue on success.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_get(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
> index 14d4418d9..c3a1ae213 100644
> --- a/drivers/net/mlx5/mlx5_rxtx.h
> +++ b/drivers/net/mlx5/mlx5_rxtx.h
> @@ -134,7 +134,7 @@ struct mlx5_ind_table_ibv {
>  	LIST_ENTRY(mlx5_ind_table_ibv) next; /* Pointer to the next
> element. */
>  	rte_atomic32_t refcnt; /* Reference counter. */
>  	struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
> -	uint16_t queues_n; /**< Number of queues in the list. */
> +	uint32_t queues_n; /**< Number of queues in the list. */
>  	uint16_t queues[]; /**< Queue list. */
>  };
> 
> @@ -145,7 +145,7 @@ struct mlx5_hrxq {
>  	struct mlx5_ind_table_ibv *ind_table; /* Indirection table. */
>  	struct ibv_qp *qp; /* Verbs queue pair. */
>  	uint64_t hash_fields; /* Verbs Hash fields. */
> -	uint8_t rss_key_len; /* Hash key length in bytes. */
> +	uint32_t rss_key_len; /* Hash key length in bytes. */
>  	uint8_t rss_key[]; /* Hash key. */
>  };
> 
> @@ -238,20 +238,22 @@ int mlx5_rxq_releasable(struct rte_eth_dev *dev,
> uint16_t idx);
>  int mlx5_rxq_verify(struct rte_eth_dev *dev);
>  int rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_new(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_get(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  int mlx5_ind_table_ibv_release(struct rte_eth_dev *dev,
>  			       struct mlx5_ind_table_ibv *ind_tbl);
>  int mlx5_ind_table_ibv_verify(struct rte_eth_dev *dev);
> -struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> -struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
>  int mlx5_hrxq_release(struct rte_eth_dev *dev, struct mlx5_hrxq *hxrq);
>  int mlx5_hrxq_ibv_verify(struct rte_eth_dev *dev);
>  uint64_t mlx5_get_rx_port_offloads(void);
> diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
> index 056405515..1a2c0299c 100644
> --- a/drivers/net/sfc/sfc_flow.c
> +++ b/drivers/net/sfc/sfc_flow.c
> @@ -1234,13 +1234,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	struct sfc_rxq *rxq;
>  	unsigned int rxq_hw_index_min;
>  	unsigned int rxq_hw_index_max;
> -	const struct rte_eth_rss_conf *rss_conf = rss->rss_conf;
> -	uint64_t rss_hf;
> -	uint8_t *rss_key = NULL;
> +	const uint8_t *rss_key;
>  	struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf;
>  	unsigned int i;
> 
> -	if (rss->num == 0)
> +	if (rss->queue_num == 0)
>  		return -EINVAL;
> 
>  	rxq_sw_index = sa->rxq_count - 1;
> @@ -1248,7 +1246,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	rxq_hw_index_min = rxq->hw_index;
>  	rxq_hw_index_max = 0;
> 
> -	for (i = 0; i < rss->num; ++i) {
> +	for (i = 0; i < rss->queue_num; ++i) {
>  		rxq_sw_index = rss->queue[i];
> 
>  		if (rxq_sw_index >= sa->rxq_count)
> @@ -1263,15 +1261,14 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  			rxq_hw_index_max = rxq->hw_index;
>  	}
> 
> -	rss_hf = (rss_conf != NULL) ? rss_conf->rss_hf : SFC_RSS_OFFLOADS;
> -	if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0)
> +	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
>  		return -EINVAL;
> 
> -	if (rss_conf != NULL) {
> -		if (rss_conf->rss_key_len != sizeof(sa->rss_key))
> +	if (rss->key_len) {
> +		if (rss->key_len != sizeof(sa->rss_key))
>  			return -EINVAL;
> 
> -		rss_key = rss_conf->rss_key;
> +		rss_key = rss->key;
>  	} else {
>  		rss_key = sa->rss_key;
>  	}
> @@ -1280,11 +1277,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
> 
>  	sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
>  	sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
> -	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf);
> +	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss-
> >types);
>  	rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key));
> 
>  	for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
> -		unsigned int rxq_sw_index = rss->queue[i % rss->num];
> +		unsigned int rxq_sw_index = rss->queue[i % rss-
> >queue_num];
>  		struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq;
> 
>  		sfc_rss_conf->rss_tbl[i] = rxq->hw_index -
> rxq_hw_index_min;
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index fe2f94010..67146aaba 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -1215,7 +1215,7 @@ priv_flow_process(struct pmd_internals *pmd,
>  				if (err)
>  					goto exit_action_not_supported;
>  			}
> -			if (flow && rss)
> +			if (flow)
>  				err = rss_add_actions(flow, pmd, rss, error);
>  		} else {
>  			goto exit_action_not_supported;
> @@ -2050,7 +2050,7 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  			   struct rte_flow_error *error)
>  {
>  	/* 4096 is the maximum number of instructions for a BPF program */
> -	int i;
> +	unsigned int i;
>  	int err;
>  	struct rss_key rss_entry = { .hash_fields = 0,
>  				     .key_size = 0 };
> @@ -2066,8 +2066,8 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  	}
> 
>  	/* Update RSS map entry with queues */
> -	rss_entry.nb_queues = rss->num;
> -	for (i = 0; i < rss->num; i++)
> +	rss_entry.nb_queues = rss->queue_num;
> +	for (i = 0; i < rss->queue_num; i++)
>  		rss_entry.queues[i] = rss->queue[i];
>  	rss_entry.hash_fields =
>  		(1 << HASH_FIELD_IPV4_L3_L4) | (1 <<
> HASH_FIELD_IPV6_L3_L4);
> diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
> index 5971937cf..ee2497352 100644
> --- a/examples/ipsec-secgw/ipsec.c
> +++ b/examples/ipsec-secgw/ipsec.c
> @@ -203,9 +203,13 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct
> ipsec_sa *sa)
>  				     i < eth_dev->data->nb_rx_queues; ++i)
>  					if (eth_dev->data->rx_queues[i])
>  						queue[j++] = i;
> -				action_rss.rss_conf = &rss_conf;
> -				action_rss.num = j;
> -				action_rss.queue = queue;
> +				action_rss = (struct rte_flow_action_rss){
> +					.types = rss_conf.rss_hf,
> +					.key_len = rss_conf.rss_key_len,
> +					.queue_num = j,
> +					.key = rss_key,
> +					.queue = queue,
> +				};
>  				ret = rte_flow_validate(sa->portid, &sa->attr,
>  							sa->pattern, sa-
> >action,
>  							&err);
> diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
> index bb19e28c6..cc7819b6a 100644
> --- a/lib/librte_ether/rte_flow.c
> +++ b/lib/librte_ether/rte_flow.c
> @@ -330,40 +330,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
> index ad2e55b8e..bbc408fa6 100644
> --- a/lib/librte_ether/rte_flow.h
> +++ b/lib/librte_ether/rte_flow.h
> @@ -1033,13 +1033,21 @@ struct rte_flow_query_count {
>   * Similar to QUEUE, except RSS is additionally performed on packets to
>   * spread them among several queues according to the provided parameters.
>   *
> + * Unlike global RSS settings used by other DPDK APIs, unsetting the
> + * @p types field does not disable RSS in a flow rule. Doing so instead
> + * requests safe unspecified "best-effort" settings from the underlying
> PMD,
> + * which depending on the flow rule, may result in anything ranging from
> + * empty (single queue) to all-inclusive RSS.
> + *
>   * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps
>   * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only,
>   * both can be requested simultaneously.
>   */
>  struct rte_flow_action_rss {
> -	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in @p queue. */
> +	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
> +	uint32_t key_len; /**< Hash key length in bytes. */
> +	uint32_t queue_num; /**< Number of entries in @p queue. */
> +	const uint8_t *key; /**< Hash key. */
>  	const uint16_t *queue; /**< Queue indices to use. */
>  };
> 
> --
> 2.11.0

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API
  2018-04-28  3:46  0%     ` Zhao1, Wei
@ 2018-04-28  5:28  0%       ` Peng, Yuan
  2018-04-28  7:45  0%         ` Peng, Yuan
  0 siblings, 1 reply; 200+ results
From: Peng, Yuan @ 2018-04-28  5:28 UTC (permalink / raw)
  To: Zhao1, Wei, Adrien Mazarguil, dev
  Cc: Xu, Qian Q, Liu, Yu Y, Lu, Wenzhuo, Wu, Jingjing

Hi,Adrien Mazarguil

There is a bug present with 18.05-rci when I test the feature "Move RSS to rte_flow" in i40e NIC
The test steps are as below:
./usertools/dpdk-devbind.py -b igb_uio 05:00.0 05:00.1
./x86_64-native-linuxapp-gcc/app/testpmd -c 0x1fffe -n 4  -- -i --nb-cores=8 --rxq=8 --txq=8 --port-topology=chained
testpmd> set fwd rxonly
Set rxonly packet forwarding mode
testpmd> set verbose 1
Change verbose level from 0 to 1
testpmd> start
testpmd> flow create 0 ingress pattern end actions rss queues 0 4 7 end / end
Caught error type 16 (specific action): cause: 0x7fff84e33658, RSS hash key too large

The rss rule can be set successfully when I test it yesterday with older dpdk version without this patch.

The NIC information is:
driver: i40e
version: 2.4.3
firmware-version: 6.01 0x80003205 1.1691.0

There is another problem with ixgbe nic:
./usertools/dpdk-devbind.py -b igb_uio 07:00.0 07:00.1
./x86_64-native-linuxapp-gcc/app/testpmd -c 0x1fffe -n 4  -- -i --nb-cores=8 --rxq=8 --txq=8 --disable-rss --port-topology=chained 
testpmd> flow create 0 ingress pattern end actions rss queues 5 6 7 end / end
Caught error type 2 (flow rule (handle)): Failed to create flow.
The rule setting command can be executed successfully with older dpdk version.

Could you help to check if there is a relationship between the bugs and this patch?

Thank you.
Yuan.


-----Original Message-----
From: Zhao1, Wei 
Sent: Saturday, April 28, 2018 11:46 AM
To: Adrien Mazarguil <adrien.mazarguil@6wind.com>; dev@dpdk.org
Cc: Peng, Yuan <yuan.peng@intel.com>; Xu, Qian Q <qian.q.xu@intel.com>; Liu, Yu Y <yu.y.liu@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
Subject: RE: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API

Hi,Adrien Mazarguil

       We have just use new RC.1 code on the feature of flow RSS API, but we find some abnormal phenomenon.
After that I check code again, I find that it is  introduced in this patch:

SHA-1: ac8d22de2394e03ba4a77d8fd24381147aafb1d3
* ethdev: flatten RSS configuration in flow API
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>


This abnormal phenomenon include i40e and ixgbe 2 NIC, it do not has these 2 bug before merge this patch.
It is first find out by yuan.peng@intel.com,  she can tell you how to reappear these abnormal phenomenon on RSS flow API.

Thank you.


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Wednesday, April 25, 2018 11:28 PM
> To: Thomas Monjalon <thomas@monjalon.net>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; dev@dpdk.org
> Cc: Xueming Li <xuemingl@mellanox.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; Nelio Laranjeiro
> <nelio.laranjeiro@6wind.com>; Yongseok Koh <yskoh@mellanox.com>;
> Andrew Rybchenko <arybchenko@solarflare.com>; Pascal Mazon
> <pascal.mazon@6wind.com>; Nicolau, Radu <radu.nicolau@intel.com>; Akhil
> Goyal <akhil.goyal@nxp.com>
> Subject: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in
> flow API
> 
> Since its inception, the rte_flow RSS action has been relying in part on
> external struct rte_eth_rss_conf for compatibility with the legacy RSS API.
> This structure lacks parameters such as the hash algorithm to use, and more
> recently, a method to tell which layer RSS should be performed on [1].
> 
> Given struct rte_eth_rss_conf will never be flexible enough to represent a
> complete RSS configuration (e.g. RETA table), this patch supersedes it by
> extending the rte_flow RSS action directly.
> 
> A subsequent patch will add a field to use a non-default RSS hash
> algorithm. To that end, a field named "types" replaces the field formerly
> known as "rss_hf" and standing for "RSS hash functions" as it was
> confusing. Actual RSS hash function types are defined by enum
> rte_eth_hash_function.
> 
> This patch updates all PMDs and example applications accordingly.
> 
> It breaks ABI compatibility for the following public functions:
> 
> - rte_flow_copy()
> - rte_flow_create()
> - rte_flow_query()
> - rte_flow_validate()
> 
> [1] commit 676b605182a5 ("doc: announce ethdev API change for RSS
>     configuration")
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Xueming Li <xuemingl@mellanox.com>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>
> Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>
> Cc: Beilei Xing <beilei.xing@intel.com>
> Cc: Qi Zhang <qi.z.zhang@intel.com>
> Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Pascal Mazon <pascal.mazon@6wind.com>
> Cc: Radu Nicolau <radu.nicolau@intel.com>
> Cc: Akhil Goyal <akhil.goyal@nxp.com>
> 
> ---
> 
> v6 changes:
> 
> - Fixed QUEUE action support in mlx5 according to Nelio's comment [1].
>   This action relies on RSS to work and even though it targets a single Rx
>   queue, a non-NULL hash key is required.
> - Updated API and ABI changes sections in release notes.
> 
> [1] http://dpdk.org/ml/archives/dev/2018-April/098635.html
> 
> v3 changes:
> 
> Documentation update regarding the meaning of a 0 value for RSS types in
> flow rules.
> 
> It used to implicitly mean "no RSS" but is redefined as requesting a kind
> of "best-effort" mode from PMDs, i.e. anything ranging from empty to
> all-inclusive RSS; what matters is it provides safe defaults that will work
> regardless of PMD capabilities.
> ---
>  app/test-pmd/cmdline_flow.c                 |  48 +++---
>  app/test-pmd/config.c                       |  39 ++---
>  doc/guides/prog_guide/rte_flow.rst          |  28 ++--
>  doc/guides/rel_notes/release_18_05.rst      |  13 +-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   6 +-
>  drivers/net/e1000/e1000_ethdev.h            |  13 +-
>  drivers/net/e1000/igb_ethdev.c              |   4 +-
>  drivers/net/e1000/igb_flow.c                |  31 ++--
>  drivers/net/e1000/igb_rxtx.c                |  51 +++++-
>  drivers/net/i40e/i40e_ethdev.c              |  53 +++++--
>  drivers/net/i40e/i40e_ethdev.h              |  15 +-
>  drivers/net/i40e/i40e_flow.c                |  47 +++---
>  drivers/net/ixgbe/ixgbe_ethdev.c            |   4 +-
>  drivers/net/ixgbe/ixgbe_ethdev.h            |  13 +-
>  drivers/net/ixgbe/ixgbe_flow.c              |  30 ++--
>  drivers/net/ixgbe/ixgbe_rxtx.c              |  51 +++++-
>  drivers/net/mlx4/mlx4.c                     |   2 +-
>  drivers/net/mlx4/mlx4_flow.c                |  61 +++----
>  drivers/net/mlx4/mlx4_flow.h                |   2 +-
>  drivers/net/mlx4/mlx4_rxq.c                 |   2 +-
>  drivers/net/mlx4/mlx4_rxtx.h                |   2 +-
>  drivers/net/mlx5/mlx5_flow.c                | 193 +++++++++++------------
>  drivers/net/mlx5/mlx5_rxq.c                 |  26 +--
>  drivers/net/mlx5/mlx5_rxtx.h                |  26 +--
>  drivers/net/sfc/sfc_flow.c                  |  21 ++-
>  drivers/net/tap/tap_flow.c                  |   8 +-
>  examples/ipsec-secgw/ipsec.c                |  10 +-
>  lib/librte_ether/rte_flow.c                 |  39 ++---
>  lib/librte_ether/rte_flow.h                 |  12 +-
>  29 files changed, 492 insertions(+), 358 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 798b7948d..c9c2c3ad9 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -192,9 +192,8 @@ enum index {
>  /** Storage for struct rte_flow_action_rss including external data. */
>  struct action_rss_data {
>  	struct rte_flow_action_rss conf;
> +	uint8_t key[RSS_HASH_KEY_LENGTH];
>  	uint16_t queue[ACTION_RSS_QUEUE_NUM];
> -	struct rte_eth_rss_conf rss_conf;
> -	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
>  };
> 
>  /** Maximum number of subsequent tokens and arguments on the stack.
> */
> @@ -1587,7 +1586,7 @@ static const struct token token_list[] = {
>  	},
>  	[ACTION_RSS_TYPES] = {
>  		.name = "types",
> -		.help = "RSS hash types",
> +		.help = "specific RSS hash types",
>  		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
>  	},
>  	[ACTION_RSS_TYPE] = {
> @@ -1602,21 +1601,21 @@ static const struct token token_list[] = {
>  		.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
>  		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
>  			     ARGS_ENTRY_ARB
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len)),
> -			     ARGS_ENTRY(struct action_rss_data, rss_key)),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len)),
> +			     ARGS_ENTRY(struct action_rss_data, key)),
>  	},
>  	[ACTION_RSS_KEY_LEN] = {
>  		.name = "key_len",
>  		.help = "RSS hash key length in bytes",
>  		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
>  		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len),
>  			      0,
>  			      RSS_HASH_KEY_LENGTH)),
>  	},
> @@ -2075,27 +2074,24 @@ parse_vc_action_rss(struct context *ctx, const
> struct token *token,
>  	action_rss_data = ctx->object;
>  	*action_rss_data = (struct action_rss_data){
>  		.conf = (struct rte_flow_action_rss){
> -			.rss_conf = &action_rss_data->rss_conf,
> -			.num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.types = rss_hf,
> +			.key_len = sizeof(action_rss_data->key),
> +			.queue_num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.key = action_rss_data->key,
>  			.queue = action_rss_data->queue,
>  		},
> +		.key = "testpmd's default RSS hash key",
>  		.queue = { 0 },
> -		.rss_conf = (struct rte_eth_rss_conf){
> -			.rss_key = action_rss_data->rss_key,
> -			.rss_key_len = sizeof(action_rss_data->rss_key),
> -			.rss_hf = rss_hf,
> -		},
> -		.rss_key = "testpmd's default RSS hash key",
>  	};
> -	for (i = 0; i < action_rss_data->conf.num; ++i)
> +	for (i = 0; i < action_rss_data->conf.queue_num; ++i)
>  		action_rss_data->queue[i] = i;
>  	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
>  	    ctx->port != (portid_t)RTE_PORT_ALL) {
>  		struct rte_eth_dev_info info;
> 
>  		rte_eth_dev_info_get(ctx->port, &info);
> -		action_rss_data->rss_conf.rss_key_len =
> -			RTE_MIN(sizeof(action_rss_data->rss_key),
> +		action_rss_data->conf.key_len =
> +			RTE_MIN(sizeof(action_rss_data->key),
>  				info.hash_key_size);
>  	}
>  	action->conf = &action_rss_data->conf;
> @@ -2123,7 +2119,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  		return -1;
>  	if (!(ctx->objdata >> 16) && ctx->object) {
>  		action_rss_data = ctx->object;
> -		action_rss_data->rss_conf.rss_hf = 0;
> +		action_rss_data->conf.types = 0;
>  	}
>  	if (!strcmp_partial("end", str, len)) {
>  		ctx->objdata &= 0xffff;
> @@ -2142,7 +2138,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
> +	action_rss_data->conf.types |= rss_type_table[i].rss_type;
>  	return len;
>  }
> 
> @@ -2192,7 +2188,7 @@ parse_vc_action_rss_queue(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->conf.num = i;
> +	action_rss_data->conf.queue_num = i;
>  	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
>  	return len;
>  }
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index eb7ac315e..4700dd674 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1117,40 +1117,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index acbeaacbd..cf252eeba 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1301,6 +1301,12 @@ Action: ``RSS``
>  Similar to QUEUE, except RSS is additionally performed on packets to spread
>  them among several queues according to the provided parameters.
> 
> +Unlike global RSS settings used by other DPDK APIs, unsetting the ``types``
> +field does not disable RSS in a flow rule. Doing so instead requests safe
> +unspecified "best-effort" settings from the underlying PMD, which
> depending
> +on the flow rule, may result in anything ranging from empty (single queue)
> +to all-inclusive RSS.
> +
>  Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
>  overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
>  field only, both can be requested simultaneously.
> @@ -1309,15 +1315,19 @@ field only, both can be requested simultaneously.
> 
>  .. table:: RSS
> 
> -   +--------------+--------------------------------+
> -   | Field        | Value                          |
> -   +==============+================================+
> -   | ``rss_conf`` | RSS parameters                 |
> -   +--------------+--------------------------------+
> -   | ``num``      | number of entries in ``queue`` |
> -   +--------------+--------------------------------+
> -   | ``queue``    | queue indices to use           |
> -   +--------------+--------------------------------+
> +   +---------------+---------------------------------------------+
> +   | Field         | Value                                       |
> +
> +===============+=========================================
> ====+
> +   | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
> +   +---------------+---------------------------------------------+
> +   | ``key_len``   | hash key length in bytes                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue_num`` | number of entries in ``queue``              |
> +   +---------------+---------------------------------------------+
> +   | ``key``       | hash key                                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue``     | queue indices to use                        |
> +   +---------------+---------------------------------------------+
> 
>  Action: ``PF``
>  ^^^^^^^^^^^^^^
> diff --git a/doc/guides/rel_notes/release_18_05.rst
> b/doc/guides/rel_notes/release_18_05.rst
> index ca173450c..b702ac66a 100644
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> @@ -254,6 +254,13 @@ API Changes
>      present.
>    * C99-style flexible arrays were replaced with standard pointers in RSS
>      action and in RAW pattern item structures due to compatibility issues.
> +  * The RSS action was modified to not rely on external
> +    ``struct rte_eth_rss_conf`` anymore to instead expose its own and more
> +    appropriately named configuration fields directly
> +    (``rss_conf->rss_key`` => ``key``,
> +    ``rss_conf->rss_key_len`` => ``key_len``,
> +    ``rss_conf->rss_hf`` => ``types``,
> +    ``num`` => ``queue_num``).
> 
> 
>  ABI Changes
> @@ -302,9 +309,9 @@ ABI Changes
>    ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
>    changes in error type definitions (``enum rte_flow_error_type``), removal
>    of the unused DUP action (``enum rte_flow_action_type``), modified
> -  behavior for flow rule actions (see API changes) and removal of C99
> -  flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
> -  pattern item (``struct rte_flow_item_raw``).
> +  behavior for flow rule actions (see API changes), removal of C99 flexible
> +  array from RAW pattern item (``struct rte_flow_item_raw``) and complete
> +  rework of the RSS action definition (``struct rte_flow_action_rss``).
> 
> 
>  Removed Items
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 68c286bd4..a12e0267a 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3422,8 +3422,10 @@ This section lists supported actions and their
> attributes, if any.
> 
>  - ``rss``: spread packets among several queues.
> 
> -  - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
> -    are the same as `set_hash_input_set`_, an empty list means none (0).
> +  - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
> +    tokens are the same as `set_hash_input_set`_, except that an empty list
> +    does not disable RSS but instead requests unspecified "best-effort"
> +    settings.
> 
>    - ``key {string}``: RSS hash key, overrides ``key_len``.
> 
> diff --git a/drivers/net/e1000/e1000_ethdev.h
> b/drivers/net/e1000/e1000_ethdev.h
> index 6354b894a..902001f36 100644
> --- a/drivers/net/e1000/e1000_ethdev.h
> +++ b/drivers/net/e1000/e1000_ethdev.h
> @@ -4,6 +4,10 @@
> 
>  #ifndef _E1000_ETHDEV_H_
>  #define _E1000_ETHDEV_H_
> +
> +#include <stdint.h>
> +
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_pci.h>
> 
> @@ -27,6 +31,7 @@
>  #define E1000_CTRL_EXT_EXTEND_VLAN  (1<<26)    /* EXTENDED VLAN */
>  #define IGB_VFTA_SIZE 128
> 
> +#define IGB_HKEY_MAX_INDEX             10
>  #define IGB_MAX_RX_QUEUE_NUM           8
>  #define IGB_MAX_RX_QUEUE_NUM_82576     16
> 
> @@ -229,8 +234,8 @@ struct igb_ethertype_filter {
>  };
> 
>  struct igb_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IGB_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key.
> */
>  	uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices
> to use. */
>  };
> 
> @@ -501,6 +506,10 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev,
>  int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
>  			struct rte_eth_flex_filter *filter,
>  			bool add);
> +int igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		      const struct rte_flow_action_rss *in);
> +int igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +			const struct rte_flow_action_rss *with);
>  int igb_config_rss_filter(struct rte_eth_dev *dev,
>  			struct igb_rte_flow_rss_conf *conf,
>  			bool add);
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c
> index c35c9352a..140334772 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -41,8 +41,6 @@
>  #define IGB_DEFAULT_TX_HTHRESH      1
>  #define IGB_DEFAULT_TX_WTHRESH      ((hw->mac.type == e1000_82576) ?
> 1 : 16)
> 
> -#define IGB_HKEY_MAX_INDEX 10
> -
>  /* Bit shift and mask */
>  #define IGB_4_BIT_WIDTH  (CHAR_BIT / 2)
>  #define IGB_4_BIT_MASK   RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)
> @@ -5662,7 +5660,7 @@ igb_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter_info->rss_info, TRUE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
> index c0f5b5190..8dc5f75f2 100644
> --- a/drivers/net/e1000/igb_flow.c
> +++ b/drivers/net/e1000/igb_flow.c
> @@ -1292,7 +1292,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -1300,7 +1300,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1310,14 +1310,18 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		}
>  	}
> 
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
> -
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (igb_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	index++;
> @@ -1518,9 +1522,8 @@ igb_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct igb_rte_flow_rss_conf));
> +			igb_rss_conf_init(&rss_filter_ptr->filter_info,
> +					  &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> @@ -1757,7 +1760,7 @@ igb_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter->rss_info.num)
> +	if (filter->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
> index 323913f0d..45bb3455c 100644
> --- a/drivers/net/e1000/igb_rxtx.c
> +++ b/drivers/net/e1000/igb_rxtx.c
> @@ -2898,12 +2898,47 @@ igb_txq_info_get(struct rte_eth_dev *dev,
> uint16_t queue_id,
>  }
> 
>  int
> +igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		  const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +		    const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  igb_config_rss_filter(struct rte_eth_dev *dev,
>  		struct igb_rte_flow_rss_conf *conf, bool add)
>  {
>  	uint32_t shift;
>  	uint16_t i, j;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
>  	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> @@ -2911,8 +2946,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct igb_rte_flow_rss_conf)) == 0) {
> +		if (igb_action_rss_same(&filter_info->rss_info.conf,
> +					&conf->conf)) {
>  			igb_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct igb_rte_flow_rss_conf));
> @@ -2921,7 +2956,7 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
> 
>  	/* Fill in redirection table. */
> @@ -2933,9 +2968,9 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		} reta;
>  		uint8_t q_idx;
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		q_idx = conf->queue[j];
> +		q_idx = conf->conf.queue[j];
>  		reta.bytes[i & 3] = (uint8_t)(q_idx << shift);
>  		if ((i & 3) == 3)
>  			E1000_WRITE_REG(hw, E1000_RETA(i >> 2),
> reta.dword);
> @@ -2952,8 +2987,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	igb_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct igb_rte_flow_rss_conf));
> +	if (igb_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 78f2be7da..50e77901c 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -11,6 +11,7 @@
>  #include <inttypes.h>
>  #include <assert.h>
> 
> +#include <rte_common.h>
>  #include <rte_eal.h>
>  #include <rte_string_fns.h>
>  #include <rte_pci.h>
> @@ -11650,7 +11651,7 @@ i40e_rss_filter_restore(struct i40e_pf *pf)
>  {
>  	struct i40e_rte_flow_rss_conf *conf =
>  					&pf->rss_info;
> -	if (conf->num)
> +	if (conf->conf.queue_num)
>  		i40e_config_rss_filter(pf, conf, TRUE);
>  }
> 
> @@ -12182,18 +12183,52 @@ i40e_cloud_filter_qinq_create(struct i40e_pf
> *pf)
>  }
> 
>  int
> +i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		   const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +		     const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
>  	uint32_t i, lut = 0;
>  	uint16_t j, num;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info;
> 
>  	if (!add) {
> -		if (memcmp(conf, rss_info,
> -			sizeof(struct i40e_rte_flow_rss_conf)) == 0) {
> +		if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) {
>  			i40e_pf_disable_rss(pf);
>  			memset(rss_info, 0,
>  				sizeof(struct i40e_rte_flow_rss_conf));
> @@ -12202,7 +12237,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  		return -EINVAL;
>  	}
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		return -EINVAL;
> 
>  	/* If both VMDQ and RSS enabled, not all of PF queues are
> configured.
> @@ -12213,7 +12248,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	else
>  		num = pf->dev_data->nb_rx_queues;
> 
> -	num = RTE_MIN(num, conf->num);
> +	num = RTE_MIN(num, conf->conf.queue_num);
>  	PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are
> configured",
>  			num);
> 
> @@ -12226,7 +12261,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
>  		if (j == num)
>  			j = 0;
> -		lut = (lut << 8) | (conf->queue[j] & ((0x1 <<
> +		lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 <<
>  			hw->func_caps.rss_table_entry_width) - 1));
>  		if ((i & 3) == 3)
>  			I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
> @@ -12251,8 +12286,8 @@ i40e_config_rss_filter(struct i40e_pf *pf,
> 
>  	i40e_hw_rss_hash_set(pf, &rss_conf);
> 
> -	rte_memcpy(rss_info,
> -		conf, sizeof(struct i40e_rte_flow_rss_conf));
> +	if (i40e_rss_conf_init(rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h
> index d33b255e7..a0569d4ae 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -5,14 +5,19 @@
>  #ifndef _I40E_ETHDEV_H_
>  #define _I40E_ETHDEV_H_
> 
> +#include <stdint.h>
> +
>  #include <rte_eth_ctrl.h>
>  #include <rte_time.h>
>  #include <rte_kvargs.h>
>  #include <rte_hash.h>
> +#include <rte_flow.h>
>  #include <rte_flow_driver.h>
>  #include <rte_tm_driver.h>
>  #include "rte_pmd_i40e.h"
> 
> +#include "base/i40e_register.h"
> +
>  #define I40E_VLAN_TAG_SIZE        4
> 
>  #define I40E_AQ_LEN               32
> @@ -878,9 +883,11 @@ struct i40e_customized_pctype {
>  };
> 
>  struct i40e_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
>  	uint16_t queue_region_conf; /**< Queue region config flag */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	uint8_t key[(I40E_VFQF_HKEY_MAX_INDEX >
> I40E_PFQF_HKEY_MAX_INDEX ?
> +		     I40E_VFQF_HKEY_MAX_INDEX :
> I40E_PFQF_HKEY_MAX_INDEX) + 1 *
> +		    sizeof(uint32_t)]; /* Hash key. */
>  	uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use.
> */
>  };
> 
> @@ -1219,6 +1226,10 @@ void i40e_init_queue_region_conf(struct
> rte_eth_dev *dev);
>  void i40e_flex_payload_reg_set_default(struct i40e_hw *hw);
>  int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
>  int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
> +int i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		       const struct rte_flow_action_rss *in);
> +int i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +			 const struct rte_flow_action_rss *with);
>  int i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index d6f5e9923..ec6231003 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -4220,7 +4220,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
> 
>  	if (action_flag) {
>  		for (n = 0; n < 64; n++) {
> -			if (rss->rss_conf->rss_hf & (hf_bit << n)) {
> +			if (rss->types & (hf_bit << n)) {
>  				conf_info->region[0].hw_flowtype[0] = n;
>  				conf_info->region[0].flowtype_num = 1;
>  				conf_info->queue_region_number = 1;
> @@ -4236,12 +4236,12 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	 * queue index for this port.
>  	 */
>  	if (conf_info->queue_region_number) {
> -		for (i = 0; i < rss->num; i++) {
> -			for (j = 0; j < rss_info->num; j++) {
> -				if (rss->queue[i] == rss_info->queue[j])
> +		for (i = 0; i < rss->queue_num; i++) {
> +			for (j = 0; j < rss_info->conf.queue_num; j++) {
> +				if (rss->queue[i] == rss_info->conf.queue[j])
>  					break;
>  			}
> -			if (j == rss_info->num) {
> +			if (j == rss_info->conf.queue_num) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4250,7 +4250,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
>  		}
> 
> -		for (i = 0; i < rss->num - 1; i++) {
> +		for (i = 0; i < rss->queue_num - 1; i++) {
>  			if (rss->queue[i + 1] != rss->queue[i] + 1) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4265,8 +4265,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	for (n = 0; n < conf_info->queue_region_number; n++) {
>  		if (conf_info->region[n].user_priority_num ||
>  				conf_info->region[n].flowtype_num) {
> -			if (!((rte_is_power_of_2(rss->num)) &&
> -					rss->num <= 64)) {
> +			if (!((rte_is_power_of_2(rss->queue_num)) &&
> +					rss->queue_num <= 64)) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4294,7 +4294,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
> 
>  			for (i = 0; i < info->queue_region_number; i++) {
> -				if (info->region[i].queue_num == rss->num
> &&
> +				if (info->region[i].queue_num ==
> +				    rss->queue_num &&
>  					info->region[i].queue_start_index ==
>  						rss->queue[0])
>  					break;
> @@ -4310,7 +4311,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  				}
> 
>  				info->region[i].queue_num =
> -					rss->num;
> +					rss->queue_num;
>  				info->region[i].queue_start_index =
>  					rss->queue[0];
>  				info->region[i].region_id =
> @@ -4356,7 +4357,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	if (rss_config->queue_region_conf)
>  		return 0;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -4364,7 +4365,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4375,15 +4376,19 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	}
> 
>  	/* Parse RSS related parameters from configuration */
> -	if (rss->rss_conf)
> -		rss_config->rss_conf = *rss->rss_conf;
> -	else
> -		rss_config->rss_conf.rss_hf =
> -			pf->adapter->flow_types_mask;
> +	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key too large");
> +	if (rss->queue_num > RTE_DIM(rss_config->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (i40e_rss_conf_init(rss_config, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_config->queue[n] = rss->queue[n];
> -	rss_config->num = rss->num;
>  	index++;
> 
>  	/* check if the next not void action is END */
> @@ -4903,7 +4908,7 @@ i40e_flow_flush_rss_filter(struct rte_eth_dev *dev)
> 
>  	ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		ret = i40e_config_rss_filter(pf, rss_info, FALSE);
>  	return ret;
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 92434809c..c00bdae3d 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -100,8 +100,6 @@
> 
>  #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) /
> sizeof(hw_stats->qprc[0]))
> 
> -#define IXGBE_HKEY_MAX_INDEX 10
> -
>  /* Additional timesync values. */
>  #define NSEC_PER_SEC             1000000000L
>  #define IXGBE_INCVAL_10GB        0x66666666
> @@ -8371,7 +8369,7 @@ ixgbe_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev,
>  			&filter_info->rss_info, TRUE);
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h
> b/drivers/net/ixgbe/ixgbe_ethdev.h
> index 655077700..9491b03f4 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -4,6 +4,9 @@
> 
>  #ifndef _IXGBE_ETHDEV_H_
>  #define _IXGBE_ETHDEV_H_
> +
> +#include <stdint.h>
> +
>  #include "base/ixgbe_type.h"
>  #include "base/ixgbe_dcb.h"
>  #include "base/ixgbe_dcb_82599.h"
> @@ -12,6 +15,7 @@
>  #ifdef RTE_LIBRTE_SECURITY
>  #include "ixgbe_ipsec.h"
>  #endif
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_hash.h>
>  #include <rte_pci.h>
> @@ -39,6 +43,7 @@
>  #define IXGBE_EXTENDED_VLAN	  (uint32_t)(1 << 26) /* EXTENDED
> VLAN ENABLE */
>  #define IXGBE_VFTA_SIZE 128
>  #define IXGBE_VLAN_TAG_SIZE 4
> +#define IXGBE_HKEY_MAX_INDEX 10
>  #define IXGBE_MAX_RX_QUEUE_NUM	128
>  #define IXGBE_MAX_INTR_QUEUE_NUM	15
>  #define IXGBE_VMDQ_DCB_NB_QUEUES     IXGBE_MAX_RX_QUEUE_NUM
> @@ -196,8 +201,8 @@ struct ixgbe_hw_fdir_info {
>  };
> 
>  struct ixgbe_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash
> key. */
>  	uint16_t queue[IXGBE_MAX_RX_QUEUE_NUM]; /**< Queues
> indices to use. */
>  };
> 
> @@ -696,6 +701,10 @@ void ixgbe_tm_conf_init(struct rte_eth_dev *dev);
>  void ixgbe_tm_conf_uninit(struct rte_eth_dev *dev);
>  int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t
> queue_idx,
>  			       uint16_t tx_rate);
> +int ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +			const struct rte_flow_action_rss *in);
> +int ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +			  const struct rte_flow_action_rss *with);
>  int ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
> index abdeac28b..4e31c7c56 100644
> --- a/drivers/net/ixgbe/ixgbe_flow.c
> +++ b/drivers/net/ixgbe/ixgbe_flow.c
> @@ -2761,7 +2761,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -2769,7 +2769,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -2778,14 +2778,19 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  			return -rte_errno;
>  		}
>  	}
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IXGBE_RSS_OFFLOAD_ALL;
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (ixgbe_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	act = next_no_void_action(actions, act);
> @@ -2834,7 +2839,7 @@ ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
>  }
> 
> @@ -3153,9 +3158,8 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct ixgbe_rte_flow_rss_conf));
> +			ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
> +					    &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index aed3f5a9a..9fbd7dbd7 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -5676,6 +5676,36 @@ ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev)
>  }
> 
>  int
> +ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +		    const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +		      const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add)
>  {
> @@ -5685,7 +5715,12 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	uint16_t j;
>  	uint16_t sp_reta_size;
>  	uint32_t reta_reg;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> @@ -5695,8 +5730,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	sp_reta_size = ixgbe_reta_size_get(hw->mac.type);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct ixgbe_rte_flow_rss_conf)) == 0) {
> +		if (ixgbe_action_rss_same(&filter_info->rss_info.conf,
> +					  &conf->conf)) {
>  			ixgbe_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct ixgbe_rte_flow_rss_conf));
> @@ -5705,7 +5740,7 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
>  	/* Fill in redirection table
>  	 * The byte-swap is needed because NIC registers are in
> @@ -5715,9 +5750,9 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	for (i = 0, j = 0; i < sp_reta_size; i++, j++) {
>  		reta_reg = ixgbe_reta_reg_get(hw->mac.type, i);
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		reta = (reta << 8) | conf->queue[j];
> +		reta = (reta << 8) | conf->conf.queue[j];
>  		if ((i & 3) == 3)
>  			IXGBE_WRITE_REG(hw, reta_reg,
>  					rte_bswap32(reta));
> @@ -5734,8 +5769,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	ixgbe_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct ixgbe_rte_flow_rss_conf));
> +	if (ixgbe_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 937074a4f..3dd72dbf5 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -571,7 +571,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct
> rte_pci_device *pci_dev)
>  			     " for UDP RSS and inner VXLAN RSS");
>  			/* Fake support for all possible RSS hash fields. */
>  			priv->hw_rss_sup = ~UINT64_C(0);
> -			priv->hw_rss_sup = mlx4_conv_rss_hf(priv, -1);
> +			priv->hw_rss_sup = mlx4_conv_rss_types(priv, -1);
>  			/* Filter out known unsupported fields. */
>  			priv->hw_rss_sup &=
>  				~(uint64_t)(IBV_RX_HASH_SRC_PORT_UDP |
> diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
> index 8feb6ae31..dd86e4ce7 100644
> --- a/drivers/net/mlx4/mlx4_flow.c
> +++ b/drivers/net/mlx4/mlx4_flow.c
> @@ -76,22 +76,22 @@ struct mlx4_drop {
>  };
> 
>  /**
> - * Convert DPDK RSS hash fields to their Verbs equivalent.
> + * Convert DPDK RSS hash types to their Verbs equivalent.
>   *
> - * This function returns the supported (default) set when @p rss_hf has
> + * This function returns the supported (default) set when @p types has
>   * special value (uint64_t)-1.
>   *
>   * @param priv
>   *   Pointer to private structure.
> - * @param rss_hf
> - *   Hash fields in DPDK format (see struct rte_eth_rss_conf).
> + * @param types
> + *   Hash types in DPDK format (see struct rte_eth_rss_conf).
>   *
>   * @return
>   *   A valid Verbs RSS hash fields mask for mlx4 on success, (uint64_t)-1
>   *   otherwise and rte_errno is set.
>   */
>  uint64_t
> -mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
> +mlx4_conv_rss_types(struct priv *priv, uint64_t types)
>  {
>  	enum { IPV4, IPV6, TCP, UDP, };
>  	const uint64_t in[] = {
> @@ -126,17 +126,17 @@ mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
>  	unsigned int i;
> 
>  	for (i = 0; i != RTE_DIM(in); ++i)
> -		if (rss_hf & in[i]) {
> -			seen |= rss_hf & in[i];
> +		if (types & in[i]) {
> +			seen |= types & in[i];
>  			conv |= out[i];
>  		}
>  	if ((conv & priv->hw_rss_sup) == conv) {
> -		if (rss_hf == (uint64_t)-1) {
> +		if (types == (uint64_t)-1) {
>  			/* Include inner RSS by default if supported. */
>  			conv |= priv->hw_rss_sup & IBV_RX_HASH_INNER;
>  			return conv;
>  		}
> -		if (!(rss_hf & ~seen))
> +		if (!(types & ~seen))
>  			return conv;
>  	}
>  	rte_errno = ENOTSUP;
> @@ -717,7 +717,8 @@ mlx4_flow_prepare(struct priv *priv,
>  		switch (action->type) {
>  			const struct rte_flow_action_queue *queue;
>  			const struct rte_flow_action_rss *rss;
> -			const struct rte_eth_rss_conf *rss_conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint64_t fields;
>  			unsigned int i;
> 
> @@ -747,58 +748,56 @@ mlx4_flow_prepare(struct priv *priv,
>  				break;
>  			rss = action->conf;
>  			/* Default RSS configuration if none is provided. */
> -			rss_conf =
> -				rss->rss_conf ?
> -				rss->rss_conf :
> -				&(struct rte_eth_rss_conf){
> -					.rss_key =
> mlx4_rss_hash_key_default,
> -					.rss_key_len =
> MLX4_RSS_HASH_KEY_SIZE,
> -					.rss_hf = -1,
> -				};
> +			if (rss->key_len) {
> +				rss_key = rss->key;
> +				rss_key_len = rss->key_len;
> +			} else {
> +				rss_key = mlx4_rss_hash_key_default;
> +				rss_key_len = MLX4_RSS_HASH_KEY_SIZE;
> +			}
>  			/* Sanity checks. */
> -			for (i = 0; i < rss->num; ++i)
> +			for (i = 0; i < rss->queue_num; ++i)
>  				if (rss->queue[i] >=
>  				    priv->dev->data->nb_rx_queues)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "queue index target beyond number
> of"
>  					" configured Rx queues";
>  				goto exit_action_not_supported;
>  			}
> -			if (!rte_is_power_of_2(rss->num)) {
> +			if (!rte_is_power_of_2(rss->queue_num)) {
>  				msg = "for RSS, mlx4 requires the number of"
>  					" queues to be a power of two";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss_conf->rss_key_len !=
> -			    sizeof(flow->rss->key)) {
> +			if (rss_key_len != sizeof(flow->rss->key)) {
>  				msg = "mlx4 supports exactly one RSS hash
> key"
>  					" length: "
> 
> 	MLX4_STR_EXPAND(MLX4_RSS_HASH_KEY_SIZE);
>  				goto exit_action_not_supported;
>  			}
> -			for (i = 1; i < rss->num; ++i)
> +			for (i = 1; i < rss->queue_num; ++i)
>  				if (rss->queue[i] - rss->queue[i - 1] != 1)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "mlx4 requires RSS contexts to use"
>  					" consecutive queue indices only";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss->queue[0] % rss->num) {
> +			if (rss->queue[0] % rss->queue_num) {
>  				msg = "mlx4 requires the first queue of a
> RSS"
>  					" context to be aligned on a multiple"
>  					" of the context size";
>  				goto exit_action_not_supported;
>  			}
>  			rte_errno = 0;
> -			fields = mlx4_conv_rss_hf(priv, rss_conf->rss_hf);
> +			fields = mlx4_conv_rss_types(priv, rss->types);
>  			if (fields == (uint64_t)-1 && rte_errno) {
>  				msg = "unsupported RSS hash type
> requested";
>  				goto exit_action_not_supported;
>  			}
>  			flow->rss = mlx4_rss_get
> -				(priv, fields, rss_conf->rss_key, rss->num,
> +				(priv, fields, rss_key, rss->queue_num,
>  				 rss->queue);
>  			if (!flow->rss) {
>  				msg = "either invalid parameters or not
> enough"
> @@ -1284,8 +1283,10 @@ mlx4_flow_internal(struct priv *priv, struct
> rte_flow_error *error)
>  		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
>  	uint16_t queue[queues];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = NULL, /* Rely on default fallback settings. */
> -		.num = queues,
> +		.types = -1,
> +		.key_len = MLX4_RSS_HASH_KEY_SIZE,
> +		.queue_num = queues,
> +		.key = mlx4_rss_hash_key_default,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h
> index 4e3889e67..7b83d74b0 100644
> --- a/drivers/net/mlx4/mlx4_flow.h
> +++ b/drivers/net/mlx4/mlx4_flow.h
> @@ -47,7 +47,7 @@ struct rte_flow {
> 
>  /* mlx4_flow.c */
> 
> -uint64_t mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf);
> +uint64_t mlx4_conv_rss_types(struct priv *priv, uint64_t rss_hf);
>  int mlx4_flow_sync(struct priv *priv, struct rte_flow_error *error);
>  void mlx4_flow_clean(struct priv *priv);
>  int mlx4_filter_ctrl(struct rte_eth_dev *dev,
> diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
> index a7acc047b..65f099423 100644
> --- a/drivers/net/mlx4/mlx4_rxq.c
> +++ b/drivers/net/mlx4/mlx4_rxq.c
> @@ -88,7 +88,7 @@
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE] = {
>   */
>  struct mlx4_rss *
>  mlx4_rss_get(struct priv *priv, uint64_t fields,
> -	     uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +	     const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  	     uint16_t queues, const uint16_t queue_id[])
>  {
>  	struct mlx4_rss *rss;
> diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
> index b1af86110..2dfee957f 100644
> --- a/drivers/net/mlx4/mlx4_rxtx.h
> +++ b/drivers/net/mlx4/mlx4_rxtx.h
> @@ -127,7 +127,7 @@ uint8_t
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE];
>  int mlx4_rss_init(struct priv *priv);
>  void mlx4_rss_deinit(struct priv *priv);
>  struct mlx4_rss *mlx4_rss_get(struct priv *priv, uint64_t fields,
> -			      uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +			      const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  			      uint16_t queues, const uint16_t queue_id[]);
>  void mlx4_rss_put(struct mlx4_rss *rss);
>  int mlx4_rss_attach(struct mlx4_rss *rss);
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 0c89bff45..af8853e09 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -214,9 +214,8 @@ struct rte_flow {
>  	TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure.
> */
>  	uint32_t mark:1; /**< Set if the flow is marked. */
>  	uint32_t drop:1; /**< Drop queue. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t (*queues)[]; /**< Queues indexes to use. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	struct ibv_counter_set *cs; /**< Holds the counters for the rule. */
>  	struct mlx5_flow_counter_stats counter_stats;/**<The counter
> stats. */
> @@ -406,9 +405,8 @@ struct mlx5_flow_parse {
>  	uint32_t mark:1; /**< Mark is present in the flow. */
>  	uint32_t count:1; /**< Count is present in the flow. */
>  	uint32_t mark_id; /**< Mark identifier. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queues
> indexes to use. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	enum hash_rxq_type layer; /**< Last pattern layer detected. */
>  	struct ibv_counter_set *cs; /**< Holds the counter set for the rule */
> @@ -540,47 +538,6 @@ mlx5_flow_item_validate(const struct
> rte_flow_item *item,
>  }
> 
>  /**
> - * Copy the RSS configuration from the user ones, of the rss_conf is null,
> - * uses the driver one.
> - *
> - * @param parser
> - *   Internal parser structure.
> - * @param rss_conf
> - *   User RSS configuration to save.
> - *
> - * @return
> - *   0 on success, a negative errno value otherwise and rte_errno is set.
> - */
> -static int
> -mlx5_flow_convert_rss_conf(struct mlx5_flow_parse *parser,
> -			   const struct rte_eth_rss_conf *rss_conf)
> -{
> -	/*
> -	 * This function is also called at the beginning of
> -	 * mlx5_flow_convert_actions() to initialize the parser with the
> -	 * device default RSS configuration.
> -	 */
> -	if (rss_conf) {
> -		if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len != 40) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len && rss_conf->rss_key) {
> -			parser->rss_conf.rss_key_len = rss_conf-
> >rss_key_len;
> -			memcpy(parser->rss_key, rss_conf->rss_key,
> -			       rss_conf->rss_key_len);
> -			parser->rss_conf.rss_key = parser->rss_key;
> -		}
> -		parser->rss_conf.rss_hf = rss_conf->rss_hf;
> -	}
> -	return 0;
> -}
> -
> -/**
>   * Extract attribute to the parser.
>   *
>   * @param[in] attr
> @@ -650,17 +607,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  	enum { FATE = 1, MARK = 2, COUNT = 4, };
>  	uint32_t overlap = 0;
>  	struct priv *priv = dev->data->dev_private;
> -	int ret;
> 
> -	/*
> -	 * Add default RSS configuration necessary for Verbs to create QP
> even
> -	 * if no RSS is necessary.
> -	 */
> -	ret = mlx5_flow_convert_rss_conf(parser,
> -					 (const struct rte_eth_rss_conf *)
> -					 &priv->rss_conf);
> -	if (ret)
> -		return ret;
>  	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
>  		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
>  			continue;
> @@ -679,25 +626,53 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  			overlap |= FATE;
>  			if (!queue || (queue->index > (priv->rxqs_n - 1)))
>  				goto exit_action_not_supported;
> -			parser->queues_n = 1;
>  			parser->queues[0] = queue->index;
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.queue_num = 1,
> +				.queue = parser->queues,
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
>  			const struct rte_flow_action_rss *rss =
>  				(const struct rte_flow_action_rss *)
>  				actions->conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint16_t n;
> 
>  			if (overlap & FATE)
>  				goto exit_action_overlap;
>  			overlap |= FATE;
> -			if (!rss || !rss->num) {
> +			if (rss->types & MLX5_RSS_HF_MASK) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "unsupported RSS type"
> +						   " requested");
> +				return -rte_errno;
> +			}
> +			if (rss->key_len) {
> +				rss_key_len = rss->key_len;
> +				rss_key = rss->key;
> +			} else {
> +				rss_key_len = rss_hash_default_key_len;
> +				rss_key = rss_hash_default_key;
> +			}
> +			if (rss_key_len != RTE_DIM(parser->rss_key)) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "RSS hash key must be"
> +						   " exactly 40 bytes long");
> +				return -rte_errno;
> +			}
> +			if (!rss->queue_num) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
>  						   "no valid queues");
>  				return -rte_errno;
>  			}
> -			if (rss->num > RTE_DIM(parser->queues)) {
> +			if (rss->queue_num > RTE_DIM(parser->queues)) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
> @@ -705,7 +680,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  						   " context");
>  				return -rte_errno;
>  			}
> -			for (n = 0; n < rss->num; ++n) {
> +			for (n = 0; n < rss->queue_num; ++n) {
>  				if (rss->queue[n] >= priv->rxqs_n) {
>  					rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -715,16 +690,16 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  					return -rte_errno;
>  				}
>  			}
> -			for (n = 0; n < rss->num; ++n)
> -				parser->queues[n] = rss->queue[n];
> -			parser->queues_n = rss->num;
> -			if (mlx5_flow_convert_rss_conf(parser, rss-
> >rss_conf)) {
> -				rte_flow_error_set(error, EINVAL,
> -
> RTE_FLOW_ERROR_TYPE_ACTION,
> -						   actions,
> -						   "wrong RSS configuration");
> -				return -rte_errno;
> -			}
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.types = rss->types,
> +				.key_len = rss_key_len,
> +				.queue_num = rss->queue_num,
> +				.key = memcpy(parser->rss_key, rss_key,
> +					      sizeof(*rss_key) * rss_key_len),
> +				.queue = memcpy(parser->queues, rss-
> >queue,
> +						sizeof(*rss->queue) *
> +						rss->queue_num),
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK)
> {
>  			const struct rte_flow_action_mark *mark =
>  				(const struct rte_flow_action_mark *)
> @@ -769,7 +744,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  		parser->drop = 1;
>  	if (parser->drop && parser->mark)
>  		parser->mark = 0;
> -	if (!parser->queues_n && !parser->drop) {
> +	if (!parser->rss_conf.queue_num && !parser->drop) {
>  		rte_flow_error_set(error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_HANDLE,
>  				   NULL, "no valid action");
>  		return -rte_errno;
> @@ -951,7 +926,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	unsigned int i;
> 
>  	/* Remove any other flow not matching the pattern. */
> -	if (parser->queues_n == 1 && !parser->rss_conf.rss_hf) {
> +	if (parser->rss_conf.queue_num == 1 && !parser->rss_conf.types) {
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			if (i == HASH_RXQ_ETH)
>  				continue;
> @@ -979,7 +954,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	}
>  	/* Remove impossible flow according to the RSS configuration. */
>  	if (hash_rxq_init[parser->layer].dpdk_rss_hf &
> -	    parser->rss_conf.rss_hf) {
> +	    parser->rss_conf.types) {
>  		/* Remove any other flow. */
>  		for (i = hmin; i != (hmax + 1); ++i) {
>  			if ((i == parser->layer) ||
> @@ -990,7 +965,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  		}
>  	} else  if (!parser->queue[ip].ibv_attr) {
>  		/* no RSS possible with the current configuration. */
> -		parser->queues_n = 1;
> +		parser->rss_conf.queue_num = 1;
>  		return;
>  	}
>  fill:
> @@ -1119,7 +1094,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev,
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			unsigned int offset;
> 
> -			if (!(parser->rss_conf.rss_hf &
> +			if (!(parser->rss_conf.types &
>  			      hash_rxq_init[i].dpdk_rss_hf) &&
>  			    (i != HASH_RXQ_ETH))
>  				continue;
> @@ -1787,20 +1762,20 @@ mlx5_flow_create_action_queue_rss(struct
> rte_eth_dev *dev,
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_get(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (flow->frxq[i].hrxq)
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_new(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (!flow->frxq[i].hrxq) {
>  			return rte_flow_error_set(error, ENOMEM,
> 
> RTE_FLOW_ERROR_TYPE_HANDLE,
> @@ -1871,9 +1846,9 @@ mlx5_flow_create_action_queue(struct
> rte_eth_dev *dev,
>  				   NULL, "internal error in flow creation");
>  		goto error;
>  	}
> -	for (i = 0; i != parser->queues_n; ++i) {
> +	for (i = 0; i != parser->rss_conf.queue_num; ++i) {
>  		struct mlx5_rxq_data *q =
> -			(*priv->rxqs)[parser->queues[i]];
> +			(*priv->rxqs)[parser->rss_conf.queue[i]];
> 
>  		q->mark |= parser->mark;
>  	}
> @@ -1937,7 +1912,8 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  	if (ret)
>  		goto exit;
>  	flow = rte_calloc(__func__, 1,
> -			  sizeof(*flow) + parser.queues_n * sizeof(uint16_t),
> +			  sizeof(*flow) +
> +			  parser.rss_conf.queue_num * sizeof(uint16_t),
>  			  0);
>  	if (!flow) {
>  		rte_flow_error_set(error, ENOMEM,
> @@ -1946,15 +1922,20 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  				   "cannot allocate flow memory");
>  		return NULL;
>  	}
> -	/* Copy queues configuration. */
> +	/* Copy configuration. */
>  	flow->queues = (uint16_t (*)[])(flow + 1);
> -	memcpy(flow->queues, parser.queues, parser.queues_n *
> sizeof(uint16_t));
> -	flow->queues_n = parser.queues_n;
> +	flow->rss_conf = (struct rte_flow_action_rss){
> +		.types = parser.rss_conf.types,
> +		.key_len = parser.rss_conf.key_len,
> +		.queue_num = parser.rss_conf.queue_num,
> +		.key = memcpy(flow->rss_key, parser.rss_conf.key,
> +			      sizeof(*parser.rss_conf.key) *
> +			      parser.rss_conf.key_len),
> +		.queue = memcpy(flow->queues, parser.rss_conf.queue,
> +				sizeof(*parser.rss_conf.queue) *
> +				parser.rss_conf.queue_num),
> +	};
>  	flow->mark = parser.mark;
> -	/* Copy RSS configuration. */
> -	flow->rss_conf = parser.rss_conf;
> -	flow->rss_conf.rss_key = flow->rss_key;
> -	memcpy(flow->rss_key, parser.rss_key,
> parser.rss_conf.rss_key_len);
>  	/* finalise the flow. */
>  	if (parser.drop)
>  		ret = mlx5_flow_create_action_queue_drop(dev, &parser,
> flow,
> @@ -2034,7 +2015,7 @@ mlx5_flow_list_destroy(struct rte_eth_dev *dev,
> struct mlx5_flows *list,
> 
>  	if (flow->drop || !flow->mark)
>  		goto free;
> -	for (i = 0; i != flow->queues_n; ++i) {
> +	for (i = 0; i != flow->rss_conf.queue_num; ++i) {
>  		struct rte_flow *tmp;
>  		int mark = 0;
> 
> @@ -2344,19 +2325,19 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  			if (!flow->frxq[i].ibv_attr)
>  				continue;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_get(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_get(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (flow->frxq[i].hrxq)
>  				goto flow_create;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_new(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_new(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (!flow->frxq[i].hrxq) {
>  				DRV_LOG(DEBUG,
>  					"port %u flow %p cannot be applied",
> @@ -2380,8 +2361,8 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  		}
>  		if (!flow->mark)
>  			continue;
> -		for (i = 0; i != flow->queues_n; ++i)
> -			(*priv->rxqs)[(*flow->queues)[i]]->mark = 1;
> +		for (i = 0; i != flow->rss_conf.queue_num; ++i)
> +			(*priv->rxqs)[flow->rss_conf.queue[i]]->mark = 1;
>  	}
>  	return 0;
>  }
> @@ -2458,8 +2439,10 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
>  	};
>  	uint16_t queue[priv->reta_idx_n];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = &priv->rss_conf,
> -		.num = priv->reta_idx_n,
> +		.types = priv->rss_conf.rss_hf,
> +		.key_len = priv->rss_conf.rss_key_len,
> +		.queue_num = priv->reta_idx_n,
> +		.key = priv->rss_conf.rss_key,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
> index eda3ba3d5..d2b25e8e8 100644
> --- a/drivers/net/mlx5/mlx5_rxq.c
> +++ b/drivers/net/mlx5/mlx5_rxq.c
> @@ -1218,8 +1218,8 @@ mlx5_rxq_verify(struct rte_eth_dev *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1286,8 +1286,8 @@ mlx5_ind_table_ibv_new(struct rte_eth_dev *dev,
> uint16_t queues[],
>   *   An indirection table if found.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1391,8 +1391,10 @@ mlx5_ind_table_ibv_verify(struct rte_eth_dev
> *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_new(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> @@ -1408,6 +1410,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  		rte_errno = ENOMEM;
>  		return NULL;
>  	}
> +	if (!rss_key_len) {
> +		rss_key_len = rss_hash_default_key_len;
> +		rss_key = rss_hash_default_key;
> +	}
>  	qp = mlx5_glue->create_qp_ex
>  		(priv->ctx,
>  		 &(struct ibv_qp_init_attr_ex){
> @@ -1419,7 +1425,7 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  			.rx_hash_conf = (struct ibv_rx_hash_conf){
>  				.rx_hash_function =
> IBV_RX_HASH_FUNC_TOEPLITZ,
>  				.rx_hash_key_len = rss_key_len,
> -				.rx_hash_key = rss_key,
> +				.rx_hash_key = (void *)(uintptr_t)rss_key,
>  				.rx_hash_fields_mask = hash_fields,
>  			},
>  			.rwq_ind_tbl = ind_tbl->ind_table,
> @@ -1469,8 +1475,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>   *   An hash Rx queue on success.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_get(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
> index 14d4418d9..c3a1ae213 100644
> --- a/drivers/net/mlx5/mlx5_rxtx.h
> +++ b/drivers/net/mlx5/mlx5_rxtx.h
> @@ -134,7 +134,7 @@ struct mlx5_ind_table_ibv {
>  	LIST_ENTRY(mlx5_ind_table_ibv) next; /* Pointer to the next
> element. */
>  	rte_atomic32_t refcnt; /* Reference counter. */
>  	struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
> -	uint16_t queues_n; /**< Number of queues in the list. */
> +	uint32_t queues_n; /**< Number of queues in the list. */
>  	uint16_t queues[]; /**< Queue list. */
>  };
> 
> @@ -145,7 +145,7 @@ struct mlx5_hrxq {
>  	struct mlx5_ind_table_ibv *ind_table; /* Indirection table. */
>  	struct ibv_qp *qp; /* Verbs queue pair. */
>  	uint64_t hash_fields; /* Verbs Hash fields. */
> -	uint8_t rss_key_len; /* Hash key length in bytes. */
> +	uint32_t rss_key_len; /* Hash key length in bytes. */
>  	uint8_t rss_key[]; /* Hash key. */
>  };
> 
> @@ -238,20 +238,22 @@ int mlx5_rxq_releasable(struct rte_eth_dev *dev,
> uint16_t idx);
>  int mlx5_rxq_verify(struct rte_eth_dev *dev);
>  int rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_new(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_get(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  int mlx5_ind_table_ibv_release(struct rte_eth_dev *dev,
>  			       struct mlx5_ind_table_ibv *ind_tbl);
>  int mlx5_ind_table_ibv_verify(struct rte_eth_dev *dev);
> -struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> -struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
>  int mlx5_hrxq_release(struct rte_eth_dev *dev, struct mlx5_hrxq *hxrq);
>  int mlx5_hrxq_ibv_verify(struct rte_eth_dev *dev);
>  uint64_t mlx5_get_rx_port_offloads(void);
> diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
> index 056405515..1a2c0299c 100644
> --- a/drivers/net/sfc/sfc_flow.c
> +++ b/drivers/net/sfc/sfc_flow.c
> @@ -1234,13 +1234,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	struct sfc_rxq *rxq;
>  	unsigned int rxq_hw_index_min;
>  	unsigned int rxq_hw_index_max;
> -	const struct rte_eth_rss_conf *rss_conf = rss->rss_conf;
> -	uint64_t rss_hf;
> -	uint8_t *rss_key = NULL;
> +	const uint8_t *rss_key;
>  	struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf;
>  	unsigned int i;
> 
> -	if (rss->num == 0)
> +	if (rss->queue_num == 0)
>  		return -EINVAL;
> 
>  	rxq_sw_index = sa->rxq_count - 1;
> @@ -1248,7 +1246,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	rxq_hw_index_min = rxq->hw_index;
>  	rxq_hw_index_max = 0;
> 
> -	for (i = 0; i < rss->num; ++i) {
> +	for (i = 0; i < rss->queue_num; ++i) {
>  		rxq_sw_index = rss->queue[i];
> 
>  		if (rxq_sw_index >= sa->rxq_count)
> @@ -1263,15 +1261,14 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  			rxq_hw_index_max = rxq->hw_index;
>  	}
> 
> -	rss_hf = (rss_conf != NULL) ? rss_conf->rss_hf : SFC_RSS_OFFLOADS;
> -	if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0)
> +	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
>  		return -EINVAL;
> 
> -	if (rss_conf != NULL) {
> -		if (rss_conf->rss_key_len != sizeof(sa->rss_key))
> +	if (rss->key_len) {
> +		if (rss->key_len != sizeof(sa->rss_key))
>  			return -EINVAL;
> 
> -		rss_key = rss_conf->rss_key;
> +		rss_key = rss->key;
>  	} else {
>  		rss_key = sa->rss_key;
>  	}
> @@ -1280,11 +1277,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
> 
>  	sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
>  	sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
> -	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf);
> +	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss-
> >types);
>  	rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key));
> 
>  	for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
> -		unsigned int rxq_sw_index = rss->queue[i % rss->num];
> +		unsigned int rxq_sw_index = rss->queue[i % rss-
> >queue_num];
>  		struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq;
> 
>  		sfc_rss_conf->rss_tbl[i] = rxq->hw_index -
> rxq_hw_index_min;
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index fe2f94010..67146aaba 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -1215,7 +1215,7 @@ priv_flow_process(struct pmd_internals *pmd,
>  				if (err)
>  					goto exit_action_not_supported;
>  			}
> -			if (flow && rss)
> +			if (flow)
>  				err = rss_add_actions(flow, pmd, rss, error);
>  		} else {
>  			goto exit_action_not_supported;
> @@ -2050,7 +2050,7 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  			   struct rte_flow_error *error)
>  {
>  	/* 4096 is the maximum number of instructions for a BPF program */
> -	int i;
> +	unsigned int i;
>  	int err;
>  	struct rss_key rss_entry = { .hash_fields = 0,
>  				     .key_size = 0 };
> @@ -2066,8 +2066,8 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  	}
> 
>  	/* Update RSS map entry with queues */
> -	rss_entry.nb_queues = rss->num;
> -	for (i = 0; i < rss->num; i++)
> +	rss_entry.nb_queues = rss->queue_num;
> +	for (i = 0; i < rss->queue_num; i++)
>  		rss_entry.queues[i] = rss->queue[i];
>  	rss_entry.hash_fields =
>  		(1 << HASH_FIELD_IPV4_L3_L4) | (1 <<
> HASH_FIELD_IPV6_L3_L4);
> diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
> index 5971937cf..ee2497352 100644
> --- a/examples/ipsec-secgw/ipsec.c
> +++ b/examples/ipsec-secgw/ipsec.c
> @@ -203,9 +203,13 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct
> ipsec_sa *sa)
>  				     i < eth_dev->data->nb_rx_queues; ++i)
>  					if (eth_dev->data->rx_queues[i])
>  						queue[j++] = i;
> -				action_rss.rss_conf = &rss_conf;
> -				action_rss.num = j;
> -				action_rss.queue = queue;
> +				action_rss = (struct rte_flow_action_rss){
> +					.types = rss_conf.rss_hf,
> +					.key_len = rss_conf.rss_key_len,
> +					.queue_num = j,
> +					.key = rss_key,
> +					.queue = queue,
> +				};
>  				ret = rte_flow_validate(sa->portid, &sa->attr,
>  							sa->pattern, sa-
> >action,
>  							&err);
> diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
> index bb19e28c6..cc7819b6a 100644
> --- a/lib/librte_ether/rte_flow.c
> +++ b/lib/librte_ether/rte_flow.c
> @@ -330,40 +330,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
> index ad2e55b8e..bbc408fa6 100644
> --- a/lib/librte_ether/rte_flow.h
> +++ b/lib/librte_ether/rte_flow.h
> @@ -1033,13 +1033,21 @@ struct rte_flow_query_count {
>   * Similar to QUEUE, except RSS is additionally performed on packets to
>   * spread them among several queues according to the provided parameters.
>   *
> + * Unlike global RSS settings used by other DPDK APIs, unsetting the
> + * @p types field does not disable RSS in a flow rule. Doing so instead
> + * requests safe unspecified "best-effort" settings from the underlying
> PMD,
> + * which depending on the flow rule, may result in anything ranging from
> + * empty (single queue) to all-inclusive RSS.
> + *
>   * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps
>   * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only,
>   * both can be requested simultaneously.
>   */
>  struct rte_flow_action_rss {
> -	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in @p queue. */
> +	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
> +	uint32_t key_len; /**< Hash key length in bytes. */
> +	uint32_t queue_num; /**< Number of entries in @p queue. */
> +	const uint8_t *key; /**< Hash key. */
>  	const uint16_t *queue; /**< Queue indices to use. */
>  };
> 
> --
> 2.11.0

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API
  2018-04-28  5:28  0%       ` Peng, Yuan
@ 2018-04-28  7:45  0%         ` Peng, Yuan
  0 siblings, 0 replies; 200+ results
From: Peng, Yuan @ 2018-04-28  7:45 UTC (permalink / raw)
  To: Peng, Yuan, Zhao1, Wei, Adrien Mazarguil, dev
  Cc: Xu, Qian Q, Liu, Yu Y, Lu, Wenzhuo, Wu, Jingjing

Hi,Adrien Mazarguil

There is a bug of queue region with 18.05-rc1
The test steps are as below:
./usertools/dpdk-devbind.py -b igb_uio 05:00.0
./x86_64-native-linuxapp-gcc/app/testpmd -c 1ffff -n 4 -- -i --rxq=16 --txq=16
testpmd> port config all rss all
Configuration of RSS hash at ethernet port 0 failed with error (22): Invalid argument.
testpmd> set fwd rxonly
testpmd> set verbose 1
testpmd> start
testpmd> set port 0 queue-region region_id 0 queue_start_index 1 queue_num 1
testpmd> set port 0 queue-region region_id 0 flowtype 31
testpmd> set port 0 queue-region flush on
testpmd> port 0/queue 0: received 1 packets
  src=00:13:3B:0C:21:95 - dst=00:00:00:00:01:00 - type=0x0800 - length=90 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4_EXT_UNKNOWN L4_UDP  - sw ptype: L2_ETHER L3_IPV4 L4_UDP  - l2_len=14 - l3_len=20 - l4_len=8 - Receive queue=0x0
  ol_flags: PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD

the packet should be distributed to queue 1 instead of queue0. And the command" port config all rss all" failed to execute.

Could you help to check if this has relationship with your patches relevant to flow api?

Thanks.
Yuan.

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Peng, Yuan
Sent: Saturday, April 28, 2018 1:29 PM
To: Zhao1, Wei <wei.zhao1@intel.com>; Adrien Mazarguil <adrien.mazarguil@6wind.com>; dev@dpdk.org
Cc: Xu, Qian Q <qian.q.xu@intel.com>; Liu, Yu Y <yu.y.liu@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
Subject: Re: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API

Hi,Adrien Mazarguil

There is a bug present with 18.05-rci when I test the feature "Move RSS to rte_flow" in i40e NIC
The test steps are as below:
./usertools/dpdk-devbind.py -b igb_uio 05:00.0 05:00.1
./x86_64-native-linuxapp-gcc/app/testpmd -c 0x1fffe -n 4  -- -i --nb-cores=8 --rxq=8 --txq=8 --port-topology=chained
testpmd> set fwd rxonly
Set rxonly packet forwarding mode
testpmd> set verbose 1
Change verbose level from 0 to 1
testpmd> start
testpmd> flow create 0 ingress pattern end actions rss queues 0 4 7 end / end
Caught error type 16 (specific action): cause: 0x7fff84e33658, RSS hash key too large

The rss rule can be set successfully when I test it yesterday with older dpdk version without this patch.

The NIC information is:
driver: i40e
version: 2.4.3
firmware-version: 6.01 0x80003205 1.1691.0

There is another problem with ixgbe nic:
./usertools/dpdk-devbind.py -b igb_uio 07:00.0 07:00.1
./x86_64-native-linuxapp-gcc/app/testpmd -c 0x1fffe -n 4  -- -i --nb-cores=8 --rxq=8 --txq=8 --disable-rss --port-topology=chained 
testpmd> flow create 0 ingress pattern end actions rss queues 5 6 7 end / end
Caught error type 2 (flow rule (handle)): Failed to create flow.
The rule setting command can be executed successfully with older dpdk version.

Could you help to check if there is a relationship between the bugs and this patch?

Thank you.
Yuan.


-----Original Message-----
From: Zhao1, Wei 
Sent: Saturday, April 28, 2018 11:46 AM
To: Adrien Mazarguil <adrien.mazarguil@6wind.com>; dev@dpdk.org
Cc: Peng, Yuan <yuan.peng@intel.com>; Xu, Qian Q <qian.q.xu@intel.com>; Liu, Yu Y <yu.y.liu@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
Subject: RE: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in flow API

Hi,Adrien Mazarguil

       We have just use new RC.1 code on the feature of flow RSS API, but we find some abnormal phenomenon.
After that I check code again, I find that it is  introduced in this patch:

SHA-1: ac8d22de2394e03ba4a77d8fd24381147aafb1d3
* ethdev: flatten RSS configuration in flow API
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>


This abnormal phenomenon include i40e and ixgbe 2 NIC, it do not has these 2 bug before merge this patch.
It is first find out by yuan.peng@intel.com,  she can tell you how to reappear these abnormal phenomenon on RSS flow API.

Thank you.


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Wednesday, April 25, 2018 11:28 PM
> To: Thomas Monjalon <thomas@monjalon.net>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; dev@dpdk.org
> Cc: Xueming Li <xuemingl@mellanox.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; Nelio Laranjeiro
> <nelio.laranjeiro@6wind.com>; Yongseok Koh <yskoh@mellanox.com>;
> Andrew Rybchenko <arybchenko@solarflare.com>; Pascal Mazon
> <pascal.mazon@6wind.com>; Nicolau, Radu <radu.nicolau@intel.com>; Akhil
> Goyal <akhil.goyal@nxp.com>
> Subject: [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in
> flow API
> 
> Since its inception, the rte_flow RSS action has been relying in part on
> external struct rte_eth_rss_conf for compatibility with the legacy RSS API.
> This structure lacks parameters such as the hash algorithm to use, and more
> recently, a method to tell which layer RSS should be performed on [1].
> 
> Given struct rte_eth_rss_conf will never be flexible enough to represent a
> complete RSS configuration (e.g. RETA table), this patch supersedes it by
> extending the rte_flow RSS action directly.
> 
> A subsequent patch will add a field to use a non-default RSS hash
> algorithm. To that end, a field named "types" replaces the field formerly
> known as "rss_hf" and standing for "RSS hash functions" as it was
> confusing. Actual RSS hash function types are defined by enum
> rte_eth_hash_function.
> 
> This patch updates all PMDs and example applications accordingly.
> 
> It breaks ABI compatibility for the following public functions:
> 
> - rte_flow_copy()
> - rte_flow_create()
> - rte_flow_query()
> - rte_flow_validate()
> 
> [1] commit 676b605182a5 ("doc: announce ethdev API change for RSS
>     configuration")
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Xueming Li <xuemingl@mellanox.com>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>
> Cc: Wenzhuo Lu <wenzhuo.lu@intel.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>
> Cc: Beilei Xing <beilei.xing@intel.com>
> Cc: Qi Zhang <qi.z.zhang@intel.com>
> Cc: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Pascal Mazon <pascal.mazon@6wind.com>
> Cc: Radu Nicolau <radu.nicolau@intel.com>
> Cc: Akhil Goyal <akhil.goyal@nxp.com>
> 
> ---
> 
> v6 changes:
> 
> - Fixed QUEUE action support in mlx5 according to Nelio's comment [1].
>   This action relies on RSS to work and even though it targets a single Rx
>   queue, a non-NULL hash key is required.
> - Updated API and ABI changes sections in release notes.
> 
> [1] http://dpdk.org/ml/archives/dev/2018-April/098635.html
> 
> v3 changes:
> 
> Documentation update regarding the meaning of a 0 value for RSS types in
> flow rules.
> 
> It used to implicitly mean "no RSS" but is redefined as requesting a kind
> of "best-effort" mode from PMDs, i.e. anything ranging from empty to
> all-inclusive RSS; what matters is it provides safe defaults that will work
> regardless of PMD capabilities.
> ---
>  app/test-pmd/cmdline_flow.c                 |  48 +++---
>  app/test-pmd/config.c                       |  39 ++---
>  doc/guides/prog_guide/rte_flow.rst          |  28 ++--
>  doc/guides/rel_notes/release_18_05.rst      |  13 +-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   6 +-
>  drivers/net/e1000/e1000_ethdev.h            |  13 +-
>  drivers/net/e1000/igb_ethdev.c              |   4 +-
>  drivers/net/e1000/igb_flow.c                |  31 ++--
>  drivers/net/e1000/igb_rxtx.c                |  51 +++++-
>  drivers/net/i40e/i40e_ethdev.c              |  53 +++++--
>  drivers/net/i40e/i40e_ethdev.h              |  15 +-
>  drivers/net/i40e/i40e_flow.c                |  47 +++---
>  drivers/net/ixgbe/ixgbe_ethdev.c            |   4 +-
>  drivers/net/ixgbe/ixgbe_ethdev.h            |  13 +-
>  drivers/net/ixgbe/ixgbe_flow.c              |  30 ++--
>  drivers/net/ixgbe/ixgbe_rxtx.c              |  51 +++++-
>  drivers/net/mlx4/mlx4.c                     |   2 +-
>  drivers/net/mlx4/mlx4_flow.c                |  61 +++----
>  drivers/net/mlx4/mlx4_flow.h                |   2 +-
>  drivers/net/mlx4/mlx4_rxq.c                 |   2 +-
>  drivers/net/mlx4/mlx4_rxtx.h                |   2 +-
>  drivers/net/mlx5/mlx5_flow.c                | 193 +++++++++++------------
>  drivers/net/mlx5/mlx5_rxq.c                 |  26 +--
>  drivers/net/mlx5/mlx5_rxtx.h                |  26 +--
>  drivers/net/sfc/sfc_flow.c                  |  21 ++-
>  drivers/net/tap/tap_flow.c                  |   8 +-
>  examples/ipsec-secgw/ipsec.c                |  10 +-
>  lib/librte_ether/rte_flow.c                 |  39 ++---
>  lib/librte_ether/rte_flow.h                 |  12 +-
>  29 files changed, 492 insertions(+), 358 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 798b7948d..c9c2c3ad9 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -192,9 +192,8 @@ enum index {
>  /** Storage for struct rte_flow_action_rss including external data. */
>  struct action_rss_data {
>  	struct rte_flow_action_rss conf;
> +	uint8_t key[RSS_HASH_KEY_LENGTH];
>  	uint16_t queue[ACTION_RSS_QUEUE_NUM];
> -	struct rte_eth_rss_conf rss_conf;
> -	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
>  };
> 
>  /** Maximum number of subsequent tokens and arguments on the stack.
> */
> @@ -1587,7 +1586,7 @@ static const struct token token_list[] = {
>  	},
>  	[ACTION_RSS_TYPES] = {
>  		.name = "types",
> -		.help = "RSS hash types",
> +		.help = "specific RSS hash types",
>  		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
>  	},
>  	[ACTION_RSS_TYPE] = {
> @@ -1602,21 +1601,21 @@ static const struct token token_list[] = {
>  		.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
>  		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
>  			     ARGS_ENTRY_ARB
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len)),
> -			     ARGS_ENTRY(struct action_rss_data, rss_key)),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len)),
> +			     ARGS_ENTRY(struct action_rss_data, key)),
>  	},
>  	[ACTION_RSS_KEY_LEN] = {
>  		.name = "key_len",
>  		.help = "RSS hash key length in bytes",
>  		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
>  		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
> -			     (offsetof(struct action_rss_data, rss_conf) +
> -			      offsetof(struct rte_eth_rss_conf, rss_key_len),
> -			      sizeof(((struct rte_eth_rss_conf *)0)->
> -				     rss_key_len),
> +			     (offsetof(struct action_rss_data, conf) +
> +			      offsetof(struct rte_flow_action_rss, key_len),
> +			      sizeof(((struct rte_flow_action_rss *)0)->
> +				     key_len),
>  			      0,
>  			      RSS_HASH_KEY_LENGTH)),
>  	},
> @@ -2075,27 +2074,24 @@ parse_vc_action_rss(struct context *ctx, const
> struct token *token,
>  	action_rss_data = ctx->object;
>  	*action_rss_data = (struct action_rss_data){
>  		.conf = (struct rte_flow_action_rss){
> -			.rss_conf = &action_rss_data->rss_conf,
> -			.num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.types = rss_hf,
> +			.key_len = sizeof(action_rss_data->key),
> +			.queue_num = RTE_MIN(nb_rxq,
> ACTION_RSS_QUEUE_NUM),
> +			.key = action_rss_data->key,
>  			.queue = action_rss_data->queue,
>  		},
> +		.key = "testpmd's default RSS hash key",
>  		.queue = { 0 },
> -		.rss_conf = (struct rte_eth_rss_conf){
> -			.rss_key = action_rss_data->rss_key,
> -			.rss_key_len = sizeof(action_rss_data->rss_key),
> -			.rss_hf = rss_hf,
> -		},
> -		.rss_key = "testpmd's default RSS hash key",
>  	};
> -	for (i = 0; i < action_rss_data->conf.num; ++i)
> +	for (i = 0; i < action_rss_data->conf.queue_num; ++i)
>  		action_rss_data->queue[i] = i;
>  	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
>  	    ctx->port != (portid_t)RTE_PORT_ALL) {
>  		struct rte_eth_dev_info info;
> 
>  		rte_eth_dev_info_get(ctx->port, &info);
> -		action_rss_data->rss_conf.rss_key_len =
> -			RTE_MIN(sizeof(action_rss_data->rss_key),
> +		action_rss_data->conf.key_len =
> +			RTE_MIN(sizeof(action_rss_data->key),
>  				info.hash_key_size);
>  	}
>  	action->conf = &action_rss_data->conf;
> @@ -2123,7 +2119,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  		return -1;
>  	if (!(ctx->objdata >> 16) && ctx->object) {
>  		action_rss_data = ctx->object;
> -		action_rss_data->rss_conf.rss_hf = 0;
> +		action_rss_data->conf.types = 0;
>  	}
>  	if (!strcmp_partial("end", str, len)) {
>  		ctx->objdata &= 0xffff;
> @@ -2142,7 +2138,7 @@ parse_vc_action_rss_type(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
> +	action_rss_data->conf.types |= rss_type_table[i].rss_type;
>  	return len;
>  }
> 
> @@ -2192,7 +2188,7 @@ parse_vc_action_rss_queue(struct context *ctx,
> const struct token *token,
>  	if (!ctx->object)
>  		return len;
>  	action_rss_data = ctx->object;
> -	action_rss_data->conf.num = i;
> +	action_rss_data->conf.queue_num = i;
>  	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
>  	return len;
>  }
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index eb7ac315e..4700dd674 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1117,40 +1117,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index acbeaacbd..cf252eeba 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1301,6 +1301,12 @@ Action: ``RSS``
>  Similar to QUEUE, except RSS is additionally performed on packets to spread
>  them among several queues according to the provided parameters.
> 
> +Unlike global RSS settings used by other DPDK APIs, unsetting the ``types``
> +field does not disable RSS in a flow rule. Doing so instead requests safe
> +unspecified "best-effort" settings from the underlying PMD, which
> depending
> +on the flow rule, may result in anything ranging from empty (single queue)
> +to all-inclusive RSS.
> +
>  Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
>  overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
>  field only, both can be requested simultaneously.
> @@ -1309,15 +1315,19 @@ field only, both can be requested simultaneously.
> 
>  .. table:: RSS
> 
> -   +--------------+--------------------------------+
> -   | Field        | Value                          |
> -   +==============+================================+
> -   | ``rss_conf`` | RSS parameters                 |
> -   +--------------+--------------------------------+
> -   | ``num``      | number of entries in ``queue`` |
> -   +--------------+--------------------------------+
> -   | ``queue``    | queue indices to use           |
> -   +--------------+--------------------------------+
> +   +---------------+---------------------------------------------+
> +   | Field         | Value                                       |
> +
> +===============+=========================================
> ====+
> +   | ``types``     | specific RSS hash types (see ``ETH_RSS_*``) |
> +   +---------------+---------------------------------------------+
> +   | ``key_len``   | hash key length in bytes                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue_num`` | number of entries in ``queue``              |
> +   +---------------+---------------------------------------------+
> +   | ``key``       | hash key                                    |
> +   +---------------+---------------------------------------------+
> +   | ``queue``     | queue indices to use                        |
> +   +---------------+---------------------------------------------+
> 
>  Action: ``PF``
>  ^^^^^^^^^^^^^^
> diff --git a/doc/guides/rel_notes/release_18_05.rst
> b/doc/guides/rel_notes/release_18_05.rst
> index ca173450c..b702ac66a 100644
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> @@ -254,6 +254,13 @@ API Changes
>      present.
>    * C99-style flexible arrays were replaced with standard pointers in RSS
>      action and in RAW pattern item structures due to compatibility issues.
> +  * The RSS action was modified to not rely on external
> +    ``struct rte_eth_rss_conf`` anymore to instead expose its own and more
> +    appropriately named configuration fields directly
> +    (``rss_conf->rss_key`` => ``key``,
> +    ``rss_conf->rss_key_len`` => ``key_len``,
> +    ``rss_conf->rss_hf`` => ``types``,
> +    ``num`` => ``queue_num``).
> 
> 
>  ABI Changes
> @@ -302,9 +309,9 @@ ABI Changes
>    ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
>    changes in error type definitions (``enum rte_flow_error_type``), removal
>    of the unused DUP action (``enum rte_flow_action_type``), modified
> -  behavior for flow rule actions (see API changes) and removal of C99
> -  flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
> -  pattern item (``struct rte_flow_item_raw``).
> +  behavior for flow rule actions (see API changes), removal of C99 flexible
> +  array from RAW pattern item (``struct rte_flow_item_raw``) and complete
> +  rework of the RSS action definition (``struct rte_flow_action_rss``).
> 
> 
>  Removed Items
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 68c286bd4..a12e0267a 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3422,8 +3422,10 @@ This section lists supported actions and their
> attributes, if any.
> 
>  - ``rss``: spread packets among several queues.
> 
> -  - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
> -    are the same as `set_hash_input_set`_, an empty list means none (0).
> +  - ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
> +    tokens are the same as `set_hash_input_set`_, except that an empty list
> +    does not disable RSS but instead requests unspecified "best-effort"
> +    settings.
> 
>    - ``key {string}``: RSS hash key, overrides ``key_len``.
> 
> diff --git a/drivers/net/e1000/e1000_ethdev.h
> b/drivers/net/e1000/e1000_ethdev.h
> index 6354b894a..902001f36 100644
> --- a/drivers/net/e1000/e1000_ethdev.h
> +++ b/drivers/net/e1000/e1000_ethdev.h
> @@ -4,6 +4,10 @@
> 
>  #ifndef _E1000_ETHDEV_H_
>  #define _E1000_ETHDEV_H_
> +
> +#include <stdint.h>
> +
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_pci.h>
> 
> @@ -27,6 +31,7 @@
>  #define E1000_CTRL_EXT_EXTEND_VLAN  (1<<26)    /* EXTENDED VLAN */
>  #define IGB_VFTA_SIZE 128
> 
> +#define IGB_HKEY_MAX_INDEX             10
>  #define IGB_MAX_RX_QUEUE_NUM           8
>  #define IGB_MAX_RX_QUEUE_NUM_82576     16
> 
> @@ -229,8 +234,8 @@ struct igb_ethertype_filter {
>  };
> 
>  struct igb_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IGB_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key.
> */
>  	uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices
> to use. */
>  };
> 
> @@ -501,6 +506,10 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev,
>  int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
>  			struct rte_eth_flex_filter *filter,
>  			bool add);
> +int igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		      const struct rte_flow_action_rss *in);
> +int igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +			const struct rte_flow_action_rss *with);
>  int igb_config_rss_filter(struct rte_eth_dev *dev,
>  			struct igb_rte_flow_rss_conf *conf,
>  			bool add);
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c
> index c35c9352a..140334772 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -41,8 +41,6 @@
>  #define IGB_DEFAULT_TX_HTHRESH      1
>  #define IGB_DEFAULT_TX_WTHRESH      ((hw->mac.type == e1000_82576) ?
> 1 : 16)
> 
> -#define IGB_HKEY_MAX_INDEX 10
> -
>  /* Bit shift and mask */
>  #define IGB_4_BIT_WIDTH  (CHAR_BIT / 2)
>  #define IGB_4_BIT_MASK   RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)
> @@ -5662,7 +5660,7 @@ igb_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter_info->rss_info, TRUE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
> index c0f5b5190..8dc5f75f2 100644
> --- a/drivers/net/e1000/igb_flow.c
> +++ b/drivers/net/e1000/igb_flow.c
> @@ -1292,7 +1292,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -1300,7 +1300,7 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1310,14 +1310,18 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
>  		}
>  	}
> 
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
> -
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (igb_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	index++;
> @@ -1518,9 +1522,8 @@ igb_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct igb_rte_flow_rss_conf));
> +			igb_rss_conf_init(&rss_filter_ptr->filter_info,
> +					  &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> @@ -1757,7 +1760,7 @@ igb_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct e1000_filter_info *filter =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter->rss_info.num)
> +	if (filter->rss_info.conf.queue_num)
>  		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
>  }
> 
> diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
> index 323913f0d..45bb3455c 100644
> --- a/drivers/net/e1000/igb_rxtx.c
> +++ b/drivers/net/e1000/igb_rxtx.c
> @@ -2898,12 +2898,47 @@ igb_txq_info_get(struct rte_eth_dev *dev,
> uint16_t queue_id,
>  }
> 
>  int
> +igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
> +		  const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +igb_action_rss_same(const struct rte_flow_action_rss *comp,
> +		    const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  igb_config_rss_filter(struct rte_eth_dev *dev,
>  		struct igb_rte_flow_rss_conf *conf, bool add)
>  {
>  	uint32_t shift;
>  	uint16_t i, j;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct e1000_filter_info *filter_info =
>  		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
>  	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> @@ -2911,8 +2946,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct igb_rte_flow_rss_conf)) == 0) {
> +		if (igb_action_rss_same(&filter_info->rss_info.conf,
> +					&conf->conf)) {
>  			igb_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct igb_rte_flow_rss_conf));
> @@ -2921,7 +2956,7 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
> 
>  	/* Fill in redirection table. */
> @@ -2933,9 +2968,9 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		} reta;
>  		uint8_t q_idx;
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		q_idx = conf->queue[j];
> +		q_idx = conf->conf.queue[j];
>  		reta.bytes[i & 3] = (uint8_t)(q_idx << shift);
>  		if ((i & 3) == 3)
>  			E1000_WRITE_REG(hw, E1000_RETA(i >> 2),
> reta.dword);
> @@ -2952,8 +2987,8 @@ igb_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	igb_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct igb_rte_flow_rss_conf));
> +	if (igb_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 78f2be7da..50e77901c 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -11,6 +11,7 @@
>  #include <inttypes.h>
>  #include <assert.h>
> 
> +#include <rte_common.h>
>  #include <rte_eal.h>
>  #include <rte_string_fns.h>
>  #include <rte_pci.h>
> @@ -11650,7 +11651,7 @@ i40e_rss_filter_restore(struct i40e_pf *pf)
>  {
>  	struct i40e_rte_flow_rss_conf *conf =
>  					&pf->rss_info;
> -	if (conf->num)
> +	if (conf->conf.queue_num)
>  		i40e_config_rss_filter(pf, conf, TRUE);
>  }
> 
> @@ -12182,18 +12183,52 @@ i40e_cloud_filter_qinq_create(struct i40e_pf
> *pf)
>  }
> 
>  int
> +i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		   const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +		     const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
>  	uint32_t i, lut = 0;
>  	uint16_t j, num;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info;
> 
>  	if (!add) {
> -		if (memcmp(conf, rss_info,
> -			sizeof(struct i40e_rte_flow_rss_conf)) == 0) {
> +		if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) {
>  			i40e_pf_disable_rss(pf);
>  			memset(rss_info, 0,
>  				sizeof(struct i40e_rte_flow_rss_conf));
> @@ -12202,7 +12237,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  		return -EINVAL;
>  	}
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		return -EINVAL;
> 
>  	/* If both VMDQ and RSS enabled, not all of PF queues are
> configured.
> @@ -12213,7 +12248,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	else
>  		num = pf->dev_data->nb_rx_queues;
> 
> -	num = RTE_MIN(num, conf->num);
> +	num = RTE_MIN(num, conf->conf.queue_num);
>  	PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are
> configured",
>  			num);
> 
> @@ -12226,7 +12261,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
>  	for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
>  		if (j == num)
>  			j = 0;
> -		lut = (lut << 8) | (conf->queue[j] & ((0x1 <<
> +		lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 <<
>  			hw->func_caps.rss_table_entry_width) - 1));
>  		if ((i & 3) == 3)
>  			I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
> @@ -12251,8 +12286,8 @@ i40e_config_rss_filter(struct i40e_pf *pf,
> 
>  	i40e_hw_rss_hash_set(pf, &rss_conf);
> 
> -	rte_memcpy(rss_info,
> -		conf, sizeof(struct i40e_rte_flow_rss_conf));
> +	if (i40e_rss_conf_init(rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h
> index d33b255e7..a0569d4ae 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -5,14 +5,19 @@
>  #ifndef _I40E_ETHDEV_H_
>  #define _I40E_ETHDEV_H_
> 
> +#include <stdint.h>
> +
>  #include <rte_eth_ctrl.h>
>  #include <rte_time.h>
>  #include <rte_kvargs.h>
>  #include <rte_hash.h>
> +#include <rte_flow.h>
>  #include <rte_flow_driver.h>
>  #include <rte_tm_driver.h>
>  #include "rte_pmd_i40e.h"
> 
> +#include "base/i40e_register.h"
> +
>  #define I40E_VLAN_TAG_SIZE        4
> 
>  #define I40E_AQ_LEN               32
> @@ -878,9 +883,11 @@ struct i40e_customized_pctype {
>  };
> 
>  struct i40e_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
>  	uint16_t queue_region_conf; /**< Queue region config flag */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	uint8_t key[(I40E_VFQF_HKEY_MAX_INDEX >
> I40E_PFQF_HKEY_MAX_INDEX ?
> +		     I40E_VFQF_HKEY_MAX_INDEX :
> I40E_PFQF_HKEY_MAX_INDEX) + 1 *
> +		    sizeof(uint32_t)]; /* Hash key. */
>  	uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use.
> */
>  };
> 
> @@ -1219,6 +1226,10 @@ void i40e_init_queue_region_conf(struct
> rte_eth_dev *dev);
>  void i40e_flex_payload_reg_set_default(struct i40e_hw *hw);
>  int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
>  int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
> +int i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
> +		       const struct rte_flow_action_rss *in);
> +int i40e_action_rss_same(const struct rte_flow_action_rss *comp,
> +			 const struct rte_flow_action_rss *with);
>  int i40e_config_rss_filter(struct i40e_pf *pf,
>  		struct i40e_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index d6f5e9923..ec6231003 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -4220,7 +4220,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
> 
>  	if (action_flag) {
>  		for (n = 0; n < 64; n++) {
> -			if (rss->rss_conf->rss_hf & (hf_bit << n)) {
> +			if (rss->types & (hf_bit << n)) {
>  				conf_info->region[0].hw_flowtype[0] = n;
>  				conf_info->region[0].flowtype_num = 1;
>  				conf_info->queue_region_number = 1;
> @@ -4236,12 +4236,12 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	 * queue index for this port.
>  	 */
>  	if (conf_info->queue_region_number) {
> -		for (i = 0; i < rss->num; i++) {
> -			for (j = 0; j < rss_info->num; j++) {
> -				if (rss->queue[i] == rss_info->queue[j])
> +		for (i = 0; i < rss->queue_num; i++) {
> +			for (j = 0; j < rss_info->conf.queue_num; j++) {
> +				if (rss->queue[i] == rss_info->conf.queue[j])
>  					break;
>  			}
> -			if (j == rss_info->num) {
> +			if (j == rss_info->conf.queue_num) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4250,7 +4250,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
>  		}
> 
> -		for (i = 0; i < rss->num - 1; i++) {
> +		for (i = 0; i < rss->queue_num - 1; i++) {
>  			if (rss->queue[i + 1] != rss->queue[i] + 1) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4265,8 +4265,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	for (n = 0; n < conf_info->queue_region_number; n++) {
>  		if (conf_info->region[n].user_priority_num ||
>  				conf_info->region[n].flowtype_num) {
> -			if (!((rte_is_power_of_2(rss->num)) &&
> -					rss->num <= 64)) {
> +			if (!((rte_is_power_of_2(rss->queue_num)) &&
> +					rss->queue_num <= 64)) {
>  				rte_flow_error_set(error, EINVAL,
>  					RTE_FLOW_ERROR_TYPE_ACTION,
>  					act,
> @@ -4294,7 +4294,8 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  			}
> 
>  			for (i = 0; i < info->queue_region_number; i++) {
> -				if (info->region[i].queue_num == rss->num
> &&
> +				if (info->region[i].queue_num ==
> +				    rss->queue_num &&
>  					info->region[i].queue_start_index ==
>  						rss->queue[0])
>  					break;
> @@ -4310,7 +4311,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  				}
> 
>  				info->region[i].queue_num =
> -					rss->num;
> +					rss->queue_num;
>  				info->region[i].queue_start_index =
>  					rss->queue[0];
>  				info->region[i].region_id =
> @@ -4356,7 +4357,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	if (rss_config->queue_region_conf)
>  		return 0;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -4364,7 +4365,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -4375,15 +4376,19 @@ i40e_flow_parse_rss_action(struct rte_eth_dev
> *dev,
>  	}
> 
>  	/* Parse RSS related parameters from configuration */
> -	if (rss->rss_conf)
> -		rss_config->rss_conf = *rss->rss_conf;
> -	else
> -		rss_config->rss_conf.rss_hf =
> -			pf->adapter->flow_types_mask;
> +	if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key too large");
> +	if (rss->queue_num > RTE_DIM(rss_config->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (i40e_rss_conf_init(rss_config, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_config->queue[n] = rss->queue[n];
> -	rss_config->num = rss->num;
>  	index++;
> 
>  	/* check if the next not void action is END */
> @@ -4903,7 +4908,7 @@ i40e_flow_flush_rss_filter(struct rte_eth_dev *dev)
> 
>  	ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
> 
> -	if (rss_info->num)
> +	if (rss_info->conf.queue_num)
>  		ret = i40e_config_rss_filter(pf, rss_info, FALSE);
>  	return ret;
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 92434809c..c00bdae3d 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -100,8 +100,6 @@
> 
>  #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) /
> sizeof(hw_stats->qprc[0]))
> 
> -#define IXGBE_HKEY_MAX_INDEX 10
> -
>  /* Additional timesync values. */
>  #define NSEC_PER_SEC             1000000000L
>  #define IXGBE_INCVAL_10GB        0x66666666
> @@ -8371,7 +8369,7 @@ ixgbe_rss_filter_restore(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev,
>  			&filter_info->rss_info, TRUE);
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h
> b/drivers/net/ixgbe/ixgbe_ethdev.h
> index 655077700..9491b03f4 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -4,6 +4,9 @@
> 
>  #ifndef _IXGBE_ETHDEV_H_
>  #define _IXGBE_ETHDEV_H_
> +
> +#include <stdint.h>
> +
>  #include "base/ixgbe_type.h"
>  #include "base/ixgbe_dcb.h"
>  #include "base/ixgbe_dcb_82599.h"
> @@ -12,6 +15,7 @@
>  #ifdef RTE_LIBRTE_SECURITY
>  #include "ixgbe_ipsec.h"
>  #endif
> +#include <rte_flow.h>
>  #include <rte_time.h>
>  #include <rte_hash.h>
>  #include <rte_pci.h>
> @@ -39,6 +43,7 @@
>  #define IXGBE_EXTENDED_VLAN	  (uint32_t)(1 << 26) /* EXTENDED
> VLAN ENABLE */
>  #define IXGBE_VFTA_SIZE 128
>  #define IXGBE_VLAN_TAG_SIZE 4
> +#define IXGBE_HKEY_MAX_INDEX 10
>  #define IXGBE_MAX_RX_QUEUE_NUM	128
>  #define IXGBE_MAX_INTR_QUEUE_NUM	15
>  #define IXGBE_VMDQ_DCB_NB_QUEUES     IXGBE_MAX_RX_QUEUE_NUM
> @@ -196,8 +201,8 @@ struct ixgbe_hw_fdir_info {
>  };
> 
>  struct ixgbe_rte_flow_rss_conf {
> -	struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss conf; /**< RSS parameters. */
> +	uint8_t key[IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash
> key. */
>  	uint16_t queue[IXGBE_MAX_RX_QUEUE_NUM]; /**< Queues
> indices to use. */
>  };
> 
> @@ -696,6 +701,10 @@ void ixgbe_tm_conf_init(struct rte_eth_dev *dev);
>  void ixgbe_tm_conf_uninit(struct rte_eth_dev *dev);
>  int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t
> queue_idx,
>  			       uint16_t tx_rate);
> +int ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +			const struct rte_flow_action_rss *in);
> +int ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +			  const struct rte_flow_action_rss *with);
>  int ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add);
> 
> diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
> index abdeac28b..4e31c7c56 100644
> --- a/drivers/net/ixgbe/ixgbe_flow.c
> +++ b/drivers/net/ixgbe/ixgbe_flow.c
> @@ -2761,7 +2761,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
> 
>  	rss = (const struct rte_flow_action_rss *)act->conf;
> 
> -	if (!rss || !rss->num) {
> +	if (!rss || !rss->queue_num) {
>  		rte_flow_error_set(error, EINVAL,
>  				RTE_FLOW_ERROR_TYPE_ACTION,
>  				act,
> @@ -2769,7 +2769,7 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  		return -rte_errno;
>  	}
> 
> -	for (n = 0; n < rss->num; n++) {
> +	for (n = 0; n < rss->queue_num; n++) {
>  		if (rss->queue[n] >= dev->data->nb_rx_queues) {
>  			rte_flow_error_set(error, EINVAL,
>  				   RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -2778,14 +2778,19 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
>  			return -rte_errno;
>  		}
>  	}
> -	if (rss->rss_conf)
> -		rss_conf->rss_conf = *rss->rss_conf;
> -	else
> -		rss_conf->rss_conf.rss_hf = IXGBE_RSS_OFFLOAD_ALL;
> 
> -	for (n = 0; n < rss->num; ++n)
> -		rss_conf->queue[n] = rss->queue[n];
> -	rss_conf->num = rss->num;
> +	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS hash key must be exactly 40 bytes");
> +	if (rss->queue_num > RTE_DIM(rss_conf->queue))
> +		return rte_flow_error_set
> +			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "too many queues for RSS context");
> +	if (ixgbe_rss_conf_init(rss_conf, rss))
> +		return rte_flow_error_set
> +			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
> act,
> +			 "RSS context initialization failure");
> 
>  	/* check if the next not void item is END */
>  	act = next_no_void_action(actions, act);
> @@ -2834,7 +2839,7 @@ ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
>  }
> 
> @@ -3153,9 +3158,8 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
>  				PMD_DRV_LOG(ERR, "failed to allocate
> memory");
>  				goto out;
>  			}
> -			rte_memcpy(&rss_filter_ptr->filter_info,
> -				&rss_conf,
> -				sizeof(struct ixgbe_rte_flow_rss_conf));
> +			ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
> +					    &rss_conf.conf);
>  			TAILQ_INSERT_TAIL(&filter_rss_list,
>  				rss_filter_ptr, entries);
>  			flow->rule = rss_filter_ptr;
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index aed3f5a9a..9fbd7dbd7 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -5676,6 +5676,36 @@ ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev)
>  }
> 
>  int
> +ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out,
> +		    const struct rte_flow_action_rss *in)
> +{
> +	if (in->key_len > RTE_DIM(out->key) ||
> +	    in->queue_num > RTE_DIM(out->queue))
> +		return -EINVAL;
> +	out->conf = (struct rte_flow_action_rss){
> +		.types = in->types,
> +		.key_len = in->key_len,
> +		.queue_num = in->queue_num,
> +		.key = memcpy(out->key, in->key, in->key_len),
> +		.queue = memcpy(out->queue, in->queue,
> +				sizeof(*in->queue) * in->queue_num),
> +	};
> +	return 0;
> +}
> +
> +int
> +ixgbe_action_rss_same(const struct rte_flow_action_rss *comp,
> +		      const struct rte_flow_action_rss *with)
> +{
> +	return (comp->types == with->types &&
> +		comp->key_len == with->key_len &&
> +		comp->queue_num == with->queue_num &&
> +		!memcmp(comp->key, with->key, with->key_len) &&
> +		!memcmp(comp->queue, with->queue,
> +			sizeof(*with->queue) * with->queue_num));
> +}
> +
> +int
>  ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		struct ixgbe_rte_flow_rss_conf *conf, bool add)
>  {
> @@ -5685,7 +5715,12 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	uint16_t j;
>  	uint16_t sp_reta_size;
>  	uint32_t reta_reg;
> -	struct rte_eth_rss_conf rss_conf = conf->rss_conf;
> +	struct rte_eth_rss_conf rss_conf = {
> +		.rss_key = conf->conf.key_len ?
> +			(void *)(uintptr_t)conf->conf.key : NULL,
> +		.rss_key_len = conf->conf.key_len,
> +		.rss_hf = conf->conf.types,
> +	};
>  	struct ixgbe_filter_info *filter_info =
>  		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data-
> >dev_private);
> 
> @@ -5695,8 +5730,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	sp_reta_size = ixgbe_reta_size_get(hw->mac.type);
> 
>  	if (!add) {
> -		if (memcmp(conf, &filter_info->rss_info,
> -			sizeof(struct ixgbe_rte_flow_rss_conf)) == 0) {
> +		if (ixgbe_action_rss_same(&filter_info->rss_info.conf,
> +					  &conf->conf)) {
>  			ixgbe_rss_disable(dev);
>  			memset(&filter_info->rss_info, 0,
>  				sizeof(struct ixgbe_rte_flow_rss_conf));
> @@ -5705,7 +5740,7 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		return -EINVAL;
>  	}
> 
> -	if (filter_info->rss_info.num)
> +	if (filter_info->rss_info.conf.queue_num)
>  		return -EINVAL;
>  	/* Fill in redirection table
>  	 * The byte-swap is needed because NIC registers are in
> @@ -5715,9 +5750,9 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  	for (i = 0, j = 0; i < sp_reta_size; i++, j++) {
>  		reta_reg = ixgbe_reta_reg_get(hw->mac.type, i);
> 
> -		if (j == conf->num)
> +		if (j == conf->conf.queue_num)
>  			j = 0;
> -		reta = (reta << 8) | conf->queue[j];
> +		reta = (reta << 8) | conf->conf.queue[j];
>  		if ((i & 3) == 3)
>  			IXGBE_WRITE_REG(hw, reta_reg,
>  					rte_bswap32(reta));
> @@ -5734,8 +5769,8 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
>  		rss_conf.rss_key = rss_intel_key; /* Default hash key */
>  	ixgbe_hw_rss_hash_set(hw, &rss_conf);
> 
> -	rte_memcpy(&filter_info->rss_info,
> -		conf, sizeof(struct ixgbe_rte_flow_rss_conf));
> +	if (ixgbe_rss_conf_init(&filter_info->rss_info, &conf->conf))
> +		return -EINVAL;
> 
>  	return 0;
>  }
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 937074a4f..3dd72dbf5 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -571,7 +571,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct
> rte_pci_device *pci_dev)
>  			     " for UDP RSS and inner VXLAN RSS");
>  			/* Fake support for all possible RSS hash fields. */
>  			priv->hw_rss_sup = ~UINT64_C(0);
> -			priv->hw_rss_sup = mlx4_conv_rss_hf(priv, -1);
> +			priv->hw_rss_sup = mlx4_conv_rss_types(priv, -1);
>  			/* Filter out known unsupported fields. */
>  			priv->hw_rss_sup &=
>  				~(uint64_t)(IBV_RX_HASH_SRC_PORT_UDP |
> diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
> index 8feb6ae31..dd86e4ce7 100644
> --- a/drivers/net/mlx4/mlx4_flow.c
> +++ b/drivers/net/mlx4/mlx4_flow.c
> @@ -76,22 +76,22 @@ struct mlx4_drop {
>  };
> 
>  /**
> - * Convert DPDK RSS hash fields to their Verbs equivalent.
> + * Convert DPDK RSS hash types to their Verbs equivalent.
>   *
> - * This function returns the supported (default) set when @p rss_hf has
> + * This function returns the supported (default) set when @p types has
>   * special value (uint64_t)-1.
>   *
>   * @param priv
>   *   Pointer to private structure.
> - * @param rss_hf
> - *   Hash fields in DPDK format (see struct rte_eth_rss_conf).
> + * @param types
> + *   Hash types in DPDK format (see struct rte_eth_rss_conf).
>   *
>   * @return
>   *   A valid Verbs RSS hash fields mask for mlx4 on success, (uint64_t)-1
>   *   otherwise and rte_errno is set.
>   */
>  uint64_t
> -mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
> +mlx4_conv_rss_types(struct priv *priv, uint64_t types)
>  {
>  	enum { IPV4, IPV6, TCP, UDP, };
>  	const uint64_t in[] = {
> @@ -126,17 +126,17 @@ mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
>  	unsigned int i;
> 
>  	for (i = 0; i != RTE_DIM(in); ++i)
> -		if (rss_hf & in[i]) {
> -			seen |= rss_hf & in[i];
> +		if (types & in[i]) {
> +			seen |= types & in[i];
>  			conv |= out[i];
>  		}
>  	if ((conv & priv->hw_rss_sup) == conv) {
> -		if (rss_hf == (uint64_t)-1) {
> +		if (types == (uint64_t)-1) {
>  			/* Include inner RSS by default if supported. */
>  			conv |= priv->hw_rss_sup & IBV_RX_HASH_INNER;
>  			return conv;
>  		}
> -		if (!(rss_hf & ~seen))
> +		if (!(types & ~seen))
>  			return conv;
>  	}
>  	rte_errno = ENOTSUP;
> @@ -717,7 +717,8 @@ mlx4_flow_prepare(struct priv *priv,
>  		switch (action->type) {
>  			const struct rte_flow_action_queue *queue;
>  			const struct rte_flow_action_rss *rss;
> -			const struct rte_eth_rss_conf *rss_conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint64_t fields;
>  			unsigned int i;
> 
> @@ -747,58 +748,56 @@ mlx4_flow_prepare(struct priv *priv,
>  				break;
>  			rss = action->conf;
>  			/* Default RSS configuration if none is provided. */
> -			rss_conf =
> -				rss->rss_conf ?
> -				rss->rss_conf :
> -				&(struct rte_eth_rss_conf){
> -					.rss_key =
> mlx4_rss_hash_key_default,
> -					.rss_key_len =
> MLX4_RSS_HASH_KEY_SIZE,
> -					.rss_hf = -1,
> -				};
> +			if (rss->key_len) {
> +				rss_key = rss->key;
> +				rss_key_len = rss->key_len;
> +			} else {
> +				rss_key = mlx4_rss_hash_key_default;
> +				rss_key_len = MLX4_RSS_HASH_KEY_SIZE;
> +			}
>  			/* Sanity checks. */
> -			for (i = 0; i < rss->num; ++i)
> +			for (i = 0; i < rss->queue_num; ++i)
>  				if (rss->queue[i] >=
>  				    priv->dev->data->nb_rx_queues)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "queue index target beyond number
> of"
>  					" configured Rx queues";
>  				goto exit_action_not_supported;
>  			}
> -			if (!rte_is_power_of_2(rss->num)) {
> +			if (!rte_is_power_of_2(rss->queue_num)) {
>  				msg = "for RSS, mlx4 requires the number of"
>  					" queues to be a power of two";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss_conf->rss_key_len !=
> -			    sizeof(flow->rss->key)) {
> +			if (rss_key_len != sizeof(flow->rss->key)) {
>  				msg = "mlx4 supports exactly one RSS hash
> key"
>  					" length: "
> 
> 	MLX4_STR_EXPAND(MLX4_RSS_HASH_KEY_SIZE);
>  				goto exit_action_not_supported;
>  			}
> -			for (i = 1; i < rss->num; ++i)
> +			for (i = 1; i < rss->queue_num; ++i)
>  				if (rss->queue[i] - rss->queue[i - 1] != 1)
>  					break;
> -			if (i != rss->num) {
> +			if (i != rss->queue_num) {
>  				msg = "mlx4 requires RSS contexts to use"
>  					" consecutive queue indices only";
>  				goto exit_action_not_supported;
>  			}
> -			if (rss->queue[0] % rss->num) {
> +			if (rss->queue[0] % rss->queue_num) {
>  				msg = "mlx4 requires the first queue of a
> RSS"
>  					" context to be aligned on a multiple"
>  					" of the context size";
>  				goto exit_action_not_supported;
>  			}
>  			rte_errno = 0;
> -			fields = mlx4_conv_rss_hf(priv, rss_conf->rss_hf);
> +			fields = mlx4_conv_rss_types(priv, rss->types);
>  			if (fields == (uint64_t)-1 && rte_errno) {
>  				msg = "unsupported RSS hash type
> requested";
>  				goto exit_action_not_supported;
>  			}
>  			flow->rss = mlx4_rss_get
> -				(priv, fields, rss_conf->rss_key, rss->num,
> +				(priv, fields, rss_key, rss->queue_num,
>  				 rss->queue);
>  			if (!flow->rss) {
>  				msg = "either invalid parameters or not
> enough"
> @@ -1284,8 +1283,10 @@ mlx4_flow_internal(struct priv *priv, struct
> rte_flow_error *error)
>  		rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1;
>  	uint16_t queue[queues];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = NULL, /* Rely on default fallback settings. */
> -		.num = queues,
> +		.types = -1,
> +		.key_len = MLX4_RSS_HASH_KEY_SIZE,
> +		.queue_num = queues,
> +		.key = mlx4_rss_hash_key_default,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h
> index 4e3889e67..7b83d74b0 100644
> --- a/drivers/net/mlx4/mlx4_flow.h
> +++ b/drivers/net/mlx4/mlx4_flow.h
> @@ -47,7 +47,7 @@ struct rte_flow {
> 
>  /* mlx4_flow.c */
> 
> -uint64_t mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf);
> +uint64_t mlx4_conv_rss_types(struct priv *priv, uint64_t rss_hf);
>  int mlx4_flow_sync(struct priv *priv, struct rte_flow_error *error);
>  void mlx4_flow_clean(struct priv *priv);
>  int mlx4_filter_ctrl(struct rte_eth_dev *dev,
> diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
> index a7acc047b..65f099423 100644
> --- a/drivers/net/mlx4/mlx4_rxq.c
> +++ b/drivers/net/mlx4/mlx4_rxq.c
> @@ -88,7 +88,7 @@
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE] = {
>   */
>  struct mlx4_rss *
>  mlx4_rss_get(struct priv *priv, uint64_t fields,
> -	     uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +	     const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  	     uint16_t queues, const uint16_t queue_id[])
>  {
>  	struct mlx4_rss *rss;
> diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
> index b1af86110..2dfee957f 100644
> --- a/drivers/net/mlx4/mlx4_rxtx.h
> +++ b/drivers/net/mlx4/mlx4_rxtx.h
> @@ -127,7 +127,7 @@ uint8_t
> mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE];
>  int mlx4_rss_init(struct priv *priv);
>  void mlx4_rss_deinit(struct priv *priv);
>  struct mlx4_rss *mlx4_rss_get(struct priv *priv, uint64_t fields,
> -			      uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
> +			      const uint8_t key[MLX4_RSS_HASH_KEY_SIZE],
>  			      uint16_t queues, const uint16_t queue_id[]);
>  void mlx4_rss_put(struct mlx4_rss *rss);
>  int mlx4_rss_attach(struct mlx4_rss *rss);
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 0c89bff45..af8853e09 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -214,9 +214,8 @@ struct rte_flow {
>  	TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure.
> */
>  	uint32_t mark:1; /**< Set if the flow is marked. */
>  	uint32_t drop:1; /**< Drop queue. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t (*queues)[]; /**< Queues indexes to use. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	struct ibv_counter_set *cs; /**< Holds the counters for the rule. */
>  	struct mlx5_flow_counter_stats counter_stats;/**<The counter
> stats. */
> @@ -406,9 +405,8 @@ struct mlx5_flow_parse {
>  	uint32_t mark:1; /**< Mark is present in the flow. */
>  	uint32_t count:1; /**< Count is present in the flow. */
>  	uint32_t mark_id; /**< Mark identifier. */
> +	struct rte_flow_action_rss rss_conf; /**< RSS configuration */
>  	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queues
> indexes to use. */
> -	uint16_t queues_n; /**< Number of entries in queue[]. */
> -	struct rte_eth_rss_conf rss_conf; /**< RSS configuration */
>  	uint8_t rss_key[40]; /**< copy of the RSS key. */
>  	enum hash_rxq_type layer; /**< Last pattern layer detected. */
>  	struct ibv_counter_set *cs; /**< Holds the counter set for the rule */
> @@ -540,47 +538,6 @@ mlx5_flow_item_validate(const struct
> rte_flow_item *item,
>  }
> 
>  /**
> - * Copy the RSS configuration from the user ones, of the rss_conf is null,
> - * uses the driver one.
> - *
> - * @param parser
> - *   Internal parser structure.
> - * @param rss_conf
> - *   User RSS configuration to save.
> - *
> - * @return
> - *   0 on success, a negative errno value otherwise and rte_errno is set.
> - */
> -static int
> -mlx5_flow_convert_rss_conf(struct mlx5_flow_parse *parser,
> -			   const struct rte_eth_rss_conf *rss_conf)
> -{
> -	/*
> -	 * This function is also called at the beginning of
> -	 * mlx5_flow_convert_actions() to initialize the parser with the
> -	 * device default RSS configuration.
> -	 */
> -	if (rss_conf) {
> -		if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len != 40) {
> -			rte_errno = EINVAL;
> -			return -rte_errno;
> -		}
> -		if (rss_conf->rss_key_len && rss_conf->rss_key) {
> -			parser->rss_conf.rss_key_len = rss_conf-
> >rss_key_len;
> -			memcpy(parser->rss_key, rss_conf->rss_key,
> -			       rss_conf->rss_key_len);
> -			parser->rss_conf.rss_key = parser->rss_key;
> -		}
> -		parser->rss_conf.rss_hf = rss_conf->rss_hf;
> -	}
> -	return 0;
> -}
> -
> -/**
>   * Extract attribute to the parser.
>   *
>   * @param[in] attr
> @@ -650,17 +607,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  	enum { FATE = 1, MARK = 2, COUNT = 4, };
>  	uint32_t overlap = 0;
>  	struct priv *priv = dev->data->dev_private;
> -	int ret;
> 
> -	/*
> -	 * Add default RSS configuration necessary for Verbs to create QP
> even
> -	 * if no RSS is necessary.
> -	 */
> -	ret = mlx5_flow_convert_rss_conf(parser,
> -					 (const struct rte_eth_rss_conf *)
> -					 &priv->rss_conf);
> -	if (ret)
> -		return ret;
>  	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
>  		if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
>  			continue;
> @@ -679,25 +626,53 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  			overlap |= FATE;
>  			if (!queue || (queue->index > (priv->rxqs_n - 1)))
>  				goto exit_action_not_supported;
> -			parser->queues_n = 1;
>  			parser->queues[0] = queue->index;
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.queue_num = 1,
> +				.queue = parser->queues,
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
>  			const struct rte_flow_action_rss *rss =
>  				(const struct rte_flow_action_rss *)
>  				actions->conf;
> +			const uint8_t *rss_key;
> +			uint32_t rss_key_len;
>  			uint16_t n;
> 
>  			if (overlap & FATE)
>  				goto exit_action_overlap;
>  			overlap |= FATE;
> -			if (!rss || !rss->num) {
> +			if (rss->types & MLX5_RSS_HF_MASK) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "unsupported RSS type"
> +						   " requested");
> +				return -rte_errno;
> +			}
> +			if (rss->key_len) {
> +				rss_key_len = rss->key_len;
> +				rss_key = rss->key;
> +			} else {
> +				rss_key_len = rss_hash_default_key_len;
> +				rss_key = rss_hash_default_key;
> +			}
> +			if (rss_key_len != RTE_DIM(parser->rss_key)) {
> +				rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						   actions,
> +						   "RSS hash key must be"
> +						   " exactly 40 bytes long");
> +				return -rte_errno;
> +			}
> +			if (!rss->queue_num) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
>  						   "no valid queues");
>  				return -rte_errno;
>  			}
> -			if (rss->num > RTE_DIM(parser->queues)) {
> +			if (rss->queue_num > RTE_DIM(parser->queues)) {
>  				rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
>  						   actions,
> @@ -705,7 +680,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  						   " context");
>  				return -rte_errno;
>  			}
> -			for (n = 0; n < rss->num; ++n) {
> +			for (n = 0; n < rss->queue_num; ++n) {
>  				if (rss->queue[n] >= priv->rxqs_n) {
>  					rte_flow_error_set(error, EINVAL,
> 
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -715,16 +690,16 @@ mlx5_flow_convert_actions(struct rte_eth_dev
> *dev,
>  					return -rte_errno;
>  				}
>  			}
> -			for (n = 0; n < rss->num; ++n)
> -				parser->queues[n] = rss->queue[n];
> -			parser->queues_n = rss->num;
> -			if (mlx5_flow_convert_rss_conf(parser, rss-
> >rss_conf)) {
> -				rte_flow_error_set(error, EINVAL,
> -
> RTE_FLOW_ERROR_TYPE_ACTION,
> -						   actions,
> -						   "wrong RSS configuration");
> -				return -rte_errno;
> -			}
> +			parser->rss_conf = (struct rte_flow_action_rss){
> +				.types = rss->types,
> +				.key_len = rss_key_len,
> +				.queue_num = rss->queue_num,
> +				.key = memcpy(parser->rss_key, rss_key,
> +					      sizeof(*rss_key) * rss_key_len),
> +				.queue = memcpy(parser->queues, rss-
> >queue,
> +						sizeof(*rss->queue) *
> +						rss->queue_num),
> +			};
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK)
> {
>  			const struct rte_flow_action_mark *mark =
>  				(const struct rte_flow_action_mark *)
> @@ -769,7 +744,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev,
>  		parser->drop = 1;
>  	if (parser->drop && parser->mark)
>  		parser->mark = 0;
> -	if (!parser->queues_n && !parser->drop) {
> +	if (!parser->rss_conf.queue_num && !parser->drop) {
>  		rte_flow_error_set(error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_HANDLE,
>  				   NULL, "no valid action");
>  		return -rte_errno;
> @@ -951,7 +926,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	unsigned int i;
> 
>  	/* Remove any other flow not matching the pattern. */
> -	if (parser->queues_n == 1 && !parser->rss_conf.rss_hf) {
> +	if (parser->rss_conf.queue_num == 1 && !parser->rss_conf.types) {
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			if (i == HASH_RXQ_ETH)
>  				continue;
> @@ -979,7 +954,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  	}
>  	/* Remove impossible flow according to the RSS configuration. */
>  	if (hash_rxq_init[parser->layer].dpdk_rss_hf &
> -	    parser->rss_conf.rss_hf) {
> +	    parser->rss_conf.types) {
>  		/* Remove any other flow. */
>  		for (i = hmin; i != (hmax + 1); ++i) {
>  			if ((i == parser->layer) ||
> @@ -990,7 +965,7 @@ mlx5_flow_convert_finalise(struct mlx5_flow_parse
> *parser)
>  		}
>  	} else  if (!parser->queue[ip].ibv_attr) {
>  		/* no RSS possible with the current configuration. */
> -		parser->queues_n = 1;
> +		parser->rss_conf.queue_num = 1;
>  		return;
>  	}
>  fill:
> @@ -1119,7 +1094,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev,
>  		for (i = 0; i != hash_rxq_init_n; ++i) {
>  			unsigned int offset;
> 
> -			if (!(parser->rss_conf.rss_hf &
> +			if (!(parser->rss_conf.types &
>  			      hash_rxq_init[i].dpdk_rss_hf) &&
>  			    (i != HASH_RXQ_ETH))
>  				continue;
> @@ -1787,20 +1762,20 @@ mlx5_flow_create_action_queue_rss(struct
> rte_eth_dev *dev,
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_get(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (flow->frxq[i].hrxq)
>  			continue;
>  		flow->frxq[i].hrxq =
>  			mlx5_hrxq_new(dev,
> -				      parser->rss_conf.rss_key,
> -				      parser->rss_conf.rss_key_len,
> +				      parser->rss_conf.key,
> +				      parser->rss_conf.key_len,
>  				      hash_fields,
> -				      parser->queues,
> -				      parser->queues_n);
> +				      parser->rss_conf.queue,
> +				      parser->rss_conf.queue_num);
>  		if (!flow->frxq[i].hrxq) {
>  			return rte_flow_error_set(error, ENOMEM,
> 
> RTE_FLOW_ERROR_TYPE_HANDLE,
> @@ -1871,9 +1846,9 @@ mlx5_flow_create_action_queue(struct
> rte_eth_dev *dev,
>  				   NULL, "internal error in flow creation");
>  		goto error;
>  	}
> -	for (i = 0; i != parser->queues_n; ++i) {
> +	for (i = 0; i != parser->rss_conf.queue_num; ++i) {
>  		struct mlx5_rxq_data *q =
> -			(*priv->rxqs)[parser->queues[i]];
> +			(*priv->rxqs)[parser->rss_conf.queue[i]];
> 
>  		q->mark |= parser->mark;
>  	}
> @@ -1937,7 +1912,8 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  	if (ret)
>  		goto exit;
>  	flow = rte_calloc(__func__, 1,
> -			  sizeof(*flow) + parser.queues_n * sizeof(uint16_t),
> +			  sizeof(*flow) +
> +			  parser.rss_conf.queue_num * sizeof(uint16_t),
>  			  0);
>  	if (!flow) {
>  		rte_flow_error_set(error, ENOMEM,
> @@ -1946,15 +1922,20 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,
>  				   "cannot allocate flow memory");
>  		return NULL;
>  	}
> -	/* Copy queues configuration. */
> +	/* Copy configuration. */
>  	flow->queues = (uint16_t (*)[])(flow + 1);
> -	memcpy(flow->queues, parser.queues, parser.queues_n *
> sizeof(uint16_t));
> -	flow->queues_n = parser.queues_n;
> +	flow->rss_conf = (struct rte_flow_action_rss){
> +		.types = parser.rss_conf.types,
> +		.key_len = parser.rss_conf.key_len,
> +		.queue_num = parser.rss_conf.queue_num,
> +		.key = memcpy(flow->rss_key, parser.rss_conf.key,
> +			      sizeof(*parser.rss_conf.key) *
> +			      parser.rss_conf.key_len),
> +		.queue = memcpy(flow->queues, parser.rss_conf.queue,
> +				sizeof(*parser.rss_conf.queue) *
> +				parser.rss_conf.queue_num),
> +	};
>  	flow->mark = parser.mark;
> -	/* Copy RSS configuration. */
> -	flow->rss_conf = parser.rss_conf;
> -	flow->rss_conf.rss_key = flow->rss_key;
> -	memcpy(flow->rss_key, parser.rss_key,
> parser.rss_conf.rss_key_len);
>  	/* finalise the flow. */
>  	if (parser.drop)
>  		ret = mlx5_flow_create_action_queue_drop(dev, &parser,
> flow,
> @@ -2034,7 +2015,7 @@ mlx5_flow_list_destroy(struct rte_eth_dev *dev,
> struct mlx5_flows *list,
> 
>  	if (flow->drop || !flow->mark)
>  		goto free;
> -	for (i = 0; i != flow->queues_n; ++i) {
> +	for (i = 0; i != flow->rss_conf.queue_num; ++i) {
>  		struct rte_flow *tmp;
>  		int mark = 0;
> 
> @@ -2344,19 +2325,19 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  			if (!flow->frxq[i].ibv_attr)
>  				continue;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_get(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_get(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (flow->frxq[i].hrxq)
>  				goto flow_create;
>  			flow->frxq[i].hrxq =
> -				mlx5_hrxq_new(dev, flow->rss_conf.rss_key,
> -					      flow->rss_conf.rss_key_len,
> +				mlx5_hrxq_new(dev, flow->rss_conf.key,
> +					      flow->rss_conf.key_len,
>  					      hash_rxq_init[i].hash_fields,
> -					      (*flow->queues),
> -					      flow->queues_n);
> +					      flow->rss_conf.queue,
> +					      flow->rss_conf.queue_num);
>  			if (!flow->frxq[i].hrxq) {
>  				DRV_LOG(DEBUG,
>  					"port %u flow %p cannot be applied",
> @@ -2380,8 +2361,8 @@ mlx5_flow_start(struct rte_eth_dev *dev, struct
> mlx5_flows *list)
>  		}
>  		if (!flow->mark)
>  			continue;
> -		for (i = 0; i != flow->queues_n; ++i)
> -			(*priv->rxqs)[(*flow->queues)[i]]->mark = 1;
> +		for (i = 0; i != flow->rss_conf.queue_num; ++i)
> +			(*priv->rxqs)[flow->rss_conf.queue[i]]->mark = 1;
>  	}
>  	return 0;
>  }
> @@ -2458,8 +2439,10 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
>  	};
>  	uint16_t queue[priv->reta_idx_n];
>  	struct rte_flow_action_rss action_rss = {
> -		.rss_conf = &priv->rss_conf,
> -		.num = priv->reta_idx_n,
> +		.types = priv->rss_conf.rss_hf,
> +		.key_len = priv->rss_conf.rss_key_len,
> +		.queue_num = priv->reta_idx_n,
> +		.key = priv->rss_conf.rss_key,
>  		.queue = queue,
>  	};
>  	struct rte_flow_action actions[] = {
> diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
> index eda3ba3d5..d2b25e8e8 100644
> --- a/drivers/net/mlx5/mlx5_rxq.c
> +++ b/drivers/net/mlx5/mlx5_rxq.c
> @@ -1218,8 +1218,8 @@ mlx5_rxq_verify(struct rte_eth_dev *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_new(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1286,8 +1286,8 @@ mlx5_ind_table_ibv_new(struct rte_eth_dev *dev,
> uint16_t queues[],
>   *   An indirection table if found.
>   */
>  struct mlx5_ind_table_ibv *
> -mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, uint16_t queues[],
> -		       uint16_t queues_n)
> +mlx5_ind_table_ibv_get(struct rte_eth_dev *dev, const uint16_t *queues,
> +		       uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_ind_table_ibv *ind_tbl;
> @@ -1391,8 +1391,10 @@ mlx5_ind_table_ibv_verify(struct rte_eth_dev
> *dev)
>   *   The Verbs object initialised, NULL otherwise and rte_errno is set.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_new(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> @@ -1408,6 +1410,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  		rte_errno = ENOMEM;
>  		return NULL;
>  	}
> +	if (!rss_key_len) {
> +		rss_key_len = rss_hash_default_key_len;
> +		rss_key = rss_hash_default_key;
> +	}
>  	qp = mlx5_glue->create_qp_ex
>  		(priv->ctx,
>  		 &(struct ibv_qp_init_attr_ex){
> @@ -1419,7 +1425,7 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>  			.rx_hash_conf = (struct ibv_rx_hash_conf){
>  				.rx_hash_function =
> IBV_RX_HASH_FUNC_TOEPLITZ,
>  				.rx_hash_key_len = rss_key_len,
> -				.rx_hash_key = rss_key,
> +				.rx_hash_key = (void *)(uintptr_t)rss_key,
>  				.rx_hash_fields_mask = hash_fields,
>  			},
>  			.rwq_ind_tbl = ind_tbl->ind_table,
> @@ -1469,8 +1475,10 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key, uint8_t rss_key_len,
>   *   An hash Rx queue on success.
>   */
>  struct mlx5_hrxq *
> -mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t *rss_key, uint8_t
> rss_key_len,
> -	      uint64_t hash_fields, uint16_t queues[], uint16_t queues_n)
> +mlx5_hrxq_get(struct rte_eth_dev *dev,
> +	      const uint8_t *rss_key, uint32_t rss_key_len,
> +	      uint64_t hash_fields,
> +	      const uint16_t *queues, uint32_t queues_n)
>  {
>  	struct priv *priv = dev->data->dev_private;
>  	struct mlx5_hrxq *hrxq;
> diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
> index 14d4418d9..c3a1ae213 100644
> --- a/drivers/net/mlx5/mlx5_rxtx.h
> +++ b/drivers/net/mlx5/mlx5_rxtx.h
> @@ -134,7 +134,7 @@ struct mlx5_ind_table_ibv {
>  	LIST_ENTRY(mlx5_ind_table_ibv) next; /* Pointer to the next
> element. */
>  	rte_atomic32_t refcnt; /* Reference counter. */
>  	struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
> -	uint16_t queues_n; /**< Number of queues in the list. */
> +	uint32_t queues_n; /**< Number of queues in the list. */
>  	uint16_t queues[]; /**< Queue list. */
>  };
> 
> @@ -145,7 +145,7 @@ struct mlx5_hrxq {
>  	struct mlx5_ind_table_ibv *ind_table; /* Indirection table. */
>  	struct ibv_qp *qp; /* Verbs queue pair. */
>  	uint64_t hash_fields; /* Verbs Hash fields. */
> -	uint8_t rss_key_len; /* Hash key length in bytes. */
> +	uint32_t rss_key_len; /* Hash key length in bytes. */
>  	uint8_t rss_key[]; /* Hash key. */
>  };
> 
> @@ -238,20 +238,22 @@ int mlx5_rxq_releasable(struct rte_eth_dev *dev,
> uint16_t idx);
>  int mlx5_rxq_verify(struct rte_eth_dev *dev);
>  int rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_new(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  struct mlx5_ind_table_ibv *mlx5_ind_table_ibv_get(struct rte_eth_dev
> *dev,
> -						  uint16_t queues[],
> -						  uint16_t queues_n);
> +						  const uint16_t *queues,
> +						  uint32_t queues_n);
>  int mlx5_ind_table_ibv_release(struct rte_eth_dev *dev,
>  			       struct mlx5_ind_table_ibv *ind_tbl);
>  int mlx5_ind_table_ibv_verify(struct rte_eth_dev *dev);
> -struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> -struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev, uint8_t
> *rss_key,
> -				uint8_t rss_key_len, uint64_t hash_fields,
> -				uint16_t queues[], uint16_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_new(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
> +struct mlx5_hrxq *mlx5_hrxq_get(struct rte_eth_dev *dev,
> +				const uint8_t *rss_key, uint32_t rss_key_len,
> +				uint64_t hash_fields,
> +				const uint16_t *queues, uint32_t queues_n);
>  int mlx5_hrxq_release(struct rte_eth_dev *dev, struct mlx5_hrxq *hxrq);
>  int mlx5_hrxq_ibv_verify(struct rte_eth_dev *dev);
>  uint64_t mlx5_get_rx_port_offloads(void);
> diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
> index 056405515..1a2c0299c 100644
> --- a/drivers/net/sfc/sfc_flow.c
> +++ b/drivers/net/sfc/sfc_flow.c
> @@ -1234,13 +1234,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	struct sfc_rxq *rxq;
>  	unsigned int rxq_hw_index_min;
>  	unsigned int rxq_hw_index_max;
> -	const struct rte_eth_rss_conf *rss_conf = rss->rss_conf;
> -	uint64_t rss_hf;
> -	uint8_t *rss_key = NULL;
> +	const uint8_t *rss_key;
>  	struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf;
>  	unsigned int i;
> 
> -	if (rss->num == 0)
> +	if (rss->queue_num == 0)
>  		return -EINVAL;
> 
>  	rxq_sw_index = sa->rxq_count - 1;
> @@ -1248,7 +1246,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  	rxq_hw_index_min = rxq->hw_index;
>  	rxq_hw_index_max = 0;
> 
> -	for (i = 0; i < rss->num; ++i) {
> +	for (i = 0; i < rss->queue_num; ++i) {
>  		rxq_sw_index = rss->queue[i];
> 
>  		if (rxq_sw_index >= sa->rxq_count)
> @@ -1263,15 +1261,14 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
>  			rxq_hw_index_max = rxq->hw_index;
>  	}
> 
> -	rss_hf = (rss_conf != NULL) ? rss_conf->rss_hf : SFC_RSS_OFFLOADS;
> -	if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0)
> +	if ((rss->types & ~SFC_RSS_OFFLOADS) != 0)
>  		return -EINVAL;
> 
> -	if (rss_conf != NULL) {
> -		if (rss_conf->rss_key_len != sizeof(sa->rss_key))
> +	if (rss->key_len) {
> +		if (rss->key_len != sizeof(sa->rss_key))
>  			return -EINVAL;
> 
> -		rss_key = rss_conf->rss_key;
> +		rss_key = rss->key;
>  	} else {
>  		rss_key = sa->rss_key;
>  	}
> @@ -1280,11 +1277,11 @@ sfc_flow_parse_rss(struct sfc_adapter *sa,
> 
>  	sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
>  	sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
> -	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf);
> +	sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss-
> >types);
>  	rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key));
> 
>  	for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
> -		unsigned int rxq_sw_index = rss->queue[i % rss->num];
> +		unsigned int rxq_sw_index = rss->queue[i % rss-
> >queue_num];
>  		struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq;
> 
>  		sfc_rss_conf->rss_tbl[i] = rxq->hw_index -
> rxq_hw_index_min;
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index fe2f94010..67146aaba 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -1215,7 +1215,7 @@ priv_flow_process(struct pmd_internals *pmd,
>  				if (err)
>  					goto exit_action_not_supported;
>  			}
> -			if (flow && rss)
> +			if (flow)
>  				err = rss_add_actions(flow, pmd, rss, error);
>  		} else {
>  			goto exit_action_not_supported;
> @@ -2050,7 +2050,7 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  			   struct rte_flow_error *error)
>  {
>  	/* 4096 is the maximum number of instructions for a BPF program */
> -	int i;
> +	unsigned int i;
>  	int err;
>  	struct rss_key rss_entry = { .hash_fields = 0,
>  				     .key_size = 0 };
> @@ -2066,8 +2066,8 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>  	}
> 
>  	/* Update RSS map entry with queues */
> -	rss_entry.nb_queues = rss->num;
> -	for (i = 0; i < rss->num; i++)
> +	rss_entry.nb_queues = rss->queue_num;
> +	for (i = 0; i < rss->queue_num; i++)
>  		rss_entry.queues[i] = rss->queue[i];
>  	rss_entry.hash_fields =
>  		(1 << HASH_FIELD_IPV4_L3_L4) | (1 <<
> HASH_FIELD_IPV6_L3_L4);
> diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
> index 5971937cf..ee2497352 100644
> --- a/examples/ipsec-secgw/ipsec.c
> +++ b/examples/ipsec-secgw/ipsec.c
> @@ -203,9 +203,13 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct
> ipsec_sa *sa)
>  				     i < eth_dev->data->nb_rx_queues; ++i)
>  					if (eth_dev->data->rx_queues[i])
>  						queue[j++] = i;
> -				action_rss.rss_conf = &rss_conf;
> -				action_rss.num = j;
> -				action_rss.queue = queue;
> +				action_rss = (struct rte_flow_action_rss){
> +					.types = rss_conf.rss_hf,
> +					.key_len = rss_conf.rss_key_len,
> +					.queue_num = j,
> +					.key = rss_key,
> +					.queue = queue,
> +				};
>  				ret = rte_flow_validate(sa->portid, &sa->attr,
>  							sa->pattern, sa-
> >action,
>  							&err);
> diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
> index bb19e28c6..cc7819b6a 100644
> --- a/lib/librte_ether/rte_flow.c
> +++ b/lib/librte_ether/rte_flow.c
> @@ -330,40 +330,27 @@ flow_action_conf_copy(void *buf, const struct
> rte_flow_action *action)
>  		off = 0;
>  		if (dst.rss)
>  			*dst.rss = (struct rte_flow_action_rss){
> -				.num = src.rss->num,
> +				.types = src.rss->types,
> +				.key_len = src.rss->key_len,
> +				.queue_num = src.rss->queue_num,
>  			};
>  		off += sizeof(*src.rss);
> -		if (src.rss->num) {
> +		if (src.rss->key_len) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->queue) * src.rss->num;
> +			size = sizeof(*src.rss->key) * src.rss->key_len;
>  			if (dst.rss)
> -				dst.rss->queue = memcpy
> +				dst.rss->key = memcpy
>  					((void *)((uintptr_t)dst.rss + off),
> -					 src.rss->queue, size);
> +					 src.rss->key, size);
>  			off += size;
>  		}
> -		off = RTE_ALIGN_CEIL(off, sizeof(double));
> -		if (dst.rss) {
> -			dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
> -			*(struct rte_eth_rss_conf *)(uintptr_t)
> -				dst.rss->rss_conf = (struct
> rte_eth_rss_conf){
> -				.rss_key_len = src.rss->rss_conf-
> >rss_key_len,
> -				.rss_hf = src.rss->rss_conf->rss_hf,
> -			};
> -		}
> -		off += sizeof(*src.rss->rss_conf);
> -		if (src.rss->rss_conf->rss_key_len) {
> +		if (src.rss->queue_num) {
>  			off = RTE_ALIGN_CEIL(off, sizeof(double));
> -			size = sizeof(*src.rss->rss_conf->rss_key) *
> -				src.rss->rss_conf->rss_key_len;
> -			if (dst.rss) {
> -				((struct rte_eth_rss_conf *)(uintptr_t)
> -				 dst.rss->rss_conf)->rss_key =
> -					(void *)((uintptr_t)dst.rss + off);
> -				memcpy(dst.rss->rss_conf->rss_key,
> -				       src.rss->rss_conf->rss_key,
> -				       size);
> -			}
> +			size = sizeof(*src.rss->queue) * src.rss->queue_num;
> +			if (dst.rss)
> +				dst.rss->queue = memcpy
> +					((void *)((uintptr_t)dst.rss + off),
> +					 src.rss->queue, size);
>  			off += size;
>  		}
>  		size = off;
> diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
> index ad2e55b8e..bbc408fa6 100644
> --- a/lib/librte_ether/rte_flow.h
> +++ b/lib/librte_ether/rte_flow.h
> @@ -1033,13 +1033,21 @@ struct rte_flow_query_count {
>   * Similar to QUEUE, except RSS is additionally performed on packets to
>   * spread them among several queues according to the provided parameters.
>   *
> + * Unlike global RSS settings used by other DPDK APIs, unsetting the
> + * @p types field does not disable RSS in a flow rule. Doing so instead
> + * requests safe unspecified "best-effort" settings from the underlying
> PMD,
> + * which depending on the flow rule, may result in anything ranging from
> + * empty (single queue) to all-inclusive RSS.
> + *
>   * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps
>   * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only,
>   * both can be requested simultaneously.
>   */
>  struct rte_flow_action_rss {
> -	const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
> -	uint16_t num; /**< Number of entries in @p queue. */
> +	uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */
> +	uint32_t key_len; /**< Hash key length in bytes. */
> +	uint32_t queue_num; /**< Number of entries in @p queue. */
> +	const uint8_t *key; /**< Hash key. */
>  	const uint16_t *queue; /**< Queue indices to use. */
>  };
> 
> --
> 2.11.0

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal/service: remove experimental tags
  2018-04-25 12:58  0%   ` Thomas Monjalon
@ 2018-04-30 13:53  0%     ` Alejandro Lucero
  0 siblings, 0 replies; 200+ results
From: Alejandro Lucero @ 2018-04-30 13:53 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Harry van Haaren, dev, Jerin Jacob

I just wanted to say I'm using the functionality for debugging NFP firmware
and getting some useful information from the device.

I did not plan to have this upstream, but after this patch for removing the
experimental tag, I think it would be a good idea.

Thanks!

On Wed, Apr 25, 2018 at 1:58 PM, Thomas Monjalon <thomas@monjalon.net>
wrote:

> > > This commit removes the experimental tags from the
> > > service cores functions, they now become part of the
> > > main DPDK API/ABI.
> > >
> > > Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> >
> > Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
>
> Applied, congratulations!
>
>
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 1/5] iFPGA: Add Intel FPGA BUS Library
  @ 2018-05-02 13:14  4%     ` Shreyansh Jain
  2018-05-02 13:33  0%       ` Zhang, Tianfei
  0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2018-05-02 13:14 UTC (permalink / raw)
  To: Xu, Rosen, dev
  Cc: declan.doherty, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, tianfei.zhang, hao.wu, gaetan.rivet

On Thursday 26 April 2018 03:13 PM, Xu, Rosen wrote:
> From: Rosen Xu <rosen.xu@intel.com>
> 
> Defined FPGA-BUS for Acceleration Drivers of AFUs
> 1. FPGA PCI Scan (1st Scan) follows DPDK UIO/VFIO PCI Scan Process,
> probe Intel FPGA Rawdev Driver.
> 2. AFU Scan(2nd Scan) bind DPDK driver to FPGA Partial-Bitstream.
> This scan is trigged by hotplug of IFPGA Rawdev probe, in this scan
> the AFUs will be created and their drivers are also probed.
> 
> Signed-off-by: Rosen Xu <rosen.xu@intel.com>
> Signed-off-by: Figo zhang <tianfei.zhang@intel.com>
> ---
>   config/common_base                          |   5 +
>   drivers/bus/Makefile                        |   1 +
>   drivers/bus/ifpga/Makefile                  |  32 ++
>   drivers/bus/ifpga/ifpga_bus.c               | 503 ++++++++++++++++++++++++++++
>   drivers/bus/ifpga/ifpga_common.c            |  88 +++++
>   drivers/bus/ifpga/ifpga_common.h            |  18 +
>   drivers/bus/ifpga/ifpga_logs.h              |  31 ++
>   drivers/bus/ifpga/meson.build               |   6 +
>   drivers/bus/ifpga/rte_bus_ifpga.h           | 168 ++++++++++
>   drivers/bus/ifpga/rte_bus_ifpga_version.map |  10 +
>   drivers/bus/meson.build                     |   2 +-
>   mk/rte.app.mk                               |   2 +
>   12 files changed, 865 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/bus/ifpga/Makefile
>   create mode 100644 drivers/bus/ifpga/ifpga_bus.c
>   create mode 100644 drivers/bus/ifpga/ifpga_common.c
>   create mode 100644 drivers/bus/ifpga/ifpga_common.h
>   create mode 100644 drivers/bus/ifpga/ifpga_logs.h
>   create mode 100644 drivers/bus/ifpga/meson.build
>   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h
>   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map
> 

Hello Rosen,

While compiling this series with meson, I found following warnings:

--->8---
3d/1& [shreyansh:~/build/DPDK/00_dpdk/ifpga-build]↥ master(6)+* ± ninja
[335/949] Compiling C object 
'drivers/tmp_rte_bus_ifpga@sta/bus_ifpga_ifpga_bus.c.o'.
../drivers/bus/ifpga/ifpga_bus.c: In function ‘rte_ifpga_scan’:
../drivers/bus/ifpga/ifpga_bus.c:217:2: warning: ‘rte_devargs_next’ is 
deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
   RTE_EAL_DEVARGS_FOREACH("ifpga", devargs) {
   ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
../lib/librte_eal/common/include/rte_devargs.h:262:1: note: declared here
  rte_devargs_next(const char *busname, const struct rte_devargs *start);
  ^~~~~~~~~~~~~~~~
../drivers/bus/ifpga/ifpga_bus.c:217:2: warning: ‘rte_devargs_next’ is 
deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
   RTE_EAL_DEVARGS_FOREACH("ifpga", devargs) {
   ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
../lib/librte_eal/common/include/rte_devargs.h:262:1: note: declared here
  rte_devargs_next(const char *busname, const struct rte_devargs *start);
  ^~~~~~~~~~~~~~~~
../drivers/bus/ifpga/ifpga_bus.c: In function ‘rte_ifpga_unplug’:
../drivers/bus/ifpga/ifpga_bus.c:419:2: warning: ‘rte_devargs_remove’ is 
deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
   rte_devargs_remove(devargs->bus->name, devargs->name);
   ^~~~~~~~~~~~~~~~~~
In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
../lib/librte_eal/common/include/rte_devargs.h:195:5: note: declared here
  int rte_devargs_remove(const char *busname,
      ^~~~~~~~~~~~~~~~~~
../drivers/bus/ifpga/ifpga_bus.c: At top level:
cc1: warning: unrecognized command line option ‘-W
--->8---

My meson configuration is:

--->8---
3d/1& [shreyansh:~/build/DPDK/00_dpdk]↥ master(6)+* 130 ± 
~/.local/bin/meson ifpga-build
The Meson build system
Version: 0.44.0
Source dir: /home/shreyansh/build/DPDK/00_dpdk
Build dir: /home/shreyansh/build/DPDK/00_dpdk/ifpga-build
Build type: native build
Project name: DPDK
Native C compiler: ccache cc (gcc 7.2.0)
Build machine cpu family: x86_64
Build machine cpu: x86_64
Library numa found: YES
Has header "numaif.h": YES
...
--->8---

Can you please look into this?

-
Shreyansh

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6 1/5] iFPGA: Add Intel FPGA BUS Library
  2018-05-02 13:14  4%     ` Shreyansh Jain
@ 2018-05-02 13:33  0%       ` Zhang, Tianfei
  0 siblings, 0 replies; 200+ results
From: Zhang, Tianfei @ 2018-05-02 13:33 UTC (permalink / raw)
  To: Shreyansh Jain, Xu, Rosen, dev
  Cc: Doherty, Declan, Richardson, Bruce, Yigit, Ferruh, Ananyev,
	Konstantin, Wu, Hao, gaetan.rivet


> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
> Sent: Wednesday, May 2, 2018 9:14 PM
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Doherty, Declan <declan.doherty@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Wu, Hao <hao.wu@intel.com>;
> gaetan.rivet@6wind.com
> Subject: Re: [dpdk-dev] [PATCH v6 1/5] iFPGA: Add Intel FPGA BUS Library
> 
> On Thursday 26 April 2018 03:13 PM, Xu, Rosen wrote:
> > From: Rosen Xu <rosen.xu@intel.com>
> >
> > Defined FPGA-BUS for Acceleration Drivers of AFUs 1. FPGA PCI Scan
> > (1st Scan) follows DPDK UIO/VFIO PCI Scan Process, probe Intel FPGA
> > Rawdev Driver.
> > 2. AFU Scan(2nd Scan) bind DPDK driver to FPGA Partial-Bitstream.
> > This scan is trigged by hotplug of IFPGA Rawdev probe, in this scan
> > the AFUs will be created and their drivers are also probed.
> >
> > Signed-off-by: Rosen Xu <rosen.xu@intel.com>
> > Signed-off-by: Figo zhang <tianfei.zhang@intel.com>
> > ---
> >   config/common_base                          |   5 +
> >   drivers/bus/Makefile                        |   1 +
> >   drivers/bus/ifpga/Makefile                  |  32 ++
> >   drivers/bus/ifpga/ifpga_bus.c               | 503
> ++++++++++++++++++++++++++++
> >   drivers/bus/ifpga/ifpga_common.c            |  88 +++++
> >   drivers/bus/ifpga/ifpga_common.h            |  18 +
> >   drivers/bus/ifpga/ifpga_logs.h              |  31 ++
> >   drivers/bus/ifpga/meson.build               |   6 +
> >   drivers/bus/ifpga/rte_bus_ifpga.h           | 168 ++++++++++
> >   drivers/bus/ifpga/rte_bus_ifpga_version.map |  10 +
> >   drivers/bus/meson.build                     |   2 +-
> >   mk/rte.app.mk                               |   2 +
> >   12 files changed, 865 insertions(+), 1 deletion(-)
> >   create mode 100644 drivers/bus/ifpga/Makefile
> >   create mode 100644 drivers/bus/ifpga/ifpga_bus.c
> >   create mode 100644 drivers/bus/ifpga/ifpga_common.c
> >   create mode 100644 drivers/bus/ifpga/ifpga_common.h
> >   create mode 100644 drivers/bus/ifpga/ifpga_logs.h
> >   create mode 100644 drivers/bus/ifpga/meson.build
> >   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h
> >   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map
> >
> 
> Hello Rosen,
> 
> While compiling this series with meson, I found following warnings:
> 
> --->8---
> 3d/1& [shreyansh:~/build/DPDK/00_dpdk/ifpga-build]↥ master(6)+* ± ninja
> [335/949] Compiling C object
> 'drivers/tmp_rte_bus_ifpga@sta/bus_ifpga_ifpga_bus.c.o'.
> ../drivers/bus/ifpga/ifpga_bus.c: In function ‘rte_ifpga_scan’:
> ../drivers/bus/ifpga/ifpga_bus.c:217:2: warning: ‘rte_devargs_next’ is
> deprecated: Symbol is not yet part of stable ABI
> [-Wdeprecated-declarations]
>    RTE_EAL_DEVARGS_FOREACH("ifpga", devargs) {
>    ^~~~~~~~~~~~~~~~~~~~~~~
> In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
> ../lib/librte_eal/common/include/rte_devargs.h:262:1: note: declared here
>   rte_devargs_next(const char *busname, const struct rte_devargs *start);
>   ^~~~~~~~~~~~~~~~
> ../drivers/bus/ifpga/ifpga_bus.c:217:2: warning: ‘rte_devargs_next’ is
> deprecated: Symbol is not yet part of stable ABI
> [-Wdeprecated-declarations]
>    RTE_EAL_DEVARGS_FOREACH("ifpga", devargs) {
>    ^~~~~~~~~~~~~~~~~~~~~~~
> In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
> ../lib/librte_eal/common/include/rte_devargs.h:262:1: note: declared here
>   rte_devargs_next(const char *busname, const struct rte_devargs *start);
>   ^~~~~~~~~~~~~~~~
> ../drivers/bus/ifpga/ifpga_bus.c: In function ‘rte_ifpga_unplug’:
> ../drivers/bus/ifpga/ifpga_bus.c:419:2: warning: ‘rte_devargs_remove’ is
> deprecated: Symbol is not yet part of stable ABI
> [-Wdeprecated-declarations]
>    rte_devargs_remove(devargs->bus->name, devargs->name);
>    ^~~~~~~~~~~~~~~~~~
> In file included from ../drivers/bus/ifpga/ifpga_bus.c:24:0:
> ../lib/librte_eal/common/include/rte_devargs.h:195:5: note: declared here
>   int rte_devargs_remove(const char *busname,
>       ^~~~~~~~~~~~~~~~~~
> ../drivers/bus/ifpga/ifpga_bus.c: At top level:
> cc1: warning: unrecognized command line option ‘-W
> --->8---
> 
> My meson configuration is:
> 
> --->8---
> 3d/1& [shreyansh:~/build/DPDK/00_dpdk]↥ master(6)+* 130 ±
> ~/.local/bin/meson ifpga-build The Meson build system
> Version: 0.44.0
> Source dir: /home/shreyansh/build/DPDK/00_dpdk
> Build dir: /home/shreyansh/build/DPDK/00_dpdk/ifpga-build
> Build type: native build
> Project name: DPDK
> Native C compiler: ccache cc (gcc 7.2.0) Build machine cpu family: x86_64
> Build machine cpu: x86_64 Library numa found: YES Has header "numaif.h":
> YES ...
> --->8---
> 
> Can you please look into this?

We will fix it and send v7 patches soon.
I try it add " allow_experimental_apis = true " in meson.build can remove those warrings.


> 
> -
> Shreyansh

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] Compiling DPDK with CentOS6
@ 2018-05-03 14:20  3% Shahar Salzman
  0 siblings, 0 replies; 200+ results
From: Shahar Salzman @ 2018-05-03 14:20 UTC (permalink / raw)
  To: dev

Hi experts!


This is my first post on this list, apologize if I am posting in the wrong dpdk list, or if this is not relevant.

I am using spdk, hence dpdk. Following the termination of CentOS6 support, I did some work in order to get dpdk to work on CentOS6 (gcc version 4.4.7).

I had to remove some of the modules due to compilation errors, use -fno-strict-aliasing to avoid non issues dereferencing void* arrays and a single patch in the code which has to do with the way my gcc handles the attribure deprecated.


I did all my work on dpdk tag v18.02. Would you consider taking some of this to dpdk? It would be really helpful for us to maintain support for CentOS6 and its toolchain, at least in the near future, and we would like to use the latest dpdk stable.


Here are the modules I removed (obviously this is only a pointer to others):

shahar.salzman@shahars-vm:~/Kaminario/git/dpdk$ git show dpdk_v18.02~1 | grep "\=n"
@@ -370,7 +370,7 @@ CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+CONFIG_RTE_LIBRTE_PMD_BOND=n
 CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
 CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
@@ -441,7 +441,7 @@ CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=n
+CONFIG_RTE_LIBRTE_CRYPTODEV=n
 CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=n
@@ -537,7 +537,7 @@ CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO_DEBUG=n
+CONFIG_RTE_LIBRTE_SECURITY=n
@@ -556,12 +556,12 @@ CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG=n
+CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV=n
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF=n
+CONFIG_RTE_LIBRTE_LPM=n
 CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+CONFIG_RTE_LIBRTE_FLOW_CLASSIFY=n
@@ -755,13 +755,13 @@ CONFIG_RTE_PORT_PCAP=n
+CONFIG_RTE_LIBRTE_TABLE=n
 CONFIG_RTE_TABLE_STATS_COLLECT=n
+CONFIG_RTE_LIBRTE_PIPELINE=n
 CONFIG_RTE_PIPELINE_STATS_COLLECT=n
@@ -805,7 +805,7 @@ CONFIG_RTE_PROC_INFO=n
+CONFIG_RTE_TEST_PMD=n
 CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
 CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+CONFIG_RTE_LIBRTE_PMD_TAP=n
+CONFIG_RTE_LIBRTE_AVP_PMD=n



Here is the patch which fixes the deprecated attribute support:


commit f218129f0584f8d94f61071ff5b759605f6cf52e
Author: shahar salzman <shahar.salzman@kaminario.com>
Date:   Tue Apr 24 10:45:34 2018 +0300

    RHEL 6.4 support - use previous 'deprecated' attibute API

    Signed-off-by: shahar salzman <shahar.salzman@kaminario.com>

diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 92ff28f..f355a1c 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -78,11 +78,15 @@

 #ifndef ALLOW_EXPERIMENTAL_API

+#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 4))
 #define __rte_experimental \
 __attribute__((deprecated("Symbol is not yet part of stable ABI"), \
 section(".text.experimental")))

 #else
+#define __rte_experimental  __attribute__((deprecated)) __attribute__((section(".text.experimental")))
+#endif
+#else

 #define __rte_experimental \
 __attribute__((section(".text.experimental")))
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index c7803e4..5941971 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -453,4 +453,12 @@ rte_exit(int exit_code, const char *format, ...)
 }
 #endif

+#ifndef RHEL_RELEASE_VERSION
+#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
+#endif
+
+#ifndef RHEL_RELEASE_CODE
+#define RHEL_RELEASE_CODE (0)
+#endif
+
 #endif

Thanks,

Shahar

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver
  @ 2018-05-03 15:51  2%   ` Nipun Gupta
  0 siblings, 0 replies; 200+ results
From: Nipun Gupta @ 2018-05-03 15:51 UTC (permalink / raw)
  To: thomas, hemant.agrawal, shreyansh.jain; +Cc: dev, Nipun Gupta

DPAA2 QDMA driver uses MC DPDMAI object. This driver enables
the user (app) to perform data DMA without involving CPU in
the DMA process

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 MAINTAINERS                                        |   8 +
 config/common_base                                 |   7 +-
 config/common_linuxapp                             |  13 +-
 drivers/raw/Makefile                               |   3 +
 drivers/raw/dpaa2_qdma/Makefile                    |  35 +++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.c                | 294 +++++++++++++++++++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma.h                |  66 +++++
 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h           |  46 ++++
 drivers/raw/dpaa2_qdma/meson.build                 |   7 +
 .../raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map  |   4 +
 drivers/raw/meson.build                            |   2 +-
 mk/rte.app.mk                                      |   3 +
 12 files changed, 480 insertions(+), 8 deletions(-)
 create mode 100644 drivers/raw/dpaa2_qdma/Makefile
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.c
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma.h
 create mode 100644 drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
 create mode 100644 drivers/raw/dpaa2_qdma/meson.build
 create mode 100644 drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ce06e93..5ca021d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -805,6 +805,14 @@ F: doc/guides/cryptodevs/zuc.rst
 F: doc/guides/cryptodevs/features/zuc.ini
 
 
+Rawdev Drivers
+--------------
+
+NXP DPAA2 QDMA
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_qdma/
+
+
 Eventdev Drivers
 ----------------
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/config/common_base b/config/common_base
index 03a8688..b6a649f 100644
--- a/config/common_base
+++ b/config/common_base
@@ -38,7 +38,7 @@ CONFIG_RTE_ARCH_STRICT_ALIGN=n
 #
 # Compile to share library
 #
-CONFIG_RTE_BUILD_SHARED_LIB=n
+CONFIG_RTE_BUILD_SHARED_LIB=y
 
 #
 # Use newest code breaking previous ABI
@@ -618,6 +618,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
 CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
 
 #
+# Compile PMD for NXP DPAA2 QDMA raw device
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 14e56cb..8ee495b 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -6,14 +6,14 @@
 CONFIG_RTE_EXEC_ENV="linuxapp"
 CONFIG_RTE_EXEC_ENV_LINUXAPP=y
 
-CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
-CONFIG_RTE_EAL_IGB_UIO=y
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
+CONFIG_RTE_EAL_IGB_UIO=n
 CONFIG_RTE_EAL_VFIO=y
-CONFIG_RTE_KNI_KMOD=y
-CONFIG_RTE_LIBRTE_KNI=y
-CONFIG_RTE_LIBRTE_PMD_KNI=y
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_PMD_KNI=n
 CONFIG_RTE_LIBRTE_VHOST=y
-CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=n
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_IFCVF_VDPA_PMD=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
@@ -38,3 +38,4 @@ CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=y
 CONFIG_RTE_LIBRTE_DPAA2_PMD=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=y
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index da7c8b4..0f2b076 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -5,5 +5,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 # DIRS-$(<configuration>) += <directory>
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
+endif
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
new file mode 100644
index 0000000..68c785a
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_qdma.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_mempool
+LDLIBS += -lrte_mempool_dpaa2
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_ring
+
+EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.c b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
new file mode 100644
index 0000000..9288350
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <string.h>
+
+#include <rte_eal.h>
+#include <rte_fslmc.h>
+#include <rte_atomic.h>
+#include <rte_lcore.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+
+#include <mc/fsl_dpdmai.h>
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+
+#include "dpaa2_qdma.h"
+#include "dpaa2_qdma_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_qdma_logtype;
+
+/* QDMA device */
+static struct qdma_device qdma_dev;
+
+/* QDMA H/W queues list */
+TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
+static struct qdma_hw_queue_list qdma_queue_list
+	= TAILQ_HEAD_INITIALIZER(qdma_queue_list);
+
+static const struct rte_rawdev_ops dpaa2_qdma_ops;
+
+static int
+add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue;
+	int i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	for (i = 0; i < dpdmai_dev->num_queues; i++) {
+		queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
+		if (!queue) {
+			DPAA2_QDMA_ERR(
+				"Memory allocation failed for QDMA queue");
+			return -ENOMEM;
+		}
+
+		queue->dpdmai_dev = dpdmai_dev;
+		queue->queue_id = i;
+
+		TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
+		qdma_dev.num_hw_queues++;
+	}
+
+	return 0;
+}
+
+static void
+remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
+{
+	struct qdma_hw_queue *queue = NULL;
+	struct qdma_hw_queue *tqueue = NULL;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
+		if (queue->dpdmai_dev == dpdmai_dev) {
+			TAILQ_REMOVE(&qdma_queue_list, queue, next);
+			rte_free(queue);
+			queue = NULL;
+		}
+	}
+}
+
+static int
+dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Remove HW queues from global list */
+	remove_hw_queues_from_list(dpdmai_dev);
+
+	ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			     dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("dmdmai disable failed");
+
+	/* Set up the DQRR storage for Rx */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
+
+		if (rxq->q_storage) {
+			dpaa2_free_dq_storage(rxq->q_storage);
+			rte_free(rxq->q_storage);
+		}
+	}
+
+	/* Close the device at underlying layer*/
+	ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
+	if (ret)
+		DPAA2_QDMA_ERR("Failure closing dpdmai device");
+
+	return 0;
+}
+
+static int
+dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
+{
+	struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
+	struct dpdmai_rx_queue_cfg rx_queue_cfg;
+	struct dpdmai_attr attr;
+	struct dpdmai_rx_queue_attr rx_attr;
+	struct dpdmai_tx_queue_attr tx_attr;
+	int ret, i;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	/* For secondary processes, the primary has done all the work */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* Open DPDMAI device */
+	dpdmai_dev->dpdmai_id = dpdmai_id;
+	dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
+	ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			  dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
+		return ret;
+	}
+
+	/* Get DPDMAI attributes */
+	ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+				    dpdmai_dev->token, &attr);
+	if (ret) {
+		DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
+			       ret);
+		goto init_err;
+	}
+	dpdmai_dev->num_queues = attr.num_of_priorities;
+
+	/* Set up Rx Queues */
+	for (i = 0; i < attr.num_of_priorities; i++) {
+		struct dpaa2_queue *rxq;
+
+		memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
+		ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
+					  CMD_PRI_LOW,
+					  dpdmai_dev->token,
+					  i, &rx_queue_cfg);
+		if (ret) {
+			DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+
+		/* Allocate DQ storage for the DPDMAI Rx queues */
+		rxq = &(dpdmai_dev->rx_queue[i]);
+		rxq->q_storage = rte_malloc("dq_storage",
+					    sizeof(struct queue_storage_info_t),
+					    RTE_CACHE_LINE_SIZE);
+		if (!rxq->q_storage) {
+			DPAA2_QDMA_ERR("q_storage allocation failed");
+			ret = -ENOMEM;
+			goto init_err;
+		}
+
+		memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
+		ret = dpaa2_alloc_dq_storage(rxq->q_storage);
+		if (ret) {
+			DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
+			goto init_err;
+		}
+	}
+
+	/* Get Rx and Tx queues FQID's */
+	for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
+		ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &rx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
+
+		ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+					  dpdmai_dev->token, i, &tx_attr);
+		if (ret) {
+			DPAA2_QDMA_ERR("Reading device failed with err: %d",
+				       ret);
+			goto init_err;
+		}
+		dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
+	}
+
+	/* Enable the device */
+	ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
+			    dpdmai_dev->token);
+	if (ret) {
+		DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
+		goto init_err;
+	}
+
+	/* Add the HW queue to the global list */
+	ret = add_hw_queues_to_list(dpdmai_dev);
+	if (ret) {
+		DPAA2_QDMA_ERR("Adding H/W queue to list failed");
+		goto init_err;
+	}
+	DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
+
+	return 0;
+init_err:
+	dpaa2_dpdmai_dev_uninit(rawdev);
+	return ret;
+}
+
+static int
+rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
+		     struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
+			sizeof(struct dpaa2_dpdmai_dev),
+			rte_socket_id());
+	if (!rawdev) {
+		DPAA2_QDMA_ERR("Unable to allocate rawdevice");
+		return -EINVAL;
+	}
+
+	dpaa2_dev->rawdev = rawdev;
+	rawdev->dev_ops = &dpaa2_qdma_ops;
+	rawdev->device = &dpaa2_dev->device;
+	rawdev->driver_name = dpaa2_drv->driver.name;
+
+	/* Invoke PMD device initialization function */
+	ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
+	if (ret) {
+		rte_rawdev_pmd_release(rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
+{
+	struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
+	int ret;
+
+	DPAA2_QDMA_FUNC_TRACE();
+
+	dpaa2_dpdmai_dev_uninit(rawdev);
+
+	ret = rte_rawdev_pmd_release(rawdev);
+	if (ret)
+		DPAA2_QDMA_ERR("Device cleanup failed");
+
+	return 0;
+}
+
+static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
+	.drv_type = DPAA2_QDMA,
+	.probe = rte_dpaa2_qdma_probe,
+	.remove = rte_dpaa2_qdma_remove,
+};
+
+RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
+
+RTE_INIT(dpaa2_qdma_init_log);
+static void
+dpaa2_qdma_init_log(void)
+{
+	dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
+	if (dpaa2_qdma_logtype >= 0)
+		rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);
+}
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
new file mode 100644
index 0000000..8b3b1b9
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_H__
+#define __DPAA2_QDMA_H__
+
+/**
+ * Represents a QDMA device.
+ * A single QDMA device exists which is combination of multiple DPDMAI rawdev's.
+ */
+struct qdma_device {
+	/** total number of hw queues. */
+	uint16_t num_hw_queues;
+	/**
+	 * Maximum number of hw queues to be alocated per core.
+	 * This is limited by MAX_HW_QUEUE_PER_CORE
+	 */
+	uint16_t max_hw_queues_per_core;
+	/** Maximum number of VQ's */
+	uint16_t max_vqs;
+	/** mode of operation - physical(h/w) or virtual */
+	uint8_t mode;
+	/** Device state - started or stopped */
+	uint8_t state;
+	/** FLE pool for the device */
+	struct rte_mempool *fle_pool;
+	/** FLE pool size */
+	int fle_pool_count;
+	/** A lock to QDMA device whenever required */
+	rte_spinlock_t lock;
+};
+
+/** Represents a QDMA H/W queue */
+struct qdma_hw_queue {
+	/** Pointer to Next instance */
+	TAILQ_ENTRY(qdma_hw_queue) next;
+	/** DPDMAI device to communicate with HW */
+	struct dpaa2_dpdmai_dev *dpdmai_dev;
+	/** queue ID to communicate with HW */
+	uint16_t queue_id;
+	/** Associated lcore id */
+	uint32_t lcore_id;
+	/** Number of users of this hw queue */
+	uint32_t num_users;
+};
+
+/** Represents a DPDMAI raw device */
+struct dpaa2_dpdmai_dev {
+	/** Pointer to Next device instance */
+	TAILQ_ENTRY(dpaa2_qdma_device) next;
+	/** handle to DPDMAI object */
+	struct fsl_mc_io dpdmai;
+	/** HW ID for DPDMAI object */
+	uint32_t dpdmai_id;
+	/** Tocken of this device */
+	uint16_t token;
+	/** Number of queue in this DPDMAI device */
+	uint8_t num_queues;
+	/** RX queues */
+	struct dpaa2_queue rx_queue[DPDMAI_PRIO_NUM];
+	/** TX queues */
+	struct dpaa2_queue tx_queue[DPDMAI_PRIO_NUM];
+};
+
+#endif /* __DPAA2_QDMA_H__ */
diff --git a/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
new file mode 100644
index 0000000..fafe352
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/dpaa2_qdma_logs.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_QDMA_LOGS_H__
+#define __DPAA2_QDMA_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dpaa2_qdma_logtype;
+
+#define DPAA2_QDMA_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, dpaa2_qdma_logtype, "dpaa2_qdma: " \
+		fmt "\n", ## args)
+
+#define DPAA2_QDMA_DEBUG(fmt, args...) \
+	rte_log(RTE_LOG_DEBUG, dpaa2_qdma_logtype, "dpaa2_qdma: %s(): " \
+		fmt "\n", __func__, ## args)
+
+#define DPAA2_QDMA_FUNC_TRACE() DPAA2_QDMA_LOG(DEBUG, ">>")
+
+#define DPAA2_QDMA_INFO(fmt, args...) \
+	DPAA2_QDMA_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_ERR(fmt, args...) \
+	DPAA2_QDMA_LOG(ERR, fmt, ## args)
+#define DPAA2_QDMA_WARN(fmt, args...) \
+	DPAA2_QDMA_LOG(WARNING, fmt, ## args)
+
+/* DP Logs, toggled out at compile time if level lower than current level */
+#define DPAA2_QDMA_DP_LOG(level, fmt, args...) \
+	RTE_LOG_DP(level, PMD, "dpaa2_qdma: " fmt "\n", ## args)
+
+#define DPAA2_QDMA_DP_DEBUG(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(DEBUG, fmt, ## args)
+#define DPAA2_QDMA_DP_INFO(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(INFO, fmt, ## args)
+#define DPAA2_QDMA_DP_WARN(fmt, args...) \
+	DPAA2_QDMA_DP_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_QDMA_LOGS_H__ */
diff --git a/drivers/raw/dpaa2_qdma/meson.build b/drivers/raw/dpaa2_qdma/meson.build
new file mode 100644
index 0000000..b747500
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+deps += ['rawdev', 'mempool_dpaa2', 'ring']
+sources = files('dpaa2_qdma.c')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
new file mode 100644
index 0000000..33d2379
--- /dev/null
+++ b/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
@@ -0,0 +1,4 @@
+EXPERIMENTAL {
+
+	local: *;
+};
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 24c82ff..1b298f8 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
-drivers = ['skeleton_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_qdma']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a60..26a6b0c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -251,6 +251,9 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 
-- 
1.9.1

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH 3/6] net/enic: set rte errno to positive value
  @ 2018-05-03 19:37  3% ` John Daley
  0 siblings, 0 replies; 200+ results
From: John Daley @ 2018-05-03 19:37 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, johndale, Hyong Youb Kim

From: johndale <johndale@cisco.com>

Related to d9fff8a31, where rte_errno should always have positive
errno values.

Technically this is an ABI change since it fixes an error code
introduced in 18.02, but is minor and inconsequential. 

Fixes: 1e81dbb5321b ("net/enic: add Tx prepare handler")

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
---
 drivers/net/enic/enic_rxtx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index aa3393700..8853a2044 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -510,7 +510,7 @@ uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 		m = tx_pkts[i];
 		ol_flags = m->ol_flags;
 		if (ol_flags & wq->tx_offload_notsup_mask) {
-			rte_errno = -ENOTSUP;
+			rte_errno = ENOTSUP;
 			return i;
 		}
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
-- 
2.16.2

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v5 1/8] bpf: add BPF loading and execution framework
  @ 2018-05-04 12:45  1% ` Konstantin Ananyev
  2018-05-10 10:23  3%   ` [dpdk-dev] [PATCH v6 2/9] bpf: add ability to load eBPF program from ELF object file Konstantin Ananyev
  0 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2018-05-04 12:45 UTC (permalink / raw)
  To: dev; +Cc: Konstantin Ananyev

librte_bpf provides a framework to load and execute eBPF bytecode
inside user-space dpdk based applications.
It supports basic set of features from eBPF spec
(https://www.kernel.org/doc/Documentation/networking/filter.txt).

Not currently supported features:
 - JIT
 - cBPF
 - tail-pointer call
 - eBPF MAP
 - skb
 - function calls for 32-bit apps
 - mbuf pointer as input parameter for 32-bit apps

It also adds dependency on libelf.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 MAINTAINERS                        |   4 +
 config/common_base                 |   5 +
 lib/Makefile                       |   2 +
 lib/librte_bpf/Makefile            |  31 +++
 lib/librte_bpf/bpf.c               |  59 +++++
 lib/librte_bpf/bpf_def.h           | 138 +++++++++++
 lib/librte_bpf/bpf_exec.c          | 453 +++++++++++++++++++++++++++++++++++++
 lib/librte_bpf/bpf_impl.h          |  41 ++++
 lib/librte_bpf/bpf_load.c          | 386 +++++++++++++++++++++++++++++++
 lib/librte_bpf/bpf_validate.c      |  55 +++++
 lib/librte_bpf/meson.build         |  19 ++
 lib/librte_bpf/rte_bpf.h           | 184 +++++++++++++++
 lib/librte_bpf/rte_bpf_version.map |  12 +
 lib/meson.build                    |   2 +-
 mk/rte.app.mk                      |   2 +
 15 files changed, 1392 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_bpf/Makefile
 create mode 100644 lib/librte_bpf/bpf.c
 create mode 100644 lib/librte_bpf/bpf_def.h
 create mode 100644 lib/librte_bpf/bpf_exec.c
 create mode 100644 lib/librte_bpf/bpf_impl.h
 create mode 100644 lib/librte_bpf/bpf_load.c
 create mode 100644 lib/librte_bpf/bpf_validate.c
 create mode 100644 lib/librte_bpf/meson.build
 create mode 100644 lib/librte_bpf/rte_bpf.h
 create mode 100644 lib/librte_bpf/rte_bpf_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ce06e93c2..4a7edbcf7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1049,6 +1049,10 @@ Latency statistics
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: lib/librte_latencystats/
 
+BPF
+M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: lib/librte_bpf/
+F: doc/guides/prog_guide/bpf_lib.rst
 
 Test Applications
 -----------------
diff --git a/config/common_base b/config/common_base
index 03a8688b5..ac425491c 100644
--- a/config/common_base
+++ b/config/common_base
@@ -863,3 +863,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile librte_bpf
+#
+CONFIG_RTE_LIBRTE_BPF=y
diff --git a/lib/Makefile b/lib/Makefile
index 057bf7890..29cea6429 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -98,6 +98,8 @@ DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ethdev
 DIRS-$(CONFIG_RTE_LIBRTE_GSO) += librte_gso
 DEPDIRS-librte_gso := librte_eal librte_mbuf librte_ethdev librte_net
 DEPDIRS-librte_gso += librte_mempool
+DIRS-$(CONFIG_RTE_LIBRTE_BPF) += librte_bpf
+DEPDIRS-librte_bpf := librte_eal librte_mempool librte_mbuf librte_ethdev
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_bpf/Makefile b/lib/librte_bpf/Makefile
new file mode 100644
index 000000000..9b714389a
--- /dev/null
+++ b/lib/librte_bpf/Makefile
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_bpf.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+LDLIBS += -lrte_net -lrte_eal
+LDLIBS += -lrte_mempool -lrte_ring
+LDLIBS += -lrte_mbuf -lrte_ethdev
+LDLIBS += -lelf
+
+EXPORT_MAP := rte_bpf_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf.c
+SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_exec.c
+SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_load.c
+SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_validate.c
+
+# install header files
+SYMLINK-$(CONFIG_RTE_LIBRTE_BPF)-include += bpf_def.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_BPF)-include += rte_bpf.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_bpf/bpf.c b/lib/librte_bpf/bpf.c
new file mode 100644
index 000000000..d7f68c017
--- /dev/null
+++ b/lib/librte_bpf/bpf.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+
+#include "bpf_impl.h"
+
+int rte_bpf_logtype;
+
+__rte_experimental void
+rte_bpf_destroy(struct rte_bpf *bpf)
+{
+	if (bpf != NULL) {
+		if (bpf->jit.func != NULL)
+			munmap(bpf->jit.func, bpf->jit.sz);
+		munmap(bpf, bpf->sz);
+	}
+}
+
+__rte_experimental int
+rte_bpf_get_jit(const struct rte_bpf *bpf, struct rte_bpf_jit *jit)
+{
+	if (bpf == NULL || jit == NULL)
+		return -EINVAL;
+
+	jit[0] = bpf->jit;
+	return 0;
+}
+
+int
+bpf_jit(struct rte_bpf *bpf)
+{
+	int32_t rc;
+
+	rc = -ENOTSUP;
+	if (rc != 0)
+		RTE_BPF_LOG(WARNING, "%s(%p) failed, error code: %d;\n",
+			__func__, bpf, rc);
+	return rc;
+}
+
+RTE_INIT(rte_bpf_init_log);
+
+static void
+rte_bpf_init_log(void)
+{
+	rte_bpf_logtype = rte_log_register("lib.bpf");
+	if (rte_bpf_logtype >= 0)
+		rte_log_set_level(rte_bpf_logtype, RTE_LOG_INFO);
+}
diff --git a/lib/librte_bpf/bpf_def.h b/lib/librte_bpf/bpf_def.h
new file mode 100644
index 000000000..6b69de345
--- /dev/null
+++ b/lib/librte_bpf/bpf_def.h
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 1982, 1986, 1990, 1993
+ *      The Regents of the University of California.
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+#ifndef _RTE_BPF_DEF_H_
+#define _RTE_BPF_DEF_H_
+
+/**
+ * @file
+ *
+ * classic BPF (cBPF) and extended BPF (eBPF) related defines.
+ * For more information regarding cBPF and eBPF ISA and their differences,
+ * please refer to:
+ * https://www.kernel.org/doc/Documentation/networking/filter.txt.
+ * As a rule of thumb for that file:
+ * all definitions used by both cBPF and eBPF start with bpf(BPF)_ prefix,
+ * while eBPF only ones start with ebpf(EBPF)) prefix.
+ */
+
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The instruction encodings.
+ */
+
+/* Instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define	BPF_LD		0x00
+#define	BPF_LDX		0x01
+#define	BPF_ST		0x02
+#define	BPF_STX		0x03
+#define	BPF_ALU		0x04
+#define	BPF_JMP		0x05
+#define	BPF_RET		0x06
+#define	BPF_MISC        0x07
+
+#define EBPF_ALU64	0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code)  ((code) & 0x18)
+#define	BPF_W		0x00
+#define	BPF_H		0x08
+#define	BPF_B		0x10
+#define	EBPF_DW		0x18
+
+#define BPF_MODE(code)  ((code) & 0xe0)
+#define	BPF_IMM		0x00
+#define	BPF_ABS		0x20
+#define	BPF_IND		0x40
+#define	BPF_MEM		0x60
+#define	BPF_LEN		0x80
+#define	BPF_MSH		0xa0
+
+#define EBPF_XADD	0xc0
+
+/* alu/jmp fields */
+#define BPF_OP(code)    ((code) & 0xf0)
+#define	BPF_ADD		0x00
+#define	BPF_SUB		0x10
+#define	BPF_MUL		0x20
+#define	BPF_DIV		0x30
+#define	BPF_OR		0x40
+#define	BPF_AND		0x50
+#define	BPF_LSH		0x60
+#define	BPF_RSH		0x70
+#define	BPF_NEG		0x80
+#define	BPF_MOD		0x90
+#define	BPF_XOR		0xa0
+
+#define EBPF_MOV	0xb0
+#define EBPF_ARSH	0xc0
+#define EBPF_END	0xd0
+
+#define	BPF_JA		0x00
+#define	BPF_JEQ		0x10
+#define	BPF_JGT		0x20
+#define	BPF_JGE		0x30
+#define	BPF_JSET        0x40
+
+#define EBPF_JNE	0x50
+#define EBPF_JSGT	0x60
+#define EBPF_JSGE	0x70
+#define EBPF_CALL	0x80
+#define EBPF_EXIT	0x90
+#define EBPF_JLT	0xa0
+#define EBPF_JLE	0xb0
+#define EBPF_JSLT	0xc0
+#define EBPF_JSLE	0xd0
+
+#define BPF_SRC(code)   ((code) & 0x08)
+#define	BPF_K		0x00
+#define	BPF_X		0x08
+
+/* if BPF_OP(code) == EBPF_END */
+#define EBPF_TO_LE	0x00  /* convert to little-endian */
+#define EBPF_TO_BE	0x08  /* convert to big-endian */
+
+/*
+ * eBPF registers
+ */
+enum {
+	EBPF_REG_0,  /* return value from internal function/for eBPF program */
+	EBPF_REG_1,  /* 0-th argument to internal function */
+	EBPF_REG_2,  /* 1-th argument to internal function */
+	EBPF_REG_3,  /* 2-th argument to internal function */
+	EBPF_REG_4,  /* 3-th argument to internal function */
+	EBPF_REG_5,  /* 4-th argument to internal function */
+	EBPF_REG_6,  /* callee saved register */
+	EBPF_REG_7,  /* callee saved register */
+	EBPF_REG_8,  /* callee saved register */
+	EBPF_REG_9,  /* callee saved register */
+	EBPF_REG_10, /* stack pointer (read-only) */
+	EBPF_REG_NUM,
+};
+
+/*
+ * eBPF instruction format
+ */
+struct ebpf_insn {
+	uint8_t code;
+	uint8_t dst_reg:4;
+	uint8_t src_reg:4;
+	int16_t off;
+	int32_t imm;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_BPF_DEF_H_ */
diff --git a/lib/librte_bpf/bpf_exec.c b/lib/librte_bpf/bpf_exec.c
new file mode 100644
index 000000000..e373b1f3d
--- /dev/null
+++ b/lib/librte_bpf/bpf_exec.c
@@ -0,0 +1,453 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+
+#include "bpf_impl.h"
+
+#define BPF_JMP_UNC(ins)	((ins) += (ins)->off)
+
+#define BPF_JMP_CND_REG(reg, ins, op, type)	\
+	((ins) += \
+		((type)(reg)[(ins)->dst_reg] op (type)(reg)[(ins)->src_reg]) ? \
+		(ins)->off : 0)
+
+#define BPF_JMP_CND_IMM(reg, ins, op, type)	\
+	((ins) += \
+		((type)(reg)[(ins)->dst_reg] op (type)(ins)->imm) ? \
+		(ins)->off : 0)
+
+#define BPF_NEG_ALU(reg, ins, type)	\
+	((reg)[(ins)->dst_reg] = (type)(-(reg)[(ins)->dst_reg]))
+
+#define EBPF_MOV_ALU_REG(reg, ins, type)	\
+	((reg)[(ins)->dst_reg] = (type)(reg)[(ins)->src_reg])
+
+#define BPF_OP_ALU_REG(reg, ins, op, type)	\
+	((reg)[(ins)->dst_reg] = \
+		(type)(reg)[(ins)->dst_reg] op (type)(reg)[(ins)->src_reg])
+
+#define EBPF_MOV_ALU_IMM(reg, ins, type)	\
+	((reg)[(ins)->dst_reg] = (type)(ins)->imm)
+
+#define BPF_OP_ALU_IMM(reg, ins, op, type)	\
+	((reg)[(ins)->dst_reg] = \
+		(type)(reg)[(ins)->dst_reg] op (type)(ins)->imm)
+
+#define BPF_DIV_ZERO_CHECK(bpf, reg, ins, type) do { \
+	if ((type)(reg)[(ins)->src_reg] == 0) { \
+		RTE_BPF_LOG(ERR, \
+			"%s(%p): division by 0 at pc: %#zx;\n", \
+			__func__, bpf, \
+			(uintptr_t)(ins) - (uintptr_t)(bpf)->prm.ins); \
+		return 0; \
+	} \
+} while (0)
+
+#define BPF_LD_REG(reg, ins, type)	\
+	((reg)[(ins)->dst_reg] = \
+		*(type *)(uintptr_t)((reg)[(ins)->src_reg] + (ins)->off))
+
+#define BPF_ST_IMM(reg, ins, type)	\
+	(*(type *)(uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off) = \
+		(type)(ins)->imm)
+
+#define BPF_ST_REG(reg, ins, type)	\
+	(*(type *)(uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off) = \
+		(type)(reg)[(ins)->src_reg])
+
+#define BPF_ST_XADD_REG(reg, ins, tp)	\
+	(rte_atomic##tp##_add((rte_atomic##tp##_t *) \
+		(uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off), \
+		reg[ins->src_reg]))
+
+static inline void
+bpf_alu_be(uint64_t reg[EBPF_REG_NUM], const struct ebpf_insn *ins)
+{
+	uint64_t *v;
+
+	v = reg + ins->dst_reg;
+	switch (ins->imm) {
+	case 16:
+		*v = rte_cpu_to_be_16(*v);
+		break;
+	case 32:
+		*v = rte_cpu_to_be_32(*v);
+		break;
+	case 64:
+		*v = rte_cpu_to_be_64(*v);
+		break;
+	}
+}
+
+static inline void
+bpf_alu_le(uint64_t reg[EBPF_REG_NUM], const struct ebpf_insn *ins)
+{
+	uint64_t *v;
+
+	v = reg + ins->dst_reg;
+	switch (ins->imm) {
+	case 16:
+		*v = rte_cpu_to_le_16(*v);
+		break;
+	case 32:
+		*v = rte_cpu_to_le_32(*v);
+		break;
+	case 64:
+		*v = rte_cpu_to_le_64(*v);
+		break;
+	}
+}
+
+static inline uint64_t
+bpf_exec(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM])
+{
+	const struct ebpf_insn *ins;
+
+	for (ins = bpf->prm.ins; ; ins++) {
+		switch (ins->code) {
+		/* 32 bit ALU IMM operations */
+		case (BPF_ALU | BPF_ADD | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, +, uint32_t);
+			break;
+		case (BPF_ALU | BPF_SUB | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, -, uint32_t);
+			break;
+		case (BPF_ALU | BPF_AND | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, &, uint32_t);
+			break;
+		case (BPF_ALU | BPF_OR | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, |, uint32_t);
+			break;
+		case (BPF_ALU | BPF_LSH | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, <<, uint32_t);
+			break;
+		case (BPF_ALU | BPF_RSH | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, >>, uint32_t);
+			break;
+		case (BPF_ALU | BPF_XOR | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, ^, uint32_t);
+			break;
+		case (BPF_ALU | BPF_MUL | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, *, uint32_t);
+			break;
+		case (BPF_ALU | BPF_DIV | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, /, uint32_t);
+			break;
+		case (BPF_ALU | BPF_MOD | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, %, uint32_t);
+			break;
+		case (BPF_ALU | EBPF_MOV | BPF_K):
+			EBPF_MOV_ALU_IMM(reg, ins, uint32_t);
+			break;
+		/* 32 bit ALU REG operations */
+		case (BPF_ALU | BPF_ADD | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, +, uint32_t);
+			break;
+		case (BPF_ALU | BPF_SUB | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, -, uint32_t);
+			break;
+		case (BPF_ALU | BPF_AND | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, &, uint32_t);
+			break;
+		case (BPF_ALU | BPF_OR | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, |, uint32_t);
+			break;
+		case (BPF_ALU | BPF_LSH | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, <<, uint32_t);
+			break;
+		case (BPF_ALU | BPF_RSH | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, >>, uint32_t);
+			break;
+		case (BPF_ALU | BPF_XOR | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, ^, uint32_t);
+			break;
+		case (BPF_ALU | BPF_MUL | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, *, uint32_t);
+			break;
+		case (BPF_ALU | BPF_DIV | BPF_X):
+			BPF_DIV_ZERO_CHECK(bpf, reg, ins, uint32_t);
+			BPF_OP_ALU_REG(reg, ins, /, uint32_t);
+			break;
+		case (BPF_ALU | BPF_MOD | BPF_X):
+			BPF_DIV_ZERO_CHECK(bpf, reg, ins, uint32_t);
+			BPF_OP_ALU_REG(reg, ins, %, uint32_t);
+			break;
+		case (BPF_ALU | EBPF_MOV | BPF_X):
+			EBPF_MOV_ALU_REG(reg, ins, uint32_t);
+			break;
+		case (BPF_ALU | BPF_NEG):
+			BPF_NEG_ALU(reg, ins, uint32_t);
+			break;
+		case (BPF_ALU | EBPF_END | EBPF_TO_BE):
+			bpf_alu_be(reg, ins);
+			break;
+		case (BPF_ALU | EBPF_END | EBPF_TO_LE):
+			bpf_alu_le(reg, ins);
+			break;
+		/* 64 bit ALU IMM operations */
+		case (EBPF_ALU64 | BPF_ADD | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, +, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_SUB | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, -, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_AND | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, &, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_OR | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, |, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_LSH | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, <<, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_RSH | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, >>, uint64_t);
+			break;
+		case (EBPF_ALU64 | EBPF_ARSH | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, >>, int64_t);
+			break;
+		case (EBPF_ALU64 | BPF_XOR | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, ^, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_MUL | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, *, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_DIV | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, /, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_MOD | BPF_K):
+			BPF_OP_ALU_IMM(reg, ins, %, uint64_t);
+			break;
+		case (EBPF_ALU64 | EBPF_MOV | BPF_K):
+			EBPF_MOV_ALU_IMM(reg, ins, uint64_t);
+			break;
+		/* 64 bit ALU REG operations */
+		case (EBPF_ALU64 | BPF_ADD | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, +, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_SUB | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, -, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_AND | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, &, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_OR | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, |, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_LSH | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, <<, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_RSH | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, >>, uint64_t);
+			break;
+		case (EBPF_ALU64 | EBPF_ARSH | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, >>, int64_t);
+			break;
+		case (EBPF_ALU64 | BPF_XOR | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, ^, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_MUL | BPF_X):
+			BPF_OP_ALU_REG(reg, ins, *, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_DIV | BPF_X):
+			BPF_DIV_ZERO_CHECK(bpf, reg, ins, uint64_t);
+			BPF_OP_ALU_REG(reg, ins, /, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_MOD | BPF_X):
+			BPF_DIV_ZERO_CHECK(bpf, reg, ins, uint64_t);
+			BPF_OP_ALU_REG(reg, ins, %, uint64_t);
+			break;
+		case (EBPF_ALU64 | EBPF_MOV | BPF_X):
+			EBPF_MOV_ALU_REG(reg, ins, uint64_t);
+			break;
+		case (EBPF_ALU64 | BPF_NEG):
+			BPF_NEG_ALU(reg, ins, uint64_t);
+			break;
+		/* load instructions */
+		case (BPF_LDX | BPF_MEM | BPF_B):
+			BPF_LD_REG(reg, ins, uint8_t);
+			break;
+		case (BPF_LDX | BPF_MEM | BPF_H):
+			BPF_LD_REG(reg, ins, uint16_t);
+			break;
+		case (BPF_LDX | BPF_MEM | BPF_W):
+			BPF_LD_REG(reg, ins, uint32_t);
+			break;
+		case (BPF_LDX | BPF_MEM | EBPF_DW):
+			BPF_LD_REG(reg, ins, uint64_t);
+			break;
+		/* load 64 bit immediate value */
+		case (BPF_LD | BPF_IMM | EBPF_DW):
+			reg[ins->dst_reg] = (uint32_t)ins[0].imm |
+				(uint64_t)(uint32_t)ins[1].imm << 32;
+			ins++;
+			break;
+		/* store instructions */
+		case (BPF_STX | BPF_MEM | BPF_B):
+			BPF_ST_REG(reg, ins, uint8_t);
+			break;
+		case (BPF_STX | BPF_MEM | BPF_H):
+			BPF_ST_REG(reg, ins, uint16_t);
+			break;
+		case (BPF_STX | BPF_MEM | BPF_W):
+			BPF_ST_REG(reg, ins, uint32_t);
+			break;
+		case (BPF_STX | BPF_MEM | EBPF_DW):
+			BPF_ST_REG(reg, ins, uint64_t);
+			break;
+		case (BPF_ST | BPF_MEM | BPF_B):
+			BPF_ST_IMM(reg, ins, uint8_t);
+			break;
+		case (BPF_ST | BPF_MEM | BPF_H):
+			BPF_ST_IMM(reg, ins, uint16_t);
+			break;
+		case (BPF_ST | BPF_MEM | BPF_W):
+			BPF_ST_IMM(reg, ins, uint32_t);
+			break;
+		case (BPF_ST | BPF_MEM | EBPF_DW):
+			BPF_ST_IMM(reg, ins, uint64_t);
+			break;
+		/* atomic add instructions */
+		case (BPF_STX | EBPF_XADD | BPF_W):
+			BPF_ST_XADD_REG(reg, ins, 32);
+			break;
+		case (BPF_STX | EBPF_XADD | EBPF_DW):
+			BPF_ST_XADD_REG(reg, ins, 64);
+			break;
+		/* jump instructions */
+		case (BPF_JMP | BPF_JA):
+			BPF_JMP_UNC(ins);
+			break;
+		/* jump IMM instructions */
+		case (BPF_JMP | BPF_JEQ | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, ==, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JNE | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, !=, uint64_t);
+			break;
+		case (BPF_JMP | BPF_JGT | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, >, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JLT | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, <, uint64_t);
+			break;
+		case (BPF_JMP | BPF_JGE | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, >=, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JLE | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, <=, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JSGT | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, >, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSLT | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, <, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSGE | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, >=, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSLE | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, <=, int64_t);
+			break;
+		case (BPF_JMP | BPF_JSET | BPF_K):
+			BPF_JMP_CND_IMM(reg, ins, &, uint64_t);
+			break;
+		/* jump REG instructions */
+		case (BPF_JMP | BPF_JEQ | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, ==, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JNE | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, !=, uint64_t);
+			break;
+		case (BPF_JMP | BPF_JGT | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, >, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JLT | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, <, uint64_t);
+			break;
+		case (BPF_JMP | BPF_JGE | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, >=, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JLE | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, <=, uint64_t);
+			break;
+		case (BPF_JMP | EBPF_JSGT | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, >, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSLT | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, <, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSGE | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, >=, int64_t);
+			break;
+		case (BPF_JMP | EBPF_JSLE | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, <=, int64_t);
+			break;
+		case (BPF_JMP | BPF_JSET | BPF_X):
+			BPF_JMP_CND_REG(reg, ins, &, uint64_t);
+			break;
+		/* call instructions */
+		case (BPF_JMP | EBPF_CALL):
+			reg[EBPF_REG_0] = bpf->prm.xsym[ins->imm].func(
+				reg[EBPF_REG_1], reg[EBPF_REG_2],
+				reg[EBPF_REG_3], reg[EBPF_REG_4],
+				reg[EBPF_REG_5]);
+			break;
+		/* return instruction */
+		case (BPF_JMP | EBPF_EXIT):
+			return reg[EBPF_REG_0];
+		default:
+			RTE_BPF_LOG(ERR,
+				"%s(%p): invalid opcode %#x at pc: %#zx;\n",
+				__func__, bpf, ins->code,
+				(uintptr_t)ins - (uintptr_t)bpf->prm.ins);
+			return 0;
+		}
+	}
+
+	/* should never be reached */
+	RTE_VERIFY(0);
+	return 0;
+}
+
+__rte_experimental uint32_t
+rte_bpf_exec_burst(const struct rte_bpf *bpf, void *ctx[], uint64_t rc[],
+	uint32_t num)
+{
+	uint32_t i;
+	uint64_t reg[EBPF_REG_NUM];
+	uint64_t stack[MAX_BPF_STACK_SIZE / sizeof(uint64_t)];
+
+	for (i = 0; i != num; i++) {
+
+		reg[EBPF_REG_1] = (uintptr_t)ctx[i];
+		reg[EBPF_REG_10] = (uintptr_t)(stack + RTE_DIM(stack));
+
+		rc[i] = bpf_exec(bpf, reg);
+	}
+
+	return i;
+}
+
+__rte_experimental uint64_t
+rte_bpf_exec(const struct rte_bpf *bpf, void *ctx)
+{
+	uint64_t rc;
+
+	rte_bpf_exec_burst(bpf, &ctx, &rc, 1);
+	return rc;
+}
diff --git a/lib/librte_bpf/bpf_impl.h b/lib/librte_bpf/bpf_impl.h
new file mode 100644
index 000000000..5d7e65c31
--- /dev/null
+++ b/lib/librte_bpf/bpf_impl.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _BPF_H_
+#define _BPF_H_
+
+#include <rte_bpf.h>
+#include <sys/mman.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_BPF_STACK_SIZE	0x200
+
+struct rte_bpf {
+	struct rte_bpf_prm prm;
+	struct rte_bpf_jit jit;
+	size_t sz;
+	uint32_t stack_sz;
+};
+
+extern int bpf_validate(struct rte_bpf *bpf);
+
+extern int bpf_jit(struct rte_bpf *bpf);
+
+#ifdef RTE_ARCH_X86_64
+extern int bpf_jit_x86(struct rte_bpf *);
+#endif
+
+extern int rte_bpf_logtype;
+
+#define	RTE_BPF_LOG(lvl, fmt, args...) \
+	rte_log(RTE_LOG_## lvl, rte_bpf_logtype, fmt, ##args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BPF_H_ */
diff --git a/lib/librte_bpf/bpf_load.c b/lib/librte_bpf/bpf_load.c
new file mode 100644
index 000000000..9450b4b79
--- /dev/null
+++ b/lib/librte_bpf/bpf_load.c
@@ -0,0 +1,386 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <fcntl.h>
+
+#include <libelf.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_errno.h>
+
+#include "bpf_impl.h"
+
+/* To overcome compatibility issue */
+#ifndef EM_BPF
+#define	EM_BPF	247
+#endif
+
+static uint32_t
+bpf_find_xsym(const char *sn, enum rte_bpf_xtype type,
+	const struct rte_bpf_xsym fp[], uint32_t fn)
+{
+	uint32_t i;
+
+	if (sn == NULL || fp == NULL)
+		return UINT32_MAX;
+
+	for (i = 0; i != fn; i++) {
+		if (fp[i].type == type && strcmp(sn, fp[i].name) == 0)
+			break;
+	}
+
+	return (i != fn) ? i : UINT32_MAX;
+}
+
+/*
+ * update BPF code at offset *ofs* with a proper address(index) for external
+ * symbol *sn*
+ */
+static int
+resolve_xsym(const char *sn, size_t ofs, struct ebpf_insn *ins, size_t ins_sz,
+	const struct rte_bpf_prm *prm)
+{
+	uint32_t idx, fidx;
+	enum rte_bpf_xtype type;
+
+	if (ofs % sizeof(ins[0]) != 0 || ofs >= ins_sz)
+		return -EINVAL;
+
+	idx = ofs / sizeof(ins[0]);
+	if (ins[idx].code == (BPF_JMP | EBPF_CALL))
+		type = RTE_BPF_XTYPE_FUNC;
+	else if (ins[idx].code == (BPF_LD | BPF_IMM | EBPF_DW) &&
+			ofs < ins_sz - sizeof(ins[idx]))
+		type = RTE_BPF_XTYPE_VAR;
+	else
+		return -EINVAL;
+
+	fidx = bpf_find_xsym(sn, type, prm->xsym, prm->nb_xsym);
+	if (fidx == UINT32_MAX)
+		return -ENOENT;
+
+	/* for function we just need an index in our xsym table */
+	if (type == RTE_BPF_XTYPE_FUNC)
+		ins[idx].imm = fidx;
+	/* for variable we need to store its absolute address */
+	else {
+		ins[idx].imm = (uintptr_t)prm->xsym[fidx].var;
+		ins[idx + 1].imm =
+			(uint64_t)(uintptr_t)prm->xsym[fidx].var >> 32;
+	}
+
+	return 0;
+}
+
+static int
+check_elf_header(const Elf64_Ehdr * eh)
+{
+	const char *err;
+
+	err = NULL;
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+	if (eh->e_ident[EI_DATA] != ELFDATA2LSB)
+#else
+	if (eh->e_ident[EI_DATA] != ELFDATA2MSB)
+#endif
+		err = "not native byte order";
+	else if (eh->e_ident[EI_OSABI] != ELFOSABI_NONE)
+		err = "unexpected OS ABI";
+	else if (eh->e_type != ET_REL)
+		err = "unexpected ELF type";
+	else if (eh->e_machine != EM_NONE && eh->e_machine != EM_BPF)
+		err = "unexpected machine type";
+
+	if (err != NULL) {
+		RTE_BPF_LOG(ERR, "%s(): %s\n", __func__, err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * helper function, find executable section by name.
+ */
+static int
+find_elf_code(Elf *elf, const char *section, Elf_Data **psd, size_t *pidx)
+{
+	Elf_Scn *sc;
+	const Elf64_Ehdr *eh;
+	const Elf64_Shdr *sh;
+	Elf_Data *sd;
+	const char *sn;
+	int32_t rc;
+
+	eh = elf64_getehdr(elf);
+	if (eh == NULL) {
+		rc = elf_errno();
+		RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n",
+			__func__, elf, section, rc, elf_errmsg(rc));
+		return -EINVAL;
+	}
+
+	if (check_elf_header(eh) != 0)
+		return -EINVAL;
+
+	/* find given section by name */
+	for (sc = elf_nextscn(elf, NULL); sc != NULL;
+			sc = elf_nextscn(elf, sc)) {
+		sh = elf64_getshdr(sc);
+		sn = elf_strptr(elf, eh->e_shstrndx, sh->sh_name);
+		if (sn != NULL && strcmp(section, sn) == 0 &&
+				sh->sh_type == SHT_PROGBITS &&
+				sh->sh_flags == (SHF_ALLOC | SHF_EXECINSTR))
+			break;
+	}
+
+	sd = elf_getdata(sc, NULL);
+	if (sd == NULL || sd->d_size == 0 ||
+			sd->d_size % sizeof(struct ebpf_insn) != 0) {
+		rc = elf_errno();
+		RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n",
+			__func__, elf, section, rc, elf_errmsg(rc));
+		return -EINVAL;
+	}
+
+	*psd = sd;
+	*pidx = elf_ndxscn(sc);
+	return 0;
+}
+
+/*
+ * helper function to process data from relocation table.
+ */
+static int
+process_reloc(Elf *elf, size_t sym_idx, Elf64_Rel *re, size_t re_sz,
+	struct ebpf_insn *ins, size_t ins_sz, const struct rte_bpf_prm *prm)
+{
+	int32_t rc;
+	uint32_t i, n;
+	size_t ofs, sym;
+	const char *sn;
+	const Elf64_Ehdr *eh;
+	Elf_Scn *sc;
+	const Elf_Data *sd;
+	Elf64_Sym *sm;
+
+	eh = elf64_getehdr(elf);
+
+	/* get symtable by section index */
+	sc = elf_getscn(elf, sym_idx);
+	sd = elf_getdata(sc, NULL);
+	if (sd == NULL)
+		return -EINVAL;
+	sm = sd->d_buf;
+
+	n = re_sz / sizeof(re[0]);
+	for (i = 0; i != n; i++) {
+
+		ofs = re[i].r_offset;
+
+		/* retrieve index in the symtable */
+		sym = ELF64_R_SYM(re[i].r_info);
+		if (sym * sizeof(sm[0]) >= sd->d_size)
+			return -EINVAL;
+
+		sn = elf_strptr(elf, eh->e_shstrndx, sm[sym].st_name);
+
+		rc = resolve_xsym(sn, ofs, ins, ins_sz, prm);
+		if (rc != 0) {
+			RTE_BPF_LOG(ERR,
+				"resolve_xsym(%s, %zu) error code: %d\n",
+				sn, ofs, rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * helper function, find relocation information (if any)
+ * and update bpf code.
+ */
+static int
+elf_reloc_code(Elf *elf, Elf_Data *ed, size_t sidx,
+	const struct rte_bpf_prm *prm)
+{
+	Elf64_Rel *re;
+	Elf_Scn *sc;
+	const Elf64_Shdr *sh;
+	const Elf_Data *sd;
+	int32_t rc;
+
+	rc = 0;
+
+	/* walk through all sections */
+	for (sc = elf_nextscn(elf, NULL); sc != NULL && rc == 0;
+			sc = elf_nextscn(elf, sc)) {
+
+		sh = elf64_getshdr(sc);
+
+		/* relocation data for our code section */
+		if (sh->sh_type == SHT_REL && sh->sh_info == sidx) {
+			sd = elf_getdata(sc, NULL);
+			if (sd == NULL || sd->d_size == 0 ||
+					sd->d_size % sizeof(re[0]) != 0)
+				return -EINVAL;
+			rc = process_reloc(elf, sh->sh_link,
+				sd->d_buf, sd->d_size, ed->d_buf, ed->d_size,
+				prm);
+		}
+	}
+
+	return rc;
+}
+
+static struct rte_bpf *
+bpf_load(const struct rte_bpf_prm *prm)
+{
+	uint8_t *buf;
+	struct rte_bpf *bpf;
+	size_t sz, bsz, insz, xsz;
+
+	xsz =  prm->nb_xsym * sizeof(prm->xsym[0]);
+	insz = prm->nb_ins * sizeof(prm->ins[0]);
+	bsz = sizeof(bpf[0]);
+	sz = insz + xsz + bsz;
+
+	buf = mmap(NULL, sz, PROT_READ | PROT_WRITE,
+		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if (buf == MAP_FAILED)
+		return NULL;
+
+	bpf = (void *)buf;
+	bpf->sz = sz;
+
+	memcpy(&bpf->prm, prm, sizeof(bpf->prm));
+
+	memcpy(buf + bsz, prm->xsym, xsz);
+	memcpy(buf + bsz + xsz, prm->ins, insz);
+
+	bpf->prm.xsym = (void *)(buf + bsz);
+	bpf->prm.ins = (void *)(buf + bsz + xsz);
+
+	return bpf;
+}
+
+__rte_experimental struct rte_bpf *
+rte_bpf_load(const struct rte_bpf_prm *prm)
+{
+	struct rte_bpf *bpf;
+	int32_t rc;
+
+	if (prm == NULL || prm->ins == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	bpf = bpf_load(prm);
+	if (bpf == NULL) {
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+
+	rc = bpf_validate(bpf);
+	if (rc == 0) {
+		bpf_jit(bpf);
+		if (mprotect(bpf, bpf->sz, PROT_READ) != 0)
+			rc = -ENOMEM;
+	}
+
+	if (rc != 0) {
+		rte_bpf_destroy(bpf);
+		rte_errno = -rc;
+		return NULL;
+	}
+
+	return bpf;
+}
+
+static struct rte_bpf *
+bpf_load_elf(const struct rte_bpf_prm *prm, int32_t fd, const char *section)
+{
+	Elf *elf;
+	Elf_Data *sd;
+	size_t sidx;
+	int32_t rc;
+	struct rte_bpf *bpf;
+	struct rte_bpf_prm np;
+
+	elf_version(EV_CURRENT);
+	elf = elf_begin(fd, ELF_C_READ, NULL);
+
+	rc = find_elf_code(elf, section, &sd, &sidx);
+	if (rc == 0)
+		rc = elf_reloc_code(elf, sd, sidx, prm);
+
+	if (rc == 0) {
+		np = prm[0];
+		np.ins = sd->d_buf;
+		np.nb_ins = sd->d_size / sizeof(struct ebpf_insn);
+		bpf = rte_bpf_load(&np);
+	} else {
+		bpf = NULL;
+		rte_errno = -rc;
+	}
+
+	elf_end(elf);
+	return bpf;
+}
+
+__rte_experimental struct rte_bpf *
+rte_bpf_elf_load(const struct rte_bpf_prm *prm, const char *fname,
+	const char *sname)
+{
+	int32_t fd, rc;
+	struct rte_bpf *bpf;
+
+	if (prm == NULL || fname == NULL || sname == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	fd = open(fname, O_RDONLY);
+	if (fd < 0) {
+		rc = errno;
+		RTE_BPF_LOG(ERR, "%s(%s) error code: %d(%s)\n",
+			__func__, fname, rc, strerror(rc));
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	bpf = bpf_load_elf(prm, fd, sname);
+	close(fd);
+
+	if (bpf == NULL) {
+		RTE_BPF_LOG(ERR,
+			"%s(fname=\"%s\", sname=\"%s\") failed, "
+			"error code: %d\n",
+			__func__, fname, sname, rte_errno);
+		return NULL;
+	}
+
+	RTE_BPF_LOG(INFO, "%s(fname=\"%s\", sname=\"%s\") "
+		"successfully creates %p(jit={.func=%p,.sz=%zu});\n",
+		__func__, fname, sname, bpf, bpf->jit.func, bpf->jit.sz);
+	return bpf;
+}
diff --git a/lib/librte_bpf/bpf_validate.c b/lib/librte_bpf/bpf_validate.c
new file mode 100644
index 000000000..6a1b33181
--- /dev/null
+++ b/lib/librte_bpf/bpf_validate.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+
+#include "bpf_impl.h"
+
+/*
+ * dummy one for now, need more work.
+ */
+int
+bpf_validate(struct rte_bpf *bpf)
+{
+	int32_t rc, ofs, stack_sz;
+	uint32_t i, op, dr;
+	const struct ebpf_insn *ins;
+
+	rc = 0;
+	stack_sz = 0;
+	for (i = 0; i != bpf->prm.nb_ins; i++) {
+
+		ins = bpf->prm.ins + i;
+		op = ins->code;
+		dr = ins->dst_reg;
+		ofs = ins->off;
+
+		if ((BPF_CLASS(op) == BPF_STX || BPF_CLASS(op) == BPF_ST) &&
+				dr == EBPF_REG_10) {
+			ofs -= sizeof(uint64_t);
+			stack_sz = RTE_MIN(ofs, stack_sz);
+		}
+	}
+
+	if (stack_sz != 0) {
+		stack_sz = -stack_sz;
+		if (stack_sz > MAX_BPF_STACK_SIZE)
+			rc = -ERANGE;
+		else
+			bpf->stack_sz = stack_sz;
+	}
+
+	if (rc != 0)
+		RTE_BPF_LOG(ERR, "%s(%p) failed, error code: %d;\n",
+			__func__, bpf, rc);
+	return rc;
+}
diff --git a/lib/librte_bpf/meson.build b/lib/librte_bpf/meson.build
new file mode 100644
index 000000000..e7c8d3398
--- /dev/null
+++ b/lib/librte_bpf/meson.build
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Intel Corporation
+
+allow_experimental_apis = true
+sources = files('bpf.c',
+		'bpf_exec.c',
+		'bpf_load.c',
+		'bpf_validate.c')
+
+install_headers = files('bpf_def.h',
+			'rte_bpf.h')
+
+deps += ['mbuf', 'net']
+
+dep = dependency('libelf', required: false)
+if dep.found() == false
+	build = false
+endif
+ext_deps += dep
diff --git a/lib/librte_bpf/rte_bpf.h b/lib/librte_bpf/rte_bpf.h
new file mode 100644
index 000000000..1d6c4a9d2
--- /dev/null
+++ b/lib/librte_bpf/rte_bpf.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_BPF_H_
+#define _RTE_BPF_H_
+
+/**
+ * @file
+ *
+ * RTE BPF support.
+ * librte_bpf provides a framework to load and execute eBPF bytecode
+ * inside user-space dpdk based applications.
+ * It supports basic set of features from eBPF spec
+ * (https://www.kernel.org/doc/Documentation/networking/filter.txt).
+ */
+
+#include <rte_common.h>
+#include <rte_mbuf.h>
+#include <bpf_def.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Possible types for function/BPF program arguments.
+ */
+enum rte_bpf_arg_type {
+	RTE_BPF_ARG_UNDEF,      /**< undefined */
+	RTE_BPF_ARG_RAW,        /**< scalar value */
+	RTE_BPF_ARG_PTR = 0x10, /**< pointer to data buffer */
+	RTE_BPF_ARG_PTR_MBUF,   /**< pointer to rte_mbuf */
+	RTE_BPF_ARG_PTR_STACK,
+};
+
+/**
+ * function argument information
+ */
+struct rte_bpf_arg {
+	enum rte_bpf_arg_type type;
+	size_t size;     /**< for pointer types, size of data it points to */
+	size_t buf_size;
+	/**< for mbuf ptr type, max size of rte_mbuf data buffer */
+};
+
+/**
+ * determine is argument a pointer
+ */
+#define RTE_BPF_ARG_PTR_TYPE(x)	((x) & RTE_BPF_ARG_PTR)
+
+/**
+ * Possible types for external symbols.
+ */
+enum rte_bpf_xtype {
+	RTE_BPF_XTYPE_FUNC, /**< function */
+	RTE_BPF_XTYPE_VAR,  /**< variable */
+	RTE_BPF_XTYPE_NUM
+};
+
+/**
+ * Definition for external symbols available in the BPF program.
+ */
+struct rte_bpf_xsym {
+	const char *name;        /**< name */
+	enum rte_bpf_xtype type; /**< type */
+	union {
+		uint64_t (*func)(uint64_t, uint64_t, uint64_t,
+				uint64_t, uint64_t);
+		void *var;
+	}; /**< value */
+};
+
+/**
+ * Input parameters for loading eBPF code.
+ */
+struct rte_bpf_prm {
+	const struct ebpf_insn *ins; /**< array of eBPF instructions */
+	uint32_t nb_ins;            /**< number of instructions in ins */
+	const struct rte_bpf_xsym *xsym;
+	/**< array of external symbols that eBPF code is allowed to reference */
+	uint32_t nb_xsym; /**< number of elements in xsym */
+	struct rte_bpf_arg prog_arg; /**< eBPF program input arg description */
+};
+
+/**
+ * Information about compiled into native ISA eBPF code.
+ */
+struct rte_bpf_jit {
+	uint64_t (*func)(void *); /**< JIT-ed native code */
+	size_t sz;                /**< size of JIT-ed code */
+};
+
+struct rte_bpf;
+
+/**
+ * De-allocate all memory used by this eBPF execution context.
+ *
+ * @param bpf
+ *   BPF handle to destroy.
+ */
+void rte_bpf_destroy(struct rte_bpf *bpf);
+
+/**
+ * Create a new eBPF execution context and load given BPF code into it.
+ *
+ * @param prm
+ *  Parameters used to create and initialise the BPF exeution context.
+ * @return
+ *   BPF handle that is used in future BPF operations,
+ *   or NULL on error, with error code set in rte_errno.
+ *   Possible rte_errno errors include:
+ *   - EINVAL - invalid parameter passed to function
+ *   - ENOMEM - can't reserve enough memory
+ */
+struct rte_bpf *rte_bpf_load(const struct rte_bpf_prm *prm);
+
+/**
+ * Create a new eBPF execution context and load BPF code from given ELF
+ * file into it.
+ *
+ * @param prm
+ *  Parameters used to create and initialise the BPF exeution context.
+ * @param fname
+ *  Pathname for a ELF file.
+ * @param sname
+ *  Name of the executable section within the file to load.
+ * @return
+ *   BPF handle that is used in future BPF operations,
+ *   or NULL on error, with error code set in rte_errno.
+ *   Possible rte_errno errors include:
+ *   - EINVAL - invalid parameter passed to function
+ *   - ENOMEM - can't reserve enough memory
+ */
+struct rte_bpf *rte_bpf_elf_load(const struct rte_bpf_prm *prm,
+	const char *fname, const char *sname);
+
+/**
+ * Execute given BPF bytecode.
+ *
+ * @param bpf
+ *   handle for the BPF code to execute.
+ * @param ctx
+ *   pointer to input context.
+ * @return
+ *   BPF execution return value.
+ */
+uint64_t rte_bpf_exec(const struct rte_bpf *bpf, void *ctx);
+
+/**
+ * Execute given BPF bytecode over a set of input contexts.
+ *
+ * @param bpf
+ *   handle for the BPF code to execute.
+ * @param ctx
+ *   array of pointers to the input contexts.
+ * @param rc
+ *   array of return values (one per input).
+ * @param num
+ *   number of elements in ctx[] (and rc[]).
+ * @return
+ *   number of successfully processed inputs.
+ */
+uint32_t rte_bpf_exec_burst(const struct rte_bpf *bpf, void *ctx[],
+	uint64_t rc[], uint32_t num);
+
+/**
+ * Provide information about natively compield code for given BPF handle.
+ *
+ * @param bpf
+ *   handle for the BPF code.
+ * @param jit
+ *   pointer to the rte_bpf_jit structure to be filled with related data.
+ * @return
+ *   - -EINVAL if the parameters are invalid.
+ *   - Zero if operation completed successfully.
+ */
+int rte_bpf_get_jit(const struct rte_bpf *bpf, struct rte_bpf_jit *jit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BPF_H_ */
diff --git a/lib/librte_bpf/rte_bpf_version.map b/lib/librte_bpf/rte_bpf_version.map
new file mode 100644
index 000000000..ff65144df
--- /dev/null
+++ b/lib/librte_bpf/rte_bpf_version.map
@@ -0,0 +1,12 @@
+EXPERIMENTAL {
+	global:
+
+	rte_bpf_destroy;
+	rte_bpf_elf_load;
+	rte_bpf_exec;
+	rte_bpf_exec_burst;
+	rte_bpf_get_jit;
+	rte_bpf_load;
+
+	local: *;
+};
diff --git a/lib/meson.build b/lib/meson.build
index 166905c1c..9635aff41 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -23,7 +23,7 @@ libraries = [ 'compat', # just a header, used for versioning
 	# add pkt framework libs which use other libs from above
 	'port', 'table', 'pipeline',
 	# flow_classify lib depends on pkt framework table lib
-	'flow_classify']
+	'flow_classify', 'bpf']
 
 foreach l:libraries
 	build = true
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 29a2a6095..6a3bde136 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -82,6 +82,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER)          += -lrte_power
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EFD)            += -lrte_efd
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BPF)            += -lrte_bpf -lelf
+
 _LDLIBS-y += --whole-archive
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE)        += -lrte_cfgfile
-- 
2.13.6

^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [PATCH 05/13] baseband/turbo_sw: scalling input LLR to range [-16 16]
  @ 2018-05-07 12:50  4%   ` De Lara Guarch, Pablo
  2018-05-09 14:23  3%   ` [dpdk-dev] [PATCH v2 04/14] baseband/turbo_sw: scalling likelihood ratio (LLR) input Kamil Chalupnik
  1 sibling, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2018-05-07 12:50 UTC (permalink / raw)
  To: Chalupnik, KamilX, dev; +Cc: Mokhtar, Amr



> -----Original Message-----
> From: Chalupnik, KamilX
> Sent: Thursday, April 26, 2018 2:30 PM
> To: dev@dpdk.org
> Cc: Mokhtar, Amr <amr.mokhtar@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Chalupnik, KamilX
> <kamilx.chalupnik@intel.com>
> Subject: [PATCH 05/13] baseband/turbo_sw: scalling input LLR to range [-16 16]

What is LLR? It is worth expanding the acronym, and then you can use it later.


> 
> From: KamilX Chalupnik <kamilx.chalupnik@intel.com>
> 
> Update Turbo Software driver for Wireless Baseband Device:
> - function scaling input LLR values to specific range [-16, 16] added
> - new test vectors to check device capabilities added
> 
> Signed-off-by: Kamil Chalupnik <kamilx.chalupnik@intel.com>
> Acked-by: Amr Mokhtar <amr.mokhtar@intel.com>

...

> --- a/app/test-bbdev/test_bbdev_perf.c
> +++ b/app/test-bbdev/test_bbdev_perf.c
> @@ -4,6 +4,7 @@
> 
>  #include <stdio.h>
>  #include <inttypes.h>
> +#include <math.h>
> 
>  #include <rte_eal.h>
>  #include <rte_common.h>
> @@ -609,10 +610,32 @@ allocate_buffers_on_socket(struct
> rte_bbdev_op_data **buffers, const int len,
>  	return (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS;  }
> 
> +static void
> +limit_input_llr_val_range(struct rte_bbdev_op_data *input_ops,
> +		const uint16_t n, const int8_t max_llr_modulus) {

No need for const in parameters passed by value.

> +	uint16_t i, byte_idx;
> +

...

>  static inline void
> diff --git a/lib/librte_bbdev/rte_bbdev_op.h b/lib/librte_bbdev/rte_bbdev_op.h
> index 1a80588..90a688e 100644
> --- a/lib/librte_bbdev/rte_bbdev_op.h
> +++ b/lib/librte_bbdev/rte_bbdev_op.h
> @@ -379,6 +379,10 @@ struct rte_bbdev_op_turbo_enc {  struct
> rte_bbdev_op_cap_turbo_dec {
>  	/**< Flags from rte_bbdev_op_td_flag_bitmasks */
>  	uint32_t capability_flags;
> +	/** Maximal LLR absolute value. Acceptable LLR values lie in range
> +	 * [-max_llr_modulus, max_llr_modulus].
> +	 */
> +	int8_t max_llr_modulus;
>  	uint8_t num_buffers_src;  /**< Num input code block buffers */
>  	/**< Num hard output code block buffers */
>  	uint8_t num_buffers_hard_out;

This is breaking ABI, add a note in ABI changes, in release notes.

> --
> 2.5.5

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v8] ethdev: check Rx/Tx offloads
  @ 2018-05-08 10:05  1% ` Wei Dai
  2018-05-10  0:49  1%   ` [dpdk-dev] [PATCH v9] ethdev: new Rx/Tx offloads API Wei Dai
  2018-05-08 10:10  1% ` [dpdk-dev] [PATCH v8] ethdev: check Rx/Tx offloads Wei Dai
  1 sibling, 1 reply; 200+ results
From: Wei Dai @ 2018-05-08 10:05 UTC (permalink / raw)
  To: ferruh.yigit, thomas, declan.doherty, linville, mw, mk, gtzalik,
	evgenys, ravi1.kumar, shepard.siegel, ed.czeck, john.miller,
	ajit.khaparde, somnath.kotur, jerin.jacob, maciej.czekaj,
	shijith.thotton, ssrinivasan, santosh.shukla, rahul.lakkireddy,
	ohndale, hyonkim, wenzhuo.lu, konstantin.ananyev, beilei.xing,
	qi.z.zhang, xiao.w.wang, jingjing.wu, tdu, dima, nsamsono,
	jianbo.liu, adrien.mazarguil, nelio.laranjeiro, yskoh, matan,
	vido, alejandro.lucero, emant.agrawal, shreyansh.jain,
	hemant.agrawal, harish.patil, rasesh.mody, asesh.mody,
	shahed.shaikh, arybchenko, yongwang, maxime.coquelin, mtetsuyah,
	tiwei.bie, allain.legacy, matt.peters, pascal.mazon,
	bruce.richardson, gaetan.rivet, jasvinder.singh,
	cristian.dumitrescu
  Cc: dev, Wei Dai

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure( ) and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If any offloading is enabled in rte_eth_dev_configure( ) by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure( ),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup( ).
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure( ) and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup( ), it must be per-queue type,
otherwise return error.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup( ) function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get( ).

In the beginning of [rt]x_queue_setup( ) of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  26 +++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  88 +++++++++++++++++
 35 files changed, 240 insertions(+), 1346 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..56483fb 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,30 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure( )`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If any offloading is enabled in ``rte_eth_dev_configure( )`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure( )``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup( )`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup( )``, it must be per-queue type, otherwise return error.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..637e684 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* **ethdev: changes to offload API**
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup( )``. Now any offloading enabled in ``rte_eth_dev_configure( )``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup( )``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup( )`` must be per-queue type, otherwise return error.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..523a07b 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		RTE_PMD_DEBUG_TRACE("ethdev port_id=%d requested Rx offloads "
+				    "0x%" PRIx64 " doesn't match Rx offloads "
+				    "capabilities 0x%" PRIx64 "\n",
+				    port_id,
+				    local_conf.rxmode.offloads,
+				    dev_info.rx_offload_capa);
+		return -EINVAL;
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		RTE_PMD_DEBUG_TRACE("ethdev port_id=%d requested Tx offloads "
+				    "0x%" PRIx64 " doesn't match Tx offloads "
+				    "capabilities 0x%" PRIx64 "\n",
+				    port_id,
+				    local_conf.txmode.offloads,
+				    dev_info.tx_offload_capa);
+		return -EINVAL;
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,39 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		RTE_PMD_DEBUG_TRACE("Ethdev port_id=%d rx_queue_id=%d, new "
+				    "added offloads 0x" PRIx64 " must be "
+				    "within pre-queue offload capabilities 0x"
+				    PRIx64 " in %s\n",
+				    port_id,
+				    rx_queue_id,
+				    local_conf.offloads,
+				    dev_info.rx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1667,39 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		RTE_PMD_DEBUG_TRACE("Ethdev port_id=%d tx_queue_id=%d, new "
+				    "added offloads 0x" PRIx64 " must be "
+				    "within pre-queue offload capabilities 0x"
+				    PRIx64 " in %s\n",
+				    port_id,
+				    tx_queue_id,
+				    local_conf.offloads,
+				    dev_info.tx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v8] ethdev: check Rx/Tx offloads
    2018-05-08 10:05  1% ` [dpdk-dev] [PATCH v8] " Wei Dai
@ 2018-05-08 10:10  1% ` Wei Dai
  1 sibling, 0 replies; 200+ results
From: Wei Dai @ 2018-05-08 10:10 UTC (permalink / raw)
  To: ferruh.yigit, thomas, shahafs, qi.z.zhang; +Cc: dev, Wei Dai

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure( ) and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If any offloading is enabled in rte_eth_dev_configure( ) by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure( ),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup( ).
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure( ) and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup( ), it must be per-queue type,
otherwise return error.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup( ) function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get( ).

In the beginning of [rt]x_queue_setup( ) of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  26 +++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  88 +++++++++++++++++
 35 files changed, 240 insertions(+), 1346 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..56483fb 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,30 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure( )`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If any offloading is enabled in ``rte_eth_dev_configure( )`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure( )``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup( )`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup( )``, it must be per-queue type, otherwise return error.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..637e684 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* **ethdev: changes to offload API**
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup( )``. Now any offloading enabled in ``rte_eth_dev_configure( )``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup( )``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup( )`` must be per-queue type, otherwise return error.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..523a07b 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		RTE_PMD_DEBUG_TRACE("ethdev port_id=%d requested Rx offloads "
+				    "0x%" PRIx64 " doesn't match Rx offloads "
+				    "capabilities 0x%" PRIx64 "\n",
+				    port_id,
+				    local_conf.rxmode.offloads,
+				    dev_info.rx_offload_capa);
+		return -EINVAL;
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		RTE_PMD_DEBUG_TRACE("ethdev port_id=%d requested Tx offloads "
+				    "0x%" PRIx64 " doesn't match Tx offloads "
+				    "capabilities 0x%" PRIx64 "\n",
+				    port_id,
+				    local_conf.txmode.offloads,
+				    dev_info.tx_offload_capa);
+		return -EINVAL;
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,39 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		RTE_PMD_DEBUG_TRACE("Ethdev port_id=%d rx_queue_id=%d, new "
+				    "added offloads 0x" PRIx64 " must be "
+				    "within pre-queue offload capabilities 0x"
+				    PRIx64 " in %s\n",
+				    port_id,
+				    rx_queue_id,
+				    local_conf.offloads,
+				    dev_info.rx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1667,39 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		RTE_PMD_DEBUG_TRACE("Ethdev port_id=%d tx_queue_id=%d, new "
+				    "added offloads 0x" PRIx64 " must be "
+				    "within pre-queue offload capabilities 0x"
+				    PRIx64 " in %s\n",
+				    port_id,
+				    tx_queue_id,
+				    local_conf.offloads,
+				    dev_info.tx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v2 04/14] baseband/turbo_sw: scalling likelihood ratio (LLR) input
    2018-05-07 12:50  4%   ` De Lara Guarch, Pablo
@ 2018-05-09 14:23  3%   ` Kamil Chalupnik
  1 sibling, 0 replies; 200+ results
From: Kamil Chalupnik @ 2018-05-09 14:23 UTC (permalink / raw)
  To: dev; +Cc: amr.mokhtar, pablo.de.lara.guarch, KamilX Chalupnik

From: KamilX Chalupnik <kamilx.chalupnik@intel.com>

Update Turbo Software driver for Wireless Baseband Device:
- function scaling input LLR values to specific range [-16, 16] added
- new test vectors to check device capabilities added
- release note updated accordingly

Signed-off-by: Kamil Chalupnik <kamilx.chalupnik@intel.com>
Acked-by: Amr Mokhtar <amr.mokhtar@intel.com>
---
 app/test-bbdev/Makefile                            |  2 +
 app/test-bbdev/test_bbdev_perf.c                   | 44 +++++++++++++++++++++-
 .../test_vectors/turbo_enc_c1_k40_r0_e1190_rm.data | 36 ++++++++++++++++++
 .../test_vectors/turbo_enc_c1_k40_r0_e1194_rm.data | 36 ++++++++++++++++++
 .../test_vectors/turbo_enc_c1_k40_r0_e1196_rm.data | 36 ++++++++++++++++++
 .../test_vectors/turbo_enc_c1_k40_r0_e272_rm.data  | 33 ++++++++++++++++
 doc/guides/rel_notes/release_18_05.rst             |  6 +++
 doc/guides/tools/testbbdev.rst                     |  7 ++++
 drivers/baseband/turbo_sw/bbdev_turbo_software.c   | 32 ++++++++++++----
 lib/librte_bbdev/rte_bbdev_op.h                    |  4 ++
 10 files changed, 226 insertions(+), 10 deletions(-)
 create mode 100644 app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1190_rm.data
 create mode 100644 app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1194_rm.data
 create mode 100644 app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1196_rm.data
 create mode 100644 app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e272_rm.data

diff --git a/app/test-bbdev/Makefile b/app/test-bbdev/Makefile
index 9aedd77..6da0c8e 100644
--- a/app/test-bbdev/Makefile
+++ b/app/test-bbdev/Makefile
@@ -20,4 +20,6 @@ SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev.c
 SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev_perf.c
 SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev_vector.c
 
+LDLIBS += -lm
+
 include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-bbdev/test_bbdev_perf.c b/app/test-bbdev/test_bbdev_perf.c
index 00f3b08..f358083 100644
--- a/app/test-bbdev/test_bbdev_perf.c
+++ b/app/test-bbdev/test_bbdev_perf.c
@@ -4,6 +4,7 @@
 
 #include <stdio.h>
 #include <inttypes.h>
+#include <math.h>
 
 #include <rte_eal.h>
 #include <rte_common.h>
@@ -609,10 +610,32 @@ allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const int len,
 	return (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS;
 }
 
+static void
+limit_input_llr_val_range(struct rte_bbdev_op_data *input_ops,
+		uint16_t n, int8_t max_llr_modulus)
+{
+	uint16_t i, byte_idx;
+
+	for (i = 0; i < n; ++i) {
+		struct rte_mbuf *m = input_ops[i].data;
+		while (m != NULL) {
+			int8_t *llr = rte_pktmbuf_mtod_offset(m, int8_t *,
+					input_ops[i].offset);
+			for (byte_idx = 0; byte_idx < input_ops[i].length;
+					++byte_idx)
+				llr[byte_idx] = round((double)max_llr_modulus *
+						llr[byte_idx] / INT8_MAX);
+
+			m = m->next;
+		}
+	}
+}
+
 static int
 fill_queue_buffers(struct test_op_params *op_params,
 		struct rte_mempool *in_mp, struct rte_mempool *hard_out_mp,
 		struct rte_mempool *soft_out_mp, uint16_t queue_id,
+		const struct rte_bbdev_op_cap *capabilities,
 		uint16_t min_alignment, const int socket_id)
 {
 	int ret;
@@ -649,6 +672,10 @@ fill_queue_buffers(struct test_op_params *op_params,
 				"Couldn't init rte_bbdev_op_data structs");
 	}
 
+	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
+		limit_input_llr_val_range(*queue_ops[DATA_INPUT], n,
+			capabilities->cap.turbo_dec.max_llr_modulus);
+
 	return 0;
 }
 
@@ -995,6 +1022,7 @@ run_test_case_on_device(test_case_function *test_case_func, uint8_t dev_id,
 	struct active_device *ad;
 	unsigned int burst_sz = get_burst_sz();
 	enum rte_bbdev_op_type op_type = test_vector.op_type;
+	const struct rte_bbdev_op_cap *capabilities = NULL;
 
 	ad = &active_devs[dev_id];
 
@@ -1027,9 +1055,20 @@ run_test_case_on_device(test_case_function *test_case_func, uint8_t dev_id,
 		goto fail;
 	}
 
-	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
+	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC) {
+		/* Find Decoder capabilities */
+		const struct rte_bbdev_op_cap *cap = info.drv.capabilities;
+		while (cap->type != RTE_BBDEV_OP_NONE) {
+			if (cap->type == RTE_BBDEV_OP_TURBO_DEC) {
+				capabilities = cap;
+				break;
+			}
+		}
+		TEST_ASSERT_NOT_NULL(capabilities,
+				"Couldn't find Decoder capabilities");
+
 		create_reference_dec_op(op_params->ref_dec_op);
-	else if (test_vector.op_type == RTE_BBDEV_OP_TURBO_ENC)
+	} else if (test_vector.op_type == RTE_BBDEV_OP_TURBO_ENC)
 		create_reference_enc_op(op_params->ref_enc_op);
 
 	for (i = 0; i < ad->nb_queues; ++i) {
@@ -1038,6 +1077,7 @@ run_test_case_on_device(test_case_function *test_case_func, uint8_t dev_id,
 				ad->hard_out_mbuf_pool,
 				ad->soft_out_mbuf_pool,
 				ad->queue_ids[i],
+				capabilities,
 				info.drv.min_alignment,
 				socket_id);
 		if (f_ret != TEST_SUCCESS) {
diff --git a/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1190_rm.data b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1190_rm.data
new file mode 100644
index 0000000..6221756
--- /dev/null
+++ b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1190_rm.data
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+op_type =
+RTE_BBDEV_OP_TURBO_ENC
+
+input0 =
+0x11D2BCAC, 0x4D
+
+output0 =
+0xD2399179, 0x640EB999, 0x2CBAF577, 0xAF224AE2, 0x9D139927, 0xE6909B29, 0xA25B7F47, 0x2AA224CE,
+0x399179F2, 0x0EB999D2, 0xBAF57764, 0x224AE22C, 0x139927AF, 0x909B299D, 0x5B7F47E6, 0xA224CEA2,
+0x9179F22A, 0xB999D239, 0xF577640E, 0x4AE22CBA, 0x9927AF22, 0x9B299D13, 0x7F47E690, 0x24CEA25B,
+0x79F22AA2, 0x99D23991, 0x77640EB9, 0xE22CBAF5, 0x27AF224A, 0x299D1399, 0x47E6909B, 0xCEA25B7F,
+0xF22AA224, 0xD2399179, 0x640EB999, 0x2CBAF577, 0xAF224AE2, 0x24
+
+e =
+1190
+
+k =
+40
+
+ncb =
+192
+
+rv_index =
+0
+
+code_block_mode =
+1
+
+op_flags =
+RTE_BBDEV_TURBO_RATE_MATCH
+
+expected_status =
+OK
diff --git a/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1194_rm.data b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1194_rm.data
new file mode 100644
index 0000000..c569abd
--- /dev/null
+++ b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1194_rm.data
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+op_type =
+RTE_BBDEV_OP_TURBO_ENC
+
+input0 =
+0x11D2BCAC, 0x4D
+
+output0 =
+0xB3E8D6DF, 0xBC8A2889, 0x744E649E, 0x99436EA6, 0x8B6EFD1D, 0xAB889238, 0xE744E6C9, 0x39E4664A,
+0xE8D6DF91, 0x8A2889B3, 0x4E649EBC, 0x436EA674, 0x6EFD1D99, 0x8892388B, 0x44E6C9AB, 0xE4664AE7,
+0xD6DF9139, 0x2889B3E8, 0x649EBC8A, 0x6EA6744E, 0xFD1D9943, 0x92388B6E, 0xE6C9AB88, 0x664AE744,
+0xDF9139E4, 0x89B3E8D6, 0x9EBC8A28, 0xA6744E64, 0x1D99436E, 0x388B6EFD, 0xC9AB8892, 0x4AE744E6,
+0x9139E466, 0xB3E8D6DF, 0xBC8A2889, 0x744E649E, 0x99436EA6, 0xC01D
+
+e =
+1194
+
+k =
+40
+
+ncb =
+192
+
+rv_index =
+2
+
+code_block_mode =
+1
+
+op_flags =
+RTE_BBDEV_TURBO_RATE_MATCH
+
+expected_status =
+OK
diff --git a/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1196_rm.data b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1196_rm.data
new file mode 100644
index 0000000..72be6f5
--- /dev/null
+++ b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e1196_rm.data
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+op_type =
+RTE_BBDEV_OP_TURBO_ENC
+
+input0 =
+0x11D2BCAC, 0x4D
+
+output0 =
+0xBC8A2889, 0x744E649E, 0x99436EA6, 0x8B6EFD1D, 0xAB889238, 0xE744E6C9, 0x39E4664A, 0xE8D6DF91,
+0x8A2889B3, 0x4E649EBC, 0x436EA674, 0x6EFD1D99, 0x8892388B, 0x44E6C9AB, 0xE4664AE7, 0xD6DF9139,
+0x2889B3E8, 0x649EBC8A, 0x6EA6744E, 0xFD1D9943, 0x92388B6E, 0xE6C9AB88, 0x664AE744, 0xDF9139E4,
+0x89B3E8D6, 0x9EBC8A28, 0xA6744E64, 0x1D99436E, 0x388B6EFD, 0xC9AB8892, 0x4AE744E6, 0x9139E466,
+0xB3E8D6DF, 0xBC8A2889, 0x744E649E, 0x99436EA6, 0x8B6EFD1D, 0x9038
+
+e =
+1196
+
+k =
+40
+
+ncb =
+192
+
+rv_index =
+3
+
+code_block_mode =
+1
+
+op_flags =
+RTE_BBDEV_TURBO_RATE_MATCH
+
+expected_status =
+OK
diff --git a/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e272_rm.data b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e272_rm.data
new file mode 100644
index 0000000..883a76c
--- /dev/null
+++ b/app/test-bbdev/test_vectors/turbo_enc_c1_k40_r0_e272_rm.data
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+op_type =
+RTE_BBDEV_OP_TURBO_ENC
+
+input0 =
+0x11d2bcac, 0x4d
+
+output0 =
+0xd2399179, 0x640eb999, 0x2cbaf577, 0xaf224ae2, 0x9d139927, 0xe6909b29, 0xa25b7f47, 0x2aa224ce,
+0x79f2
+
+e =
+272
+
+k =
+40
+
+ncb =
+192
+
+rv_index =
+0
+
+code_block_mode =
+1
+
+op_flags =
+RTE_BBDEV_TURBO_RATE_MATCH
+
+expected_status =
+OK
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 3923dc2..427ce6d 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -69,6 +69,12 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* **New parameter added to rte_bbdev_op_cap_turbo_dec.**
+
+  A new parameter ``max_llr_modulus`` has been added to
+  ``rte_bbdev_op_cap_turbo_dec`` structure to specify maximal LLR (likelihood
+  ratio) absolute value.
+
 
 Removed Items
 -------------
diff --git a/doc/guides/tools/testbbdev.rst b/doc/guides/tools/testbbdev.rst
index 5c7112d..8203787 100644
--- a/doc/guides/tools/testbbdev.rst
+++ b/doc/guides/tools/testbbdev.rst
@@ -151,6 +151,13 @@ It runs all tests with following vectors:
 
 - ``bbdev_vector_te_default.data``
 
+- ``turbo_enc_c1_k40_r0_e1190_rm.data``
+
+- ``turbo_enc_c1_k40_r0_e1194_rm.data``
+
+- ``turbo_enc_c1_k40_r0_e1196_rm.data``
+
+- ``turbo_enc_c1_k40_r0_e272_rm.data``
 
 .. code-block:: console
 
diff --git a/drivers/baseband/turbo_sw/bbdev_turbo_software.c b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
index 4f46284..9f01abf 100644
--- a/drivers/baseband/turbo_sw/bbdev_turbo_software.c
+++ b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
@@ -135,6 +135,7 @@ info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
 					RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN |
 					RTE_BBDEV_TURBO_CRC_TYPE_24B |
 					RTE_BBDEV_TURBO_EARLY_TERMINATION,
+				.max_llr_modulus = 16,
 				.num_buffers_src = RTE_BBDEV_MAX_CODE_BLOCKS,
 				.num_buffers_hard_out =
 						RTE_BBDEV_MAX_CODE_BLOCKS,
@@ -578,8 +579,16 @@ process_enc_cb(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,
 
 	/* Rate-matching */
 	if (enc->op_flags & RTE_BBDEV_TURBO_RATE_MATCH) {
+		uint8_t mask_id;
+		/* Integer round up division by 8 */
+		uint16_t out_len = (e + 7) >> 3;
+		/* The mask array is indexed using E%8. E is an even number so
+		 * there are only 4 possible values.
+		 */
+		const uint8_t mask_out[] = {0xFF, 0xC0, 0xF0, 0xFC};
+
 		/* get output data starting address */
-		rm_out = (uint8_t *)rte_pktmbuf_append(m_out, (e >> 3));
+		rm_out = (uint8_t *)rte_pktmbuf_append(m_out, out_len);
 		if (rm_out == NULL) {
 			op->status |= 1 << RTE_BBDEV_DATA_ERROR;
 			rte_bbdev_log(ERR,
@@ -619,7 +628,7 @@ process_enc_cb(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,
 		rm_req.tin1 = out1;
 		rm_req.tin2 = out2;
 		rm_resp.output = rm_out;
-		rm_resp.OutputLen = (e >> 3);
+		rm_resp.OutputLen = out_len;
 		if (enc->op_flags & RTE_BBDEV_TURBO_RV_INDEX_BYPASS)
 			rm_req.bypass_rvidx = 1;
 		else
@@ -630,6 +639,13 @@ process_enc_cb(struct turbo_sw_queue *q, struct rte_bbdev_enc_op *op,
 			rte_bbdev_log(ERR, "Rate matching failed");
 			return;
 		}
+
+		/* SW fills an entire last byte even if E%8 != 0. Clear the
+		 * superfluous data bits for consistency with HW device.
+		 */
+		mask_id = (e & 7) >> 1;
+		rm_out[out_len - 1] &= mask_out[mask_id];
+
 		enc->output.length += rm_resp.OutputLen;
 	} else {
 		/* Rate matching is bypassed */
@@ -806,7 +822,7 @@ remove_nulls_from_circular_buf(const uint8_t *in, uint8_t *out, uint16_t k,
 	}
 
 	/* Last interlaced row is different - its last byte is the only padding
-	 * byte. We can have from 2 up to 26 padding bytes (Nd) per sub-block.
+	 * byte. We can have from 4 up to 28 padding bytes (Nd) per sub-block.
 	 * After interlacing the 1st and 2nd parity sub-blocks we can have 0, 1
 	 * or 2 padding bytes each time we make a step of 2 * R_SUBBLOCK bytes
 	 * (moving to another column). 2nd parity sub-block uses the same
@@ -817,10 +833,10 @@ remove_nulls_from_circular_buf(const uint8_t *in, uint8_t *out, uint16_t k,
 	 * 32nd (31+1) byte, then 64th etc. (step is C_SUBBLOCK == 32) and the
 	 * last byte will be the first byte from the sub-block:
 	 * (32 + 32 * (R_SUBBLOCK-1)) % Kw == Kw % Kw == 0. Nd can't  be smaller
-	 * than 2 so we know that bytes with ids 0 and 1 must be the padding
-	 * bytes. The bytes from the 1st parity sub-block are the bytes from the
-	 * 31st column - Nd can't be greater than 26 so we are sure that there
-	 * are no padding bytes in 31st column.
+	 * than 4 so we know that bytes with ids 0, 1, 2 and 3 must be the
+	 * padding bytes. The bytes from the 1st parity sub-block are the bytes
+	 * from the 31st column - Nd can't be greater than 28 so we are sure
+	 * that there are no padding bytes in 31st column.
 	 */
 	rte_memcpy(&out[out_idx], &in[in_idx], 2 * r_subblock - 1);
 }
@@ -835,7 +851,7 @@ move_padding_bytes(const uint8_t *in, uint8_t *out, uint16_t k,
 
 	rte_memcpy(&out[nd], in, d);
 	rte_memcpy(&out[nd + kpi + 64], &in[kpi], d);
-	rte_memcpy(&out[nd + 2 * (kpi + 64)], &in[2 * kpi], d);
+	rte_memcpy(&out[(nd - 1) + 2 * (kpi + 64)], &in[2 * kpi], d);
 }
 
 static inline void
diff --git a/lib/librte_bbdev/rte_bbdev_op.h b/lib/librte_bbdev/rte_bbdev_op.h
index 1a80588..90a688e 100644
--- a/lib/librte_bbdev/rte_bbdev_op.h
+++ b/lib/librte_bbdev/rte_bbdev_op.h
@@ -379,6 +379,10 @@ struct rte_bbdev_op_turbo_enc {
 struct rte_bbdev_op_cap_turbo_dec {
 	/**< Flags from rte_bbdev_op_td_flag_bitmasks */
 	uint32_t capability_flags;
+	/** Maximal LLR absolute value. Acceptable LLR values lie in range
+	 * [-max_llr_modulus, max_llr_modulus].
+	 */
+	int8_t max_llr_modulus;
 	uint8_t num_buffers_src;  /**< Num input code block buffers */
 	/**< Num hard output code block buffers */
 	uint8_t num_buffers_hard_out;
-- 
2.5.5

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 08/14] bbdev: split queue groups
  2018-04-26 13:30  5% ` [dpdk-dev] [PATCH 12/13] bbdev: split queue groups Kamil Chalupnik
@ 2018-05-09 14:35  5%   ` Kamil Chalupnik
  0 siblings, 0 replies; 200+ results
From: Kamil Chalupnik @ 2018-05-09 14:35 UTC (permalink / raw)
  To: dev; +Cc: amr.mokhtar, pablo.de.lara.guarch, KamilX Chalupnik

From: KamilX Chalupnik <kamilx.chalupnik@intel.com>

Splitting Queue Groups into UL/DL Groups in Turbo Software
Driver. They are independent for Decode/Encode.
Release note updated accordingly.

Signed-off-by: Kamil Chalupnik <kamilx.chalupnik@intel.com>
---
 app/test-bbdev/test_bbdev.c                      | 11 ++---------
 doc/guides/rel_notes/release_18_05.rst           |  6 ++++++
 drivers/baseband/null/bbdev_null.c               |  3 ++-
 drivers/baseband/turbo_sw/bbdev_turbo_software.c |  3 ++-
 lib/librte_bbdev/rte_bbdev.c                     | 13 +++++++++++--
 lib/librte_bbdev/rte_bbdev.h                     |  6 ++++--
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/app/test-bbdev/test_bbdev.c b/app/test-bbdev/test_bbdev.c
index 10579ea..5d325b6 100644
--- a/app/test-bbdev/test_bbdev.c
+++ b/app/test-bbdev/test_bbdev.c
@@ -273,7 +273,7 @@ test_bbdev_configure_stop_queue(void)
 
 	/* Valid queue configuration */
 	ts_params->qconf.queue_size = info.drv.queue_size_lim;
-	ts_params->qconf.priority = info.drv.max_queue_priority;
+	ts_params->qconf.priority = info.drv.max_ul_queue_priority;
 
 	/* Device - started; queue - started */
 	rte_bbdev_start(dev_id);
@@ -413,14 +413,7 @@ test_bbdev_configure_invalid_queue_configure(void)
 			ts_params->qconf.queue_size);
 
 	ts_params->qconf.queue_size = info.drv.queue_size_lim;
-	ts_params->qconf.priority = info.drv.max_queue_priority + 1;
-	TEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,
-			&ts_params->qconf),
-			"Failed test for rte_bbdev_queue_configure: "
-			"invalid value qconf.queue_size: %u",
-			ts_params->qconf.queue_size);
-
-	ts_params->qconf.priority = info.drv.max_queue_priority;
+	ts_params->qconf.priority = info.drv.max_ul_queue_priority;
 	queue_id = info.num_queues;
 	TEST_ASSERT_FAIL(rte_bbdev_queue_configure(dev_id, queue_id,
 			&ts_params->qconf),
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 427ce6d..86b669c 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -75,6 +75,12 @@ ABI Changes
   ``rte_bbdev_op_cap_turbo_dec`` structure to specify maximal LLR (likelihood
   ratio) absolute value.
 
+* **Queue Groups split into UL/DL Groups**
+
+  Queue Groups have been split into UL/DL Groups in Turbo Software Driver.
+  They are independent for Decode/Encode. ``rte_bbdev_driver_info`` reflects
+  introduced changes.
+
 
 Removed Items
 -------------
diff --git a/drivers/baseband/null/bbdev_null.c b/drivers/baseband/null/bbdev_null.c
index 6bc8491..e8e541f 100644
--- a/drivers/baseband/null/bbdev_null.c
+++ b/drivers/baseband/null/bbdev_null.c
@@ -71,7 +71,8 @@ info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
 	dev_info->max_num_queues = internals->max_nb_queues;
 	dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT;
 	dev_info->hardware_accelerated = false;
-	dev_info->max_queue_priority = 0;
+	dev_info->max_dl_queue_priority = 0;
+	dev_info->max_ul_queue_priority = 0;
 	dev_info->default_queue_conf = default_queue_conf;
 	dev_info->capabilities = bbdev_capabilities;
 	dev_info->cpu_flag_reqs = NULL;
diff --git a/drivers/baseband/turbo_sw/bbdev_turbo_software.c b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
index bbb4e40..696addf 100644
--- a/drivers/baseband/turbo_sw/bbdev_turbo_software.c
+++ b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
@@ -175,7 +175,8 @@ info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
 	dev_info->max_num_queues = internals->max_nb_queues;
 	dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT;
 	dev_info->hardware_accelerated = false;
-	dev_info->max_queue_priority = 0;
+	dev_info->max_dl_queue_priority = 0;
+	dev_info->max_ul_queue_priority = 0;
 	dev_info->default_queue_conf = default_queue_conf;
 	dev_info->capabilities = bbdev_capabilities;
 	dev_info->cpu_flag_reqs = &cpu_flag;
diff --git a/lib/librte_bbdev/rte_bbdev.c b/lib/librte_bbdev/rte_bbdev.c
index 74ecc49..28434e0 100644
--- a/lib/librte_bbdev/rte_bbdev.c
+++ b/lib/librte_bbdev/rte_bbdev.c
@@ -495,11 +495,20 @@ rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,
 					conf->queue_size, queue_id, dev_id);
 			return -EINVAL;
 		}
-		if (conf->priority > dev_info.max_queue_priority) {
+		if (conf->op_type == RTE_BBDEV_OP_TURBO_DEC &&
+			conf->priority > dev_info.max_ul_queue_priority) {
 			rte_bbdev_log(ERR,
 					"Priority (%u) of queue %u of bdev %u must be <= %u",
 					conf->priority, queue_id, dev_id,
-					dev_info.max_queue_priority);
+					dev_info.max_ul_queue_priority);
+			return -EINVAL;
+		}
+		if (conf->op_type == RTE_BBDEV_OP_TURBO_ENC &&
+			conf->priority > dev_info.max_dl_queue_priority) {
+			rte_bbdev_log(ERR,
+					"Priority (%u) of queue %u of bdev %u must be <= %u",
+					conf->priority, queue_id, dev_id,
+					dev_info.max_dl_queue_priority);
 			return -EINVAL;
 		}
 	}
diff --git a/lib/librte_bbdev/rte_bbdev.h b/lib/librte_bbdev/rte_bbdev.h
index bdcd1d0..6693de2 100644
--- a/lib/librte_bbdev/rte_bbdev.h
+++ b/lib/librte_bbdev/rte_bbdev.h
@@ -281,8 +281,10 @@ struct rte_bbdev_driver_info {
 	uint32_t queue_size_lim;
 	/** Set if device off-loads operation to hardware  */
 	bool hardware_accelerated;
-	/** Max value supported by queue priority */
-	uint8_t max_queue_priority;
+	/** Max value supported by queue priority for DL */
+	uint8_t max_dl_queue_priority;
+	/** Max value supported by queue priority for UL */
+	uint8_t max_ul_queue_priority;
 	/** Set if device supports per-queue interrupts */
 	bool queue_intr_supported;
 	/** Minimum alignment of buffers, in bytes */
-- 
2.5.5

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
  @ 2018-05-09 15:59  3%   ` Van Haaren, Harry
  2018-05-09 16:11  0%     ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Van Haaren, Harry @ 2018-05-09 15:59 UTC (permalink / raw)
  To: Burakov, Anatoly, dev; +Cc: Richardson, Bruce, thomas

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Anatoly Burakov
> Sent: Monday, April 30, 2018 1:09 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; thomas@monjalon.net
> Subject: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
> 
> As has been suggested [1], all DPDK runtime paths should be put
> into a single place. This patchset accomplishes exactly that.
> 
> If running as root, all files will be put under /var/run/dpdk/<prefix>,
> otherwise they will be put under $XDG_RUNTIME_PATH/dpdk/<prefix>, or, if
> that environment variable is not defined, all files will go under
> /tmp/dpdk/<prefix>.
> 
> [1] http://dpdk.org/dev/patchwork/patch/38688/
> 
> v2:
> - Rebase on rc1
> 
> Anatoly Burakov (4):
>   eal: remove unused define
>   eal: rename function returning hugepage data path
>   eal: add directory for DPDK runtime data
>   eal: move all runtime data into DPDK runtime dir

<snip>


No full code review, high level comments:

We have to be careful in changing /var/run/.rte_config, which has always been
the default DPDK primary application lockfile. This has been used to identify
if a primary DPDK application is alive (see rte_eal_primary_proc_alive()) and
possibly the write-lock on this file is checked by other tools/utilities directly
without any DPDK function call.

Changing the filepath just before a release isn't a good idea - we should treat
this as an ABI/API break, as the change will break functionality in other projects
such as CollectD[1], which (by default ;) rely on the defaults. There is a config
file for CollectD to manually override the location, but this will cause headaches
from a usability POV.

I'm not opposed to the change - particularly as I gather the new memory subsystem
causes a number of lockfiles to be created - but we must do our due diligence and
give other projects fair-warning that this change is coming.

As such, I recommend this patchset in its current form (particularly patches 2,3,4)
to be deferred past 18.05.


-Harry


[1] https://github.com/collectd/collectd/blob/master/src/utils_dpdk.c#L46

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
  2018-05-09 15:59  3%   ` Van Haaren, Harry
@ 2018-05-09 16:11  0%     ` Bruce Richardson
  2018-05-09 19:03  0%       ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2018-05-09 16:11 UTC (permalink / raw)
  To: Van Haaren, Harry; +Cc: Burakov, Anatoly, dev, thomas

On Wed, May 09, 2018 at 04:59:39PM +0100, Van Haaren, Harry wrote:
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Anatoly Burakov
> > Sent: Monday, April 30, 2018 1:09 PM
> > To: dev@dpdk.org
> > Cc: Richardson, Bruce <bruce.richardson@intel.com>; thomas@monjalon.net
> > Subject: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
> > 
> > As has been suggested [1], all DPDK runtime paths should be put
> > into a single place. This patchset accomplishes exactly that.
> > 
> > If running as root, all files will be put under /var/run/dpdk/<prefix>,
> > otherwise they will be put under $XDG_RUNTIME_PATH/dpdk/<prefix>, or, if
> > that environment variable is not defined, all files will go under
> > /tmp/dpdk/<prefix>.
> > 
> > [1] http://dpdk.org/dev/patchwork/patch/38688/
> > 
> > v2:
> > - Rebase on rc1
> > 
> > Anatoly Burakov (4):
> >   eal: remove unused define
> >   eal: rename function returning hugepage data path
> >   eal: add directory for DPDK runtime data
> >   eal: move all runtime data into DPDK runtime dir
> 
> <snip>
> 
> 
> No full code review, high level comments:
> 
> We have to be careful in changing /var/run/.rte_config, which has always been
> the default DPDK primary application lockfile. This has been used to identify
> if a primary DPDK application is alive (see rte_eal_primary_proc_alive()) and
> possibly the write-lock on this file is checked by other tools/utilities directly
> without any DPDK function call.
> 
> Changing the filepath just before a release isn't a good idea - we should treat
> this as an ABI/API break, as the change will break functionality in other projects
> such as CollectD[1], which (by default ;) rely on the defaults. There is a config
> file for CollectD to manually override the location, but this will cause headaches
> from a usability POV.
> 
> I'm not opposed to the change - particularly as I gather the new memory subsystem
> causes a number of lockfiles to be created - but we must do our due diligence and
> give other projects fair-warning that this change is coming.
> 
> As such, I recommend this patchset in its current form (particularly patches 2,3,4)
> to be deferred past 18.05.
> 
> 
What about if we keep the .rte_config file in the same place but move the
rest? The number of new files causes quite a bit of clutter. We can then
have a deprecation notice for the move in 18.05 and finish the cleanup in
18.08.

/Bruce

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] rte_eth_dev_socket_id() vs KVM/AWS/...
@ 2018-05-09 17:08  3% Mike Stolarchuk
  2018-05-14  8:09  0% ` Burakov, Anatoly
  0 siblings, 1 reply; 200+ results
From: Mike Stolarchuk @ 2018-05-09 17:08 UTC (permalink / raw)
  To: dev

Hello Dpdk,

rte_eth_dev_socket_id() describes a -1 return value as:

*Returns*

The NUMA socket id to which the Ethernet device is connected or a default
of zero if the socket could not be determined. -1 is returned is the
port_id value is out of range.

But, rte_eth_dev_socket_id() is implemented as:

int
rte_eth_dev_socket_id(uint16_t port_id)
{
    RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
    return rte_eth_devices[port_id].data->numa_node;
}

And numa_node here is set from /sys/bus/pci/<device>/numa_node.
And https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
documents numa_node as:

What: /sys/bus/pci/devices/.../numa_node
Date: Oct 2014
Contact: Prarit Bhargava <prarit@redhat.com>
Description:
This file contains the NUMA node to which the PCI device is
attached, or -1 if the node is unknown.  The initial value
comes from an ACPI _PXM method or a similar firmware
source.  If that is missing or incorrect, this file can be
written to override the node.  In that case, please report
a firmware bug to the system vendor.  Writing to this file
taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
reduces the supportability of your system.

in other words, a value of -1 for numa_node means the association of the
pci device WRT socket is unknown.
And as an example, in a KVM with e1000's.
/sys/bus/pci/devices/<d>/numa_node can return -1.

This means that rte_eth_dev_socket_id() returns -1 in situations other than
'port_id value is out of range'.
And its not possible to identify whether the port_id is invalid, or whether
the base system didn't
announce the numa_node association.

Perhaps a -1 return value should be an indication the the numa_node
association isn't known,
and a different return value, say -2, should indicate the port_id value is
out of range.


mts.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
  2018-05-09 16:11  0%     ` Bruce Richardson
@ 2018-05-09 19:03  0%       ` Thomas Monjalon
  2018-05-14  8:26  0%         ` Burakov, Anatoly
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-09 19:03 UTC (permalink / raw)
  To: Bruce Richardson, Van Haaren, Harry, Burakov, Anatoly; +Cc: dev

09/05/2018 18:11, Bruce Richardson:
> On Wed, May 09, 2018 at 04:59:39PM +0100, Van Haaren, Harry wrote:
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Anatoly Burakov
> > > Sent: Monday, April 30, 2018 1:09 PM
> > > To: dev@dpdk.org
> > > Cc: Richardson, Bruce <bruce.richardson@intel.com>; thomas@monjalon.net
> > > Subject: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
> > > 
> > > As has been suggested [1], all DPDK runtime paths should be put
> > > into a single place. This patchset accomplishes exactly that.
> > > 
> > > If running as root, all files will be put under /var/run/dpdk/<prefix>,
> > > otherwise they will be put under $XDG_RUNTIME_PATH/dpdk/<prefix>, or, if
> > > that environment variable is not defined, all files will go under
> > > /tmp/dpdk/<prefix>.
> > > 
> > > [1] http://dpdk.org/dev/patchwork/patch/38688/
> > > 
> > > v2:
> > > - Rebase on rc1
> > > 
> > > Anatoly Burakov (4):
> > >   eal: remove unused define
> > >   eal: rename function returning hugepage data path
> > >   eal: add directory for DPDK runtime data
> > >   eal: move all runtime data into DPDK runtime dir
> > 
> > <snip>
> > 
> > 
> > No full code review, high level comments:
> > 
> > We have to be careful in changing /var/run/.rte_config, which has always been
> > the default DPDK primary application lockfile. This has been used to identify
> > if a primary DPDK application is alive (see rte_eal_primary_proc_alive()) and
> > possibly the write-lock on this file is checked by other tools/utilities directly
> > without any DPDK function call.
> > 
> > Changing the filepath just before a release isn't a good idea - we should treat
> > this as an ABI/API break, as the change will break functionality in other projects
> > such as CollectD[1], which (by default ;) rely on the defaults. There is a config
> > file for CollectD to manually override the location, but this will cause headaches
> > from a usability POV.
> > 
> > I'm not opposed to the change - particularly as I gather the new memory subsystem
> > causes a number of lockfiles to be created - but we must do our due diligence and
> > give other projects fair-warning that this change is coming.
> > 
> > As such, I recommend this patchset in its current form (particularly patches 2,3,4)
> > to be deferred past 18.05.
> > 
> > 
> What about if we keep the .rte_config file in the same place but move the
> rest? The number of new files causes quite a bit of clutter. We can then
> have a deprecation notice for the move in 18.05 and finish the cleanup in
> 18.08.

I agree

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v9] ethdev: new Rx/Tx offloads API
  2018-05-08 10:05  1% ` [dpdk-dev] [PATCH v8] " Wei Dai
@ 2018-05-10  0:49  1%   ` Wei Dai
  2018-05-10  0:56  1%     ` [dpdk-dev] [PATCH v10] " Wei Dai
  0 siblings, 1 reply; 200+ results
From: Wei Dai @ 2018-05-10  0:49 UTC (permalink / raw)
  To: ferruh.yigit, thomas; +Cc: dev, Wei Dai, Qi Zhang

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure( ) and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If any offloading is enabled in rte_eth_dev_configure( ) by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure( ),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup( ).
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure( ) and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup( ), it must be per-queue type,
otherwise triger an error log.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup( ) function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get( ).

In the beginning of [rt]x_queue_setup( ) of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v9:
replace RTE_PMD_DEBUG_TRACE with ethdev_log(ERR, in ethdev
to avoid failure of application which hasn't been completely
converted to new offload API.

v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  26 +++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  86 +++++++++++++++++
 35 files changed, 238 insertions(+), 1346 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..56483fb 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,30 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure( )`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If any offloading is enabled in ``rte_eth_dev_configure( )`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure( )``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup( )`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup( )``, it must be per-queue type, otherwise return error.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..637e684 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* **ethdev: changes to offload API**
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup( )``. Now any offloading enabled in ``rte_eth_dev_configure( )``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup( )``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup( )`` must be per-queue type, otherwise return error.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..ddfd020 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Rx offloads "
+				"0x%" PRIx64 " doesn't match Rx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.rxmode.offloads,
+				dev_info.rx_offload_capa,
+				__func__);
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Tx offloads "
+				"0x%" PRIx64 " doesn't match Tx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.txmode.offloads,
+				dev_info.tx_offload_capa,
+				__func__);
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,38 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d rx_queue_id=%d, new "
+				"added offloads 0x" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x"
+				PRIx64 " in %s( )\n",
+				port_id,
+				rx_queue_id,
+				local_conf.offloads,
+				dev_info.rx_queue_offload_capa,
+				__func__);
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1666,38 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d tx_queue_id=%d, new "
+				"added offloads 0x" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x"
+				PRIx64 " in %s( )\n",
+				port_id,
+				tx_queue_id,
+				local_conf.offloads,
+				dev_info.tx_queue_offload_capa,
+				__func__);
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v10] ethdev: new Rx/Tx offloads API
  2018-05-10  0:49  1%   ` [dpdk-dev] [PATCH v9] ethdev: new Rx/Tx offloads API Wei Dai
@ 2018-05-10  0:56  1%     ` Wei Dai
  2018-05-10 11:30  1%       ` [dpdk-dev] [PATCH v11] " Wei Dai
  0 siblings, 1 reply; 200+ results
From: Wei Dai @ 2018-05-10  0:56 UTC (permalink / raw)
  To: ferruh.yigit, thomas; +Cc: dev, Wei Dai, Qi Zhang

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure( ) and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If any offloading is enabled in rte_eth_dev_configure( ) by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup( ).
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure( ),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup( ).
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure( ) and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup( ), it must be per-queue type,
otherwise triger an error log.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup( ) function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get( ).

In the beginning of [rt]x_queue_setup( ) of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v10:
sorry, miss the code change, fix the buidling error

v9:
replace RTE_PMD_DEBUG_TRACE with ethdev_log(ERR, in ethdev
to avoid failure of application which hasn't been completely
converted to new offload API.

v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  26 +++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  86 +++++++++++++++++
 35 files changed, 238 insertions(+), 1346 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..56483fb 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,30 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure( )`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If any offloading is enabled in ``rte_eth_dev_configure( )`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure( )``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup( )`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup( )`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup( )``, it must be per-queue type, otherwise return error.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..637e684 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* **ethdev: changes to offload API**
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup( )``. Now any offloading enabled in ``rte_eth_dev_configure( )``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup( )``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure( )`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup( )`` must be per-queue type, otherwise return error.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..5baa2aa 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Rx offloads "
+				"0x%" PRIx64 " doesn't match Rx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.rxmode.offloads,
+				dev_info.rx_offload_capa,
+				__func__);
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Tx offloads "
+				"0x%" PRIx64 " doesn't match Tx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.txmode.offloads,
+				dev_info.tx_offload_capa,
+				__func__);
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,38 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d rx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				rx_queue_id,
+				local_conf.offloads,
+				dev_info.rx_queue_offload_capa,
+				__func__);
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1666,38 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d tx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				tx_queue_id,
+				local_conf.offloads,
+				dev_info.tx_queue_offload_capa,
+				__func__);
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH] doc: update release notes.
@ 2018-05-10  4:19  4% Qi Zhang
  0 siblings, 0 replies; 200+ results
From: Qi Zhang @ 2018-05-10  4:19 UTC (permalink / raw)
  To: john.mcnamara; +Cc: dev, Qi Zhang

Add updates for runtime queue setup.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 doc/guides/rel_notes/release_18_05.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 718734852..589649121 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -183,7 +183,6 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
-
 API Changes
 -----------
 
@@ -322,6 +321,12 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* ethdev: runtime queue setup:
+  * ``rte_eth_rx_queue_setup`` and ``rte_eth_rx_queue_setup`` can be called after
+    ``rte_eth_dev_start`` if device support runtime queue setup. Device driver can
+    expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue be
+    setup at runtime need to be started explictly by ``rte_eth_dev_rx_queue_start``
+    or ``rte_eth_dev_tx_queue_start``.
 
 ABI Changes
 -----------
-- 
2.13.6

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2] doc: update release notes.
@ 2018-05-10  4:22  4% Qi Zhang
  2018-05-10  6:24  0% ` Tonghao Zhang
  0 siblings, 1 reply; 200+ results
From: Qi Zhang @ 2018-05-10  4:22 UTC (permalink / raw)
  To: john.mcnamara; +Cc: dev, Qi Zhang

Add updates for runtime queue setup.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---

v2:
- fix typo.

 doc/guides/rel_notes/release_18_05.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 718734852..589649121 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -183,7 +183,6 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
-
 API Changes
 -----------
 
@@ -322,6 +321,12 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* ethdev: runtime queue setup:
+  * ``rte_eth_rx_queue_setup`` and ``rte_eth_rx_queue_setup`` can be called after
+    ``rte_eth_dev_start`` if device support runtime queue setup. Device driver can
+    expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue be
+    setup at runtime need to be started explicitly by ``rte_eth_dev_rx_queue_start``
+    or ``rte_eth_dev_tx_queue_start``.
 
 ABI Changes
 -----------
-- 
2.13.6

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  @ 2018-05-10  4:31  3%   ` Jerin Jacob
  2018-05-10 13:48  4%     ` [dpdk-dev] [dpdk-stable] " Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-05-10  4:31 UTC (permalink / raw)
  To: Nikhil Rao; +Cc: ferruh.yigit, lei.a.yao, dev, stable

-----Original Message-----
> Date: Thu, 10 May 2018 02:22:40 +0530
> From: Nikhil Rao <nikhil.rao@intel.com>
> To: jerin.jacob@caviumnetworks.com
> CC: ferruh.yigit@intel.com, lei.a.yao@intel.com, dev@dpdk.org, Nikhil Rao
>  <nikhil.rao@intel.com>, stable@dpdk.org
> Subject: [PATCH v2] eventdev: make ethernet port identifiers 16 bit
> X-Mailer: git-send-email 1.8.3.1
> 
> Ethernet port ID data size has been extended to 16 bits size 17.11
> Update the Rx event adapter interface and implementation accordingly.
> 
> Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> Cc: stable@dpdk.org

Since it is an ABI change, please bump the library version.
eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
required.

Reference commit for library version update:

commit dfb7f82a5ae3eea5b9229828cc26ff2c291ffc9f
Author: Harry van Haaren <harry.van.haaren@intel.com>
Date:   Wed Sep 20 14:36:03 2017 +0100

    eventdev: bump library version


> --
> 
> Supersedes the following posts:
> http://dpdk.org/ml/archives/dev/2018-May/100917.html
> http://dpdk.org/ml/archives/dev/2018-May/100426.html
> ---
>  lib/librte_eventdev/rte_event_eth_rx_adapter.h |  4 ++--
>  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 23 ++++++++++++-----------
>  2 files changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.h b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> index e6a6435..834eb53 100644
> --- a/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.h
> @@ -307,7 +307,7 @@ int rte_event_eth_rx_adapter_create(uint8_t id, uint8_t dev_id,
>   *  combination of the two error codes.
>   */
>  int rte_event_eth_rx_adapter_queue_add(uint8_t id,
> -			uint8_t eth_dev_id,
> +			uint16_t eth_dev_id,
>  			int32_t rx_queue_id,
>  			const struct rte_event_eth_rx_adapter_queue_conf *conf);
>  
> @@ -335,7 +335,7 @@ int rte_event_eth_rx_adapter_queue_add(uint8_t id,
>   *  - 0: Success, Receive queue deleted correctly.
>   *  - <0: Error code on failure.
>   */
> -int rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id,
> +int rte_event_eth_rx_adapter_queue_del(uint8_t id, uint16_t eth_dev_id,
>  				       int32_t rx_queue_id);
>  
>  /**
> diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.c b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
> index 4c0c025..6f70509 100644
> --- a/lib/librte_eventdev/rte_event_eth_rx_adapter.c
> +++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
> @@ -31,7 +31,7 @@
>   */
>  struct eth_rx_poll_entry {
>  	/* Eth port to poll */
> -	uint8_t eth_dev_id;
> +	uint16_t eth_dev_id;
>  	/* Eth rx queue to poll */
>  	uint16_t eth_rx_qid;
>  };
> @@ -168,7 +168,7 @@ static uint16_t gcd_u16(uint16_t a, uint16_t b)
>  
>  	while (1) {
>  		uint16_t q;
> -		uint8_t d;
> +		uint16_t d;
>  
>  		i = (i + 1) % n;
>  		if (i == 0) {
> @@ -190,7 +190,7 @@ static uint16_t gcd_u16(uint16_t a, uint16_t b)
>  static int
>  eth_poll_wrr_calc(struct rte_event_eth_rx_adapter *rx_adapter)
>  {
> -	uint8_t d;
> +	uint16_t d;
>  	uint16_t q;
>  	unsigned int i;
>  
> @@ -510,7 +510,7 @@ static uint16_t gcd_u16(uint16_t a, uint16_t b)
>  	for (num_queue = 0; num_queue < rx_adapter->wrr_len; num_queue++) {
>  		unsigned int poll_idx = rx_adapter->wrr_sched[wrr_pos];
>  		uint16_t qid = rx_adapter->eth_rx_poll[poll_idx].eth_rx_qid;
> -		uint8_t d = rx_adapter->eth_rx_poll[poll_idx].eth_dev_id;
> +		uint16_t d = rx_adapter->eth_rx_poll[poll_idx].eth_dev_id;
>  
>  		/* Don't do a batch dequeue from the rx queue if there isn't
>  		 * enough space in the enqueue buffer.
> @@ -755,7 +755,7 @@ static uint16_t gcd_u16(uint16_t a, uint16_t b)
>  }
>  
>  static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
> -		uint8_t eth_dev_id,
> +		uint16_t eth_dev_id,
>  		int rx_queue_id,
>  		const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
>  {
> @@ -859,7 +859,7 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  	struct rte_event_eth_rx_adapter *rx_adapter;
>  	int ret;
>  	int socket_id;
> -	uint8_t i;
> +	uint16_t i;
>  	char mem_name[ETH_RX_ADAPTER_SERVICE_NAME_LEN];
>  	const uint8_t default_rss_key[] = {
>  		0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
> @@ -978,7 +978,7 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  
>  int
>  rte_event_eth_rx_adapter_queue_add(uint8_t id,
> -		uint8_t eth_dev_id,
> +		uint16_t eth_dev_id,
>  		int32_t rx_queue_id,
>  		const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
>  {
> @@ -1002,7 +1002,7 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  						&cap);
>  	if (ret) {
>  		RTE_EDEV_LOG_ERR("Failed to get adapter caps edev %" PRIu8
> -			"eth port %" PRIu8, id, eth_dev_id);
> +			"eth port %" PRIu16, id, eth_dev_id);
>  		return ret;
>  	}
>  
> @@ -1010,7 +1010,7 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  		&& (queue_conf->rx_queue_flags &
>  			RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID)) {
>  		RTE_EDEV_LOG_ERR("Flow ID override is not supported,"
> -				" eth port: %" PRIu8 " adapter id: %" PRIu8,
> +				" eth port: %" PRIu16 " adapter id: %" PRIu8,
>  				eth_dev_id, id);
>  		return -EINVAL;
>  	}
> @@ -1018,7 +1018,8 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  	if ((cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) == 0 &&
>  		(rx_queue_id != -1)) {
>  		RTE_EDEV_LOG_ERR("Rx queues can only be connected to single "
> -			"event queue id %u eth port %u", id, eth_dev_id);
> +			"event queue, eth port: %" PRIu16 " adapter id: %"
> +			PRIu8, eth_dev_id, id);
>  		return -EINVAL;
>  	}
>  
> @@ -1075,7 +1076,7 @@ static int add_rx_queue(struct rte_event_eth_rx_adapter *rx_adapter,
>  }
>  
>  int
> -rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id,
> +rte_event_eth_rx_adapter_queue_del(uint8_t id, uint16_t eth_dev_id,
>  				int32_t rx_queue_id)
>  {
>  	int ret = 0;
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] eventdev: bump library version
@ 2018-05-09 21:54  4% Nikhil Rao
  0 siblings, 0 replies; 200+ results
From: Nikhil Rao @ 2018-05-09 21:54 UTC (permalink / raw)
  To: jerin.jacob; +Cc: dev, Nikhil Rao

This commit bumps the library version to refect the ABI change
caused by extending the ethernet port parameter in Rx adapter
functions from 8 to 16 bits.

Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>

--

The ABI change is caused by the following commit:
http://dpdk.org/ml/archives/dev/2018-May/100979.html
---
 doc/guides/rel_notes/release_18_05.rst | 2 +-
 lib/librte_eventdev/Makefile           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index ee8b735..4d84401 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -456,7 +456,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
    + librte_eal.so.7
    + librte_ethdev.so.9
-     librte_eventdev.so.3
+   + librte_eventdev.so.4
      librte_flow_classify.so.1
      librte_gro.so.1
      librte_gso.so.1
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index 804b036..d7aafd9 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_eventdev.a
 
 # library version
-LIBABIVER := 3
+LIBABIVER := 4
 
 # build flags
 CFLAGS += -DALLOW_EXPERIMENTAL_API
-- 
1.8.3.1

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2] doc: update release notes.
  2018-05-10  4:22  4% [dpdk-dev] [PATCH v2] " Qi Zhang
@ 2018-05-10  6:24  0% ` Tonghao Zhang
  2018-05-10  6:45  0%   ` Zhang, Qi Z
  0 siblings, 1 reply; 200+ results
From: Tonghao Zhang @ 2018-05-10  6:24 UTC (permalink / raw)
  To: Qi Zhang; +Cc: john.mcnamara, dev

On Thu, May 10, 2018 at 12:22 PM, Qi Zhang <qi.z.zhang@intel.com> wrote:
> Add updates for runtime queue setup.
>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
>
> v2:
> - fix typo.
>
>  doc/guides/rel_notes/release_18_05.rst | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
> index 718734852..589649121 100644
> --- a/doc/guides/rel_notes/release_18_05.rst
> +++ b/doc/guides/rel_notes/release_18_05.rst
> @@ -183,7 +183,6 @@ New Features
>    stats/xstats on shared memory from secondary process, and also pdump packets on
>    those virtual devices.
>
> -
>  API Changes
>  -----------
>
> @@ -322,6 +321,12 @@ API Changes
>    * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
>    * ``rte_flow_query()`` API parameter changed from action type to action structure.
>
> +* ethdev: runtime queue setup:
> +  * ``rte_eth_rx_queue_setup`` and ``rte_eth_rx_queue_setup`` can be called after
I guess that one of rte_eth_rx_queue_setup  -> rte_eth_tx_queue_setup

> +    ``rte_eth_dev_start`` if device support runtime queue setup. Device driver can
> +    expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue be
> +    setup at runtime need to be started explicitly by ``rte_eth_dev_rx_queue_start``
> +    or ``rte_eth_dev_tx_queue_start``.
>
>  ABI Changes
>  -----------
> --
> 2.13.6
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] doc: update release notes.
  2018-05-10  6:24  0% ` Tonghao Zhang
@ 2018-05-10  6:45  0%   ` Zhang, Qi Z
  0 siblings, 0 replies; 200+ results
From: Zhang, Qi Z @ 2018-05-10  6:45 UTC (permalink / raw)
  To: Tonghao Zhang; +Cc: Mcnamara, John, dev



> -----Original Message-----
> From: Tonghao Zhang [mailto:xiangxia.m.yue@gmail.com]
> Sent: Thursday, May 10, 2018 2:25 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>
> Cc: Mcnamara, John <john.mcnamara@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2] doc: update release notes.
> 
> On Thu, May 10, 2018 at 12:22 PM, Qi Zhang <qi.z.zhang@intel.com> wrote:
> > Add updates for runtime queue setup.
> >
> > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > ---
> >
> > v2:
> > - fix typo.
> >
> >  doc/guides/rel_notes/release_18_05.rst | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/guides/rel_notes/release_18_05.rst
> b/doc/guides/rel_notes/release_18_05.rst
> > index 718734852..589649121 100644
> > --- a/doc/guides/rel_notes/release_18_05.rst
> > +++ b/doc/guides/rel_notes/release_18_05.rst
> > @@ -183,7 +183,6 @@ New Features
> >    stats/xstats on shared memory from secondary process, and also
> pdump packets on
> >    those virtual devices.
> >
> > -
> >  API Changes
> >  -----------
> >
> > @@ -322,6 +321,12 @@ API Changes
> >    * ``rte_flow_create()`` API count action now requires the ``struct
> rte_flow_action_count``.
> >    * ``rte_flow_query()`` API parameter changed from action type to action
> structure.
> >
> > +* ethdev: runtime queue setup:
> > +  * ``rte_eth_rx_queue_setup`` and ``rte_eth_rx_queue_setup`` can be
> called after
> I guess that one of rte_eth_rx_queue_setup  -> rte_eth_tx_queue_setup

Thanks, will fix

> 
> > +    ``rte_eth_dev_start`` if device support runtime queue setup. Device
> driver can
> > +    expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx
> queue be
> > +    setup at runtime need to be started explicitly by
> ``rte_eth_dev_rx_queue_start``
> > +    or ``rte_eth_dev_tx_queue_start``.
> >
> >  ABI Changes
> >  -----------
> > --
> > 2.13.6
> >

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3] doc: update release notes.
@ 2018-05-10  6:55  4% Qi Zhang
  0 siblings, 0 replies; 200+ results
From: Qi Zhang @ 2018-05-10  6:55 UTC (permalink / raw)
  To: john.mcnamara; +Cc: dev, Qi Zhang

Add updates for runtime queue setup.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
v3:
- fix typo.

v2:
- fix typo.

 doc/guides/rel_notes/release_18_05.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 718734852..589649121 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -183,7 +183,6 @@ New Features
   stats/xstats on shared memory from secondary process, and also pdump packets on
   those virtual devices.
 
-
 API Changes
 -----------
 
@@ -322,6 +321,12 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* ethdev: runtime queue setup:
+  * ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup`` can be called after
+    ``rte_eth_dev_start`` if device support runtime queue setup. Device driver can
+    expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue be
+    setup at runtime need to be started explicitly by ``rte_eth_dev_rx_queue_start``
+    or ``rte_eth_dev_tx_queue_start``.
 
 ABI Changes
 -----------
-- 
2.13.6

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v6 2/9] bpf: add ability to load eBPF program from ELF object file
  2018-05-04 12:45  1% ` [dpdk-dev] [PATCH v5 1/8] bpf: add BPF loading and execution framework Konstantin Ananyev
@ 2018-05-10 10:23  3%   ` Konstantin Ananyev
  0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2018-05-10 10:23 UTC (permalink / raw)
  To: dev; +Cc: Konstantin Ananyev

Introduce rte_bpf_elf_load() function to provide ability to
load eBPF program from ELF object file.
It also adds dependency on libelf.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 config/common_base                 |   3 +
 lib/librte_bpf/Makefile            |   6 +
 lib/librte_bpf/bpf_load.c          |  16 ++
 lib/librte_bpf/bpf_load_elf.c      | 322 +++++++++++++++++++++++++++++++++++++
 lib/librte_bpf/meson.build         |   6 +
 lib/librte_bpf/rte_bpf.h           |  20 +++
 lib/librte_bpf/rte_bpf_version.map |   1 +
 mk/rte.app.mk                      |   3 +
 8 files changed, 377 insertions(+)
 create mode 100644 lib/librte_bpf/bpf_load_elf.c

diff --git a/config/common_base b/config/common_base
index b598feae8..6a1908104 100644
--- a/config/common_base
+++ b/config/common_base
@@ -878,3 +878,6 @@ CONFIG_RTE_APP_EVENTDEV=y
 # Compile librte_bpf
 #
 CONFIG_RTE_LIBRTE_BPF=y
+
+# allow load BPF from ELF files (requires liblef)
+CONFIG_RTE_LIBRTE_BPF_ELF=n
diff --git a/lib/librte_bpf/Makefile b/lib/librte_bpf/Makefile
index da9306564..885a31381 100644
--- a/lib/librte_bpf/Makefile
+++ b/lib/librte_bpf/Makefile
@@ -12,6 +12,9 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_net -lrte_eal
 LDLIBS += -lrte_mempool -lrte_ring
 LDLIBS += -lrte_mbuf -lrte_ethdev
+ifeq ($(CONFIG_RTE_LIBRTE_BPF_ELF),y)
+LDLIBS += -lelf
+endif
 
 EXPORT_MAP := rte_bpf_version.map
 
@@ -22,6 +25,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf.c
 SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_exec.c
 SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_load.c
 SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_validate.c
+ifeq ($(CONFIG_RTE_LIBRTE_BPF_ELF),y)
+SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_load_elf.c
+endif
 
 # install header files
 SYMLINK-$(CONFIG_RTE_LIBRTE_BPF)-include += bpf_def.h
diff --git a/lib/librte_bpf/bpf_load.c b/lib/librte_bpf/bpf_load.c
index f28ecfb4d..d1c9abd7f 100644
--- a/lib/librte_bpf/bpf_load.c
+++ b/lib/librte_bpf/bpf_load.c
@@ -83,3 +83,19 @@ rte_bpf_load(const struct rte_bpf_prm *prm)
 
 	return bpf;
 }
+
+__rte_experimental __attribute__ ((weak)) struct rte_bpf *
+rte_bpf_elf_load(const struct rte_bpf_prm *prm, const char *fname,
+	const char *sname)
+{
+	if (prm == NULL || fname == NULL || sname == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	RTE_BPF_LOG(ERR, "%s() is not supported with current config\n"
+		"rebuild with libelf installed\n",
+		__func__);
+	rte_errno = ENOTSUP;
+	return NULL;
+}
diff --git a/lib/librte_bpf/bpf_load_elf.c b/lib/librte_bpf/bpf_load_elf.c
new file mode 100644
index 000000000..6ab03d86e
--- /dev/null
+++ b/lib/librte_bpf/bpf_load_elf.c
@@ -0,0 +1,322 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <fcntl.h>
+
+#include <libelf.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_byteorder.h>
+#include <rte_errno.h>
+
+#include "bpf_impl.h"
+
+/* To overcome compatibility issue */
+#ifndef EM_BPF
+#define	EM_BPF	247
+#endif
+
+static uint32_t
+bpf_find_xsym(const char *sn, enum rte_bpf_xtype type,
+	const struct rte_bpf_xsym fp[], uint32_t fn)
+{
+	uint32_t i;
+
+	if (sn == NULL || fp == NULL)
+		return UINT32_MAX;
+
+	for (i = 0; i != fn; i++) {
+		if (fp[i].type == type && strcmp(sn, fp[i].name) == 0)
+			break;
+	}
+
+	return (i != fn) ? i : UINT32_MAX;
+}
+
+/*
+ * update BPF code at offset *ofs* with a proper address(index) for external
+ * symbol *sn*
+ */
+static int
+resolve_xsym(const char *sn, size_t ofs, struct ebpf_insn *ins, size_t ins_sz,
+	const struct rte_bpf_prm *prm)
+{
+	uint32_t idx, fidx;
+	enum rte_bpf_xtype type;
+
+	if (ofs % sizeof(ins[0]) != 0 || ofs >= ins_sz)
+		return -EINVAL;
+
+	idx = ofs / sizeof(ins[0]);
+	if (ins[idx].code == (BPF_JMP | EBPF_CALL))
+		type = RTE_BPF_XTYPE_FUNC;
+	else if (ins[idx].code == (BPF_LD | BPF_IMM | EBPF_DW) &&
+			ofs < ins_sz - sizeof(ins[idx]))
+		type = RTE_BPF_XTYPE_VAR;
+	else
+		return -EINVAL;
+
+	fidx = bpf_find_xsym(sn, type, prm->xsym, prm->nb_xsym);
+	if (fidx == UINT32_MAX)
+		return -ENOENT;
+
+	/* for function we just need an index in our xsym table */
+	if (type == RTE_BPF_XTYPE_FUNC)
+		ins[idx].imm = fidx;
+	/* for variable we need to store its absolute address */
+	else {
+		ins[idx].imm = (uintptr_t)prm->xsym[fidx].var;
+		ins[idx + 1].imm =
+			(uint64_t)(uintptr_t)prm->xsym[fidx].var >> 32;
+	}
+
+	return 0;
+}
+
+static int
+check_elf_header(const Elf64_Ehdr *eh)
+{
+	const char *err;
+
+	err = NULL;
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+	if (eh->e_ident[EI_DATA] != ELFDATA2LSB)
+#else
+	if (eh->e_ident[EI_DATA] != ELFDATA2MSB)
+#endif
+		err = "not native byte order";
+	else if (eh->e_ident[EI_OSABI] != ELFOSABI_NONE)
+		err = "unexpected OS ABI";
+	else if (eh->e_type != ET_REL)
+		err = "unexpected ELF type";
+	else if (eh->e_machine != EM_NONE && eh->e_machine != EM_BPF)
+		err = "unexpected machine type";
+
+	if (err != NULL) {
+		RTE_BPF_LOG(ERR, "%s(): %s\n", __func__, err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * helper function, find executable section by name.
+ */
+static int
+find_elf_code(Elf *elf, const char *section, Elf_Data **psd, size_t *pidx)
+{
+	Elf_Scn *sc;
+	const Elf64_Ehdr *eh;
+	const Elf64_Shdr *sh;
+	Elf_Data *sd;
+	const char *sn;
+	int32_t rc;
+
+	eh = elf64_getehdr(elf);
+	if (eh == NULL) {
+		rc = elf_errno();
+		RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n",
+			__func__, elf, section, rc, elf_errmsg(rc));
+		return -EINVAL;
+	}
+
+	if (check_elf_header(eh) != 0)
+		return -EINVAL;
+
+	/* find given section by name */
+	for (sc = elf_nextscn(elf, NULL); sc != NULL;
+			sc = elf_nextscn(elf, sc)) {
+		sh = elf64_getshdr(sc);
+		sn = elf_strptr(elf, eh->e_shstrndx, sh->sh_name);
+		if (sn != NULL && strcmp(section, sn) == 0 &&
+				sh->sh_type == SHT_PROGBITS &&
+				sh->sh_flags == (SHF_ALLOC | SHF_EXECINSTR))
+			break;
+	}
+
+	sd = elf_getdata(sc, NULL);
+	if (sd == NULL || sd->d_size == 0 ||
+			sd->d_size % sizeof(struct ebpf_insn) != 0) {
+		rc = elf_errno();
+		RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n",
+			__func__, elf, section, rc, elf_errmsg(rc));
+		return -EINVAL;
+	}
+
+	*psd = sd;
+	*pidx = elf_ndxscn(sc);
+	return 0;
+}
+
+/*
+ * helper function to process data from relocation table.
+ */
+static int
+process_reloc(Elf *elf, size_t sym_idx, Elf64_Rel *re, size_t re_sz,
+	struct ebpf_insn *ins, size_t ins_sz, const struct rte_bpf_prm *prm)
+{
+	int32_t rc;
+	uint32_t i, n;
+	size_t ofs, sym;
+	const char *sn;
+	const Elf64_Ehdr *eh;
+	Elf_Scn *sc;
+	const Elf_Data *sd;
+	Elf64_Sym *sm;
+
+	eh = elf64_getehdr(elf);
+
+	/* get symtable by section index */
+	sc = elf_getscn(elf, sym_idx);
+	sd = elf_getdata(sc, NULL);
+	if (sd == NULL)
+		return -EINVAL;
+	sm = sd->d_buf;
+
+	n = re_sz / sizeof(re[0]);
+	for (i = 0; i != n; i++) {
+
+		ofs = re[i].r_offset;
+
+		/* retrieve index in the symtable */
+		sym = ELF64_R_SYM(re[i].r_info);
+		if (sym * sizeof(sm[0]) >= sd->d_size)
+			return -EINVAL;
+
+		sn = elf_strptr(elf, eh->e_shstrndx, sm[sym].st_name);
+
+		rc = resolve_xsym(sn, ofs, ins, ins_sz, prm);
+		if (rc != 0) {
+			RTE_BPF_LOG(ERR,
+				"resolve_xsym(%s, %zu) error code: %d\n",
+				sn, ofs, rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * helper function, find relocation information (if any)
+ * and update bpf code.
+ */
+static int
+elf_reloc_code(Elf *elf, Elf_Data *ed, size_t sidx,
+	const struct rte_bpf_prm *prm)
+{
+	Elf64_Rel *re;
+	Elf_Scn *sc;
+	const Elf64_Shdr *sh;
+	const Elf_Data *sd;
+	int32_t rc;
+
+	rc = 0;
+
+	/* walk through all sections */
+	for (sc = elf_nextscn(elf, NULL); sc != NULL && rc == 0;
+			sc = elf_nextscn(elf, sc)) {
+
+		sh = elf64_getshdr(sc);
+
+		/* relocation data for our code section */
+		if (sh->sh_type == SHT_REL && sh->sh_info == sidx) {
+			sd = elf_getdata(sc, NULL);
+			if (sd == NULL || sd->d_size == 0 ||
+					sd->d_size % sizeof(re[0]) != 0)
+				return -EINVAL;
+			rc = process_reloc(elf, sh->sh_link,
+				sd->d_buf, sd->d_size, ed->d_buf, ed->d_size,
+				prm);
+		}
+	}
+
+	return rc;
+}
+
+static struct rte_bpf *
+bpf_load_elf(const struct rte_bpf_prm *prm, int32_t fd, const char *section)
+{
+	Elf *elf;
+	Elf_Data *sd;
+	size_t sidx;
+	int32_t rc;
+	struct rte_bpf *bpf;
+	struct rte_bpf_prm np;
+
+	elf_version(EV_CURRENT);
+	elf = elf_begin(fd, ELF_C_READ, NULL);
+
+	rc = find_elf_code(elf, section, &sd, &sidx);
+	if (rc == 0)
+		rc = elf_reloc_code(elf, sd, sidx, prm);
+
+	if (rc == 0) {
+		np = prm[0];
+		np.ins = sd->d_buf;
+		np.nb_ins = sd->d_size / sizeof(struct ebpf_insn);
+		bpf = rte_bpf_load(&np);
+	} else {
+		bpf = NULL;
+		rte_errno = -rc;
+	}
+
+	elf_end(elf);
+	return bpf;
+}
+
+__rte_experimental struct rte_bpf *
+rte_bpf_elf_load(const struct rte_bpf_prm *prm, const char *fname,
+	const char *sname)
+{
+	int32_t fd, rc;
+	struct rte_bpf *bpf;
+
+	if (prm == NULL || fname == NULL || sname == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	fd = open(fname, O_RDONLY);
+	if (fd < 0) {
+		rc = errno;
+		RTE_BPF_LOG(ERR, "%s(%s) error code: %d(%s)\n",
+			__func__, fname, rc, strerror(rc));
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	bpf = bpf_load_elf(prm, fd, sname);
+	close(fd);
+
+	if (bpf == NULL) {
+		RTE_BPF_LOG(ERR,
+			"%s(fname=\"%s\", sname=\"%s\") failed, "
+			"error code: %d\n",
+			__func__, fname, sname, rte_errno);
+		return NULL;
+	}
+
+	RTE_BPF_LOG(INFO, "%s(fname=\"%s\", sname=\"%s\") "
+		"successfully creates %p(jit={.func=%p,.sz=%zu});\n",
+		__func__, fname, sname, bpf, bpf->jit.func, bpf->jit.sz);
+	return bpf;
+}
diff --git a/lib/librte_bpf/meson.build b/lib/librte_bpf/meson.build
index 4fa000f5a..a6a9229bd 100644
--- a/lib/librte_bpf/meson.build
+++ b/lib/librte_bpf/meson.build
@@ -11,3 +11,9 @@ install_headers = files('bpf_def.h',
 			'rte_bpf.h')
 
 deps += ['mbuf', 'net']
+
+dep = cc.find_library('elf', required: false)
+if dep.found() == true and cc.has_header('libelf.h', dependencies: dep)
+	sources += files('bpf_load_elf.c')
+	ext_deps += dep
+endif
diff --git a/lib/librte_bpf/rte_bpf.h b/lib/librte_bpf/rte_bpf.h
index 4b3d970b9..1d6c4a9d2 100644
--- a/lib/librte_bpf/rte_bpf.h
+++ b/lib/librte_bpf/rte_bpf.h
@@ -116,6 +116,26 @@ void rte_bpf_destroy(struct rte_bpf *bpf);
 struct rte_bpf *rte_bpf_load(const struct rte_bpf_prm *prm);
 
 /**
+ * Create a new eBPF execution context and load BPF code from given ELF
+ * file into it.
+ *
+ * @param prm
+ *  Parameters used to create and initialise the BPF exeution context.
+ * @param fname
+ *  Pathname for a ELF file.
+ * @param sname
+ *  Name of the executable section within the file to load.
+ * @return
+ *   BPF handle that is used in future BPF operations,
+ *   or NULL on error, with error code set in rte_errno.
+ *   Possible rte_errno errors include:
+ *   - EINVAL - invalid parameter passed to function
+ *   - ENOMEM - can't reserve enough memory
+ */
+struct rte_bpf *rte_bpf_elf_load(const struct rte_bpf_prm *prm,
+	const char *fname, const char *sname);
+
+/**
  * Execute given BPF bytecode.
  *
  * @param bpf
diff --git a/lib/librte_bpf/rte_bpf_version.map b/lib/librte_bpf/rte_bpf_version.map
index ea1d621c4..ff65144df 100644
--- a/lib/librte_bpf/rte_bpf_version.map
+++ b/lib/librte_bpf/rte_bpf_version.map
@@ -2,6 +2,7 @@ EXPERIMENTAL {
 	global:
 
 	rte_bpf_destroy;
+	rte_bpf_elf_load;
 	rte_bpf_exec;
 	rte_bpf_exec_burst;
 	rte_bpf_get_jit;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 9d3c421cc..e54cc5c4e 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -83,6 +83,9 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER)          += -lrte_power
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EFD)            += -lrte_efd
 
 _LDLIBS-$(CONFIG_RTE_LIBRTE_BPF)            += -lrte_bpf
+ifeq ($(CONFIG_RTE_LIBRTE_BPF_ELF),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BPF)            += -lelf
+endif
 
 _LDLIBS-y += --whole-archive
 
-- 
2.13.6

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v11] ethdev: new Rx/Tx offloads API
  2018-05-10  0:56  1%     ` [dpdk-dev] [PATCH v10] " Wei Dai
@ 2018-05-10 11:30  1%       ` Wei Dai
  2018-05-10 11:56  1%         ` [dpdk-dev] [PATCH v12] " Wei Dai
  0 siblings, 1 reply; 200+ results
From: Wei Dai @ 2018-05-10 11:30 UTC (permalink / raw)
  To: thomas, ferruh.yigit; +Cc: dev, Wei Dai, Qi Zhang

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure() and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup().
If any offloading is enabled in rte_eth_dev_configure() by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup().
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure(),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup().
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure() and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup(), it must be per-queue type,
otherwise trigger an error log.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup() function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get().

In the beginning of [rt]x_queue_setup() of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v11:
This patch set is based on 18.05-rc2 .
document update according to feedback
revise rte_ethdev.h for doxygen

v10:
sorry, miss the code change, fix the buidling error

v9:
replace RTE_PMD_DEBUG_TRACE with ethdev_log(ERR, in ethdev
to avoid failure of application which hasn't been completely
converted to new offload API.

v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  28 ++++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  86 +++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h          |  20 +++-
 36 files changed, 257 insertions(+), 1349 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..bbb85f0 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,32 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offload is the one supported by device but not per-queue type.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+Any offloading is per-queue or pure per-port type, but can't be both types at same devices.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure()`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()``.
+If any offloading is enabled in ``rte_eth_dev_configure()`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure()``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup()`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup()``, it must be per-queue type, otherwise trigger an error log.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..716e9f4 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* ethdev: changes to offload API
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup()``. Now any offloading enabled in ``rte_eth_dev_configure()``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup()``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup()`` must be per-queue type, otherwise trigger an error log.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..5baa2aa 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Rx offloads "
+				"0x%" PRIx64 " doesn't match Rx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.rxmode.offloads,
+				dev_info.rx_offload_capa,
+				__func__);
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Tx offloads "
+				"0x%" PRIx64 " doesn't match Tx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.txmode.offloads,
+				dev_info.tx_offload_capa,
+				__func__);
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,38 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d rx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				rx_queue_id,
+				local_conf.offloads,
+				dev_info.rx_queue_offload_capa,
+				__func__);
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1666,38 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d tx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				tx_queue_id,
+				local_conf.offloads,
+				dev_info.tx_queue_offload_capa,
+				__func__);
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 7ccf4ba..56eca2c 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1067,9 +1067,9 @@ struct rte_eth_dev_info {
 	uint16_t max_vfs; /**< Maximum number of VFs. */
 	uint16_t max_vmdq_pools; /**< Maximum number of VMDq pools. */
 	uint64_t rx_offload_capa;
-	/**< Device per port RX offload capabilities. */
+	/**< All RX offload capabilities including all per queue ones */
 	uint64_t tx_offload_capa;
-	/**< Device per port TX offload capabilities. */
+	/**< All TX offload capabilities.including all per-queue ones */
 	uint64_t rx_queue_offload_capa;
 	/**< Device per queue RX offload capabilities. */
 	uint64_t tx_queue_offload_capa;
@@ -1546,6 +1546,13 @@ const char * __rte_experimental rte_eth_dev_tx_offload_name(uint64_t offload);
  *        The Rx offload bitfield API is obsolete and will be deprecated.
  *        Applications should set the ignore_bitfield_offloads bit on *rxmode*
  *        structure and use offloads field to set per-port offloads instead.
+ *     -  Any offloading set in eth_conf->[rt]xmode.offloads must be within
+ *        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 [RT]x queues and it can't be disabled no matter whether
+ *        it is cleared or set in the input argument [rt]x_conf->offloads
+*         to rte_eth_[rt]x_queue_setup().
  *     - the Receive Side Scaling (RSS) configuration when using multiple RX
  *         queues per port.
  *
@@ -1602,6 +1609,10 @@ rte_eth_dev_is_removed(uint16_t port_id);
  *   ring.
  *   In addition it contains the hardware offloads features to activate using
  *   the DEV_RX_OFFLOAD_* flags.
+ *   If an offloading set in rx_conf->offloads
+ *   hasn't been set in the input argument eth_conf->rxmode.offloads
+ *   to rte_eth_dev_configure(), it is a new added offloading, it must be
+ *   per-queue type and it is enabled for the queue.
  * @param mb_pool
  *   The pointer to the memory pool from which to allocate *rte_mbuf* network
  *   memory buffers to populate each descriptor of the receive ring.
@@ -1660,7 +1671,10 @@ int rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
  *     should set it to ETH_TXQ_FLAGS_IGNORE and use
  *     the offloads field below.
  *   - The *offloads* member contains Tx offloads to be enabled.
- *     Offloads which are not set cannot be used on the datapath.
+ *     If an offloading set in tx_conf->offloads
+ *     hasn't been set in the input argument eth_conf->txmode.offloads
+ *     to rte_eth_dev_configure(), it is a new added offloading, it must be
+ *     per-queue type and it is enabled for the queue.
  *
  *     Note that setting *tx_free_thresh* or *tx_rs_thresh* value to 0 forces
  *     the transmit function to use default values.
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v12] ethdev: new Rx/Tx offloads API
  2018-05-10 11:30  1%       ` [dpdk-dev] [PATCH v11] " Wei Dai
@ 2018-05-10 11:56  1%         ` Wei Dai
  0 siblings, 0 replies; 200+ results
From: Wei Dai @ 2018-05-10 11:56 UTC (permalink / raw)
  To: thomas, ferruh.yigit; +Cc: dev, Wei Dai, Qi Zhang

This patch check if a input requested offloading is valid or not.
Any reuqested offloading must be supported in the device capabilities.
Any offloading is disabled by default if it is not set in the parameter
dev_conf->[rt]xmode.offloads to rte_eth_dev_configure() and
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup().
If any offloading is enabled in rte_eth_dev_configure() by application,
it is enabled on all queues no matter whether it is per-queue or
per-port type and no matter whether it is set or cleared in
[rt]x_conf->offloads to rte_eth_[rt]x_queue_setup().
If a per-queue offloading hasn't be enabled in rte_eth_dev_configure(),
it can be enabled or disabled for individual queue in
ret_eth_[rt]x_queue_setup().
A new added offloading is the one which hasn't been enabled in
rte_eth_dev_configure() and is reuqested to be enabled in
rte_eth_[rt]x_queue_setup(), it must be per-queue type,
otherwise trigger an error log.
The underlying PMD must be aware that the requested offloadings
to PMD specific queue_setup() function only carries those
new added offloadings of per-queue type.

This patch can make above such checking in a common way in rte_ethdev
layer to avoid same checking in underlying PMD.

This patch assumes that all PMDs in 18.05-rc2 have already
converted to offload API defined in 17.11 . It also assumes
that all PMDs can return correct offloading capabilities
in rte_eth_dev_infos_get().

In the beginning of [rt]x_queue_setup() of underlying PMD,
add offloads = [rt]xconf->offloads |
dev->data->dev_conf.[rt]xmode.offloads; to keep same as offload API
defined in 17.11 to avoid upper application broken due to offload
API change.
PMD can use the info that input [rt]xconf->offloads only carry
the new added per-queue offloads to do some optimization or some
code change on base of this patch.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>

---
v12:
fix coding style warning

v11:
This patch set is based on 18.05-rc2 .
document update according to feedback
revise rte_ethdev.h for doxygen

v10:
sorry, miss the code change, fix the buidling error

v9:
replace RTE_PMD_DEBUG_TRACE with ethdev_log(ERR, in ethdev
to avoid failure of application which hasn't been completely
converted to new offload API.

v8:
Revise PMD codes to comply with offload API in v7
update document

v7:
Give the maximum freedom for upper application,
only minimal checking is performed in ethdev layer.
Only requested specific pure per-queue offloadings are input
to underlying PMD.

v6:
No need enable an offload in queue_setup( ) if it has already
been enabled in dev_configure( )

v5:
keep offload settings sent to PMD same as those from application

v4:
fix a wrong description in git log message.

v3:
rework according to dicision of offloading API in community

v2:
add offloads checking in rte_eth_dev_configure( ).
check if a requested offloading is supported.
---
 doc/guides/prog_guide/poll_mode_drv.rst |  28 ++++--
 doc/guides/rel_notes/release_18_05.rst  |   8 ++
 drivers/net/avf/avf_rxtx.c              |   5 +-
 drivers/net/bnxt/bnxt_ethdev.c          |  17 ----
 drivers/net/cxgbe/cxgbe_ethdev.c        |  50 +---------
 drivers/net/dpaa/dpaa_ethdev.c          |  16 ----
 drivers/net/dpaa2/dpaa2_ethdev.c        |  16 ----
 drivers/net/e1000/em_ethdev.c           |  19 ----
 drivers/net/e1000/em_rxtx.c             |  64 ++-----------
 drivers/net/e1000/igb_rxtx.c            |  64 ++-----------
 drivers/net/ena/ena_ethdev.c            |  65 +------------
 drivers/net/failsafe/failsafe_ops.c     |  81 ----------------
 drivers/net/fm10k/fm10k_ethdev.c        |  82 ++--------------
 drivers/net/i40e/i40e_rxtx.c            |  58 ++----------
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 --------
 drivers/net/ixgbe/ixgbe_rxtx.c          |  66 ++-----------
 drivers/net/mlx4/mlx4_rxq.c             |  43 ++-------
 drivers/net/mlx4/mlx4_txq.c             |  42 ++------
 drivers/net/mlx5/mlx5_ethdev.c          |  22 -----
 drivers/net/mlx5/mlx5_rxq.c             |  50 ++--------
 drivers/net/mlx5/mlx5_txq.c             |  44 +--------
 drivers/net/mvpp2/mrvl_ethdev.c         |  97 +------------------
 drivers/net/nfp/nfp_net.c               | 163 --------------------------------
 drivers/net/octeontx/octeontx_ethdev.c  |  72 +-------------
 drivers/net/sfc/sfc_ethdev.c            |   9 +-
 drivers/net/sfc/sfc_rx.c                |  42 ++------
 drivers/net/sfc/sfc_rx.h                |   3 +-
 drivers/net/sfc/sfc_tx.c                |  42 ++------
 drivers/net/sfc/sfc_tx.h                |   3 +-
 drivers/net/tap/rte_eth_tap.c           |  88 ++---------------
 drivers/net/thunderx/nicvf_ethdev.c     |  70 ++------------
 drivers/net/virtio/virtio_rxtx.c        |   9 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ----
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   8 +-
 lib/librte_ethdev/rte_ethdev.c          |  86 +++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h          |  20 +++-
 36 files changed, 257 insertions(+), 1349 deletions(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 09a93ba..bbb85f0 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -297,16 +297,32 @@ Per-Port and Per-Queue Offloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In the DPDK offload API, offloads are divided into per-port and per-queue offloads.
+A per-queue offloading can be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offload is the one supported by device but not per-queue type.
+A pure per-port offloading can't be enabled on a queue and disabled on another queue at the same time.
+A pure per-port offloading must be enabled or disabled on all queues at the same time.
+Any offloading is per-queue or pure per-port type, but can't be both types at same devices.
+A per-port offloading can be enabled or disabled on all queues at the same time.
+It is certain that both per-queue and pure per-port offloading are per-port type.
 The different offloads capabilities can be queried using ``rte_eth_dev_info_get()``.
+The dev_info->[rt]x_queue_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-queue offloading capabilities.
+The dev_info->[rt]x_offload_capa returned from ``rte_eth_dev_info_get()`` includes all per-port and per-queue offloading capabilities.
 Supported offloads can be either per-port or per-queue.
 
 Offloads are enabled using the existing ``DEV_TX_OFFLOAD_*`` or ``DEV_RX_OFFLOAD_*`` flags.
-Per-port offload configuration is set using ``rte_eth_dev_configure``.
-Per-queue offload configuration is set using ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup``.
-To enable per-port offload, the offload should be set on both device configuration and queue setup.
-In case of a mixed configuration the queue setup shall return with an error.
-To enable per-queue offload, the offload can be set only on the queue setup.
-Offloads which are not enabled are disabled by default.
+Any requested offloading by application must be within the device capabilities.
+Any offloading is disabled by default if it is not set in the parameter
+dev_conf->[rt]xmode.offloads to ``rte_eth_dev_configure()`` and
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()``.
+If any offloading is enabled in ``rte_eth_dev_configure()`` by application,
+it is enabled on all queues no matter whether it is per-queue or
+per-port type and no matter whether it is set or cleared in
+[rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()``.
+If a per-queue offloading hasn't been enabled in ``rte_eth_dev_configure()``,
+it can be enabled or disabled in ``rte_eth_[rt]x_queue_setup()`` for individual queue.
+A new added offloads in [rt]x_conf->offloads to ``rte_eth_[rt]x_queue_setup()`` input by application
+is the one which hasn't been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled
+in ``rte_eth_[rt]x_queue_setup()``, it must be per-queue type, otherwise trigger an error log.
 
 For an application to use the Tx offloads API it should set the ``ETH_TXQ_FLAGS_IGNORE`` flag in the ``txq_flags`` field located in ``rte_eth_txconf`` struct.
 In such cases it is not required to set other flags in ``txq_flags``.
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 0ae61e8..716e9f4 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -303,6 +303,14 @@ API Changes
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
+* ethdev: changes to offload API
+
+   A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
+   ``rte_eth_[rt]x_queue_setup()``. Now any offloading enabled in ``rte_eth_dev_configure()``
+   can't be disabled by ``rte_eth_[rt]x_queue_setup()``. Any new added offloading which has
+   not been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled in
+   ``rte_eth_[rt]x_queue_setup()`` must be per-queue type, otherwise trigger an error log.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/avf/avf_rxtx.c b/drivers/net/avf/avf_rxtx.c
index 1824ed7..e03a136 100644
--- a/drivers/net/avf/avf_rxtx.c
+++ b/drivers/net/avf/avf_rxtx.c
@@ -435,9 +435,12 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint32_t ring_size;
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t i, base, bsf, tc_mapping;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
 	if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
 	    nb_desc > AVF_MAX_RING_DESC ||
 	    nb_desc < AVF_MIN_RING_DESC) {
@@ -474,7 +477,7 @@ avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->free_thresh = tx_free_thresh;
 	txq->queue_id = queue_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
 	/* Allocate software ring */
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 348129d..d00b99f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -500,25 +500,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	uint64_t tx_offloads = eth_dev->data->dev_conf.txmode.offloads;
 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 
-	if (tx_offloads != (tx_offloads & BNXT_DEV_TX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Tx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			 tx_offloads, BNXT_DEV_TX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
-	if (rx_offloads != (rx_offloads & BNXT_DEV_RX_OFFLOAD_SUPPORT)) {
-		PMD_DRV_LOG
-			(ERR,
-			 "Rx offloads requested 0x%" PRIx64 " supported 0x%x\n",
-			    rx_offloads, BNXT_DEV_RX_OFFLOAD_SUPPORT);
-		return -ENOTSUP;
-	}
-
 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 3df51b5..fadf684 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -366,31 +366,15 @@ int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
-	uint64_t unsupported_offloads, configured_offloads;
+	uint64_t configured_offloads;
 	int err;
 
 	CXGBE_FUNC_TRACE();
 	configured_offloads = eth_dev->data->dev_conf.rxmode.offloads;
 	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
-	configured_offloads = eth_dev->data->dev_conf.txmode.offloads;
-	unsupported_offloads = configured_offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
+		eth_dev->data->dev_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
 	if (!(adapter->flags & FW_QUEUE_BOUND)) {
@@ -440,7 +424,7 @@ int cxgbe_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_txconf *tx_conf)
+			     const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -448,15 +432,6 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
 	int err = 0;
 	unsigned int temp_nb_desc;
-	uint64_t unsupported_offloads;
-
-	unsupported_offloads = tx_conf->offloads & ~CXGBE_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Tx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
@@ -553,7 +528,7 @@ int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     uint16_t queue_idx, uint16_t nb_desc,
 			     unsigned int socket_id,
-			     const struct rte_eth_rxconf *rx_conf,
+			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
 	struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
@@ -565,21 +540,6 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 	unsigned int temp_nb_desc;
 	struct rte_eth_dev_info dev_info;
 	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
-	uint64_t unsupported_offloads, configured_offloads;
-
-	configured_offloads = rx_conf->offloads;
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		dev_info(adapter, "can't disable hw crc strip\n");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~CXGBE_RX_OFFLOADS;
-	if (unsupported_offloads) {
-		dev_err(adapter, "Rx offloads 0x%" PRIx64 " are not supported. "
-			"Supported:0x%" PRIx64 "\n",
-			unsupported_offloads, (uint64_t)CXGBE_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 6bf8c15..199afdd 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -176,14 +176,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -192,14 +184,6 @@ dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c304b82..de8d83a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -309,14 +309,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	/* Rx offloads validation */
-	if (~(dev_rx_offloads_sup | dev_rx_offloads_nodis) & rx_offloads) {
-		DPAA2_PMD_ERR(
-		"Rx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			rx_offloads,
-			dev_rx_offloads_sup | dev_rx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_rx_offloads_nodis & ~rx_offloads) {
 		DPAA2_PMD_WARN(
 		"Rx offloads non configurable - requested 0x%" PRIx64
@@ -325,14 +317,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Tx offloads validation */
-	if (~(dev_tx_offloads_sup | dev_tx_offloads_nodis) & tx_offloads) {
-		DPAA2_PMD_ERR(
-		"Tx offloads non supported - requested 0x%" PRIx64
-		" supported 0x%" PRIx64,
-			tx_offloads,
-			dev_tx_offloads_sup | dev_tx_offloads_nodis);
-		return -ENOTSUP;
-	}
 	if (dev_tx_offloads_nodis & ~tx_offloads) {
 		DPAA2_PMD_WARN(
 		"Tx offloads non configurable - requested 0x%" PRIx64
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 694a624..4e890ad 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -454,29 +454,10 @@ eth_em_configure(struct rte_eth_dev *dev)
 {
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
 
-	eth_em_infos_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	PMD_INIT_FUNC_TRACE();
 
 	return 0;
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 2b3c63e..a6b3e92 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1183,22 +1183,6 @@ em_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return tx_queue_offload_capa;
 }
 
-static int
-em_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = em_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1211,21 +1195,11 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	struct e1000_hw     *hw;
 	uint32_t tsize;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			em_get_tx_port_offloads_capa(dev),
-			em_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -1330,7 +1304,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	em_reset_tx_queue(txq);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	return 0;
 }
 
@@ -1412,22 +1386,6 @@ em_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-em_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = em_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = em_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
@@ -1440,21 +1398,11 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 	struct em_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	uint32_t rsize;
+	uint64_t offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!em_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			em_get_rx_port_offloads_capa(dev),
-			em_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -1523,7 +1471,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	dev->data->rx_queues[queue_idx] = rxq;
 	em_reset_rx_queue(rxq);
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	return 0;
 }
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index a3776a0..128ed0b 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1475,22 +1475,6 @@ igb_get_tx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = igb_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1502,19 +1486,9 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_tx_queue *txq;
 	struct e1000_hw     *hw;
 	uint32_t size;
+	uint64_t offloads;
 
-	if (!igb_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			igb_get_tx_port_offloads_capa(dev),
-			igb_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1599,7 +1573,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	dev->tx_pkt_burst = eth_igb_xmit_pkts;
 	dev->tx_pkt_prepare = &eth_igb_prep_pkts;
 	dev->data->tx_queues[queue_idx] = txq;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	return 0;
 }
@@ -1690,22 +1664,6 @@ igb_get_rx_queue_offloads_capa(struct rte_eth_dev *dev)
 	return rx_queue_offload_capa;
 }
 
-static int
-igb_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = igb_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = igb_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int
 eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -1718,19 +1676,9 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	struct igb_rx_queue *rxq;
 	struct e1000_hw     *hw;
 	unsigned int size;
+	uint64_t offloads;
 
-	if (!igb_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev,
-			rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			igb_get_rx_port_offloads_capa(dev),
-			igb_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1756,7 +1704,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL)
 		return -ENOMEM;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 	rxq->mb_pool = mp;
 	rxq->nb_rx_desc = nb_desc;
 	rxq->pthresh = rx_conf->rx_thresh.pthresh;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 41b5638..c595cc7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -238,10 +238,6 @@ static int ena_rss_reta_query(struct rte_eth_dev *dev,
 			      struct rte_eth_rss_reta_entry64 *reta_conf,
 			      uint16_t reta_size);
 static int ena_get_sset_count(struct rte_eth_dev *dev, int sset);
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -1005,12 +1001,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (tx_conf->txq_flags == ETH_TXQ_FLAGS_IGNORE &&
-	    !ena_are_tx_queue_offloads_allowed(adapter, tx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_TXQ_IDX(queue_idx);
 
 	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1065,7 +1055,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
 	for (i = 0; i < txq->ring_size; i++)
 		txq->empty_tx_reqs[i] = i;
 
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* Store pointer to this queue in upper layer */
 	txq->configured = 1;
@@ -1078,7 +1068,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 			      uint16_t queue_idx,
 			      uint16_t nb_desc,
 			      __rte_unused unsigned int socket_id,
-			      const struct rte_eth_rxconf *rx_conf,
+			      __rte_unused const struct rte_eth_rxconf *rx_conf,
 			      struct rte_mempool *mp)
 {
 	struct ena_com_create_io_ctx ctx =
@@ -1114,11 +1104,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	if (!ena_are_rx_queue_offloads_allowed(adapter, rx_conf->offloads)) {
-		RTE_LOG(ERR, PMD, "Unsupported queue offloads\n");
-		return -EINVAL;
-	}
-
 	ena_qid = ENA_IO_RXQ_IDX(queue_idx);
 
 	ctx.qid = ena_qid;
@@ -1422,22 +1407,6 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter =
 		(struct ena_adapter *)(dev->data->dev_private);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-
-	if ((tx_offloads & adapter->tx_supported_offloads) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    tx_offloads, adapter->tx_supported_offloads);
-		return -ENOTSUP;
-	}
-
-	if ((rx_offloads & adapter->rx_supported_offloads) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported "
-		    "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		    rx_offloads, adapter->rx_supported_offloads);
-		return -ENOTSUP;
-	}
 
 	if (!(adapter->state == ENA_ADAPTER_STATE_INIT ||
 	      adapter->state == ENA_ADAPTER_STATE_STOPPED)) {
@@ -1459,8 +1428,8 @@ static int ena_dev_configure(struct rte_eth_dev *dev)
 		break;
 	}
 
-	adapter->tx_selected_offloads = tx_offloads;
-	adapter->rx_selected_offloads = rx_offloads;
+	adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads;
+	adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads;
 	return 0;
 }
 
@@ -1489,32 +1458,6 @@ static void ena_init_rings(struct ena_adapter *adapter)
 	}
 }
 
-static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->tx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
-static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter,
-					      uint64_t offloads)
-{
-	uint64_t port_offloads = adapter->rx_selected_offloads;
-
-	/* Check if port supports all requested offloads.
-	 * True if all offloads selected for queue are set for port.
-	 */
-	if ((offloads & port_offloads) != offloads)
-		return false;
-	return true;
-}
-
 static void ena_infos_get(struct rte_eth_dev *dev,
 			  struct rte_eth_dev_info *dev_info)
 {
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 6d44884..368d23f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -90,22 +90,10 @@ static int
 fs_dev_configure(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
-	uint64_t supp_tx_offloads;
-	uint64_t tx_offloads;
 	uint8_t i;
 	int ret;
 
 	fs_lock(dev, 0);
-	supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		ERROR("Some Tx offloads are not supported, "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-		      tx_offloads, supp_tx_offloads);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	FOREACH_SUBDEV(sdev, i, dev) {
 		int rmv_interrupt = 0;
 		int lsc_interrupt = 0;
@@ -297,25 +285,6 @@ fs_dev_close(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
-static bool
-fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.rxmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_rx_queue_release(void *queue)
 {
@@ -368,19 +337,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 		fs_rx_queue_release(rxq);
 		dev->data->rx_queues[rx_queue_id] = NULL;
 	}
-	/* Verify application offloads are valid for our port and queue. */
-	if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Rx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      rx_conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      PRIV(dev)->infos.rx_offload_capa |
-		      PRIV(dev)->infos.rx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
@@ -499,25 +455,6 @@ fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 	return rc;
 }
 
-static bool
-fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads;
-	uint64_t queue_supp_offloads;
-	uint64_t port_supp_offloads;
-
-	port_offloads = dev->data->dev_conf.txmode.offloads;
-	queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
-	port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	     offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 fs_tx_queue_release(void *queue)
 {
@@ -557,24 +494,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 		fs_tx_queue_release(txq);
 		dev->data->tx_queues[tx_queue_id] = NULL;
 	}
-	/*
-	 * Don't verify queue offloads for applications which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
-		rte_errno = ENOTSUP;
-		ERROR("Tx queue offloads 0x%" PRIx64
-		      " don't match port offloads 0x%" PRIx64
-		      " or supported offloads 0x%" PRIx64,
-		      tx_conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      PRIV(dev)->infos.tx_offload_capa |
-		      PRIV(dev)->infos.tx_queue_offload_capa);
-		fs_unlock(dev, 0);
-		return -rte_errno;
-	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
 			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 7dfeddf..7a59530 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -448,29 +448,13 @@ static int
 fm10k_dev_configure(struct rte_eth_dev *dev)
 {
 	int ret;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0)
+	if ((dev->data->dev_conf.rxmode.offloads &
+	     DEV_RX_OFFLOAD_CRC_STRIP) == 0)
 		PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
 
-	fm10k_dev_infos_get(dev, &dev_info);
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* multipe queue mode checking */
 	ret  = fm10k_check_mq_mode(dev);
 	if (ret != 0) {
@@ -1827,22 +1811,6 @@ static uint64_t fm10k_get_rx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = fm10k_get_rx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_rx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
@@ -1852,20 +1820,11 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 	struct fm10k_rx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_rx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			fm10k_get_rx_port_offloads_capa(dev),
-			fm10k_get_rx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/* make sure the mempool element size can account for alignment. */
 	if (!mempool_element_size_valid(mp)) {
@@ -1911,7 +1870,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->queue_id = queue_id;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	if (handle_rxconf(q, conf))
 		return -EINVAL;
 
@@ -2040,22 +1999,6 @@ static uint64_t fm10k_get_tx_port_offloads_capa(struct rte_eth_dev *dev)
 }
 
 static int
-fm10k_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = fm10k_get_tx_queue_offloads_capa(dev);
-	uint64_t port_supported = fm10k_get_tx_port_offloads_capa(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
-static int
 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	uint16_t nb_desc, unsigned int socket_id,
 	const struct rte_eth_txconf *conf)
@@ -2063,20 +2006,11 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct fm10k_tx_queue *q;
 	const struct rte_memzone *mz;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!fm10k_check_tx_queue_offloads(dev, conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			fm10k_get_tx_port_offloads_capa(dev),
-			fm10k_get_tx_queue_offloads_capa(dev));
-		return -ENOTSUP;
-	}
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/* make sure a valid number of descriptors have been requested */
 	if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
@@ -2115,7 +2049,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 	q->port_id = dev->data->port_id;
 	q->queue_id = queue_id;
 	q->txq_flags = conf->txq_flags;
-	q->offloads = conf->offloads;
+	q->offloads = offloads;
 	q->ops = &def_txq_ops;
 	q->tail_ptr = (volatile uint32_t *)
 		&((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 62985c3..05b4950 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1690,20 +1690,6 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
-	if ((requested & dev_info.rx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_first_queue(uint16_t idx, void **queues, int num)
 {
 	uint16_t i;
@@ -1792,18 +1778,9 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len, i;
 	uint16_t reg_idx, base, bsf, tc_mapping;
 	int q_offset, use_def_burst_func = 1;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1857,7 +1834,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->vsi = vsi;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/* Allocate the maximun number of RX ring hardware descriptor. */
 	len = I40E_MAX_RING_DESC;
@@ -2075,20 +2052,6 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
 }
 
 static int
-i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	struct rte_eth_dev_info dev_info;
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported; /* All per port offloads */
-
-	dev->dev_ops->dev_infos_get(dev, &dev_info);
-	supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
-	if ((requested & dev_info.tx_offload_capa) != requested)
-		return 0; /* requested range check */
-	return !((mandatory ^ requested) & supported);
-}
-
-static int
 i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
 				struct i40e_tx_queue *txq)
 {
@@ -2151,18 +2114,9 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_rs_thresh, tx_free_thresh;
 	uint16_t reg_idx, i, base, bsf, tc_mapping;
 	int q_offset;
-	struct rte_eth_dev_info dev_info;
+	uint64_t offloads;
 
-	if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		dev->dev_ops->dev_infos_get(dev, &dev_info);
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port  offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			dev_info.tx_offload_capa);
-			return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
 		vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2297,7 +2251,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->queue_id = queue_idx;
 	txq->reg_idx = reg_idx;
 	txq->port_id = dev->data->port_id;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 91179e9..320ab21 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2365,9 +2365,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2379,22 +2376,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 		return ret;
 	}
 
-	ixgbe_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* set flag to update link status after init */
 	intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -4965,29 +4946,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 	struct ixgbe_adapter *adapter =
 			(struct ixgbe_adapter *)dev->data->dev_private;
-	struct rte_eth_dev_info dev_info;
-	uint64_t rx_offloads;
-	uint64_t tx_offloads;
 
 	PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
 		     dev->data->port_id);
 
-	ixgbevf_dev_info_get(dev, &dev_info);
-	rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    rx_offloads, dev_info.rx_offload_capa);
-		return -ENOTSUP;
-	}
-	tx_offloads = dev->data->dev_conf.txmode.offloads;
-	if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-		PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-			    "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			    tx_offloads, dev_info.tx_offload_capa);
-		return -ENOTSUP;
-	}
-
 	/*
 	 * VF has no ability to enable/disable HW CRC
 	 * Keep the persistent behavior the same as Host PF
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 2892436..7de6f00 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2448,22 +2448,6 @@ ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
 	return tx_offload_capa;
 }
 
-static int
-ixgbe_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supported = ixgbe_get_tx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_tx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2475,25 +2459,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	struct ixgbe_tx_queue *txq;
 	struct ixgbe_hw     *hw;
 	uint16_t tx_rs_thresh, tx_free_thresh;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!ixgbe_check_tx_queue_offloads(dev, tx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64,
-			(void *)dev, tx_conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			ixgbe_get_tx_queue_offloads(dev),
-			ixgbe_get_tx_port_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	/*
 	 * Validate number of transmit descriptors.
@@ -2621,7 +2592,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 		queue_idx : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + queue_idx);
 	txq->port_id = dev->data->port_id;
 	txq->txq_flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 	txq->ops = &def_txq_ops;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 #ifdef RTE_LIBRTE_SECURITY
@@ -2915,22 +2886,6 @@ ixgbe_get_rx_port_offloads(struct rte_eth_dev *dev)
 	return offloads;
 }
 
-static int
-ixgbe_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supported = ixgbe_get_rx_queue_offloads(dev);
-	uint64_t port_supported = ixgbe_get_rx_port_offloads(dev);
-
-	if ((requested & (queue_supported | port_supported)) != requested)
-		return 0;
-
-	if ((port_offloads ^ requested) & port_supported)
-		return 0;
-
-	return 1;
-}
-
 int __attribute__((cold))
 ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			 uint16_t queue_idx,
@@ -2945,21 +2900,12 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t len;
 	struct ixgbe_adapter *adapter =
 		(struct ixgbe_adapter *)dev->data->dev_private;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	if (!ixgbe_check_rx_queue_offloads(dev, rx_conf->offloads)) {
-		PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported port offloads 0x%" PRIx64
-			" or supported queue offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			ixgbe_get_rx_port_offloads(dev),
-			ixgbe_get_rx_queue_offloads(dev));
-		return -ENOTSUP;
-	}
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	/*
 	 * Validate number of receive descriptors.
@@ -2994,7 +2940,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
 	rxq->drop_en = rx_conf->rx_drop_en;
 	rxq->rx_deferred_start = rx_conf->rx_deferred_start;
-	rxq->offloads = rx_conf->offloads;
+	rxq->offloads = offloads;
 
 	/*
 	 * The packet type in RX descriptor is different for different NICs.
diff --git a/drivers/net/mlx4/mlx4_rxq.c b/drivers/net/mlx4/mlx4_rxq.c
index 65f0994..35c44ff 100644
--- a/drivers/net/mlx4/mlx4_rxq.c
+++ b/drivers/net/mlx4/mlx4_rxq.c
@@ -693,26 +693,6 @@ mlx4_get_rx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_rx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = mlx4_get_rx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Rx queue.
  *
  * @param dev
@@ -754,20 +734,13 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	};
 	int ret;
 	uint32_t crc_present;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
-	(void)conf; /* Thresholds configuration (ignored). */
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	if (!mlx4_check_rx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Rx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.rxmode.offloads,
-		      (mlx4_get_rx_port_offloads(priv) |
-		       mlx4_get_rx_queue_offloads(priv)));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -793,7 +766,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		     (void *)dev, idx, desc);
 	}
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		crc_present = 0;
 	} else if (priv->hw_fcs_strip) {
 		crc_present = 1;
@@ -825,9 +798,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts = elts,
 		/* Toggle Rx checksum offload if hardware supports it. */
 		.csum = priv->hw_csum &&
-			(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			(offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads & DEV_RX_OFFLOAD_CHECKSUM),
+			      (offloads & DEV_RX_OFFLOAD_CHECKSUM),
 		.crc_present = crc_present,
 		.l2tun_offload = priv->hw_csum_l2tun,
 		.stats = {
@@ -840,7 +813,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		uint32_t size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c
index fe6a8e0..2443333 100644
--- a/drivers/net/mlx4/mlx4_txq.c
+++ b/drivers/net/mlx4/mlx4_txq.c
@@ -180,26 +180,6 @@ mlx4_get_tx_port_offloads(struct priv *priv)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param priv
- *   Pointer to private structure.
- * @param requested
- *   Per-queue offloads configuration.
- *
- * @return
- *   Nonzero when configuration is valid.
- */
-static int
-mlx4_check_tx_queue_offloads(struct priv *priv, uint64_t requested)
-{
-	uint64_t mandatory = priv->dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = mlx4_get_tx_port_offloads(priv);
-
-	return !((mandatory ^ requested) & supported);
-}
-
-/**
  * DPDK callback to configure a Tx queue.
  *
  * @param dev
@@ -246,23 +226,13 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		},
 	};
 	int ret;
+	uint64_t offloads;
+
+	offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
 
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if ((conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx4_check_tx_queue_offloads(priv, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		ERROR("%p: Tx queue offloads 0x%" PRIx64 " don't match port "
-		      "offloads 0x%" PRIx64 " or supported offloads 0x%" PRIx64,
-		      (void *)dev, conf->offloads,
-		      dev->data->dev_conf.txmode.offloads,
-		      mlx4_get_tx_port_offloads(priv));
-		return -rte_errno;
-	}
+
 	if (idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
@@ -313,11 +283,11 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		.elts_comp_cd_init =
 			RTE_MIN(MLX4_PMD_TX_PER_COMP_REQ, desc / 4),
 		.csum = priv->hw_csum &&
-			(conf->offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
+			(offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM |
 					   DEV_TX_OFFLOAD_UDP_CKSUM |
 					   DEV_TX_OFFLOAD_TCP_CKSUM)),
 		.csum_l2tun = priv->hw_csum_l2tun &&
-			      (conf->offloads &
+			      (offloads &
 			       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM),
 		/* Enable Tx loopback for VF devices. */
 		.lb = !!priv->vf,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 746b94f..df369cd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -330,30 +330,8 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 	unsigned int reta_idx_n;
 	const uint8_t use_app_rss_key =
 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
-	uint64_t supp_tx_offloads = mlx5_get_tx_port_offloads(dev);
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t supp_rx_offloads =
-		(mlx5_get_rx_port_offloads() |
-		 mlx5_get_rx_queue_offloads(dev));
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	int ret = 0;
 
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Tx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, tx_offloads, supp_tx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
-	if ((rx_offloads & supp_rx_offloads) != rx_offloads) {
-		DRV_LOG(ERR,
-			"port %u some Rx offloads are not supported requested"
-			" 0x%" PRIx64 " supported 0x%" PRIx64,
-			dev->data->port_id, rx_offloads, supp_rx_offloads);
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (use_app_rss_key &&
 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
 	     rss_hash_default_key_len)) {
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 126412d..cea93cf 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -237,32 +237,6 @@ mlx5_get_rx_port_offloads(void)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_rx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = mlx5_get_rx_queue_offloads(dev);
-	uint64_t port_supp_offloads = mlx5_get_rx_port_offloads();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return 0;
-	if (((port_offloads ^ offloads) & port_supp_offloads))
-		return 0;
-	return 1;
-}
-
-/**
  *
  * @param dev
  *   Pointer to Ethernet device structure.
@@ -305,18 +279,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		rte_errno = EOVERFLOW;
 		return -rte_errno;
 	}
-	if (!mlx5_is_rx_queue_offloads_allowed(dev, conf->offloads)) {
-		DRV_LOG(ERR,
-			"port %u Rx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(mlx5_get_rx_port_offloads() |
-			 mlx5_get_rx_queue_offloads(dev)));
-		rte_errno = ENOTSUP;
-		return -rte_errno;
-	}
 	if (!mlx5_rxq_releasable(dev, idx)) {
 		DRV_LOG(ERR, "port %u unable to release queue index %u",
 			dev->data->port_id, idx);
@@ -980,6 +942,8 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 */
 	const uint16_t desc_n =
 		desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP;
+	uint64_t offloads = conf->offloads |
+			   dev->data->dev_conf.rxmode.offloads;
 
 	tmpl = rte_calloc_socket("RXQ", 1,
 				 sizeof(*tmpl) +
@@ -997,7 +961,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (dev->data->dev_conf.rxmode.max_rx_pkt_len <=
 	    (mb_len - RTE_PKTMBUF_HEADROOM)) {
 		tmpl->rxq.sges_n = 0;
-	} else if (conf->offloads & DEV_RX_OFFLOAD_SCATTER) {
+	} else if (offloads & DEV_RX_OFFLOAD_SCATTER) {
 		unsigned int size =
 			RTE_PKTMBUF_HEADROOM +
 			dev->data->dev_conf.rxmode.max_rx_pkt_len;
@@ -1044,12 +1008,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		goto error;
 	}
 	/* Toggle RX checksum offload if hardware supports it. */
-	tmpl->rxq.csum = !!(conf->offloads & DEV_RX_OFFLOAD_CHECKSUM);
-	tmpl->rxq.hw_timestamp = !!(conf->offloads & DEV_RX_OFFLOAD_TIMESTAMP);
+	tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
+	tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
 	/* Configure VLAN stripping. */
-	tmpl->rxq.vlan_strip = !!(conf->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+	tmpl->rxq.vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 	/* By default, FCS (CRC) is stripped by hardware. */
-	if (conf->offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
+	if (offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
 		tmpl->rxq.crc_present = 0;
 	} else if (config->hw_fcs_strip) {
 		tmpl->rxq.crc_present = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4435874..fb7b4ad 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -127,31 +127,6 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 }
 
 /**
- * Checks if the per-queue offload configuration is valid.
- *
- * @param dev
- *   Pointer to Ethernet device.
- * @param offloads
- *   Per-queue offloads configuration.
- *
- * @return
- *   1 if the configuration is valid, 0 otherwise.
- */
-static int
-mlx5_is_tx_queue_offloads_allowed(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t port_supp_offloads = mlx5_get_tx_port_offloads(dev);
-
-	/* There are no Tx offloads which are per queue. */
-	if ((offloads & port_supp_offloads) != offloads)
-		return 0;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return 0;
-	return 1;
-}
-
-/**
  * DPDK callback to configure a TX queue.
  *
  * @param dev
@@ -177,22 +152,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mlx5_txq_ctrl *txq_ctrl =
 		container_of(txq, struct mlx5_txq_ctrl, txq);
 
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (!!(conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
-	    !mlx5_is_tx_queue_offloads_allowed(dev, conf->offloads)) {
-		rte_errno = ENOTSUP;
-		DRV_LOG(ERR,
-			"port %u Tx queue offloads 0x%" PRIx64 " don't match"
-			" port offloads 0x%" PRIx64 " or supported offloads 0x%"
-			PRIx64,
-			dev->data->port_id, conf->offloads,
-			dev->data->dev_conf.txmode.offloads,
-			mlx5_get_tx_port_offloads(dev));
-		return -rte_errno;
-	}
 	if (desc <= MLX5_TX_COMP_THRESH) {
 		DRV_LOG(WARNING,
 			"port %u number of descriptors requested for Tx queue"
@@ -810,7 +769,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		return NULL;
 	}
 	assert(desc > MLX5_TX_COMP_THRESH);
-	tmpl->txq.offloads = conf->offloads;
+	tmpl->txq.offloads = conf->offloads |
+			     dev->data->dev_conf.txmode.offloads;
 	tmpl->priv = priv;
 	tmpl->socket = socket;
 	tmpl->txq.elts_n = log2above(desc);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 05998bf..c9d85ca 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -318,26 +318,11 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
-		RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.split_hdr_size) {
 		RTE_LOG(INFO, PMD, "Split headers not supported\n");
 		return -EINVAL;
 	}
 
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
-		RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
-		return -EINVAL;
-	}
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		RTE_LOG(INFO, PMD, "LRO not supported\n");
-		return -EINVAL;
-	}
-
 	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
 		dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
 				 ETHER_HDR_LEN - ETHER_CRC_LEN;
@@ -1522,42 +1507,6 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
 }
 
 /**
- * Check whether requested rx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_rx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = MRVL_RX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Rx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the receive queue.
  *
  * @param dev
@@ -1587,9 +1536,9 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	uint32_t min_size,
 		 max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	int ret, tc, inq;
+	uint64_t offloads;
 
-	if (!mrvl_rx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
+	offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
 
 	if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
 		/*
@@ -1622,8 +1571,7 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 
 	rxq->priv = priv;
 	rxq->mp = mp;
-	rxq->cksum_enabled =
-		dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
+	rxq->cksum_enabled = offloads & DEV_RX_OFFLOAD_IPV4_CKSUM;
 	rxq->queue_id = idx;
 	rxq->port_id = dev->data->port_id;
 	mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
@@ -1686,42 +1634,6 @@ mrvl_rx_queue_release(void *rxq)
 }
 
 /**
- * Check whether requested tx queue offloads match port offloads.
- *
- * @param
- *   dev Pointer to the device.
- * @param
- *   requested Bitmap of the requested offloads.
- *
- * @return
- *   1 if requested offloads are okay, 0 otherwise.
- */
-static int
-mrvl_tx_queue_offloads_okay(struct rte_eth_dev *dev, uint64_t requested)
-{
-	uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = MRVL_TX_OFFLOADS;
-	uint64_t unsupported = requested & ~supported;
-	uint64_t missing = mandatory & ~requested;
-
-	if (unsupported) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are not supported. "
-			"Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-			requested, supported);
-		return 0;
-	}
-
-	if (missing) {
-		RTE_LOG(ERR, PMD, "Some Tx offloads are missing. "
-			"Requested 0x%" PRIx64 " missing 0x%" PRIx64 ".\n",
-			requested, missing);
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
  * DPDK callback to configure the transmit queue.
  *
  * @param dev
@@ -1746,9 +1658,6 @@ mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct mrvl_priv *priv = dev->data->dev_private;
 	struct mrvl_txq *txq;
 
-	if (!mrvl_tx_queue_offloads_okay(dev, conf->offloads))
-		return -ENOTSUP;
-
 	if (dev->data->tx_queues[idx]) {
 		rte_free(dev->data->tx_queues[idx]);
 		dev->data->tx_queues[idx] = NULL;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 048324e..d3b8ec0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -412,148 +412,9 @@ nfp_net_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Checking RX offloads */
-	if (rxmode->offloads & DEV_RX_OFFLOAD_HEADER_SPLIT) {
-		PMD_INIT_LOG(INFO, "rxmode does not support split header");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXCSUM))
-		PMD_INIT_LOG(INFO, "RXCSUM not supported");
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
-		PMD_INIT_LOG(INFO, "VLAN filter not supported");
-		return -EINVAL;
-	}
-
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_RXVLAN)) {
-		PMD_INIT_LOG(INFO, "hw vlan strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
-		PMD_INIT_LOG(INFO, "VLAN extended not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TCP_LRO) {
-		PMD_INIT_LOG(INFO, "LRO not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) {
-		PMD_INIT_LOG(INFO, "QINQ STRIP not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "Outer IP checksum not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_MACSEC_STRIP) {
-		PMD_INIT_LOG(INFO, "MACSEC strip not supported");
-		return -EINVAL;
-	}
-
 	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP))
 		PMD_INIT_LOG(INFO, "HW does strip CRC. No configurable!");
 
-	if ((rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_SCATTER)) {
-		PMD_INIT_LOG(INFO, "Scatter not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		PMD_INIT_LOG(INFO, "timestamp offfload not supported");
-		return -EINVAL;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "security offload not supported");
-		return -EINVAL;
-	}
-
-	/* checking TX offloads */
-	if ((txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXVLAN)) {
-		PMD_INIT_LOG(INFO, "vlan insert offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_TXCSUM)) {
-		PMD_INIT_LOG(INFO, "TX checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_LSO_ANY)) {
-		PMD_INIT_LOG(INFO, "TSO TCP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_UDP_TSO) {
-		PMD_INIT_LOG(INFO, "TSO UDP offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
-		PMD_INIT_LOG(INFO, "TX outer checksum offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) {
-		PMD_INIT_LOG(INFO, "QINQ insert offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_VXLAN_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GRE_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_IPIP_TNL_TSO ||
-	    txmode->offloads & DEV_TX_OFFLOAD_GENEVE_TNL_TSO) {
-		PMD_INIT_LOG(INFO, "tunneling offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-		PMD_INIT_LOG(INFO, "TX MACSEC offload not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE) {
-		PMD_INIT_LOG(INFO, "multiqueue lockfree not supported");
-		return -EINVAL;
-	}
-
-	if ((txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) &&
-	    !(hw->cap & NFP_NET_CFG_CTRL_GATHER)) {
-		PMD_INIT_LOG(INFO, "TX multisegs  not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) {
-		PMD_INIT_LOG(INFO, "mbuf fast-free not supported");
-		return -EINVAL;
-	}
-
-	if (txmode->offloads & DEV_TX_OFFLOAD_SECURITY) {
-		PMD_INIT_LOG(INFO, "TX security offload not supported");
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -1600,8 +1461,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_rxmode *rxmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1615,17 +1474,6 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	rxmode = &dev_conf->rxmode;
-
-	if (rx_conf->offloads != rxmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u rx offloads not as port offloads",
-				  queue_idx);
-		PMD_DRV_LOG(ERR, "\tport: %" PRIx64 "", rxmode->offloads);
-		PMD_DRV_LOG(ERR, "\tqueue: %" PRIx64 "", rx_conf->offloads);
-		return -EINVAL;
-	}
-
 	/*
 	 * Free memory prior to re-allocation if needed. This is the case after
 	 * calling nfp_net_stop
@@ -1762,8 +1610,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	struct nfp_net_hw *hw;
-	struct rte_eth_conf *dev_conf;
-	struct rte_eth_txmode *txmode;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -1777,15 +1623,6 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -EINVAL;
 	}
 
-	dev_conf = &dev->data->dev_conf;
-	txmode = &dev_conf->txmode;
-
-	if (tx_conf->offloads != txmode->offloads) {
-		PMD_DRV_LOG(ERR, "queue %u tx offloads not as port offloads",
-				  queue_idx);
-		return -EINVAL;
-	}
-
 	tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
 				    tx_conf->tx_free_thresh :
 				    DEFAULT_TX_FREE_THRESH);
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 04120f5..4b14b8f 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -262,8 +262,6 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -285,38 +283,14 @@ octeontx_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	configured_offloads = rxmode->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
+	if (!(rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
+		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
 
-	configured_offloads = txmode->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
+	if (!(txmode->offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
 		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
+		txmode->offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
 	}
 
 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
@@ -738,14 +712,12 @@ octeontx_dev_tx_queue_release(void *tx_queue)
 static int
 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 			    uint16_t nb_desc, unsigned int socket_id,
-			    const struct rte_eth_txconf *tx_conf)
+			    const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 	struct octeontx_txq *txq = NULL;
 	uint16_t dq_num;
 	int res = 0;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 	RTE_SET_USED(socket_id);
@@ -766,22 +738,6 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		dev->data->tx_queues[qidx] = NULL;
 	}
 
-	configured_offloads = tx_conf->offloads;
-
-	if (!(configured_offloads & DEV_TX_OFFLOAD_MT_LOCKFREE)) {
-		PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
-		configured_offloads |= DEV_TX_OFFLOAD_MT_LOCKFREE;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_TX_OFFLOADS;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_TX_OFFLOADS);
-		return -ENOTSUP;
-	}
-
 	/* Allocating tx queue data structure */
 	txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
 				 RTE_CACHE_LINE_SIZE, nic->node);
@@ -837,8 +793,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint8_t gaura;
 	unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
 	unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
-	uint64_t configured_offloads;
-	uint64_t unsupported_offloads;
 
 	RTE_SET_USED(nb_desc);
 
@@ -861,22 +815,6 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	port = nic->port_id;
 
-	configured_offloads = rx_conf->offloads;
-
-	if (!(configured_offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
-		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
-		configured_offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-	}
-
-	unsupported_offloads = configured_offloads & ~OCTEONTX_RX_OFFLOADS;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, configured_offloads,
-		      (uint64_t)OCTEONTX_RX_OFFLOADS);
-		return -ENOTSUP;
-	}
 	/* Rx deferred start is not supported */
 	if (rx_conf->rx_deferred_start) {
 		octeontx_log_err("rx deferred start not supported");
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e42d553..fc2b254 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -413,14 +413,16 @@ sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "RxQ=%u nb_rx_desc=%u socket_id=%u",
 		     rx_queue_id, nb_rx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	rc = sfc_rx_qinit(sa, rx_queue_id, nb_rx_desc, socket_id,
-			  rx_conf, mb_pool);
+			  rx_conf, mb_pool, offloads);
 	if (rc != 0)
 		goto fail_rx_qinit;
 
@@ -469,13 +471,16 @@ sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	int rc;
+	uint64_t offloads;
 
 	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
 		     tx_queue_id, nb_tx_desc, socket_id);
 
 	sfc_adapter_lock(sa);
 
-	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id,
+			  tx_conf, offloads);
 	if (rc != 0)
 		goto fail_tx_qinit;
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 57ed34f..dbdd000 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -830,32 +830,10 @@ sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 	}
 }
 
-static boolean_t
-sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads;
-	uint64_t supported = sfc_rx_get_dev_offload_caps(sa) |
-			     sfc_rx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_rx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
 static int
 sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
-		   const struct rte_eth_rxconf *rx_conf)
+		   const struct rte_eth_rxconf *rx_conf,
+		   uint64_t offloads)
 {
 	uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) |
 				      sfc_rx_get_queue_offload_caps(sa);
@@ -880,17 +858,14 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		rc = EINVAL;
 	}
 
-	if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
+	if ((offloads & DEV_RX_OFFLOAD_CHECKSUM) !=
 	    DEV_RX_OFFLOAD_CHECKSUM)
 		sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)");
 
 	if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
+	    (~offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM))
 		sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on");
 
-	if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -998,7 +973,8 @@ int
 sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_rx_desc, unsigned int socket_id,
 	     const struct rte_eth_rxconf *rx_conf,
-	     struct rte_mempool *mb_pool)
+	     struct rte_mempool *mb_pool,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_rss *rss = &sa->rss;
@@ -1020,7 +996,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
 	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
-	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -1033,7 +1009,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	}
 
 	if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
-	    (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) {
+	    (~offloads & DEV_RX_OFFLOAD_SCATTER)) {
 		sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
 			"object size is too small", sw_index);
 		sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
@@ -1056,7 +1032,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 
 	rxq_info->type_flags =
-		(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ?
+		(offloads & DEV_RX_OFFLOAD_SCATTER) ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 3fba7d8..2898fe5 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -138,7 +138,8 @@ void sfc_rx_stop(struct sfc_adapter *sa);
 int sfc_rx_qinit(struct sfc_adapter *sa, unsigned int rx_queue_id,
 		 uint16_t nb_rx_desc, unsigned int socket_id,
 		 const struct rte_eth_rxconf *rx_conf,
-		 struct rte_mempool *mb_pool);
+		 struct rte_mempool *mb_pool,
+		 uint64_t offloads);
 void sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
 void sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1cd08d8..a4a21fa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -90,31 +90,9 @@ sfc_tx_log_offloads(struct sfc_adapter *sa, const char *offload_group,
 }
 
 static int
-sfc_tx_queue_offload_mismatch(struct sfc_adapter *sa, uint64_t requested)
-{
-	uint64_t mandatory = sa->eth_dev->data->dev_conf.txmode.offloads;
-	uint64_t supported = sfc_tx_get_dev_offload_caps(sa) |
-			     sfc_tx_get_queue_offload_caps(sa);
-	uint64_t rejected = requested & ~supported;
-	uint64_t missing = (requested & mandatory) ^ mandatory;
-	boolean_t mismatch = B_FALSE;
-
-	if (rejected) {
-		sfc_tx_log_offloads(sa, "queue", "is unsupported", rejected);
-		mismatch = B_TRUE;
-	}
-
-	if (missing) {
-		sfc_tx_log_offloads(sa, "queue", "must be set", missing);
-		mismatch = B_TRUE;
-	}
-
-	return mismatch;
-}
-
-static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
-		   const struct rte_eth_txconf *tx_conf)
+		   const struct rte_eth_txconf *tx_conf,
+		   uint64_t offloads)
 {
 	int rc = 0;
 
@@ -138,15 +116,12 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 	}
 
 	/* We either perform both TCP and UDP offload, or no offload at all */
-	if (((tx_conf->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
-	    ((tx_conf->offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
+	if (((offloads & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) !=
+	    ((offloads & DEV_TX_OFFLOAD_UDP_CKSUM) == 0)) {
 		sfc_err(sa, "TCP and UDP offloads can't be set independently");
 		rc = EINVAL;
 	}
 
-	if (sfc_tx_queue_offload_mismatch(sa, tx_conf->offloads))
-		rc = EINVAL;
-
 	return rc;
 }
 
@@ -160,7 +135,8 @@ sfc_tx_qflush_done(struct sfc_txq *txq)
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
-	     const struct rte_eth_txconf *tx_conf)
+	     const struct rte_eth_txconf *tx_conf,
+	     uint64_t offloads)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	unsigned int txq_entries;
@@ -183,7 +159,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(txq_entries >= nb_tx_desc);
 	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
-	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf, offloads);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -210,7 +186,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		(tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
 		SFC_TX_DEFAULT_FREE_THRESH;
 	txq->flags = tx_conf->txq_flags;
-	txq->offloads = tx_conf->offloads;
+	txq->offloads = offloads;
 
 	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
 			   socket_id, &txq->mem);
@@ -221,7 +197,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
-	info.offloads = tx_conf->offloads;
+	info.offloads = offloads;
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index c2e5f13..d2b2c4d 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -121,7 +121,8 @@ void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-		 const struct rte_eth_txconf *tx_conf);
+		 const struct rte_eth_txconf *tx_conf,
+		 uint64_t offloads);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
 void sfc_tx_qflush_done(struct sfc_txq *txq);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 172a7ba..78fe89b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -280,21 +280,6 @@ tap_rx_offload_get_queue_capa(void)
 	       DEV_RX_OFFLOAD_CRC_STRIP;
 }
 
-static bool
-tap_rxq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t queue_supp_offloads = tap_rx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_rx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -408,22 +393,6 @@ tap_tx_offload_get_queue_capa(void)
 	       DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
-static bool
-tap_txq_are_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
-{
-	uint64_t port_offloads = dev->data->dev_conf.txmode.offloads;
-	uint64_t queue_supp_offloads = tap_tx_offload_get_queue_capa();
-	uint64_t port_supp_offloads = tap_tx_offload_get_port_capa();
-
-	if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
-	    offloads)
-		return false;
-	/* Verify we have no conflict with port offloads */
-	if ((port_offloads ^ offloads) & port_supp_offloads)
-		return false;
-	return true;
-}
-
 static void
 tap_tx_offload(char *packet, uint64_t ol_flags, unsigned int l2_len,
 	       unsigned int l3_len)
@@ -668,18 +637,6 @@ tap_dev_stop(struct rte_eth_dev *dev)
 static int
 tap_dev_configure(struct rte_eth_dev *dev)
 {
-	uint64_t supp_tx_offloads = tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa();
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
-
-	if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"Some Tx offloads are not supported "
-			"requested 0x%" PRIx64 " supported 0x%" PRIx64,
-			tx_offloads, supp_tx_offloads);
-		return -rte_errno;
-	}
 	if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) {
 		TAP_LOG(ERR,
 			"%s: number of rx queues %d exceeds max num of queues %d",
@@ -1081,19 +1038,6 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
-	/* Verify application offloads are valid for our port and queue. */
-	if (!tap_rxq_are_offloads_valid(dev, rx_conf->offloads)) {
-		rte_errno = ENOTSUP;
-		TAP_LOG(ERR,
-			"%p: Rx queue offloads 0x%" PRIx64
-			" don't match port offloads 0x%" PRIx64
-			" or supported offloads 0x%" PRIx64,
-			(void *)dev, rx_conf->offloads,
-			dev->data->dev_conf.rxmode.offloads,
-			(tap_rx_offload_get_port_capa() |
-			 tap_rx_offload_get_queue_capa()));
-		return -rte_errno;
-	}
 	rxq->mp = mp;
 	rxq->trigger_seen = 1; /* force initial burst */
 	rxq->in_port = dev->data->port_id;
@@ -1157,35 +1101,19 @@ tap_tx_queue_setup(struct rte_eth_dev *dev,
 	struct pmd_internals *internals = dev->data->dev_private;
 	struct tx_queue *txq;
 	int ret;
+	uint64_t offloads;
 
 	if (tx_queue_id >= dev->data->nb_tx_queues)
 		return -1;
 	dev->data->tx_queues[tx_queue_id] = &internals->txq[tx_queue_id];
 	txq = dev->data->tx_queues[tx_queue_id];
-	/*
-	 * Don't verify port offloads for application which
-	 * use the old API.
-	 */
-	if (tx_conf != NULL &&
-	    !!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-		if (tap_txq_are_offloads_valid(dev, tx_conf->offloads)) {
-			txq->csum = !!(tx_conf->offloads &
-					(DEV_TX_OFFLOAD_IPV4_CKSUM |
-					 DEV_TX_OFFLOAD_UDP_CKSUM |
-					 DEV_TX_OFFLOAD_TCP_CKSUM));
-		} else {
-			rte_errno = ENOTSUP;
-			TAP_LOG(ERR,
-				"%p: Tx queue offloads 0x%" PRIx64
-				" don't match port offloads 0x%" PRIx64
-				" or supported offloads 0x%" PRIx64,
-				(void *)dev, tx_conf->offloads,
-				dev->data->dev_conf.txmode.offloads,
-				(tap_tx_offload_get_port_capa() |
-				tap_tx_offload_get_queue_capa()));
-			return -rte_errno;
-		}
-	}
+
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->csum = !!(offloads &
+			(DEV_TX_OFFLOAD_IPV4_CKSUM |
+			 DEV_TX_OFFLOAD_UDP_CKSUM |
+			 DEV_TX_OFFLOAD_TCP_CKSUM));
+
 	ret = tap_setup_queue(dev, internals, tx_queue_id, 0);
 	if (ret == -1)
 		return -1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b673b47..23baa99 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -931,7 +931,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	bool is_single_pool;
 	struct nicvf_txq *txq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +945,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-	conf_offloads = tx_conf->offloads;
-	offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	unsupported_offloads = conf_offloads & ~offload_capa;
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Tx deferred start is not supported */
 	if (tx_conf->tx_deferred_start) {
 		PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +996,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
 	txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-	txq->offloads = conf_offloads;
+	offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->offloads = offloads;
 
-	is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+	is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
 	/* Choose optimum free threshold value for multipool case */
 	if (!is_single_pool) {
@@ -1269,7 +1259,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 	uint16_t rx_free_thresh;
 	struct nicvf_rxq *rxq;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
-	uint64_t conf_offloads, offload_capa, unsupported_offloads;
+	uint64_t offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1283,24 +1273,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 		PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
 		socket_id, nic->node);
 
-
-	conf_offloads = rx_conf->offloads;
-
-	if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	offload_capa = NICVF_RX_OFFLOAD_CAPA;
-	unsupported_offloads = conf_offloads & ~offload_capa;
-
-	if (unsupported_offloads) {
-		PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-		      "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      unsupported_offloads, conf_offloads, offload_capa);
-		return -ENOTSUP;
-	}
-
 	/* Mempool memory must be contiguous, so must be one memory segment*/
 	if (mp->nb_mem_chunks != 1) {
 		PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1381,10 +1353,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
 	nicvf_rx_queue_reset(rxq);
 
+	offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
 	PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
 			" phy=0x%" PRIx64 " offloads=0x%" PRIx64,
 			nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-			rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+			rte_mempool_avail_count(mp), rxq->phys, offloads);
 
 	dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
 	dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1912,8 +1885,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 	struct rte_eth_txmode *txmode = &conf->txmode;
 	struct nicvf *nic = nicvf_pmd_priv(dev);
 	uint8_t cqcount;
-	uint64_t conf_rx_offloads, rx_offload_capa;
-	uint64_t conf_tx_offloads, tx_offload_capa;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1922,32 +1893,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-	tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-	if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_tx_offloads, tx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-		PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-		rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-	}
-
-	conf_rx_offloads = rxmode->offloads;
-	rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-	if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-		PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-		      "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-		      conf_rx_offloads, rx_offload_capa);
-		return -ENOTSUP;
-	}
-
-	if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+	if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
 		PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
 		rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 	}
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a8aa87b..92fab21 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -385,10 +385,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
 			unsigned int socket_id __rte_unused,
-			const struct rte_eth_rxconf *rx_conf,
+			const struct rte_eth_rxconf *rx_conf __rte_unused,
 			struct rte_mempool *mp)
 {
-	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -408,10 +407,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			"Cannot allocate mbufs for rx virtqueue");
 	}
 
-	if ((rx_conf->offloads ^ rxmode->offloads) &
-	    VIRTIO_PMD_PER_DEVICE_RX_OFFLOADS)
-		return -EINVAL;
-
 	dev->data->rx_queues[queue_idx] = rxvq;
 
 	return 0;
@@ -504,7 +499,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	PMD_INIT_FUNC_TRACE();
 
 	/* cannot use simple rxtx funcs with multisegs or offloads */
-	if (tx_conf->offloads)
+	if (dev->data->dev_conf.txmode.offloads)
 		hw->use_simple_tx = 0;
 
 	if (nb_desc == 0 || nb_desc > vq->vq_nentries)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c850241..ba932ff 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -393,25 +393,9 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	const struct rte_memzone *mz;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	size_t size;
-	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
-	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((rx_offloads & VMXNET3_RX_OFFLOAD_CAP) != rx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested RX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			rx_offloads, (uint64_t)VMXNET3_RX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
-	if ((tx_offloads & VMXNET3_TX_OFFLOAD_CAP) != tx_offloads) {
-		RTE_LOG(ERR, PMD, "Requested TX offloads 0x%" PRIx64
-			" do not match supported 0x%" PRIx64,
-			tx_offloads, (uint64_t)VMXNET3_TX_OFFLOAD_CAP);
-		return -ENOTSUP;
-	}
-
 	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
 	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
 		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index f6e2d98..cf85f3d 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1013,7 +1013,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			   uint16_t queue_idx,
 			   uint16_t nb_desc,
 			   unsigned int socket_id,
-			   const struct rte_eth_txconf *tx_conf)
+			   const struct rte_eth_txconf *tx_conf __rte_unused)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	const struct rte_memzone *mz;
@@ -1025,12 +1025,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP) !=
-	    ETH_TXQ_FLAGS_NOXSUMSCTP) {
-		PMD_INIT_LOG(ERR, "SCTP checksum offload not supported");
-		return -EINVAL;
-	}
-
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index e560524..5baa2aa 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1139,6 +1139,28 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offloading must be within its device capabilities */
+	if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
+	     local_conf.rxmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Rx offloads "
+				"0x%" PRIx64 " doesn't match Rx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.rxmode.offloads,
+				dev_info.rx_offload_capa,
+				__func__);
+	}
+	if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
+	     local_conf.txmode.offloads) {
+		ethdev_log(ERR, "ethdev port_id=%d requested Tx offloads "
+				"0x%" PRIx64 " doesn't match Tx offloads "
+				"capabilities 0x%" PRIx64 " in %s( )\n",
+				port_id,
+				local_conf.txmode.offloads,
+				dev_info.tx_offload_capa,
+				__func__);
+	}
+
 	/* Check that device supports requested rss hash functions. */
 	if ((dev_info.flow_type_rss_offloads |
 	     dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
@@ -1504,6 +1526,38 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d rx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				rx_queue_id,
+				local_conf.offloads,
+				dev_info.rx_queue_offload_capa,
+				__func__);
+	}
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1612,6 +1666,38 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * If an offloading has already been enabled in
+	 * rte_eth_dev_configure(), it has been enabled on all queues,
+	 * so there is no need to enable it in this queue again.
+	 * The local_conf.offloads input to underlying PMD only carries
+	 * those offloadings which are only enabled on this queue and
+	 * not enabled on all queues.
+	 * The underlying PMD must be aware of this point.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
+	/*
+	 * New added offloadings for this queue are those not enabled in
+	 * rte_eth_dev_configure( ) and they must be per-queue type.
+	 * A pure per-port offloading can't be enabled on a queue while
+	 * disabled on another queue. A pure per-port offloading can't
+	 * be enabled for any queue as new added one if it hasn't been
+	 * enabled in rte_eth_dev_configure( ).
+	 */
+	if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
+	     local_conf.offloads) {
+		ethdev_log(ERR, "Ethdev port_id=%d tx_queue_id=%d, new "
+				"added offloads 0x%" PRIx64 " must be "
+				"within pre-queue offload capabilities 0x%"
+				PRIx64 " in %s( )\n",
+				port_id,
+				tx_queue_id,
+				local_conf.offloads,
+				dev_info.tx_queue_offload_capa,
+				__func__);
+	}
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 7ccf4ba..e719442 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1067,9 +1067,9 @@ struct rte_eth_dev_info {
 	uint16_t max_vfs; /**< Maximum number of VFs. */
 	uint16_t max_vmdq_pools; /**< Maximum number of VMDq pools. */
 	uint64_t rx_offload_capa;
-	/**< Device per port RX offload capabilities. */
+	/**< All RX offload capabilities including all per queue ones */
 	uint64_t tx_offload_capa;
-	/**< Device per port TX offload capabilities. */
+	/**< All TX offload capabilities.including all per-queue ones */
 	uint64_t rx_queue_offload_capa;
 	/**< Device per queue RX offload capabilities. */
 	uint64_t tx_queue_offload_capa;
@@ -1546,6 +1546,13 @@ const char * __rte_experimental rte_eth_dev_tx_offload_name(uint64_t offload);
  *        The Rx offload bitfield API is obsolete and will be deprecated.
  *        Applications should set the ignore_bitfield_offloads bit on *rxmode*
  *        structure and use offloads field to set per-port offloads instead.
+ *     -  Any offloading set in eth_conf->[rt]xmode.offloads must be within
+ *        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 [RT]x queues and it can't be disabled no matter whether
+ *        it is cleared or set in the input argument [rt]x_conf->offloads
+ *        to rte_eth_[rt]x_queue_setup().
  *     - the Receive Side Scaling (RSS) configuration when using multiple RX
  *         queues per port.
  *
@@ -1602,6 +1609,10 @@ rte_eth_dev_is_removed(uint16_t port_id);
  *   ring.
  *   In addition it contains the hardware offloads features to activate using
  *   the DEV_RX_OFFLOAD_* flags.
+ *   If an offloading set in rx_conf->offloads
+ *   hasn't been set in the input argument eth_conf->rxmode.offloads
+ *   to rte_eth_dev_configure(), it is a new added offloading, it must be
+ *   per-queue type and it is enabled for the queue.
  * @param mb_pool
  *   The pointer to the memory pool from which to allocate *rte_mbuf* network
  *   memory buffers to populate each descriptor of the receive ring.
@@ -1660,7 +1671,10 @@ int rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
  *     should set it to ETH_TXQ_FLAGS_IGNORE and use
  *     the offloads field below.
  *   - The *offloads* member contains Tx offloads to be enabled.
- *     Offloads which are not set cannot be used on the datapath.
+ *     If an offloading set in tx_conf->offloads
+ *     hasn't been set in the input argument eth_conf->txmode.offloads
+ *     to rte_eth_dev_configure(), it is a new added offloading, it must be
+ *     per-queue type and it is enabled for the queue.
  *
  *     Note that setting *tx_free_thresh* or *tx_rs_thresh* value to 0 forces
  *     the transmit function to use default values.
-- 
2.7.5

^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10  4:31  3%   ` Jerin Jacob
@ 2018-05-10 13:48  4%     ` Thomas Monjalon
  2018-05-10 14:30  0%       ` Jerin Jacob
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-10 13:48 UTC (permalink / raw)
  To: Nikhil Rao; +Cc: Jerin Jacob, ferruh.yigit, lei.a.yao, dev

10/05/2018 06:31, Jerin Jacob:
> > Date: Thu, 10 May 2018 02:22:40 +0530
> > From: Nikhil Rao <nikhil.rao@intel.com>
> > 
> > Ethernet port ID data size has been extended to 16 bits size 17.11
> > Update the Rx event adapter interface and implementation accordingly.
> > 
> > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > Cc: stable@dpdk.org
> 
> Since it is an ABI change, please bump the library version.
> eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> required.

The ABI changes must be described in the release notes too.

There is no deprecation notice for this ABI change.
According the the policy, you must send a notice in 18.05,
and do the change in 18.08.

This commit will be dropped when pulling the eventdev tree, sorry.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10 13:48  4%     ` [dpdk-dev] [dpdk-stable] " Thomas Monjalon
@ 2018-05-10 14:30  0%       ` Jerin Jacob
  2018-05-10 14:54  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-05-10 14:30 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Nikhil Rao, ferruh.yigit, lei.a.yao, dev

-----Original Message-----
> Date: Thu, 10 May 2018 15:48:54 +0200
> From: Thomas Monjalon <thomas@monjalon.net>
> To: Nikhil Rao <nikhil.rao@intel.com>
> Cc: Jerin Jacob <jerin.jacob@caviumnetworks.com>, ferruh.yigit@intel.com,
>  lei.a.yao@intel.com, dev@dpdk.org
> Subject: Re: [dpdk-stable] [PATCH v2] eventdev: make ethernet port
>  identifiers 16 bit
> 
> 10/05/2018 06:31, Jerin Jacob:
> > > Date: Thu, 10 May 2018 02:22:40 +0530
> > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > 
> > > Ethernet port ID data size has been extended to 16 bits size 17.11
> > > Update the Rx event adapter interface and implementation accordingly.
> > > 
> > > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > Cc: stable@dpdk.org
> > 
> > Since it is an ABI change, please bump the library version.
> > eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> > required.
> 
> The ABI changes must be described in the release notes too.
> 
> There is no deprecation notice for this ABI change.
> According the the policy, you must send a notice in 18.05,
> and do the change in 18.08.

Even for the APIs with experimental tag? If so, I don't see any
difference between experimental vs non experimental API? 

> 
> This commit will be dropped when pulling the eventdev tree, sorry.
> 
> 
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10 14:30  0%       ` Jerin Jacob
@ 2018-05-10 14:54  0%         ` Thomas Monjalon
  2018-05-10 15:16  0%           ` Jerin Jacob
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-10 14:54 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: Nikhil Rao, ferruh.yigit, lei.a.yao, dev

10/05/2018 16:30, Jerin Jacob:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 10/05/2018 06:31, Jerin Jacob:
> > > > Date: Thu, 10 May 2018 02:22:40 +0530
> > > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > > 
> > > > Ethernet port ID data size has been extended to 16 bits size 17.11
> > > > Update the Rx event adapter interface and implementation accordingly.
> > > > 
> > > > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > > Cc: stable@dpdk.org
> > > 
> > > Since it is an ABI change, please bump the library version.
> > > eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> > > required.
> > 
> > The ABI changes must be described in the release notes too.
> > 
> > There is no deprecation notice for this ABI change.
> > According the the policy, you must send a notice in 18.05,
> > and do the change in 18.08.
> 
> Even for the APIs with experimental tag?

No, experimental can change without prior notice.

> If so, I don't see any
> difference between experimental vs non experimental API? 

Rx adapter is not experimental as far as I know.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10 14:54  0%         ` Thomas Monjalon
@ 2018-05-10 15:16  0%           ` Jerin Jacob
  2018-05-10 15:45  0%             ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-05-10 15:16 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Nikhil Rao, ferruh.yigit, lei.a.yao, dev

-----Original Message-----
> Date: Thu, 10 May 2018 16:54:45 +0200
> From: Thomas Monjalon <thomas@monjalon.net>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> Cc: Nikhil Rao <nikhil.rao@intel.com>, ferruh.yigit@intel.com,
>  lei.a.yao@intel.com, dev@dpdk.org
> Subject: Re: [dpdk-stable] [PATCH v2] eventdev: make ethernet port
>  identifiers 16 bit
> 
> 10/05/2018 16:30, Jerin Jacob:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 10/05/2018 06:31, Jerin Jacob:
> > > > > Date: Thu, 10 May 2018 02:22:40 +0530
> > > > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > > > 
> > > > > Ethernet port ID data size has been extended to 16 bits size 17.11
> > > > > Update the Rx event adapter interface and implementation accordingly.
> > > > > 
> > > > > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > > > Cc: stable@dpdk.org
> > > > 
> > > > Since it is an ABI change, please bump the library version.
> > > > eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> > > > required.
> > > 
> > > The ABI changes must be described in the release notes too.
> > > 
> > > There is no deprecation notice for this ABI change.
> > > According the the policy, you must send a notice in 18.05,
> > > and do the change in 18.08.
> > 
> > Even for the APIs with experimental tag?
> 
> No, experimental can change without prior notice.
> 
> > If so, I don't see any
> > difference between experimental vs non experimental API? 
> 
> Rx adapter is not experimental as far as I know.

It is experimental. Please see the links.

http://dpdk.org/browse/dpdk/tree/MAINTAINERS#n351
http://dpdk.org/browse/dpdk/tree/lib/librte_eventdev/rte_event_eth_rx_adapter.h#n276

If you agree then take dropped patch.

> 
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10 15:16  0%           ` Jerin Jacob
@ 2018-05-10 15:45  0%             ` Thomas Monjalon
  2018-05-10 16:11  3%               ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-10 15:45 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: Nikhil Rao, ferruh.yigit, lei.a.yao, dev

10/05/2018 17:16, Jerin Jacob:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 10/05/2018 16:30, Jerin Jacob:
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > 10/05/2018 06:31, Jerin Jacob:
> > > > > > Date: Thu, 10 May 2018 02:22:40 +0530
> > > > > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > > > > 
> > > > > > Ethernet port ID data size has been extended to 16 bits size 17.11
> > > > > > Update the Rx event adapter interface and implementation accordingly.
> > > > > > 
> > > > > > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > > > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > > > > Cc: stable@dpdk.org
> > > > > 
> > > > > Since it is an ABI change, please bump the library version.
> > > > > eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> > > > > required.
> > > > 
> > > > The ABI changes must be described in the release notes too.
> > > > 
> > > > There is no deprecation notice for this ABI change.
> > > > According the the policy, you must send a notice in 18.05,
> > > > and do the change in 18.08.
> > > 
> > > Even for the APIs with experimental tag?
> > 
> > No, experimental can change without prior notice.
> > 
> > > If so, I don't see any
> > > difference between experimental vs non experimental API? 
> > 
> > Rx adapter is not experimental as far as I know.
> 
> It is experimental. Please see the links.
> 
> http://dpdk.org/browse/dpdk/tree/MAINTAINERS#n351
> http://dpdk.org/browse/dpdk/tree/lib/librte_eventdev/rte_event_eth_rx_adapter.h#n276

Yes, you're right.
I've looked at the map file, where the symbols are not in EXPERIMENTAL block.

> If you agree then take dropped patch.

I'll take it.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH v2] eventdev: make ethernet port identifiers 16 bit
  2018-05-10 15:45  0%             ` Thomas Monjalon
@ 2018-05-10 16:11  3%               ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-05-10 16:11 UTC (permalink / raw)
  To: Jerin Jacob, Nikhil Rao; +Cc: dev, ferruh.yigit, lei.a.yao

10/05/2018 17:45, Thomas Monjalon:
> 10/05/2018 17:16, Jerin Jacob:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 10/05/2018 16:30, Jerin Jacob:
> > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > 10/05/2018 06:31, Jerin Jacob:
> > > > > > > Date: Thu, 10 May 2018 02:22:40 +0530
> > > > > > > From: Nikhil Rao <nikhil.rao@intel.com>
> > > > > > > 
> > > > > > > Ethernet port ID data size has been extended to 16 bits size 17.11
> > > > > > > Update the Rx event adapter interface and implementation accordingly.
> > > > > > > 
> > > > > > > Fixes: 9c38b704d280 ("eventdev: add eth Rx adapter implementation")
> > > > > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > > > > > > Cc: stable@dpdk.org
> > > > > > 
> > > > > > Since it is an ABI change, please bump the library version.
> > > > > > eth_rx_adapter still under experimental tag, IMO, no deprecation notice is
> > > > > > required.
> > > > > 
> > > > > The ABI changes must be described in the release notes too.
> > > > > 
> > > > > There is no deprecation notice for this ABI change.
> > > > > According the the policy, you must send a notice in 18.05,
> > > > > and do the change in 18.08.
> > > > 
> > > > Even for the APIs with experimental tag?
> > > 
> > > No, experimental can change without prior notice.
> > > 
> > > > If so, I don't see any
> > > > difference between experimental vs non experimental API? 
> > > 
> > > Rx adapter is not experimental as far as I know.
> > 
> > It is experimental. Please see the links.
> > 
> > http://dpdk.org/browse/dpdk/tree/MAINTAINERS#n351
> > http://dpdk.org/browse/dpdk/tree/lib/librte_eventdev/rte_event_eth_rx_adapter.h#n276
> 
> Yes, you're right.
> I've looked at the map file, where the symbols are not in EXPERIMENTAL block.
> 
> > If you agree then take dropped patch.
> 
> I'll take it.

Applied with a fix in meson file (ABI version to increase).

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 00/11] ethdev: fix race conditions in iterator and notifications
  @ 2018-05-10 22:27  3% ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-05-10 22:27 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Wed,  9 May 2018 11:43:26 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:

> We have discovered some race conditions when using the port iterator
> and/or the notifications recently added.
> The work was done mostly with failsafe but some bugs could
> be reproduced with other drivers.
> These 11 patches are fixing all these issues.
> The PMDs are modified to call a new function at the end of the probing.
> 
> Matan Azrad (4):
>   ethdev: allow ownership operations on unused port
>   ethdev: add lock to port allocation check
>   net/failsafe: fix sub-device ownership race
>   ethdev: fix port removal notification timing
> 
> Thomas Monjalon (7):
>   ethdev: fix debug log of owner id
>   net/failsafe: fix sub-device visibility
>   ethdev: add doxygen comments for each state
>   drivers/net: use higher level of probing helper for PCI
>   ethdev: add probing finish function
>   ethdev: fix port visibility before initialization
>   ethdev: fix port probing notification
> 
>  drivers/net/af_packet/rte_eth_af_packet.c |  2 +
>  drivers/net/ark/ark_ethdev.c              |  2 +
>  drivers/net/avp/avp_ethdev.c              | 15 +-----
>  drivers/net/bnx2x/bnx2x_ethdev.c          | 20 ++-----
>  drivers/net/bonding/rte_eth_bond_pmd.c    |  2 +
>  drivers/net/cxgbe/cxgbe_ethdev.c          |  1 +
>  drivers/net/cxgbe/cxgbe_main.c            |  5 ++
>  drivers/net/cxgbe/cxgbevf_ethdev.c        |  1 +
>  drivers/net/cxgbe/cxgbevf_main.c          |  5 ++
>  drivers/net/dpaa/dpaa_ethdev.c            |  5 +-
>  drivers/net/dpaa2/dpaa2_ethdev.c          |  4 +-
>  drivers/net/failsafe/failsafe.c           | 24 +++++++--
>  drivers/net/failsafe/failsafe_eal.c       | 59 ++++++++++++--------
>  drivers/net/failsafe/failsafe_ether.c     | 23 ++++++++
>  drivers/net/failsafe/failsafe_private.h   |  4 ++
>  drivers/net/kni/rte_eth_kni.c             |  2 +
>  drivers/net/liquidio/lio_ethdev.c         | 15 +-----
>  drivers/net/mlx4/mlx4.c                   |  1 +
>  drivers/net/mlx5/mlx5.c                   |  2 +
>  drivers/net/mvpp2/mrvl_ethdev.c           |  1 +
>  drivers/net/nfp/nfp_net.c                 |  2 +
>  drivers/net/null/rte_eth_null.c           |  2 +
>  drivers/net/octeontx/octeontx_ethdev.c    |  3 ++
>  drivers/net/pcap/rte_eth_pcap.c           |  2 +
>  drivers/net/ring/rte_eth_ring.c           |  1 +
>  drivers/net/softnic/rte_eth_softnic.c     |  3 ++
>  drivers/net/szedata2/rte_eth_szedata2.c   |  2 +
>  drivers/net/tap/rte_eth_tap.c             |  2 +
>  drivers/net/vhost/rte_eth_vhost.c         |  2 +
>  drivers/net/virtio/virtio_user_ethdev.c   |  3 ++
>  lib/librte_ethdev/rte_ethdev.c            | 89 ++++++++++++++++++++-----------
>  lib/librte_ethdev/rte_ethdev.h            |  6 ++-
>  lib/librte_ethdev/rte_ethdev_driver.h     | 14 +++++
>  lib/librte_ethdev/rte_ethdev_pci.h        |  2 +
>  lib/librte_ethdev/rte_ethdev_version.map  |  1 +
>  test/test/virtual_pmd.c                   |  2 +
>  36 files changed, 230 insertions(+), 99 deletions(-)
> 

This looks like the best way forward for 18.05. Still want to consider generalizing
and enhancing this for 18.11 (and break the ABI of ethdev).

Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] rte_eth_dev_socket_id() vs KVM/AWS/...
  2018-05-09 17:08  3% [dpdk-dev] rte_eth_dev_socket_id() vs KVM/AWS/ Mike Stolarchuk
@ 2018-05-14  8:09  0% ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-05-14  8:09 UTC (permalink / raw)
  To: Mike Stolarchuk, dev

On 09-May-18 6:08 PM, Mike Stolarchuk wrote:
> Hello Dpdk,
> 
> rte_eth_dev_socket_id() describes a -1 return value as:
> 
> *Returns*
> 
> The NUMA socket id to which the Ethernet device is connected or a default
> of zero if the socket could not be determined. -1 is returned is the
> port_id value is out of range.
> 
> But, rte_eth_dev_socket_id() is implemented as:
> 
> int
> rte_eth_dev_socket_id(uint16_t port_id)
> {
>      RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
>      return rte_eth_devices[port_id].data->numa_node;
> }
> 
> And numa_node here is set from /sys/bus/pci/<device>/numa_node.
> And https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
> documents numa_node as:
> 
> What: /sys/bus/pci/devices/.../numa_node
> Date: Oct 2014
> Contact: Prarit Bhargava <prarit@redhat.com>
> Description:
> This file contains the NUMA node to which the PCI device is
> attached, or -1 if the node is unknown.  The initial value
> comes from an ACPI _PXM method or a similar firmware
> source.  If that is missing or incorrect, this file can be
> written to override the node.  In that case, please report
> a firmware bug to the system vendor.  Writing to this file
> taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
> reduces the supportability of your system.
> 
> in other words, a value of -1 for numa_node means the association of the
> pci device WRT socket is unknown.
> And as an example, in a KVM with e1000's.
> /sys/bus/pci/devices/<d>/numa_node can return -1.
> 
> This means that rte_eth_dev_socket_id() returns -1 in situations other than
> 'port_id value is out of range'.
> And its not possible to identify whether the port_id is invalid, or whether
> the base system didn't
> announce the numa_node association.
> 
> Perhaps a -1 return value should be an indication the the numa_node
> association isn't known,
> and a different return value, say -2, should indicate the port_id value is
> out of range.
> 
> 
> mts.
> 

For cases like these, we have rte_errno - we could set it to EINVAL in 
case of invalid value, and e.g. ENODEV (?) on invalid NUMA node.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
  2018-05-09 19:03  0%       ` Thomas Monjalon
@ 2018-05-14  8:26  0%         ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-05-14  8:26 UTC (permalink / raw)
  To: Thomas Monjalon, Bruce Richardson, Van Haaren, Harry; +Cc: dev

On 09-May-18 8:03 PM, Thomas Monjalon wrote:
> 09/05/2018 18:11, Bruce Richardson:
>> On Wed, May 09, 2018 at 04:59:39PM +0100, Van Haaren, Harry wrote:
>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Anatoly Burakov
>>>> Sent: Monday, April 30, 2018 1:09 PM
>>>> To: dev@dpdk.org
>>>> Cc: Richardson, Bruce <bruce.richardson@intel.com>; thomas@monjalon.net
>>>> Subject: [dpdk-dev] [PATCH v2 0/4] Clean up EAL runtime data paths
>>>>
>>>> As has been suggested [1], all DPDK runtime paths should be put
>>>> into a single place. This patchset accomplishes exactly that.
>>>>
>>>> If running as root, all files will be put under /var/run/dpdk/<prefix>,
>>>> otherwise they will be put under $XDG_RUNTIME_PATH/dpdk/<prefix>, or, if
>>>> that environment variable is not defined, all files will go under
>>>> /tmp/dpdk/<prefix>.
>>>>
>>>> [1] http://dpdk.org/dev/patchwork/patch/38688/
>>>>
>>>> v2:
>>>> - Rebase on rc1
>>>>
>>>> Anatoly Burakov (4):
>>>>    eal: remove unused define
>>>>    eal: rename function returning hugepage data path
>>>>    eal: add directory for DPDK runtime data
>>>>    eal: move all runtime data into DPDK runtime dir
>>>
>>> <snip>
>>>
>>>
>>> No full code review, high level comments:
>>>
>>> We have to be careful in changing /var/run/.rte_config, which has always been
>>> the default DPDK primary application lockfile. This has been used to identify
>>> if a primary DPDK application is alive (see rte_eal_primary_proc_alive()) and
>>> possibly the write-lock on this file is checked by other tools/utilities directly
>>> without any DPDK function call.
>>>
>>> Changing the filepath just before a release isn't a good idea - we should treat
>>> this as an ABI/API break, as the change will break functionality in other projects
>>> such as CollectD[1], which (by default ;) rely on the defaults. There is a config
>>> file for CollectD to manually override the location, but this will cause headaches
>>> from a usability POV.
>>>
>>> I'm not opposed to the change - particularly as I gather the new memory subsystem
>>> causes a number of lockfiles to be created - but we must do our due diligence and
>>> give other projects fair-warning that this change is coming.
>>>
>>> As such, I recommend this patchset in its current form (particularly patches 2,3,4)
>>> to be deferred past 18.05.
>>>
>>>
>> What about if we keep the .rte_config file in the same place but move the
>> rest? The number of new files causes quite a bit of clutter. We can then
>> have a deprecation notice for the move in 18.05 and finish the cleanup in
>> 18.08.
> 
> I agree
> 

Thanks for catching this, Harry. I'll resubmit the patches then, along 
with a deprecation notice about /var/run/.<prefix>_config.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] librte_hash: new hash del abi to returns stored value
@ 2018-05-14 21:09  4% Vijaya Mohan Guvva
  0 siblings, 0 replies; 200+ results
From: Vijaya Mohan Guvva @ 2018-05-14 21:09 UTC (permalink / raw)
  To: Bruce Richardson, Pablo de Lara; +Cc: dev, Vijaya Mohan Guvva

Add a new key delete interface rte_hash_del_key_with_hash_data to
delete the key from hash and return the value stored. This is useful
for hash users to free the data stored in the table after key delete
and to avoid maintaining a user data array in the dpdk application.

Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
---
 lib/librte_hash/rte_cuckoo_hash.c | 20 +++++++++++++++++---
 lib/librte_hash/rte_hash.h        | 24 ++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c
index a07543a..693b543 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -808,7 +808,7 @@ struct rte_hash *
 
 static inline int32_t
 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
-						hash_sig_t sig)
+						hash_sig_t sig, void **data)
 {
 	uint32_t bucket_idx;
 	hash_sig_t alt_hash;
@@ -827,6 +827,8 @@ struct rte_hash *
 			k = (struct rte_hash_key *) ((char *)keys +
 					bkt->key_idx[i] * h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
+				if (data != NULL)
+					*data = k->pdata;
 				remove_entry(h, bkt, i);
 
 				/*
@@ -852,6 +854,8 @@ struct rte_hash *
 			k = (struct rte_hash_key *) ((char *)keys +
 					bkt->key_idx[i] * h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
+				if (data != NULL)
+					*data = k->pdata;
 				remove_entry(h, bkt, i);
 
 				/*
@@ -869,18 +873,28 @@ struct rte_hash *
 }
 
 int32_t
+rte_hash_del_key_with_hash_data(const struct rte_hash *h,
+			const void *key, hash_sig_t sig, void **data)
+{
+	RETURN_IF_TRUE(((h == NULL) || (key == NULL) ||
+			(data == NULL)), -EINVAL);
+	return __rte_hash_del_key_with_hash(h, key, sig, data);
+}
+
+int32_t
 rte_hash_del_key_with_hash(const struct rte_hash *h,
 			const void *key, hash_sig_t sig)
 {
 	RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
-	return __rte_hash_del_key_with_hash(h, key, sig);
+	return __rte_hash_del_key_with_hash(h, key, sig, NULL);
 }
 
 int32_t
 rte_hash_del_key(const struct rte_hash *h, const void *key)
 {
 	RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
-	return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
+	return __rte_hash_del_key_with_hash(h, key,
+					    rte_hash_hash(h, key), NULL);
 }
 
 int
diff --git a/lib/librte_hash/rte_hash.h b/lib/librte_hash/rte_hash.h
index f71ca9f..73e1efb 100644
--- a/lib/librte_hash/rte_hash.h
+++ b/lib/librte_hash/rte_hash.h
@@ -222,6 +222,30 @@ struct rte_hash *
 rte_hash_del_key(const struct rte_hash *h, const void *key);
 
 /**
+ * Remove a key from an existing hash table and return the data stored.
+ * This operation is not multi-thread safe
+ * and should only be called from one thread.
+ *
+ * @param h
+ *   Hash table to remove the key from.
+ * @param key
+ *   Key to remove from the hash table.
+ * @param sig
+ *   Precomputed hash value for 'key'.
+ * @param data
+ *   Output with pointer to data returned from the hash table.
+ * @return
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if the key is not found.
+ *   - A positive value that can be used by the caller as an offset into an
+ *     array of user data. This value is unique for this key, and is the same
+ *     value that was returned when the key was added.
+ */
+int32_t
+rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
+				hash_sig_t sig, void **data);
+
+/**
  * Remove a key from an existing hash table.
  * This operation is not multi-thread safe
  * and should only be called from one thread.
-- 
1.8.3.1

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
@ 2018-05-17  1:26  3% Vijaya Mohan Guvva
  2018-05-17  8:06  7% ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 200+ results
From: Vijaya Mohan Guvva @ 2018-05-17  1:26 UTC (permalink / raw)
  To: Bruce Richardson, Pablo de Lara; +Cc: dev, Vijaya Mohan Guvva

V2:
Adding another new interface rte_hash_del_key_data to delete key
from hash table and return stored data.

V1:
Add a new key delete interface rte_hash_del_key_with_hash_data to
delete the key from hash and return the value stored. This is useful
for hash users to free the data stored in the table after key delete
and to avoid maintaining a user data array in the dpdk application.

Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
---
 lib/librte_hash/rte_cuckoo_hash.c | 30 +++++++++++++++++++++++---
 lib/librte_hash/rte_hash.h        | 45 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c
index a07543a..6ea0ef0 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -808,7 +808,7 @@ struct rte_hash *
 
 static inline int32_t
 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
-						hash_sig_t sig)
+						hash_sig_t sig, void **data)
 {
 	uint32_t bucket_idx;
 	hash_sig_t alt_hash;
@@ -827,6 +827,8 @@ struct rte_hash *
 			k = (struct rte_hash_key *) ((char *)keys +
 					bkt->key_idx[i] * h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
+				if (data != NULL)
+					*data = k->pdata;
 				remove_entry(h, bkt, i);
 
 				/*
@@ -852,6 +854,8 @@ struct rte_hash *
 			k = (struct rte_hash_key *) ((char *)keys +
 					bkt->key_idx[i] * h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
+				if (data != NULL)
+					*data = k->pdata;
 				remove_entry(h, bkt, i);
 
 				/*
@@ -869,18 +873,38 @@ struct rte_hash *
 }
 
 int32_t
+rte_hash_del_key_with_hash_data(const struct rte_hash *h,
+			const void *key, hash_sig_t sig, void **data)
+{
+	RETURN_IF_TRUE(((h == NULL) || (key == NULL) ||
+			(data == NULL)), -EINVAL);
+	return __rte_hash_del_key_with_hash(h, key, sig, data);
+}
+
+int32_t
 rte_hash_del_key_with_hash(const struct rte_hash *h,
 			const void *key, hash_sig_t sig)
 {
 	RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
-	return __rte_hash_del_key_with_hash(h, key, sig);
+	return __rte_hash_del_key_with_hash(h, key, sig, NULL);
+}
+
+int32_t
+rte_hash_del_key_data(const struct rte_hash *h, const void *key,
+		      void **data)
+{
+	RETURN_IF_TRUE(((h == NULL) || (key == NULL) ||
+			(data == NULL)), -EINVAL);
+	return __rte_hash_del_key_with_hash(h, key,
+					    rte_hash_hash(h, key), data);
 }
 
 int32_t
 rte_hash_del_key(const struct rte_hash *h, const void *key)
 {
 	RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
-	return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
+	return __rte_hash_del_key_with_hash(h, key,
+					    rte_hash_hash(h, key), NULL);
 }
 
 int
diff --git a/lib/librte_hash/rte_hash.h b/lib/librte_hash/rte_hash.h
index f71ca9f..e0c08e3 100644
--- a/lib/librte_hash/rte_hash.h
+++ b/lib/librte_hash/rte_hash.h
@@ -222,6 +222,51 @@ struct rte_hash *
 rte_hash_del_key(const struct rte_hash *h, const void *key);
 
 /**
+ * Remove a key from an existing hash table and return data stored.
+ * This operation is not multi-thread safe
+ * and should only be called from one thread.
+ *
+ * @param h
+ *   Hash table to remove the key from.
+ * @param key
+ *   Key to remove from the hash table.
+ * @param data
+ *   Output with pointer to data returned from the hash table.
+ * @return
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if the key is not found.
+ *   - A positive value that can be used by the caller as an offset into an
+ *     array of user data. This value is unique for this key, and is the same
+ *     value that was returned when the key was added.
+ */
+int32_t
+rte_hash_del_key_data(const struct rte_hash *h, const void *key, void **data);
+
+/**
+ * Remove a key from an existing hash table and return data stored.
+ * This operation is not multi-thread safe
+ * and should only be called from one thread.
+ *
+ * @param h
+ *   Hash table to remove the key from.
+ * @param key
+ *   Key to remove from the hash table.
+ * @param sig
+ *   Precomputed hash value for 'key'.
+ * @param data
+ *   Output with pointer to data returned from the hash table.
+ * @return
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if the key is not found.
+ *   - A positive value that can be used by the caller as an offset into an
+ *     array of user data. This value is unique for this key, and is the same
+ *     value that was returned when the key was added.
+ */
+int32_t
+rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
+				hash_sig_t sig, void **data);
+
+/**
  * Remove a key from an existing hash table.
  * This operation is not multi-thread safe
  * and should only be called from one thread.
-- 
1.8.3.1

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
  2018-05-17  1:26  3% [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return " Vijaya Mohan Guvva
@ 2018-05-17  8:06  7% ` De Lara Guarch, Pablo
  2018-05-24 17:47  4%   ` Wang, Yipeng1
  0 siblings, 1 reply; 200+ results
From: De Lara Guarch, Pablo @ 2018-05-17  8:06 UTC (permalink / raw)
  To: Vijaya Mohan Guvva, Richardson, Bruce; +Cc: dev

Hi Vijaya,

> -----Original Message-----
> From: Vijaya Mohan Guvva [mailto:vguvva@caviumnetworks.com]
> Sent: Thursday, May 17, 2018 2:27 AM
> To: Richardson, Bruce <bruce.richardson@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Cc: dev@dpdk.org; Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
> Subject: [PATCH V2] librte_hash: new hash del abi to return stored value
> 

You are actually adding new API, not ABI, so I would reword the commit message.

"hash: add API to return stored value at deletion" maybe?

I would add some information in the commit message and move the changelog (V1, V2 notes)
after the three dashes.
 
> V2:
> Adding another new interface rte_hash_del_key_data to delete key from hash
> table and return stored data.
> 
> V1:
> Add a new key delete interface rte_hash_del_key_with_hash_data to delete the
> key from hash and return the value stored. This is useful for hash users to free
> the data stored in the table after key delete and to avoid maintaining a user data
> array in the dpdk application.
> 
> Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
> ---
>  lib/librte_hash/rte_cuckoo_hash.c | 30 +++++++++++++++++++++++---
>  lib/librte_hash/rte_hash.h        | 45
> +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 72 insertions(+), 3 deletions(-)

...

> +int32_t
> +rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
> +				hash_sig_t sig, void **data);
> +
> +/**
>   * Remove a key from an existing hash table.
>   * This operation is not multi-thread safe
>   * and should only be called from one thread.
> --
> 1.8.3.1

You need to update the version.map file to add the two new functions
(you might need to wait until 18.05 is released, so you can use the 18.08 tag).

^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices
  @ 2018-05-17  9:00  8% ` Pablo de Lara
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct Pablo de Lara
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto " Pablo de Lara
  2018-05-21 11:06  8% ` [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2 siblings, 2 replies; 200+ results
From: Pablo de Lara @ 2018-05-17  9:00 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal; +Cc: dev, Pablo de Lara

v3:
- Added an extra deprecation announcement (replacing rte_pci_device
  with rte_device)
- Rebased against latest DPDK code

v2:
- Added an extra deprecation announcement
- Bonded the other two deprecation notices with the new one in a
  patchset

Pablo de Lara (4):
  doc: announce ABI change for crypto sym info struct
  doc: announce ABI change for crypto info struct
  doc: announce deprecation for attach/detach crypto session
  doc: announce deprecation in crypto queue pair start/stop

 doc/guides/rel_notes/deprecation.rst | 17 +++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.h |  4 ++++
 2 files changed, 21 insertions(+)

-- 
2.17.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct
  2018-05-17  9:00  8% ` [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices Pablo de Lara
@ 2018-05-17  9:00  4%   ` Pablo de Lara
  2018-05-18 11:42  4%     ` Akhil Goyal
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto " Pablo de Lara
  1 sibling, 1 reply; 200+ results
From: Pablo de Lara @ 2018-05-17  9:00 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal; +Cc: dev, Pablo de Lara

Since the API changes made in 17.08, the session mempool
is not created anymore in each crypto device.
Therefore, there is no need to have, in the cryptodev info
structure, the maximum number of sessions supported per device
and per queue pair.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index c3b79a22f..d6cccbfde 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,3 +71,10 @@ Deprecation Notices
   - ``rte_pdump_set_socket_dir`` will be removed;
   - The parameter, ``path``, of ``rte_pdump_init`` will be removed;
   - The enum ``rte_pdump_socktype`` will be removed.
+
+* cryptodev: The following changes will be made in the library
+  for 18.08:
+
+  - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
+    containing fields not relevant anymore since the session mempool
+    is not internal in the crypto device anymore.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto info struct
  2018-05-17  9:00  8% ` [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct Pablo de Lara
@ 2018-05-17  9:00  4%   ` Pablo de Lara
  2018-05-17 11:18  4%     ` Trahe, Fiona
  2018-05-18 11:41  4%     ` Akhil Goyal
  1 sibling, 2 replies; 200+ results
From: Pablo de Lara @ 2018-05-17  9:00 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal; +Cc: dev, Pablo de Lara

Cryptodev info structure currently contains
a pointer to an rte_pci_device structure.
This field depends on a specific bus type (PCI),
which is not following a bus independent design.
Following the same approach taken in ethdev, the field
will be replaced with a pointer to an rte_device structure.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d6cccbfde..85945ee72 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,3 +78,5 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
+  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
+    structure.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto info struct
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto " Pablo de Lara
@ 2018-05-17 11:18  4%     ` Trahe, Fiona
  2018-05-18 11:41  4%     ` Akhil Goyal
  1 sibling, 0 replies; 200+ results
From: Trahe, Fiona @ 2018-05-17 11:18 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Doherty, Declan, akhil.goyal; +Cc: dev, Trahe, Fiona



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> Sent: Thursday, May 17, 2018 10:01 AM
> To: Doherty, Declan <declan.doherty@intel.com>; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto info struct
> 
> Cryptodev info structure currently contains
> a pointer to an rte_pci_device structure.
> This field depends on a specific bus type (PCI),
> which is not following a bus independent design.
> Following the same approach taken in ethdev, the field
> will be replaced with a pointer to an rte_device structure.
> 
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

Acked-by: Fiona Trahe <fiona.trahe@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto info struct
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto " Pablo de Lara
  2018-05-17 11:18  4%     ` Trahe, Fiona
@ 2018-05-18 11:41  4%     ` Akhil Goyal
  1 sibling, 0 replies; 200+ results
From: Akhil Goyal @ 2018-05-18 11:41 UTC (permalink / raw)
  To: Pablo de Lara, declan.doherty, akhil.goyal; +Cc: dev

On 5/17/2018 2:30 PM, Pablo de Lara wrote:
> Cryptodev info structure currently contains
> a pointer to an rte_pci_device structure.
> This field depends on a specific bus type (PCI),
> which is not following a bus independent design.
> Following the same approach taken in ethdev, the field
> will be replaced with a pointer to an rte_device structure.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct
  2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct Pablo de Lara
@ 2018-05-18 11:42  4%     ` Akhil Goyal
  0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2018-05-18 11:42 UTC (permalink / raw)
  To: Pablo de Lara, declan.doherty, akhil.goyal; +Cc: dev

On 5/17/2018 2:30 PM, Pablo de Lara wrote:
> Since the API changes made in 17.08, the session mempool
> is not created anymore in each crypto device.
> Therefore, there is no need to have, in the cryptodev info
> structure, the maximum number of sessions supported per device
> and per queue pair.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
> ---
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices
    2018-05-17  9:00  8% ` [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices Pablo de Lara
@ 2018-05-21 11:06  8% ` Pablo de Lara
  2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
  2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 2/6] doc: announce ABI change for crypto " Pablo de Lara
  2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2 siblings, 2 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 11:06 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

v4:
- Fixed DPDK versions called out to deprecate/remove API.
- Removed rte_cryptodev_queue_pair_attach_sym_session call
  from the IPSec gw app, since the function is deprecated now.
- Added patch announcing a replacement of some of the crypto
  feature flags
- Added patch renaming two symmetric specific functions
  from *_session_* to *_sym_session_*.

v3:
- Added an extra deprecation announcement (replacing rte_pci_device
  with rte_device)
- Rebased against latest DPDK code

v2:
- Added an extra deprecation announcement
- Bonded the other two deprecation notices with the new one in a
  patchset


Pablo de Lara (6):
  doc: announce ABI change for crypto sym info struct
  doc: announce ABI change for crypto info struct
  doc: announce deprecation for attach/detach crypto session
  doc: announce deprecation in crypto queue pair start/stop
  doc: announce deprecation in crypto feature flags
  cryptodev: rename get session size API

 app/test-crypto-perf/main.c                   |  2 +-
 doc/guides/prog_guide/cryptodev_lib.rst       |  6 ++--
 doc/guides/rel_notes/deprecation.rst          | 25 +++++++++++++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c      |  2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c    |  2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c          |  2 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c        |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c      |  2 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c        |  2 +-
 drivers/crypto/zuc/rte_zuc_pmd.c              |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c            |  2 +-
 examples/ipsec-secgw/ipsec.c                  | 12 -------
 examples/l2fwd-crypto/main.c                  |  2 +-
 examples/vhost_crypto/main.c                  |  2 +-
 lib/librte_cryptodev/rte_cryptodev.c          | 12 +++++++
 lib/librte_cryptodev/rte_cryptodev.h          | 35 +++++++++++++++++++
 .../rte_cryptodev_version.map                 |  8 +++++
 test/test/test_cryptodev.c                    |  6 ++--
 test/test/test_event_crypto_adapter.c         |  2 +-
 19 files changed, 99 insertions(+), 29 deletions(-)

-- 
2.17.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v4 1/6] doc: announce ABI change for crypto sym info struct
  2018-05-21 11:06  8% ` [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
@ 2018-05-21 11:06  4%   ` Pablo de Lara
  2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 2/6] doc: announce ABI change for crypto " Pablo de Lara
  1 sibling, 0 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 11:06 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

Since the API changes made in 17.08, the session mempool
is not created anymore in each crypto device.
Therefore, there is no need to have, in the cryptodev info
structure, the maximum number of sessions supported per device
and per queue pair.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index c3b79a22f..d6cccbfde 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,3 +71,10 @@ Deprecation Notices
   - ``rte_pdump_set_socket_dir`` will be removed;
   - The parameter, ``path``, of ``rte_pdump_init`` will be removed;
   - The enum ``rte_pdump_socktype`` will be removed.
+
+* cryptodev: The following changes will be made in the library
+  for 18.08:
+
+  - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
+    containing fields not relevant anymore since the session mempool
+    is not internal in the crypto device anymore.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v4 2/6] doc: announce ABI change for crypto info struct
  2018-05-21 11:06  8% ` [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
@ 2018-05-21 11:06  4%   ` Pablo de Lara
  1 sibling, 0 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 11:06 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

Cryptodev info structure currently contains
a pointer to an rte_pci_device structure.
This field depends on a specific bus type (PCI),
which is not following a bus independent design.
Following the same approach taken in ethdev, the field
will be replaced with a pointer to an rte_device structure.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d6cccbfde..85945ee72 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,3 +78,5 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
+  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
+    structure.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices
    2018-05-17  9:00  8% ` [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-21 11:06  8% ` [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
@ 2018-05-21 13:08  8% ` Pablo de Lara
  2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
                     ` (2 more replies)
  2 siblings, 3 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 13:08 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

v5:
- Renamed rte_cryptodev_get_header_session_size with
  rte_cryptodev_sym_get_header_session_size, and
  rte_cryptodev_get_private_session_size with
  rte_cryptodev_sym_get_private_session_size.

v4:
- Fixed DPDK versions called out to deprecate/remove API.
- Removed rte_cryptodev_queue_pair_attach_sym_session call
  from the IPSec gw app, since the function is deprecated now.
- Added patch announcing a replacement of some of the crypto
  feature flags
- Added patch renaming two symmetric specific functions
  from *_session_* to *_sym_session_*.

v3:
- Added an extra deprecation announcement (replacing rte_pci_device
  with rte_device)
- Rebased against latest DPDK code

v2:
- Added an extra deprecation announcement
- Bonded the other two deprecation notices with the new one in a
  patchset

Pablo de Lara (6):
  doc: announce ABI change for crypto sym info struct
  doc: announce ABI change for crypto info struct
  doc: announce deprecation for attach/detach crypto session
  doc: announce deprecation in crypto queue pair start/stop
  doc: announce deprecation in crypto feature flags
  cryptodev: rename get session size API

 app/test-crypto-perf/main.c                   |  2 +-
 doc/guides/prog_guide/cryptodev_lib.rst       |  6 ++--
 doc/guides/rel_notes/deprecation.rst          | 25 +++++++++++++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c      |  2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c    |  2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c          |  2 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c        |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c      |  2 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c        |  2 +-
 drivers/crypto/zuc/rte_zuc_pmd.c              |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c            |  2 +-
 examples/ipsec-secgw/ipsec.c                  | 12 -------
 examples/l2fwd-crypto/main.c                  |  2 +-
 examples/vhost_crypto/main.c                  |  2 +-
 lib/librte_cryptodev/rte_cryptodev.c          | 12 +++++++
 lib/librte_cryptodev/rte_cryptodev.h          | 35 +++++++++++++++++++
 .../rte_cryptodev_version.map                 |  8 +++++
 test/test/test_cryptodev.c                    |  6 ++--
 test/test/test_event_crypto_adapter.c         |  2 +-
 19 files changed, 99 insertions(+), 29 deletions(-)

-- 
2.17.0

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH v5 1/6] doc: announce ABI change for crypto sym info struct
  2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
@ 2018-05-21 13:08  4%   ` Pablo de Lara
  2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 2/6] doc: announce ABI change for crypto " Pablo de Lara
  2018-05-22 14:30  4%   ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Jain, Deepak K
  2 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 13:08 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

Since the API changes made in 17.08, the session mempool
is not created anymore in each crypto device.
Therefore, there is no need to have, in the cryptodev info
structure, the maximum number of sessions supported per device
and per queue pair.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index c3b79a22f..d6cccbfde 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,3 +71,10 @@ Deprecation Notices
   - ``rte_pdump_set_socket_dir`` will be removed;
   - The parameter, ``path``, of ``rte_pdump_init`` will be removed;
   - The enum ``rte_pdump_socktype`` will be removed.
+
+* cryptodev: The following changes will be made in the library
+  for 18.08:
+
+  - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
+    containing fields not relevant anymore since the session mempool
+    is not internal in the crypto device anymore.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v5 2/6] doc: announce ABI change for crypto info struct
  2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
@ 2018-05-21 13:08  4%   ` Pablo de Lara
  2018-05-22 14:30  4%   ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Jain, Deepak K
  2 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-05-21 13:08 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma; +Cc: dev, Pablo de Lara

Cryptodev info structure currently contains
a pointer to an rte_pci_device structure.
This field depends on a specific bus type (PCI),
which is not following a bus independent design.
Following the same approach taken in ethdev, the field
will be replaced with a pointer to an rte_device structure.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d6cccbfde..85945ee72 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,3 +78,5 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
+  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
+    structure.
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices
  2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
  2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
  2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 2/6] doc: announce ABI change for crypto " Pablo de Lara
@ 2018-05-22 14:30  4%   ` Jain, Deepak K
  2018-05-22 14:35  4%     ` De Lara Guarch, Pablo
  2 siblings, 1 reply; 200+ results
From: Jain, Deepak K @ 2018-05-22 14:30 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Doherty, Declan, akhil.goyal, shally.verma
  Cc: dev, De Lara Guarch, Pablo


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> Sent: Monday, May 21, 2018 2:09 PM
> To: Doherty, Declan <declan.doherty@intel.com>; akhil.goyal@nxp.com;
> shally.verma@cavium.com
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices
> 
> v5:
> - Renamed rte_cryptodev_get_header_session_size with
>   rte_cryptodev_sym_get_header_session_size, and
>   rte_cryptodev_get_private_session_size with
>   rte_cryptodev_sym_get_private_session_size.
> 
> v4:
> - Fixed DPDK versions called out to deprecate/remove API.
> - Removed rte_cryptodev_queue_pair_attach_sym_session call
>   from the IPSec gw app, since the function is deprecated now.
> - Added patch announcing a replacement of some of the crypto
>   feature flags
> - Added patch renaming two symmetric specific functions
>   from *_session_* to *_sym_session_*.
> 
> v3:
> - Added an extra deprecation announcement (replacing rte_pci_device
>   with rte_device)
> - Rebased against latest DPDK code
> 
> v2:
> - Added an extra deprecation announcement
> - Bonded the other two deprecation notices with the new one in a
>   patchset
> 
> Pablo de Lara (6):
>   doc: announce ABI change for crypto sym info struct
>   doc: announce ABI change for crypto info struct
>   doc: announce deprecation for attach/detach crypto session
>   doc: announce deprecation in crypto queue pair start/stop
>   doc: announce deprecation in crypto feature flags
>   cryptodev: rename get session size API
> 
>  app/test-crypto-perf/main.c                   |  2 +-
>  doc/guides/prog_guide/cryptodev_lib.rst       |  6 ++--
>  doc/guides/rel_notes/deprecation.rst          | 25 +++++++++++++
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd.c      |  2 +-
>  drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c    |  2 +-
>  drivers/crypto/armv8/rte_armv8_pmd.c          |  2 +-
>  drivers/crypto/kasumi/rte_kasumi_pmd.c        |  2 +-
>  drivers/crypto/openssl/rte_openssl_pmd.c      |  2 +-
>  drivers/crypto/snow3g/rte_snow3g_pmd.c        |  2 +-
>  drivers/crypto/zuc/rte_zuc_pmd.c              |  2 +-
>  examples/ipsec-secgw/ipsec-secgw.c            |  2 +-
>  examples/ipsec-secgw/ipsec.c                  | 12 -------
>  examples/l2fwd-crypto/main.c                  |  2 +-
>  examples/vhost_crypto/main.c                  |  2 +-
>  lib/librte_cryptodev/rte_cryptodev.c          | 12 +++++++
>  lib/librte_cryptodev/rte_cryptodev.h          | 35 +++++++++++++++++++
>  .../rte_cryptodev_version.map                 |  8 +++++
>  test/test/test_cryptodev.c                    |  6 ++--
>  test/test/test_event_crypto_adapter.c         |  2 +-
>  19 files changed, 99 insertions(+), 29 deletions(-)
> 
> --
> 2.17.0

Series Acked-by: Deepak Kumar Jain <deepak.k.jain@intel.com>

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices
  2018-05-22 14:30  4%   ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Jain, Deepak K
@ 2018-05-22 14:35  4%     ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2018-05-22 14:35 UTC (permalink / raw)
  To: Jain, Deepak K, Doherty, Declan, akhil.goyal, shally.verma; +Cc: dev



> -----Original Message-----
> From: Jain, Deepak K
> Sent: Tuesday, May 22, 2018 3:30 PM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Doherty, Declan
> <declan.doherty@intel.com>; akhil.goyal@nxp.com; shally.verma@cavium.com
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> > Sent: Monday, May 21, 2018 2:09 PM
> > To: Doherty, Declan <declan.doherty@intel.com>; akhil.goyal@nxp.com;
> > shally.verma@cavium.com
> > Cc: dev@dpdk.org; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>
> > Subject: [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation
> > notices
> >
> > v5:
> > - Renamed rte_cryptodev_get_header_session_size with
> >   rte_cryptodev_sym_get_header_session_size, and
> >   rte_cryptodev_get_private_session_size with
> >   rte_cryptodev_sym_get_private_session_size.
> >
> > v4:
> > - Fixed DPDK versions called out to deprecate/remove API.
> > - Removed rte_cryptodev_queue_pair_attach_sym_session call
> >   from the IPSec gw app, since the function is deprecated now.
> > - Added patch announcing a replacement of some of the crypto
> >   feature flags
> > - Added patch renaming two symmetric specific functions
> >   from *_session_* to *_sym_session_*.
> >
> > v3:
> > - Added an extra deprecation announcement (replacing rte_pci_device
> >   with rte_device)
> > - Rebased against latest DPDK code
> >
> > v2:
> > - Added an extra deprecation announcement
> > - Bonded the other two deprecation notices with the new one in a
> >   patchset
> >
> > Pablo de Lara (6):
> >   doc: announce ABI change for crypto sym info struct
> >   doc: announce ABI change for crypto info struct
> >   doc: announce deprecation for attach/detach crypto session
> >   doc: announce deprecation in crypto queue pair start/stop
> >   doc: announce deprecation in crypto feature flags
> >   cryptodev: rename get session size API
> >
> >  app/test-crypto-perf/main.c                   |  2 +-
> >  doc/guides/prog_guide/cryptodev_lib.rst       |  6 ++--
> >  doc/guides/rel_notes/deprecation.rst          | 25 +++++++++++++
> >  drivers/crypto/aesni_gcm/aesni_gcm_pmd.c      |  2 +-
> >  drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c    |  2 +-
> >  drivers/crypto/armv8/rte_armv8_pmd.c          |  2 +-
> >  drivers/crypto/kasumi/rte_kasumi_pmd.c        |  2 +-
> >  drivers/crypto/openssl/rte_openssl_pmd.c      |  2 +-
> >  drivers/crypto/snow3g/rte_snow3g_pmd.c        |  2 +-
> >  drivers/crypto/zuc/rte_zuc_pmd.c              |  2 +-
> >  examples/ipsec-secgw/ipsec-secgw.c            |  2 +-
> >  examples/ipsec-secgw/ipsec.c                  | 12 -------
> >  examples/l2fwd-crypto/main.c                  |  2 +-
> >  examples/vhost_crypto/main.c                  |  2 +-
> >  lib/librte_cryptodev/rte_cryptodev.c          | 12 +++++++
> >  lib/librte_cryptodev/rte_cryptodev.h          | 35 +++++++++++++++++++
> >  .../rte_cryptodev_version.map                 |  8 +++++
> >  test/test/test_cryptodev.c                    |  6 ++--
> >  test/test/test_event_crypto_adapter.c         |  2 +-
> >  19 files changed, 99 insertions(+), 29 deletions(-)
> >
> > --
> > 2.17.0
> 
> Series Acked-by: Deepak Kumar Jain <deepak.k.jain@intel.com>

Applied to dpdk-next-crypto.
Thanks,

Pablo

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [pull-request] next-crypto 18.05-rc5
@ 2018-05-22 14:38  4% Pablo de Lara
  0 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-05-22 14:38 UTC (permalink / raw)
  To: thomas; +Cc: dev

The following changes since commit 3291abb5a2a5f24c109ab74e6aad0545927333a7:

  ethdev: fix type and scope of variables in Rx burst (2018-05-22 16:32:36 +0200)

are available in the Git repository at:

  http://dpdk.org/git/next/dpdk-next-crypto 

for you to fetch changes up to bbabaddd854f858477df32e7882ba848bd33317d:

  doc/crypto: update ZUC installation section (2018-05-22 15:36:12 +0100)

----------------------------------------------------------------
Fan Zhang (1):
      crypto/scheduler: fix possible duplicated ring names

Fiona Trahe (4):
      doc/crypto: add clarification about chained mbuf feature
      compressdev: clarify buffer size limitation
      compressdev: clarify when private xform can be cleared
      cryptodev: clarify when session can be cleared

Jerin Jacob (2):
      app/crypto-perf: use strcpy for allocated string
      app/crypto-perf: fix memcpy source

Kamil Chalupnik (1):
      app/bbdev: fix unchecked return value

Kirill Rybalchenko (2):
      crypto/scheduler: fix multicore rings re-use
      crypto/scheduler: fix 64-bit mask of workers cores

Pablo de Lara (16):
      crypto/aesni_mb: fix capabilities
      crypto/aesni_gcm: remove unneeded cast
      cryptodev: fix supported size check
      cryptodev: extend feature flags description
      cryptodev: add missing feature string
      compressdev: remove unused driver id
      compressdev: clarify mbuf offsets
      doc: announce ABI change for crypto sym info struct
      doc: announce ABI change for crypto info struct
      doc: announce deprecation for attach/detach crypto session
      doc: announce deprecation in crypto queue pair start/stop
      doc: announce deprecation in crypto feature flags
      cryptodev: rename get session size API
      doc/crypto: update KASUMI installation section
      doc/crypto: update SNOW3G installation section
      doc/crypto: update ZUC installation section

 app/test-bbdev/test_bbdev_perf.c                   |  8 ++-
 app/test-crypto-perf/cperf_test_vector_parsing.c   |  7 +--
 app/test-crypto-perf/main.c                        |  2 +-
 doc/guides/cryptodevs/kasumi.rst                   | 10 ++--
 doc/guides/cryptodevs/overview.rst                 | 10 ++++
 doc/guides/cryptodevs/snow3g.rst                   | 10 ++--
 doc/guides/cryptodevs/zuc.rst                      | 10 ++--
 doc/guides/prog_guide/cryptodev_lib.rst            |  6 +-
 doc/guides/rel_notes/deprecation.rst               | 25 ++++++++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c           |  4 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c         |  2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c     | 23 +++++++-
 drivers/crypto/armv8/rte_armv8_pmd.c               |  2 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c             |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c           |  2 +-
 drivers/crypto/scheduler/rte_cryptodev_scheduler.h |  2 +-
 drivers/crypto/scheduler/scheduler_multicore.c     | 38 ++++++++----
 drivers/crypto/scheduler/scheduler_pmd.c           | 68 +++++++++++++++++-----
 drivers/crypto/scheduler/scheduler_pmd_private.h   |  2 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c             |  2 +-
 drivers/crypto/zuc/rte_zuc_pmd.c                   |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |  2 +-
 examples/ipsec-secgw/ipsec.c                       | 12 ----
 examples/l2fwd-crypto/main.c                       |  2 +-
 examples/vhost_crypto/main.c                       |  2 +-
 lib/librte_compressdev/rte_comp.h                  | 18 +++++-
 lib/librte_compressdev/rte_compressdev.h           |  3 +-
 lib/librte_compressdev/rte_compressdev_internal.h  |  3 -
 lib/librte_cryptodev/rte_cryptodev.c               | 59 +++++++++++++++----
 lib/librte_cryptodev/rte_cryptodev.h               | 44 +++++++++++++-
 lib/librte_cryptodev/rte_cryptodev_version.map     |  8 +++
 test/test/test_cryptodev.c                         |  8 ++-
 test/test/test_event_crypto_adapter.c              |  2 +-
 33 files changed, 294 insertions(+), 106 deletions(-)

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
  2018-05-17  8:06  7% ` De Lara Guarch, Pablo
@ 2018-05-24 17:47  4%   ` Wang, Yipeng1
  0 siblings, 0 replies; 200+ results
From: Wang, Yipeng1 @ 2018-05-24 17:47 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Vijaya Mohan Guvva, Richardson, Bruce; +Cc: dev

Hi, Vijaya, 

Thanks for contributing the new API.

We actually have a patch to support read-write concurrency for rte_hash coming in a couple of weeks.  The new del function you proposed may need to be protected under the new concurrency scheme as well. If you like, we could collaborate together to fit your del function under the new concurrency support. 

Thanks
Yipeng

>-----Original Message-----
>From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of De Lara Guarch, Pablo
>Sent: Thursday, May 17, 2018 1:06 AM
>To: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>; Richardson, Bruce <bruce.richardson@intel.com>
>Cc: dev@dpdk.org
>Subject: Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
>
>Hi Vijaya,
>
>> -----Original Message-----
>> From: Vijaya Mohan Guvva [mailto:vguvva@caviumnetworks.com]
>> Sent: Thursday, May 17, 2018 2:27 AM
>> To: Richardson, Bruce <bruce.richardson@intel.com>; De Lara Guarch, Pablo
>> <pablo.de.lara.guarch@intel.com>
>> Cc: dev@dpdk.org; Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> Subject: [PATCH V2] librte_hash: new hash del abi to return stored value
>>
>
>You are actually adding new API, not ABI, so I would reword the commit message.
>
>"hash: add API to return stored value at deletion" maybe?
>
>I would add some information in the commit message and move the changelog (V1, V2 notes)
>after the three dashes.
>
>> V2:
>> Adding another new interface rte_hash_del_key_data to delete key from hash
>> table and return stored data.
>>
>> V1:
>> Add a new key delete interface rte_hash_del_key_with_hash_data to delete the
>> key from hash and return the value stored. This is useful for hash users to free
>> the data stored in the table after key delete and to avoid maintaining a user data
>> array in the dpdk application.
>>
>> Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> ---
>>  lib/librte_hash/rte_cuckoo_hash.c | 30 +++++++++++++++++++++++---
>>  lib/librte_hash/rte_hash.h        | 45
>> +++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 72 insertions(+), 3 deletions(-)
>
>...
>
>> +int32_t
>> +rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
>> +				hash_sig_t sig, void **data);
>> +
>> +/**
>>   * Remove a key from an existing hash table.
>>   * This operation is not multi-thread safe
>>   * and should only be called from one thread.
>> --
>> 1.8.3.1
>
>You need to update the version.map file to add the two new functions
>(you might need to wait until 18.05 is released, so you can use the 18.08 tag).

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
@ 2018-05-24 18:35  7% Guvva, Vijaya
  2018-05-25  1:58  8% ` Honnappa Nagarahalli
  0 siblings, 1 reply; 200+ results
From: Guvva, Vijaya @ 2018-05-24 18:35 UTC (permalink / raw)
  To: Wang, Yipeng1, De Lara Guarch, Pablo, Richardson, Bruce; +Cc: dev

Hi Yipeng,
Sure, It will be great help if you can include these changes in the patches you are proposing with the necessary locks.

Thanks,
Vijay 

-----Original Message-----
From: Wang, Yipeng1 <yipeng1.wang@intel.com> 
Sent: Thursday, May 24, 2018 10:47 AM
To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Guvva, Vijaya <Vijaya.Guvva@cavium.com>; Richardson, Bruce <bruce.richardson@intel.com>
Cc: dev@dpdk.org
Subject: RE: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value

Hi, Vijaya, 

Thanks for contributing the new API.

We actually have a patch to support read-write concurrency for rte_hash coming in a couple of weeks.  The new del function you proposed may need to be protected under the new concurrency scheme as well. If you like, we could collaborate together to fit your del function under the new concurrency support. 

Thanks
Yipeng

>-----Original Message-----
>From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of De Lara Guarch, 
>Pablo
>Sent: Thursday, May 17, 2018 1:06 AM
>To: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>; Richardson, Bruce 
><bruce.richardson@intel.com>
>Cc: dev@dpdk.org
>Subject: Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to 
>return stored value
>
>Hi Vijaya,
>
>> -----Original Message-----
>> From: Vijaya Mohan Guvva [mailto:vguvva@caviumnetworks.com]
>> Sent: Thursday, May 17, 2018 2:27 AM
>> To: Richardson, Bruce <bruce.richardson@intel.com>; De Lara Guarch, 
>> Pablo <pablo.de.lara.guarch@intel.com>
>> Cc: dev@dpdk.org; Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> Subject: [PATCH V2] librte_hash: new hash del abi to return stored 
>> value
>>
>
>You are actually adding new API, not ABI, so I would reword the commit message.
>
>"hash: add API to return stored value at deletion" maybe?
>
>I would add some information in the commit message and move the 
>changelog (V1, V2 notes) after the three dashes.
>
>> V2:
>> Adding another new interface rte_hash_del_key_data to delete key from 
>> hash table and return stored data.
>>
>> V1:
>> Add a new key delete interface rte_hash_del_key_with_hash_data to 
>> delete the key from hash and return the value stored. This is useful 
>> for hash users to free the data stored in the table after key delete 
>> and to avoid maintaining a user data array in the dpdk application.
>>
>> Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> ---
>>  lib/librte_hash/rte_cuckoo_hash.c | 30 +++++++++++++++++++++++---
>>  lib/librte_hash/rte_hash.h        | 45
>> +++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 72 insertions(+), 3 deletions(-)
>
>...
>
>> +int32_t
>> +rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
>> +				hash_sig_t sig, void **data);
>> +
>> +/**
>>   * Remove a key from an existing hash table.
>>   * This operation is not multi-thread safe
>>   * and should only be called from one thread.
>> --
>> 1.8.3.1
>
>You need to update the version.map file to add the two new functions 
>(you might need to wait until 18.05 is released, so you can use the 18.08 tag).

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value
  2018-05-24 18:35  7% [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value Guvva, Vijaya
@ 2018-05-25  1:58  8% ` Honnappa Nagarahalli
  0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2018-05-25  1:58 UTC (permalink / raw)
  To: Guvva, Vijaya, Wang, Yipeng1, De Lara Guarch, Pablo, Richardson, Bruce
  Cc: dev, nd

Hi Yipeng,
	Can you please elaborate on the read-write concurrency changes you are making? I am looking at few changes myself, want to see how we can align.

Issues that I am looking at are:
1) The delete APIs are not multithread safe - from writers perspective
2) Memory ordering between writer and reader while adding the keys
3) Additional APIs to support RCU while deleting the entries

Thank you,
Honnappa

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of Guvva, Vijaya
Sent: Thursday, May 24, 2018 1:35 PM
To: Wang, Yipeng1 <yipeng1.wang@intel.com>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>
Cc: dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value

Hi Yipeng,
Sure, It will be great help if you can include these changes in the patches you are proposing with the necessary locks.

Thanks,
Vijay 

-----Original Message-----
From: Wang, Yipeng1 <yipeng1.wang@intel.com>
Sent: Thursday, May 24, 2018 10:47 AM
To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Guvva, Vijaya <Vijaya.Guvva@cavium.com>; Richardson, Bruce <bruce.richardson@intel.com>
Cc: dev@dpdk.org
Subject: RE: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value

Hi, Vijaya, 

Thanks for contributing the new API.

We actually have a patch to support read-write concurrency for rte_hash coming in a couple of weeks.  The new del function you proposed may need to be protected under the new concurrency scheme as well. If you like, we could collaborate together to fit your del function under the new concurrency support. 

Thanks
Yipeng

>-----Original Message-----
>From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of De Lara Guarch, 
>Pablo
>Sent: Thursday, May 17, 2018 1:06 AM
>To: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>; Richardson, Bruce 
><bruce.richardson@intel.com>
>Cc: dev@dpdk.org
>Subject: Re: [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to 
>return stored value
>
>Hi Vijaya,
>
>> -----Original Message-----
>> From: Vijaya Mohan Guvva [mailto:vguvva@caviumnetworks.com]
>> Sent: Thursday, May 17, 2018 2:27 AM
>> To: Richardson, Bruce <bruce.richardson@intel.com>; De Lara Guarch, 
>> Pablo <pablo.de.lara.guarch@intel.com>
>> Cc: dev@dpdk.org; Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> Subject: [PATCH V2] librte_hash: new hash del abi to return stored 
>> value
>>
>
>You are actually adding new API, not ABI, so I would reword the commit message.
>
>"hash: add API to return stored value at deletion" maybe?
>
>I would add some information in the commit message and move the 
>changelog (V1, V2 notes) after the three dashes.
>
>> V2:
>> Adding another new interface rte_hash_del_key_data to delete key from 
>> hash table and return stored data.
>>
>> V1:
>> Add a new key delete interface rte_hash_del_key_with_hash_data to 
>> delete the key from hash and return the value stored. This is useful 
>> for hash users to free the data stored in the table after key delete 
>> and to avoid maintaining a user data array in the dpdk application.
>>
>> Signed-off-by: Vijaya Mohan Guvva <vguvva@caviumnetworks.com>
>> ---
>>  lib/librte_hash/rte_cuckoo_hash.c | 30 +++++++++++++++++++++++---
>>  lib/librte_hash/rte_hash.h        | 45
>> +++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 72 insertions(+), 3 deletions(-)
>
>...
>
>> +int32_t
>> +rte_hash_del_key_with_hash_data(const struct rte_hash *h, const void *key,
>> +				hash_sig_t sig, void **data);
>> +
>> +/**
>>   * Remove a key from an existing hash table.
>>   * This operation is not multi-thread safe
>>   * and should only be called from one thread.
>> --
>> 1.8.3.1
>
>You need to update the version.map file to add the two new functions 
>(you might need to wait until 18.05 is released, so you can use the 18.08 tag).

^ permalink raw reply	[relevance 8%]

* [dpdk-dev] [PATCH] doc: remove old deprecation notice
@ 2018-05-25  9:17  5% Kirill Rybalchenko
  0 siblings, 0 replies; 200+ results
From: Kirill Rybalchenko @ 2018-05-25  9:17 UTC (permalink / raw)
  To: dev
  Cc: kirill.rybalchenko, nhorman, john.mcnamara, marko.kovacevic,
	beilei.xing, qi.z.zhang, stable

New default configuration without flexible payload
is implemented now.

Fixes: 09dd01ad9a68 ("doc: announce behaviour change to i40e RSS")
Cc: stable@dpdk.org

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1e2443c..df54674 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -59,12 +59,6 @@ Deprecation Notices
   Target release for removal of the legacy API will be defined once most
   PMDs have switched to rte_flow.
 
-* i40e: The default flexible payload configuration which extracts the first 16
-  bytes of the payload for RSS will be deprecated starting from 18.02. If
-  required the previous behavior can be configured using existing flow
-  director APIs. There is no ABI/API break. This change will just remove a
-  global configuration setting and require explicit configuration.
-
 * pdump: As we changed to use generic IPC, some changes in APIs and structure
   are expected in subsequent release.
 
-- 
2.5.5

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] Process for removing __rte_experimental
@ 2018-05-25  9:35  4% Shreyansh Jain
  2018-05-25  9:49  0% ` Thomas Monjalon
  2018-05-25 11:23  3% ` Neil Horman
  0 siblings, 2 replies; 200+ results
From: Shreyansh Jain @ 2018-05-25  9:35 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, bluca, nhorman

While reading through [1], I couldn't understand if __rte_experimental 
and EXPERIMENTAL tag removed from code and map file, respectively, are 
categorized under ABI breakage or not. Thus, whether deprecation for 
them should be sent or not in a release cycle for removal in subsequent 
release.

Logically, EXPERIMENTAL APIs are not part of stable APIs/ABIs and hence 
they don't really break an ABI. Thus, deprecation for them doesn't make 
sense. (or, as Luca noted on IRC, removing experimental is like 
de-deprecation :) )

On IRC, Luca pointed out that in one of the Tech Board meeting minutes 
[2], this was recorded but that too has slight ambiguity to it.

Any thoughts on this? Or, was this documented somewhere other than [1]?

[1] http://dpdk.org/doc/guides/contributing/versioning.html
[2] https://dpdk.org/ml/archives/dev/2017-October/079961.html (Section 2-b)

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] Process for removing __rte_experimental
  2018-05-25  9:35  4% [dpdk-dev] Process for removing __rte_experimental Shreyansh Jain
@ 2018-05-25  9:49  0% ` Thomas Monjalon
  2018-05-25 10:17  0%   ` Luca Boccassi
  2018-05-25 11:23  3% ` Neil Horman
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-25  9:49 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Ferruh Yigit, bluca, nhorman

25/05/2018 11:35, Shreyansh Jain:
> While reading through [1], I couldn't understand if __rte_experimental 
> and EXPERIMENTAL tag removed from code and map file, respectively, are 
> categorized under ABI breakage or not. Thus, whether deprecation for 
> them should be sent or not in a release cycle for removal in subsequent 
> release.
> 
> Logically, EXPERIMENTAL APIs are not part of stable APIs/ABIs and hence 
> they don't really break an ABI. Thus, deprecation for them doesn't make 
> sense. (or, as Luca noted on IRC, removing experimental is like 
> de-deprecation :) )

I agree, no need for prior notice, in my opinion.


> On IRC, Luca pointed out that in one of the Tech Board meeting minutes 
> [2], this was recorded but that too has slight ambiguity to it.
> 
> Any thoughts on this? Or, was this documented somewhere other than [1]?
> 
> [1] http://dpdk.org/doc/guides/contributing/versioning.html
> [2] https://dpdk.org/ml/archives/dev/2017-October/079961.html (Section 2-b)
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] Process for removing __rte_experimental
  2018-05-25  9:49  0% ` Thomas Monjalon
@ 2018-05-25 10:17  0%   ` Luca Boccassi
  2018-05-25 11:16  0%     ` Shreyansh Jain
  0 siblings, 1 reply; 200+ results
From: Luca Boccassi @ 2018-05-25 10:17 UTC (permalink / raw)
  To: Thomas Monjalon, Shreyansh Jain; +Cc: dev, Ferruh Yigit, nhorman

On Fri, 2018-05-25 at 11:49 +0200, Thomas Monjalon wrote:
> 25/05/2018 11:35, Shreyansh Jain:
> > While reading through [1], I couldn't understand if
> > __rte_experimental 
> > and EXPERIMENTAL tag removed from code and map file, respectively,
> > are 
> > categorized under ABI breakage or not. Thus, whether deprecation
> > for 
> > them should be sent or not in a release cycle for removal in
> > subsequent 
> > release.
> > 
> > Logically, EXPERIMENTAL APIs are not part of stable APIs/ABIs and
> > hence 
> > they don't really break an ABI. Thus, deprecation for them doesn't
> > make 
> > sense. (or, as Luca noted on IRC, removing experimental is like 
> > de-deprecation :) )
> 
> I agree, no need for prior notice, in my opinion.

Yeah that makes sense for me as well.

> > On IRC, Luca pointed out that in one of the Tech Board meeting
> > minutes 
> > [2], this was recorded but that too has slight ambiguity to it.
> > 
> > Any thoughts on this? Or, was this documented somewhere other than
> > [1]?
> > 
> > [1] http://dpdk.org/doc/guides/contributing/versioning.html
> > [2] https://dpdk.org/ml/archives/dev/2017-October/079961.html
> > (Section 2-b)

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] Process for removing __rte_experimental
  2018-05-25 10:17  0%   ` Luca Boccassi
@ 2018-05-25 11:16  0%     ` Shreyansh Jain
  0 siblings, 0 replies; 200+ results
From: Shreyansh Jain @ 2018-05-25 11:16 UTC (permalink / raw)
  To: Luca Boccassi, Thomas Monjalon; +Cc: dev, Ferruh Yigit, nhorman

> -----Original Message-----
> From: Luca Boccassi [mailto:bluca@debian.org]
> Sent: Friday, May 25, 2018 3:47 PM
> To: Thomas Monjalon <thomas@monjalon.net>; Shreyansh Jain
> <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; Ferruh Yigit <ferruh.yigit@intel.com>;
> nhorman@tuxdriver.com
> Subject: Re: Process for removing __rte_experimental
> 
> On Fri, 2018-05-25 at 11:49 +0200, Thomas Monjalon wrote:
> > 25/05/2018 11:35, Shreyansh Jain:
> > > While reading through [1], I couldn't understand if
> > > __rte_experimental
> > > and EXPERIMENTAL tag removed from code and map file, respectively,
> > > are
> > > categorized under ABI breakage or not. Thus, whether deprecation
> > > for
> > > them should be sent or not in a release cycle for removal in
> > > subsequent
> > > release.
> > >
> > > Logically, EXPERIMENTAL APIs are not part of stable APIs/ABIs and
> > > hence
> > > they don't really break an ABI. Thus, deprecation for them doesn't
> > > make
> > > sense. (or, as Luca noted on IRC, removing experimental is like
> > > de-deprecation :) )
> >
> > I agree, no need for prior notice, in my opinion.
> 
> Yeah that makes sense for me as well.

[...]

Ok. I will send across a small documentation edit for this clarification.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] Process for removing __rte_experimental
  2018-05-25  9:35  4% [dpdk-dev] Process for removing __rte_experimental Shreyansh Jain
  2018-05-25  9:49  0% ` Thomas Monjalon
@ 2018-05-25 11:23  3% ` Neil Horman
  1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2018-05-25 11:23 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Ferruh Yigit, Thomas Monjalon, bluca

On Fri, May 25, 2018 at 03:05:34PM +0530, Shreyansh Jain wrote:
> While reading through [1], I couldn't understand if __rte_experimental and
> EXPERIMENTAL tag removed from code and map file, respectively, are
> categorized under ABI breakage or not. Thus, whether deprecation for them
> should be sent or not in a release cycle for removal in subsequent release.
> 
> Logically, EXPERIMENTAL APIs are not part of stable APIs/ABIs and hence they
> don't really break an ABI. Thus, deprecation for them doesn't make sense.
> (or, as Luca noted on IRC, removing experimental is like de-deprecation :) )
> 
> On IRC, Luca pointed out that in one of the Tech Board meeting minutes [2],
> this was recorded but that too has slight ambiguity to it.
> 
> Any thoughts on this? Or, was this documented somewhere other than [1]?
> 
> [1] http://dpdk.org/doc/guides/contributing/versioning.html
> [2] https://dpdk.org/ml/archives/dev/2017-October/079961.html (Section 2-b)
> 
Concur with Thomas and Luca.  Use of __rte_experimental denotes APIs that are
not bound by ABI requirements.  Removing the experimental tag is,as you say
de-deprication.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] doc: move and update experimental API description
@ 2018-05-25 12:07 28% Shreyansh Jain
  2018-05-25 12:22  0% ` Luca Boccassi
  0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2018-05-25 12:07 UTC (permalink / raw)
  To: thomas, bluca, nhorman; +Cc: dev, Shreyansh Jain

Experimental API text has been moved into a sub-section of ABI Policy.
A paragraph has been added to explain the process for removal of an
experimental tag.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

---
note:
 The movement of text into a sub-section is relevant as the previous position
 was in middle of a continuous text explaining ABI policy - whereas,
 experimental is not truly an ABI policy.
 No change to the original text has been made, except appending a new
 paragraph. Though, this does spoil the blame/praise.

 doc/guides/contributing/versioning.rst | 54 +++++++++++++++-----------
 1 file changed, 31 insertions(+), 23 deletions(-)

diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index c495294db..7127d39ee 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -43,29 +43,6 @@ ABI versions are set at the time of major release labeling, and the ABI may
 change multiple times, without warning, between the last release label and the
 HEAD label of the git tree.
 
-APIs marked as ``experimental`` are not considered part of the ABI and may
-change without warning at any time.  Since changes to APIs are most likely
-immediately after their introduction, as users begin to take advantage of
-those new APIs and start finding issues with them, new DPDK APIs will be
-automatically marked as ``experimental`` to allow for a period of stabilization
-before they become part of a tracked ABI.
-
-Note that marking an API as experimental is a multi step process.
-To mark an API as experimental, the symbols which are desired to be exported
-must be placed in an EXPERIMENTAL version block in the corresponding libraries'
-version map script.
-Secondly, the corresponding definitions of those exported functions, and
-their forward declarations (in the development header files), must be marked
-with the ``__rte_experimental`` tag (see ``rte_compat.h``).
-The DPDK build makefiles perform a check to ensure that the map file and the
-C code reflect the same list of symbols.
-This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
-during compilation in the corresponding library Makefile.
-
-In addition to tagging the code with ``__rte_experimental``,
-the doxygen markup must also contain the EXPERIMENTAL string,
-and the MAINTAINERS file should note the EXPERIMENTAL libraries.
-
 ABI versions, once released, are available until such time as their
 deprecation has been noted in the Release Notes for at least one major release
 cycle. For example consider the case where the ABI for DPDK 2.0 has been
@@ -119,6 +96,37 @@ readability purposes should be avoided.
    follow the relevant deprecation policy procedures as above: 3 acks and
    announcement at least one release in advance.
 
+Experimental APIs
+~~~~~~~~~~~~~~~~~
+
+APIs marked as ``experimental`` are not considered part of the ABI and may
+change without warning at any time.  Since changes to APIs are most likely
+immediately after their introduction, as users begin to take advantage of
+those new APIs and start finding issues with them, new DPDK APIs will be
+automatically marked as ``experimental`` to allow for a period of stabilization
+before they become part of a tracked ABI.
+
+Note that marking an API as experimental is a multi step process.
+To mark an API as experimental, the symbols which are desired to be exported
+must be placed in an EXPERIMENTAL version block in the corresponding libraries'
+version map script.
+Secondly, the corresponding definitions of those exported functions, and
+their forward declarations (in the development header files), must be marked
+with the ``__rte_experimental`` tag (see ``rte_compat.h``).
+The DPDK build makefiles perform a check to ensure that the map file and the
+C code reflect the same list of symbols.
+This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
+during compilation in the corresponding library Makefile.
+
+In addition to tagging the code with ``__rte_experimental``,
+the doxygen markup must also contain the EXPERIMENTAL string,
+and the MAINTAINERS file should note the EXPERIMENTAL libraries.
+
+For removing the experimental tag associated with an API, deprecation notice
+is not required. Though, an API should remain in experimental state for at least
+one release. Thereafter, normal process of posting patch for review to mailing
+list can be followed.
+
 Examples of Deprecation Notices
 -------------------------------
 
-- 
2.17.0

^ permalink raw reply	[relevance 28%]

* Re: [dpdk-dev] [PATCH] doc: move and update experimental API description
  2018-05-25 12:07 28% [dpdk-dev] [PATCH] doc: move and update experimental API description Shreyansh Jain
@ 2018-05-25 12:22  0% ` Luca Boccassi
  2018-05-25 15:37  0%   ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Luca Boccassi @ 2018-05-25 12:22 UTC (permalink / raw)
  To: Shreyansh Jain, thomas, nhorman; +Cc: dev

On Fri, 2018-05-25 at 17:37 +0530, Shreyansh Jain wrote:
> Experimental API text has been moved into a sub-section of ABI
> Policy.
> A paragraph has been added to explain the process for removal of an
> experimental tag.
> 
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> 
> ---
> note:
>  The movement of text into a sub-section is relevant as the previous
> position
>  was in middle of a continuous text explaining ABI policy - whereas,
>  experimental is not truly an ABI policy.
>  No change to the original text has been made, except appending a new
>  paragraph. Though, this does spoil the blame/praise.
> 
>  doc/guides/contributing/versioning.rst | 54 +++++++++++++++---------
> --
>  1 file changed, 31 insertions(+), 23 deletions(-)

Acked-by: Luca Boccassi <bluca@debian.org>

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] doc: deprecation notice for EAL runtime path changes
@ 2018-05-25 13:38  5% Anatoly Burakov
  0 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-05-25 13:38 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, John McNamara, Marko Kovacevic, thomas,
	bruce.richardson, harry.van.haaren

Most of this work was already done, but runtime config path is
considered to be part of public API because of high likelihood of
it being used by various tools in the DPDK ecosystem, and thus
requires a deprecation notice.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1e2443c..36d2e23 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,15 @@ API and ABI deprecation notices are to be posted here.
 Deprecation Notices
 -------------------
 
+* eal: DPDK runtime configuration file (located at
+  ``/var/run/.<prefix>_config``) will be moved. The new path will be as follows:
+  - if DPDK is running as root, path will be set to
+    ``/var/run/dpdk/<prefix>/config``
+  - if DPDK is not running as root and $XDG_RUNTIME_DIR is set, path will be set
+    to ``$XDG_RUNTIME_DIR/dpdk/<prefix>/config``
+  - if DPDK is not running as root and $XDG_RUNTIME_DIR is not set, path will be
+    set to ``/tmp/dpdk/<prefix>/config``
+
 * eal: both declaring and identifying devices will be streamlined in v18.05.
   New functions will appear to query a specific port from buses, classes of
   device and device drivers. Device declaration will be made coherent with the
-- 
2.7.4

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH] doc: move and update experimental API description
  2018-05-25 12:22  0% ` Luca Boccassi
@ 2018-05-25 15:37  0%   ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-05-25 15:37 UTC (permalink / raw)
  To: Luca Boccassi, Shreyansh Jain, thomas, nhorman; +Cc: dev

On 5/25/2018 1:22 PM, Luca Boccassi wrote:
> On Fri, 2018-05-25 at 17:37 +0530, Shreyansh Jain wrote:
>> Experimental API text has been moved into a sub-section of ABI
>> Policy.
>> A paragraph has been added to explain the process for removal of an
>> experimental tag.
>>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>
>> ---
>> note:
>>  The movement of text into a sub-section is relevant as the previous
>> position
>>  was in middle of a continuous text explaining ABI policy - whereas,
>>  experimental is not truly an ABI policy.
>>  No change to the original text has been made, except appending a new
>>  paragraph. Though, this does spoil the blame/praise.
>>
>>  doc/guides/contributing/versioning.rst | 54 +++++++++++++++---------
>> --
>>  1 file changed, 31 insertions(+), 23 deletions(-)
> 
> Acked-by: Luca Boccassi <bluca@debian.org>

Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6] checkpatches.sh: Add checks for ABI symbol addition
  @ 2018-05-27 19:34  4%   ` Thomas Monjalon
  2018-05-27 21:00  4%     ` Neil Horman
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-27 19:34 UTC (permalink / raw)
  To: Neil Horman
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

Hi Neil,

Sorry, this patch has been forgotten during the whole release cycle.

I see an issue about the dependency on filterdiff.
Is there a way to avoid it?

I have some minor comments below.

14/02/2018 20:19, Neil Horman:
> @@ -61,6 +65,7 @@ print_usage () {
>  	END_OF_HELP
>  }
>  
> +

This new blank line is probably a leftover.

>  number=0
>  quiet=false
>  verbose=false
> @@ -86,19 +91,50 @@ total=0
>  status=0
>  
>  check () { # <patch> <commit> <title>
> +	local ret=0
> +	TMPINPUT=`mktemp checkpatches.XXXXXX`

It is preferred to use $() construct to be consistent in the file.

> +
>  	total=$(($total + 1))
>  	! $verbose || printf '\n### %s\n\n' "$3"
>  	if [ -n "$1" ] ; then
>  		report=$($DPDK_CHECKPATCH_PATH $options "$1" 2>/dev/null)
>  	elif [ -n "$2" ] ; then
> -		report=$(git format-patch --find-renames --no-stat --stdout -1 $commit |
> +		git format-patch --find-renames --no-stat --stdout -1 $commit > ./$TMPINPUT
> +		report=$(cat ./$TMPINPUT |
>  			$DPDK_CHECKPATCH_PATH $options - 2>/dev/null)

No need to use cat here.

>  	else
> -		report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
> +		cat > ./$TMPINPUT
> +		report=$(cat ./$TMPINPUT | $DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
> +	fi

All calls to DPDK_CHECKPATCH_PATH can be moved to one call after the "fi".
Just need to set TPMINPUT=$1 in first case (and not remove TPMINPUT
in this case).

> +	if [ $? -ne 0 ]
> +	then

For consistency, the style in this file is:
	if [ $? -ne 0 ] ; then

> +		$verbose || printf '\n### %s\n\n' "$3"
> +		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
> +		ret=1
> +	fi
> +
> +	! $verbose || printf '\nChecking API additions/removals:\n'
> +
> +	if [ -n "$1" ] ; then
> +		report=$($VALIDATE_NEW_API "$1")
> +	elif [ -n "$2" ] ; then
> +		report=$( cat ./$TMPINPUT | 
> +			$VALIDATE_NEW_API -)
> +	else
> +		report=$(cat ./$TMPINPUT | $VALIDATE_NEW_API -)
> +	fi

Same as above, it can be simplified by only one line for all cases.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6] checkpatches.sh: Add checks for ABI symbol addition
  2018-05-27 19:34  4%   ` Thomas Monjalon
@ 2018-05-27 21:00  4%     ` Neil Horman
  2018-05-27 22:01  4%       ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-05-27 21:00 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

On Sun, May 27, 2018 at 09:34:13PM +0200, Thomas Monjalon wrote:
> Hi Neil,
> 
> Sorry, this patch has been forgotten during the whole release cycle.
> 
Its ok, though that is frustrating, as we now need to re-familiarize ourselves
with how this patch works.

> I see an issue about the dependency on filterdiff.
> Is there a way to avoid it?
> 
I suppose, but to do so would require some awk magic.  Is there any advantage to
having an awk dependency rather than a filterdiff dependency?  filterdiff is a
pretty universal tool.

> I have some minor comments below.
> 
> 14/02/2018 20:19, Neil Horman:
> > @@ -61,6 +65,7 @@ print_usage () {
> >  	END_OF_HELP
> >  }
> >  
> > +
> 
> This new blank line is probably a leftover.
Yeah, if I wind up respinning this, I'll remove it.

> 
> >  number=0
> >  quiet=false
> >  verbose=false
> > @@ -86,19 +91,50 @@ total=0
> >  status=0
> >  
> >  check () { # <patch> <commit> <title>
> > +	local ret=0
> > +	TMPINPUT=`mktemp checkpatches.XXXXXX`
> 
> It is preferred to use $() construct to be consistent in the file.
> 
> > +
> >  	total=$(($total + 1))
> >  	! $verbose || printf '\n### %s\n\n' "$3"
> >  	if [ -n "$1" ] ; then
> >  		report=$($DPDK_CHECKPATCH_PATH $options "$1" 2>/dev/null)
> >  	elif [ -n "$2" ] ; then
> > -		report=$(git format-patch --find-renames --no-stat --stdout -1 $commit |
> > +		git format-patch --find-renames --no-stat --stdout -1 $commit > ./$TMPINPUT
> > +		report=$(cat ./$TMPINPUT |
> >  			$DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
> 
> No need to use cat here.
> 
Actually, I vaguely recall with these changes I did encounter a problem with passing
output to checkpatch, but its been so long I can't recall now.

> >  	else
> > -		report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
> > +		cat > ./$TMPINPUT
> > +		report=$(cat ./$TMPINPUT | $DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
> > +	fi
> 
> All calls to DPDK_CHECKPATCH_PATH can be moved to one call after the "fi".
> Just need to set TPMINPUT=$1 in first case (and not remove TPMINPUT
> in this case).
> 
Sure.

> > +	if [ $? -ne 0 ]
> > +	then
> 
> For consistency, the style in this file is:
> 	if [ $? -ne 0 ] ; then
> 
> > +		$verbose || printf '\n### %s\n\n' "$3"
> > +		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
> > +		ret=1
> > +	fi
> > +
> > +	! $verbose || printf '\nChecking API additions/removals:\n'
> > +
> > +	if [ -n "$1" ] ; then
> > +		report=$($VALIDATE_NEW_API "$1")
> > +	elif [ -n "$2" ] ; then
> > +		report=$( cat ./$TMPINPUT | 
> > +			$VALIDATE_NEW_API -)
> > +	else
> > +		report=$(cat ./$TMPINPUT | $VALIDATE_NEW_API -)
> > +	fi
> 
> Same as above, it can be simplified by only one line for all cases.

Fine, at this point, I don't know when I'll get to this though, its pretty busy
here at the moment.

> 
> 
> 
> 

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v6] checkpatches.sh: Add checks for ABI symbol addition
  2018-05-27 21:00  4%     ` Neil Horman
@ 2018-05-27 22:01  4%       ` Thomas Monjalon
  2018-05-28 17:08  4%         ` Neil Horman
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-05-27 22:01 UTC (permalink / raw)
  To: Neil Horman
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

27/05/2018 23:00, Neil Horman:
> On Sun, May 27, 2018 at 09:34:13PM +0200, Thomas Monjalon wrote:
> > Hi Neil,
> > 
> > Sorry, this patch has been forgotten during the whole release cycle.
> > 
> Its ok, though that is frustrating, as we now need to re-familiarize ourselves
> with how this patch works.

I understand and apologize.

> > I see an issue about the dependency on filterdiff.
> > Is there a way to avoid it?
> > 
> I suppose, but to do so would require some awk magic.  Is there any advantage to
> having an awk dependency rather than a filterdiff dependency?  filterdiff is a
> pretty universal tool.

filterdiff is not installed on my machine.
I guess it is the same for a lot of people.

I will check how we can replace it.

[...]
> Fine, at this point, I don't know when I'll get to this though, its pretty busy
> here at the moment.

This delay is my fault, and I want to help.
If I find a good solution, do you accept I send a version 7 of this patch?

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config
@ 2018-05-28  3:31  8% Andy Green
  2018-05-30  0:32  4% ` Andy Green
  0 siblings, 1 reply; 200+ results
From: Andy Green @ 2018-05-28  3:31 UTC (permalink / raw)
  To: dev

Hi -

Between 18.02 and the putative 18.05 there were changes in the way the 
meter stuff deals with its config.

I updated the related code in lagopus, but I get warnings about using 
the new APIs (it's the same for rte_meter_trtcm_profile_config())

./dpdk/meter.c: In function 'dpdk_register_meter':
./dpdk/meter.c:119:7: warning: 'rte_meter_srtcm_profile_config' is 
deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
        rte_meter_srtcm_profile_config(&lband->sp, &param);
        ^
In file included from ./dpdk/meter.c:27:0:
/home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note: 
declared here
  rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
  ^
./dpdk/meter.c:132:7: warning: 'rte_meter_srtcm_profile_config' is 
deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
        rte_meter_srtcm_profile_config(&lband->sp, &param);
        ^
In file included from ./dpdk/meter.c:27:0:
/home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note: 
declared here
  rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,


As far as I can see this api change is not optional, it changes the 
parameters for related apis to require a struct prepared with these new 
apis.

-Andy

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH v6] checkpatches.sh: Add checks for ABI symbol addition
  2018-05-27 22:01  4%       ` Thomas Monjalon
@ 2018-05-28 17:08  4%         ` Neil Horman
  0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-05-28 17:08 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

On Mon, May 28, 2018 at 12:01:15AM +0200, Thomas Monjalon wrote:
> 27/05/2018 23:00, Neil Horman:
> > On Sun, May 27, 2018 at 09:34:13PM +0200, Thomas Monjalon wrote:
> > > Hi Neil,
> > > 
> > > Sorry, this patch has been forgotten during the whole release cycle.
> > > 
> > Its ok, though that is frustrating, as we now need to re-familiarize ourselves
> > with how this patch works.
> 
> I understand and apologize.
> 
No worries.

> > > I see an issue about the dependency on filterdiff.
> > > Is there a way to avoid it?
> > > 
> > I suppose, but to do so would require some awk magic.  Is there any advantage to
> > having an awk dependency rather than a filterdiff dependency?  filterdiff is a
> > pretty universal tool.
> 
> filterdiff is not installed on my machine.
> I guess it is the same for a lot of people.
> 
My guess is that awk is only installed on your machine because you needed it for
another script (possibly this one).  Neither is commonly installed by default,
but both are readily available.

> I will check how we can replace it.
> 
No need, I know how I can use awk to replace it, the only question is, do we
need to do it?  I suppose there is an implicit advantage in just using ask, as
we already require it.

All thats needed is an awk program like the following:
awk 'BEGIN {startprint=0;} /.*diff.*map.*/ {startprint=1;} \
	/.*diff.*[^map].*/ {startprint=0 /.*/ {if (startprint) {print $0}}'

its basically a state machine that prints every line in a file after hitting the
regex diff.*map (i.e. a map file), and stops when it hits the next diff block
that isn't for a map file.  The above isn't exactly right, but its close.

> [...]
> > Fine, at this point, I don't know when I'll get to this though, its pretty busy
> > here at the moment.
> 
> This delay is my fault, and I want to help.
> If I find a good solution, do you accept I send a version 7 of this patch?
Sure, if you have the time to take care of it, that would be great, thanks.  And
thank you for asking.  If I find time, I'll take a stab at it as well, but I
think given Red Hats schedule, it will be a few weeks before I'm able.

Best
Neil
> 
> 
> 

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config
  2018-05-28  3:31  8% [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config Andy Green
@ 2018-05-30  0:32  4% ` Andy Green
  2018-05-30  9:55  4%   ` Singh, Jasvinder
  0 siblings, 1 reply; 200+ results
From: Andy Green @ 2018-05-30  0:32 UTC (permalink / raw)
  To: dev; +Cc: Cristian Dumitrescu, Jasvinder Singh



On 05/28/2018 11:31 AM, Andy Green wrote:
> Hi -
> 
> Between 18.02 and the putative 18.05 there were changes in the way the 
> meter stuff deals with its config.
> 
> I updated the related code in lagopus, but I get warnings about using 
> the new APIs (it's the same for rte_meter_trtcm_profile_config())
> 
> ./dpdk/meter.c: In function 'dpdk_register_meter':
> ./dpdk/meter.c:119:7: warning: 'rte_meter_srtcm_profile_config' is 
> deprecated: Symbol is not yet part of stable ABI 
> [-Wdeprecated-declarations]
>         rte_meter_srtcm_profile_config(&lband->sp, &param);
>         ^
> In file included from ./dpdk/meter.c:27:0:
> /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note: 
> declared here
>   rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
>   ^
> ./dpdk/meter.c:132:7: warning: 'rte_meter_srtcm_profile_config' is 
> deprecated: Symbol is not yet part of stable ABI 
> [-Wdeprecated-declarations]
>         rte_meter_srtcm_profile_config(&lband->sp, &param);
>         ^
> In file included from ./dpdk/meter.c:27:0:
> /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note: 
> declared here
>   rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
> 
> 
> As far as I can see this api change is not optional, it changes the 
> parameters for related apis to require a struct prepared with these new 
> apis.

IOW should these exports still be "experimental"

EXPERIMENTAL {
         global:

         rte_meter_srtcm_profile_config;
         rte_meter_trtcm_profile_config;
};

...when the changes also introduced in 
c06ddf9698e0c2a9653cfa971f9ddc205065662c unconditionally modify the 
existing APIs to require the new stuff?

@@ -138,6 +187,7 @@ rte_meter_srtcm_color_aware_check(struct 
rte_meter_srtcm *m,
   */
  static inline enum rte_meter_color
  rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+       struct rte_meter_trtcm_profile *p,
         uint64_t time,
         uint32_t pkt_len);

etc

-Andy

> -Andy

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config
  2018-05-30  0:32  4% ` Andy Green
@ 2018-05-30  9:55  4%   ` Singh, Jasvinder
  2018-05-30 10:13  4%     ` Andy Green
  0 siblings, 1 reply; 200+ results
From: Singh, Jasvinder @ 2018-05-30  9:55 UTC (permalink / raw)
  To: Andy Green, dev; +Cc: Dumitrescu, Cristian

<snip>

> On 05/28/2018 11:31 AM, Andy Green wrote:
> > Hi -
> >
> > Between 18.02 and the putative 18.05 there were changes in the way the
> > meter stuff deals with its config.
> >
> > I updated the related code in lagopus, but I get warnings about using
> > the new APIs (it's the same for rte_meter_trtcm_profile_config())
> >
> > ./dpdk/meter.c: In function 'dpdk_register_meter':
> > ./dpdk/meter.c:119:7: warning: 'rte_meter_srtcm_profile_config' is
> > deprecated: Symbol is not yet part of stable ABI
> > [-Wdeprecated-declarations]
> >         rte_meter_srtcm_profile_config(&lband->sp, &param);
> >         ^
> > In file included from ./dpdk/meter.c:27:0:
> > /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note:
> > declared here
> >   rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
> >   ^
> > ./dpdk/meter.c:132:7: warning: 'rte_meter_srtcm_profile_config' is
> > deprecated: Symbol is not yet part of stable ABI
> > [-Wdeprecated-declarations]
> >         rte_meter_srtcm_profile_config(&lband->sp, &param);
> >         ^
> > In file included from ./dpdk/meter.c:27:0:
> > /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note:
> > declared here
> >   rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
> >
> >
> > As far as I can see this api change is not optional, it changes the
> > parameters for related apis to require a struct prepared with these
> > new apis.
> 
> IOW should these exports still be "experimental"
> 
> EXPERIMENTAL {
>          global:
> 
>          rte_meter_srtcm_profile_config;
>          rte_meter_trtcm_profile_config; };
> 
> ...when the changes also introduced in
> c06ddf9698e0c2a9653cfa971f9ddc205065662c unconditionally modify the
> existing APIs to require the new stuff?
> 
> @@ -138,6 +187,7 @@ rte_meter_srtcm_color_aware_check(struct
> rte_meter_srtcm *m,
>    */
>   static inline enum rte_meter_color
>   rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
> +       struct rte_meter_trtcm_profile *p,
>          uint64_t time,
>          uint32_t pkt_len);
> 
> etc

The above meter APIs change has followed the deprecation procedure, therefore, IMO, should not be treated as experimental. In general, this is open question as nothing is specified in the docs.

   

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config
  2018-05-30  9:55  4%   ` Singh, Jasvinder
@ 2018-05-30 10:13  4%     ` Andy Green
  0 siblings, 0 replies; 200+ results
From: Andy Green @ 2018-05-30 10:13 UTC (permalink / raw)
  To: Singh, Jasvinder, dev; +Cc: Dumitrescu, Cristian



On 05/30/2018 05:55 PM, Singh, Jasvinder wrote:
> <snip>
> 
>> On 05/28/2018 11:31 AM, Andy Green wrote:
>>> Hi -
>>>
>>> Between 18.02 and the putative 18.05 there were changes in the way the
>>> meter stuff deals with its config.
>>>
>>> I updated the related code in lagopus, but I get warnings about using
>>> the new APIs (it's the same for rte_meter_trtcm_profile_config())
>>>
>>> ./dpdk/meter.c: In function 'dpdk_register_meter':
>>> ./dpdk/meter.c:119:7: warning: 'rte_meter_srtcm_profile_config' is
>>> deprecated: Symbol is not yet part of stable ABI
>>> [-Wdeprecated-declarations]
>>>          rte_meter_srtcm_profile_config(&lband->sp, &param);
>>>          ^
>>> In file included from ./dpdk/meter.c:27:0:
>>> /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note:
>>> declared here
>>>    rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
>>>    ^
>>> ./dpdk/meter.c:132:7: warning: 'rte_meter_srtcm_profile_config' is
>>> deprecated: Symbol is not yet part of stable ABI
>>> [-Wdeprecated-declarations]
>>>          rte_meter_srtcm_profile_config(&lband->sp, &param);
>>>          ^
>>> In file included from ./dpdk/meter.c:27:0:
>>> /home/agreen/lagopus/src/dpdk/build/include/rte_meter.h:86:1: note:
>>> declared here
>>>    rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
>>>
>>>
>>> As far as I can see this api change is not optional, it changes the
>>> parameters for related apis to require a struct prepared with these
>>> new apis.
>>
>> IOW should these exports still be "experimental"
>>
>> EXPERIMENTAL {
>>           global:
>>
>>           rte_meter_srtcm_profile_config;
>>           rte_meter_trtcm_profile_config; };
>>
>> ...when the changes also introduced in
>> c06ddf9698e0c2a9653cfa971f9ddc205065662c unconditionally modify the
>> existing APIs to require the new stuff?
>>
>> @@ -138,6 +187,7 @@ rte_meter_srtcm_color_aware_check(struct
>> rte_meter_srtcm *m,
>>     */
>>    static inline enum rte_meter_color
>>    rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
>> +       struct rte_meter_trtcm_profile *p,
>>           uint64_t time,
>>           uint32_t pkt_len);
>>
>> etc
> 
> The above meter APIs change has followed the deprecation procedure, therefore, IMO, should not be treated as experimental. In general, this is open question as nothing is specified in the docs.

Thanks.

Another way to ask the same question is: "after we changed the related, 
pre-existing api to require this, why is it useful to want it to blow 
warnings unless we enable EXPERIMENTAL"?

Before the patch, meter api itself wasn't experimental evidently. 
Lagopus uses the old api without EXPERIMENTAL enabled for 18.02; then on 
18.05, after the api it was previously using without EXPERIMENTAL 
changed, it blows warnings after it was actually unconditionally forced 
to adapt to use the new stuff.

Unless I misunderstood it, you can't meaningfully, retrospectively, mark 
a public API EXPERIMENTAL after you changed it, and this is marking 
EXPERIMENTAL a new unconditional dependency on a new type for an API 
that was a previously available via a non-EXPERIMENTAL public api.

Effectively I think you just decided to change the public api (which is 
normal enough for living projects...) and that's the end of it. 
EXPERIMENTAL is only meaningful for stuff you can cleanly enable or 
disable at build-time, this is not such a situation.

If so it should get un-experimentalized for export...

-Andy

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v1] doc: update release notes for 18.05
@ 2018-05-30 20:25  7% John McNamara
  2018-05-30 20:54 12% ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: John McNamara @ 2018-05-30 20:25 UTC (permalink / raw)
  To: dev; +Cc: John McNamara

Fix grammar, spelling and formatting of DPDK 18.05 release notes.

Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_18_05.rst | 308 +++++++++++++++++----------------
 1 file changed, 157 insertions(+), 151 deletions(-)

diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 42a5b37..b24217e 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -45,7 +45,7 @@ New Features
 
   Memory subsystem has been reworked to support new functionality.
 
-  On Linux, support for reserving/unreserving hugepage memory at runtime was
+  On Linux, support for reserving/unreserving hugepage memory at runtime has been
   added, so applications no longer need to pre-reserve memory at startup. Due to
   reorganized internal workings of memory subsystem, any memory allocated
   through ``rte_malloc()`` or ``rte_memzone_reserve()`` is no longer guaranteed
@@ -53,64 +53,64 @@ New Features
 
   This functionality has introduced the following changes:
 
-  * ``rte_eal_get_physmem_layout()`` was removed
+  * ``rte_eal_get_physmem_layout()`` was removed.
   * A new flag for memzone reservation (``RTE_MEMZONE_IOVA_CONTIG``) was added
     to ensure reserved memory will be IOVA-contiguous, for use with device
-    drivers and other cases requiring such memory
-  * New callbacks for memory allocation/deallocation events, allowing user (or
+    drivers and other cases requiring such memory.
+  * New callbacks for memory allocation/deallocation events, allowing users (or
     drivers) to be notified of new memory being allocated or deallocated
-  * New callbacks for validating memory allocations above specified limit,
-    allowing user to permit or deny memory allocations
+  * New callbacks for validating memory allocations above a specified limit,
+    allowing user to permit or deny memory allocations.
   * A new command-line switch ``--legacy-mem`` to enable EAL behavior similar to
     how older versions of DPDK worked (memory segments that are IOVA-contiguous,
-    but hugepages are reserved at startup only, and can never be released)
+    but hugepages are reserved at startup only, and can never be released).
   * A new command-line switch ``--single-file-segments`` to put all memory
-    segments within a segment list in a single file
+    segments within a segment list in a single file.
   * A set of convenience function calls to look up and iterate over allocated
-    memory segments
+    memory segments.
   * ``-m`` and ``--socket-mem`` command-line arguments now carry an additional
     meaning and mark pre-reserved hugepages as "unfree-able", thereby acting as
     a mechanism guaranteeing minimum availability of hugepage memory to the
-    application
+    application.
 
   Reserving/unreserving memory at runtime is not currently supported on FreeBSD.
 
 * **Added bucket mempool driver.**
 
-  Added bucket mempool driver which provides a way to allocate contiguous
+  Added a bucket mempool driver which provides a way to allocate contiguous
   block of objects.
-  Number of objects in the block depends on how many objects fit in
-  RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB memory chunk which is build time option.
-  The number may be obtained using rte_mempool_ops_get_info() API.
-  Contiguous blocks may be allocated using rte_mempool_get_contig_blocks() API.
+  The number of objects in the block depends on how many objects fit in the
+  ``RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB`` memory chunk which is a build time option.
+  The number may be obtained using ``rte_mempool_ops_get_info()`` API.
+  Contiguous blocks may be allocated using ``rte_mempool_get_contig_blocks()`` API.
 
 * **Added support for port representors.**
 
-  The DPDK port representors (also known as "VF representors" in the specific
+  Added DPDK port representors (also known as "VF representors" in the specific
   context of VFs), which are to DPDK what the Ethernet switch device driver
   model (**switchdev**) is to Linux, and which can be thought as a software
   "patch panel" front-end for applications. DPDK port representors are
   implemented as additional virtual Ethernet device (**ethdev**) instances,
-  spawned on an as needed basis through configuration parameters passed to the
+  spawned on an as-needed basis through configuration parameters passed to the
   driver of the underlying device using devargs.
 
 * **Added support for VXLAN and NVGRE tunnel endpoint.**
 
   New actions types have been added to support encapsulation and decapsulation
   operations for a tunnel endpoint. The new action types are
-  RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_ENCAP, RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_DECAP,
-  RTE_FLOW_ACTION_TYPE_JUMP. New item type RTE_FLOW_ACTION_TYPE_MARK has been
-  added to match a flow against a previously marked flow. It also introduced shared
-  counter to flow API to counte for a group of flows.
+  ``RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_ENCAP``, ``RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_DECAP``,
+  ``RTE_FLOW_ACTION_TYPE_JUMP``. A new item type ``RTE_FLOW_ACTION_TYPE_MARK`` has been
+  added to match a flow against a previously marked flow. A shared counter has also been
+  introduced to the flow API to count a group of flows.
 
-* **Added PMD-recommended Tx and Rx parameters**
+* **Added PMD-recommended Tx and Rx parameters.**
 
   Applications can now query drivers for device-tuned values of
   ring sizes, burst sizes, and number of queues.
 
 * **Added RSS hash and key update to CXGBE PMD.**
 
-  Support to update RSS hash and key has been added to CXGBE PMD.
+  Added support for updating the RSS hash and key to the CXGBE PMD.
 
 * **Added CXGBE VF PMD.**
 
@@ -121,29 +121,29 @@ New Features
 
   Updated the mlx5 driver including the following changes:
 
-  * Introduced Multi-packet Rx. With it, achieved 100Gb/sec with 64B frames.
-  * Supported to be run by non-root users given reduced set of capabilities
-    CAP_NET_ADMIN, CAP_NET_RAW and CAP_IPC_LOCK.
-  * Supported TSO and checksum for generic UDP and IP tunnels.
-  * Supported inner checksum and RSS for GRE, VXLAN-GPE, MPLSoGRE
+  * Introduced Multi-packet Rx to enable 100Gb/sec with 64B frames.
+  * Support for being run by non-root users given a reduced set of capabilities
+    ``CAP_NET_ADMIN``, ``CAP_NET_RAW`` and ``CAP_IPC_LOCK``.
+  * Support for TSO and checksum for generic UDP and IP tunnels.
+  * Support for  inner checksum and RSS for GRE, VXLAN-GPE, MPLSoGRE
     and MPLSoUDP tunnels.
-  * Accommodate to the new memory hotplug model.
-  * Supported non virtually contiguous mempools.
-  * Supported MAC adding along with allmulti and promiscuous modes from VF.
-  * Supported Mellanox BlueField SoC device.
-  * Supported PMD defaults for queue number and depth to improve the out
+  * Accommodate the new memory hotplug model.
+  * Support for non virtually contiguous mempools.
+  * Support for MAC adding along with allmulti and promiscuous modes from VF.
+  * Support for Mellanox BlueField SoC device.
+  * Support for PMD defaults for queue number and depth to improve the out
     of the box performance.
 
 * **Updated mlx4 driver.**
 
   Updated the mlx4 driver including the following changes:
 
-  * Supported to be run by non-root users given reduced set of capabilities
-    CAP_NET_ADMIN, CAP_NET_RAW and CAP_IPC_LOCK.
+  * Support for to being run by non-root users given a reduced set of capabilities
+    ``CAP_NET_ADMIN``, ``CAP_NET_RAW`` and ``CAP_IPC_LOCK``.
   * Supported CRC strip toggling.
-  * Accommodate to the new memory hotplug model.
-  * Supported non virtually contiguous mempools.
-  * Dropped support in Mellanox OFED 4.2.
+  * Accommodate the new memory hotplug model.
+  * Support non virtually contiguous mempools.
+  * Dropped support for Mellanox OFED 4.2.
 
 * **Updated Solarflare network PMD.**
 
@@ -164,58 +164,61 @@ New Features
 * **Updated szedata2 PMD.**
 
   Added support for new NFB-200G2QL card.
-  New API was introduced in the libsze2 library which the szedata2 PMD depends
-  on thus the new version of the library was needed.
+  A new API was introduced in the libsze2 library which the szedata2 PMD depends
+  on, thus the new version of the library was needed.
   New versions of the packages are available and the minimum required version
   is 4.4.1.
 
-* **Added support for Broadcom NetXtreme-S (BCM58800) family of controllers (aka Stingray)**
+* **Added support for Broadcom NetXtreme-S (BCM58800) family of controllers (aka Stingray).**
 
-  The BCM58800 devices feature a NetXtreme E-Series advanced network controller, a high-performance
-  ARM CPU block, PCI Express (PCIe) Gen3 interfaces, key accelerators for compute offload and a high-
-  speed memory subsystem including L3 cache and DDR4 interfaces, all interconnected by a coherent
-  Network-on-chip (NOC) fabric.
+  Added support for the Broadcom NetXtreme-S (BCM58800) family of controllers
+  (aka Stingray). The BCM58800 devices feature a NetXtreme E-Series advanced
+  network controller, a high-performance ARM CPU block, PCI Express (PCIe)
+  Gen3 interfaces, key accelerators for compute offload and a high-speed
+  memory subsystem including L3 cache and DDR4 interfaces, all interconnected
+  by a coherent Network-on-chip (NOC) fabric.
 
-  The ARM CPU subsystem features eight ARMv8 Cortex-A72 CPUs at 3.0 GHz, arranged in a multi-cluster
-  configuration.
+  The ARM CPU subsystem features eight ARMv8 Cortex-A72 CPUs at 3.0 GHz,
+  arranged in a multi-cluster configuration.
 
 * **Added vDPA in vhost-user lib.**
 
-  Added support for selective datapath in vhost-user lib. vDPA stands for vhost
+  Added support for selective datapath in the vhost-user lib. vDPA stands for vhost
   Data Path Acceleration. It supports virtio ring compatible devices to serve
-  virtio driver directly to enable datapath acceleration.
+  the virtio driver directly to enable datapath acceleration.
 
 * **Added IFCVF vDPA driver.**
 
-  Added IFCVF vDPA driver to support Intel FPGA 100G VF device. IFCVF works
+  Added IFCVF vDPA driver to support Intel FPGA 100G VF devices. IFCVF works
   as a HW vhost data path accelerator, it supports live migration and is
-  compatible with virtio 0.95 and 1.0. This driver registers ifcvf vDPA driver
-  to vhost lib, when virtio connected, with the help of the registered vDPA
+  compatible with virtio 0.95 and 1.0. This driver registers the ifcvf vDPA driver
+  to vhost lib, when virtio connects. With the help of the registered vDPA
   driver the assigned VF gets configured to Rx/Tx directly to VM's virtio
   vrings.
 
 * **Added support for vhost dequeue interrupt mode.**
 
-  Added support for vhost dequeue interrupt mode to release cpus to others when
-  no data to transmit. Applications could register an epoll event fd to associate
-  Rx queues with interrupt vectors.
+  Added support for vhost dequeue interrupt mode to release CPUs to others
+  when there is no data to transmit. Applications can register an epoll event
+  file descriptor to associate Rx queues with interrupt vectors.
 
 * **Added support for virtio-user server mode.**
+
   In a container environment if the vhost-user backend restarts, there's no way
   for it to reconnect to virtio-user. To address this, support for server mode
-  is added. In this mode the socket file is created by virtio-user, which the
+  has been added. In this mode the socket file is created by virtio-user, which the
   backend connects to. This means that if the backend restarts, it can reconnect
   to virtio-user and continue communications.
 
 * **Added crypto workload support to vhost library.**
 
-  New APIs are introduced in vhost library to enable virtio crypto support
+  New APIs have been introduced in the vhost library to enable virtio crypto support
   including session creation/deletion handling and translating virtio-crypto
-  request into DPDK crypto operations. A sample application is also introduced.
+  requests into DPDK crypto operations. A sample application has also been introduced.
 
 * **Added virtio crypto PMD.**
 
-  Added a new poll mode driver for virtio crypto devices, which provides
+  Added a new Poll Mode Driver for virtio crypto devices, which provides
   AES-CBC ciphering and AES-CBC with HMAC-SHA1 algorithm-chaining. See the
   :doc:`../cryptodevs/virtio` crypto driver guide for more details on
   this new driver.
@@ -232,9 +235,9 @@ New Features
 
   * AES-CMAC (128-bit key).
 
-* **Added Compressdev Library, a generic compression service library.**
+* **Added the Compressdev Library, a generic compression service library.**
 
-  The compressdev library provides an API for offload of compression and
+  Added the Compressdev library which provides an API for offload of compression and
   decompression operations to hardware or software accelerator devices.
 
 * **Added a new compression poll mode driver using Intels ISA-L.**
@@ -253,36 +256,36 @@ New Features
 * **Added OcteonTx TIM Driver (Event timer adapter).**
 
   The OcteonTx Timer block enables software to schedule events for a future
-  time, it is exposed to an application via Event timer adapter library.
+  time, it is exposed to an application via the Event timer adapter library.
 
   See the :doc:`../eventdevs/octeontx` guide for more details
 
 * **Added Event Crypto Adapter Library.**
 
-    Added the Event Crypto Adapter Library.  This library extends the
-    event-based model by introducing APIs that allow applications to
-    enqueue/dequeue crypto operations to/from cryptodev as events scheduled
-    by an event device.
+  Added the Event Crypto Adapter Library.  This library extends the
+  event-based model by introducing APIs that allow applications to
+  enqueue/dequeue crypto operations to/from cryptodev as events scheduled
+  by an event device.
 
 * **Added Ifpga Bus, a generic Intel FPGA Bus library.**
 
-  The Ifpga Bus library provides support for integrating any Intel FPGA device with
-  the DPDK framework. It provides Intel FPGA Partial Bit Stream AFU (Accelerated
-  Function Unit) scan and drivers probe.
+  Added the Ifpga Bus library which provides support for integrating any Intel
+  FPGA device with the DPDK framework. It provides Intel FPGA Partial Bit
+  Stream AFU (Accelerated Function Unit) scan and drivers probe.
 
 * **Added IFPGA (Intel FPGA) Rawdev Driver.**
 
-  Added a new Rawdev driver called IFPGA(Intel FPGA) Rawdev Driver, which cooperates
-  with OPAE (Open Programmable Acceleration Engine) share code provides common FPGA
+  Added a new Rawdev driver called IFPGA (Intel FPGA) Rawdev Driver, which cooperates
+  with OPAE (Open Programmable Acceleration Engine) shared code to provide common FPGA
   management ops for FPGA operation.
 
   See the :doc:`../rawdevs/ifpga_rawdev` programmer's guide for more details.
 
 * **Added DPAA2 QDMA Driver (in rawdev).**
 
-  The DPAA2 QDMA is an implementation of the rawdev API, that provide means
-  to initiate a DMA transaction from CPU. The initiated DMA is performed
-  without CPU being involved in the actual DMA transaction.
+  The DPAA2 QDMA is an implementation of the rawdev API, that provide a means
+  of initiating a DMA transaction from CPU. The initiated DMA is performed
+  without the CPU being involved in the actual DMA transaction.
 
   See the :doc:`../rawdevs/dpaa2_qdma` guide for more details.
 
@@ -290,8 +293,8 @@ New Features
 
   The DPAA2 CMDIF is an implementation of the rawdev API, that provides
   communication between the GPP and NXP's QorIQ based AIOP Block (Firmware).
-  Advanced IO Processor i.e. AIOP is clusters of programmable RISC engines
-  optimised for flexible networking and I/O operations. The communication
+  Advanced IO Processor i.e. AIOP are clusters of programmable RISC engines
+  optimized for flexible networking and I/O operations. The communication
   between GPP and AIOP is achieved via using DPCI devices exposed by MC for
   GPP <--> AIOP interaction.
 
@@ -299,26 +302,27 @@ New Features
 
 * **Added device event monitor framework.**
 
-  Added a general device event monitor framework at EAL, for device dynamic management.
-  Such as device hotplug awareness and actions adopted accordingly. The list of new APIs:
+  Added a general device event monitor framework to EAL, for device dynamic
+  management to facilitate device hotplug awareness and associated
+  actions. The list of new APIs is:
 
-  * ``rte_dev_event_monitor_start`` and ``rte_dev_event_monitor_stop`` are for
-    the event monitor enable and disable.
+  * ``rte_dev_event_monitor_start`` and ``rte_dev_event_monitor_stop`` for
+    the event monitor enabling and disabling.
   * ``rte_dev_event_callback_register`` and ``rte_dev_event_callback_unregister``
-    are for the user's callbacks register and unregister.
+    for registering and un-registering user callbacks.
 
-  Linux uevent is supported as backend of this device event notification framework.
+  Linux uevent is supported as a backend of this device event notification framework.
 
 * **Added support for procinfo and pdump on eth vdev.**
 
-  For ethernet virtual devices (like tap, pcap, etc), with this feature, we can get
-  stats/xstats on shared memory from secondary process, and also pdump packets on
+  For ethernet virtual devices (like TAP, PCAP, etc.), with this feature, we can get
+  stats/xstats on shared memory from a secondary process, and also pdump packets on
   those virtual devices.
 
-* **Advancement to Packet Framework Library.**
+* **Enhancements to the Packet Framework Library.**
 
   Design and development of new API functions for Packet Framework library that
-  implements common set of actions such as traffic metering, packet
+  implement a common set of actions such as traffic metering, packet
   encapsulation, network address translation, TTL update, etc., for pipeline
   table and input ports to speed up application development. The API functions
   includes creating action profiles, registering actions to the profiles,
@@ -327,10 +331,10 @@ New Features
 * **Added the BPF Library.**
 
   The BPF Library provides the ability to load and execute
-  Enhanced Berkeley Packet Filter (eBPF) within user-space dpdk application.
-  Also it introduces basic framework to load/unload BPF-based filters
-  on eth devices (right now only via SW RX/TX callbacks).
-  It also adds dependency on libelf.
+  Enhanced Berkeley Packet Filters (eBPF) within user-space DPDK applications.
+  It also introduces a basic framework to load/unload BPF-based filters
+  on Eth devices (right now only via SW RX/TX callbacks).
+  It also adds a dependency on libelf.
 
 
 API Changes
@@ -346,28 +350,28 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* service cores: no longer marked as experimental.
+* service cores: Service cores no longer marked as experimental.
 
   The service cores functions are no longer marked as experimental, and have
   become part of the normal DPDK API and ABI. Any future ABI changes will be
   announced at least one release before the ABI change is made. There are no
   ABI breaking changes planned.
 
-* eal: ``rte_lcore_has_role()`` return value changed.
+* eal: The ``rte_lcore_has_role()`` return value changed.
 
   This function now returns true or false, respectively,
-  rather than 0 or <0 for success or failure.
+  rather than 0 or < 0 for success or failure.
   It makes use of the function more intuitive.
 
-* mempool: capability flags and related functions have been removed.
+* mempool: The capability flags and related functions have been removed.
 
   Flags ``MEMPOOL_F_CAPA_PHYS_CONTIG`` and
   ``MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS`` were used by octeontx mempool
-  driver to customize generic mempool library behaviour.
+  driver to customize generic mempool library behavior.
   Now the new driver callbacks ``calc_mem_size`` and ``populate`` may be
   used to achieve it without specific knowledge in the generic code.
 
-* mempool: xmem functions have been deprecated:
+* mempool: The following xmem functions have been deprecated:
 
   - ``rte_mempool_xmem_create``
   - ``rte_mempool_xmem_size``
@@ -387,59 +391,59 @@ API Changes
 
   The packet mbuf API should be used as a replacement.
 
-* meter: updated to accommodate configuration profiles.
+* meter: API updated to accommodate configuration profiles.
 
-  The meter API is changed to support meter configuration profiles. The
+  The meter API has been changed to support meter configuration profiles. The
   configuration profile represents the set of configuration parameters
   for a given meter object, such as the rates and sizes for the token
-  buckets. These configuration parameters were previously the part of meter
-  object internal data strcuture. The separation of the configuration
-  parameters from meter object data structure results in reducing its
-  memory footprint which helps in better cache utilization when large number
+  buckets. These configuration parameters were previously part of the meter
+  object internal data structure. The separation of the configuration
+  parameters from the meter object data structure results in reducing its
+  memory footprint which helps in better cache utilization when a large number
   of meter objects are used.
 
-* ethdev: The function ``rte_eth_dev_count``, often mis-used to iterate
-  over ports, is deprecated and replaced by ``rte_eth_dev_count_avail``.
-  There is also a new function ``rte_eth_dev_count_total`` to get the
+* ethdev: The function ``rte_eth_dev_count()``, often mis-used to iterate
+  over ports, is deprecated and replaced by ``rte_eth_dev_count_avail()``.
+  There is also a new function ``rte_eth_dev_count_total()`` to get the
   total number of allocated ports, available or not.
   The hotplug-proof applications should use ``RTE_ETH_FOREACH_DEV`` or
   ``RTE_ETH_FOREACH_DEV_OWNED_BY`` as port iterators.
 
-* ethdev, in struct ``struct rte_eth_dev_info``, field ``rte_pci_device *pci_dev``
-  replaced with field ``struct rte_device *device``.
+* ethdev: In struct ``struct rte_eth_dev_info``, field ``rte_pci_device *pci_dev``
+  has been replaced with field ``struct rte_device *device``.
 
-* **Changes to semantics of rte_eth_dev_configure() parameters.**
+* Changes to the semantics of ``rte_eth_dev_configure()`` parameters.
 
-   If both the ``nb_rx_q`` and ``nb_tx_q`` parameters are zero,
-   ``rte_eth_dev_configure`` will now use PMD-recommended queue sizes, or if
-   recommendations are not provided by the PMD the function will use ethdev
-   fall-back values. Previously setting both of the parameters to zero would
-   have resulted in ``-EINVAL`` being returned.
+  If both the ``nb_rx_q`` and ``nb_tx_q`` parameters are zero,
+  ``rte_eth_dev_configure()`` will now use PMD-recommended queue sizes, or if
+  recommendations are not provided by the PMD the function will use ethdev
+  fall-back values. Previously setting both of the parameters to zero would
+  have resulted in ``-EINVAL`` being returned.
 
-* **Changes to semantics of rte_eth_rx_queue_setup() parameters.**
+* Changes to the semantics of ``rte_eth_rx_queue_setup()`` parameters.
 
-   If the ``nb_rx_desc`` parameter is zero, ``rte_eth_rx_queue_setup`` will
-   now use the PMD-recommended Rx ring size, or in the case where the PMD
-   does not provide a recommendation, will use an ethdev-provided
-   fall-back value. Previously, setting ``nb_rx_desc`` to zero would have
-   resulted in an error.
+  If the ``nb_rx_desc`` parameter is zero, ``rte_eth_rx_queue_setup`` will
+  now use the PMD-recommended Rx ring size, or in the case where the PMD
+  does not provide a recommendation, will use an ethdev-provided
+  fall-back value. Previously, setting ``nb_rx_desc`` to zero would have
+  resulted in an error.
 
-* **Changes to semantics of rte_eth_tx_queue_setup() parameters.**
+* Changes to the semantics of ``rte_eth_tx_queue_setup()`` parameters.
 
    If the ``nb_tx_desc`` parameter is zero, ``rte_eth_tx_queue_setup`` will
    now use the PMD-recommended Tx ring size, or in the case where the PMD
-   does not provide a recoomendation, will use an ethdev-provided
+   does not provide a recommendation, will use an ethdev-provided
    fall-back value. Previously, setting ``nb_tx_desc`` to zero would have
    resulted in an error.
 
 * ethdev: several changes were made to the flow API.
 
-  * Unused DUP action was removed.
+  * The unused DUP action was removed.
   * Actions semantics in flow rules: list order now matters ("first
     to last" instead of "all simultaneously"), repeated actions are now
     all performed, and they do not individually have (non-)terminating
     properties anymore.
-  * Flow rules are now always terminating unless a PASSTHRU action is
+  * Flow rules are now always terminating unless a ``PASSTHRU`` action is
     present.
   * C99-style flexible arrays were replaced with standard pointers in RSS
     action and in RAW pattern item structures due to compatibility issues.
@@ -458,7 +462,7 @@ API Changes
   * A new transfer attribute was added to ``struct rte_flow_attr`` in order
     to clarify the behavior of some pattern items.
   * PF and VF pattern items are now only accepted by PMDs that implement
-    them (bnxt and i40e) when the transfer attribute is also present for
+    them (bnxt and i40e) when the transfer attribute is also present, for
     consistency.
   * Pattern item PORT was renamed PHY_PORT to avoid confusion with DPDK port
     IDs.
@@ -466,16 +470,17 @@ API Changes
     redirect matching traffic to a specific physical port.
   * PORT_ID pattern item and actions were added to match and target DPDK
     port IDs at a higher level than PHY_PORT.
-  * RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_ENCAP action items were added to support
+  * ``RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_ENCAP`` action items were added to support
     tunnel encapsulation operation for VXLAN and NVGRE type tunnel endpoint.
-  * RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_DECAP action items were added to support
+  * ``RTE_FLOW_ACTION_TYPE_[VXLAN/NVGRE]_DECAP`` action items were added to support
     tunnel decapsulation operation for VXLAN and NVGRE type tunnel endpoint.
-  * RTE_FLOW_ACTION_TYPE_JUMP action item was added to support a matched flow
+  * ``RTE_FLOW_ACTION_TYPE_JUMP`` action item was added to support a matched flow
     to be redirected to the specific group.
-  * RTE_FLOW_ACTION_TYPE_MARK item type has been added to match a flow against
+  * ``RTE_FLOW_ACTION_TYPE_MARK`` item type has been added to match a flow against
     a previously marked flow.
 
 * ethdev: change flow APIs regarding count action:
+
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
@@ -485,14 +490,14 @@ API Changes
    ``rte_eth_[rt]x_queue_setup()``. Now any offloading enabled in ``rte_eth_dev_configure()``
    can't be disabled by ``rte_eth_[rt]x_queue_setup()``. Any new added offloading which has
    not been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled in
-   ``rte_eth_[rt]x_queue_setup()`` must be per-queue type, otherwise trigger an error log.
+   ``rte_eth_[rt]x_queue_setup()`` must be per-queue type, or otherwise trigger an error log.
 
 * ethdev: runtime queue setup:
 
   ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup`` can be called after
-  ``rte_eth_dev_start`` if device support runtime queue setup. Device driver can
-  expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue be
-  setup at runtime need to be started explicitly by ``rte_eth_dev_rx_queue_start``
+  ``rte_eth_dev_start`` if the device supports runtime queue setup. The device driver can
+  expose this capability through ``rte_eth_dev_info_get``. A Rx or Tx queue
+  set up at runtime need to be started explicitly by ``rte_eth_dev_rx_queue_start``
   or ``rte_eth_dev_tx_queue_start``.
 
 
@@ -509,18 +514,18 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* ring: the alignment constraints on the ring structure has been relaxed
+* ring: The alignment constraints on the ring structure has been relaxed
   to one cache line instead of two, and an empty cache line padding is
   added between the producer and consumer structures. The size of the
   structure and the offset of the fields remains the same on platforms
-  with 64B cache line, but change on other platforms.
+  with 64B cache line, but changes on other platforms.
 
-* mempool: ops have changed.
+* mempool: Some Ops have changed.
 
   A new callback ``calc_mem_size`` has been added to ``rte_mempool_ops``
-  to allow to customize required memory size calculation.
+  to allow customization of the required memory size calculation.
   A new callback ``populate`` has been added to ``rte_mempool_ops``
-  to allow to customize objects population.
+  to allow customized object population.
   Callback ``get_capabilities`` has been removed from ``rte_mempool_ops``
   since its features are covered by ``calc_mem_size`` and ``populate``
   callbacks.
@@ -554,9 +559,9 @@ ABI Changes
   ``rte_bbdev_op_cap_turbo_dec`` structure to specify maximal LLR (likelihood
   ratio) absolute value.
 
-* **BBdev Queue Groups split into UL/DL Groups**
+* **BBdev Queue Groups split into UL/DL Groups.**
 
-  Queue Groups have been split into UL/DL Groups in Turbo Software Driver.
+  Queue Groups have been split into UL/DL Groups in the Turbo Software Driver.
   They are independent for Decode/Encode. ``rte_bbdev_driver_info`` reflects
   introduced changes.
 
@@ -591,7 +596,7 @@ Known Issues
 * **Secondary process launch is not reliable.**
 
   Recent memory hotplug patches have made multiprocess startup less reliable
-  than it was in the past. A number of workarounds are known to work depending
+  than it was in past releases. A number of workarounds are known to work depending
   on the circumstances. As such it isn't recommended to use the secondary
   process mechanism for critical systems. The underlying issues will be
   addressed in upcoming releases.
@@ -603,29 +608,30 @@ Known Issues
 
 * **pdump is not compatible with old applications.**
 
-  As we changed to use generic multi-process communication for pdump negotiation
-  instead of previous dedicated unix socket way, pdump applications, including
-  dpdk-pdump example and any other applications using librte_pdump, cannot work
-  with older version DPDK primary applications.
+  As we changed to use generic multi-process communication for pdump
+  negotiation instead of previous dedicated unix socket way, pdump
+  applications, including the dpdk-pdump example and any other applications
+  using ``librte_pdump``, will not work with older version DPDK primary
+  applications.
 
 * **rte_abort takes a long time on FreeBSD.**
 
-  DPDK processes now allocates a large area of virtual memory address space,
-  with this change during rte_abort FreeBSD now dumps the contents of the
+  DPDK processes now allocates a large area of virtual memory address space.
+  As a result ``rte_abort`` on FreeBSD now dumps the contents of the
   whole reserved memory range, not just the used portion, to a core dump file.
-  Write this large core file can take a significant amount of time, causing
-  processes to appear hung on the system.
+  Writing this large core file can take a significant amount of time, causing
+  processes to appear to hang on the system.
 
   The work around for the issue is to set the system resource limits for core
-  dumps before running any tests e.g."limit coredumpsize 0". This will
+  dumps before running any tests, e.g. ``limit coredumpsize 0``. This will
   effectively disable core dumps on FreeBSD. If they are not to be completely
   disabled, a suitable limit, e.g. 1G might be specified instead of 0. This
   needs to be run per-shell session, or before every test run. This change
-  can also be made persistent by adding "kern.coredump=0" to /etc/sysctl.conf
+  can also be made persistent by adding ``kern.coredump=0`` to ``/etc/sysctl.conf``.
 
   Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=53
 
-* **Bonding PMD may fail to accept new slaves in certain conditions.**
+* **Bonding PMD may fail to accept new slaves ports in certain conditions.**
 
   In certain conditions when using testpmd,
   bonding may fail to register new slave ports.
-- 
2.7.5

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v1] doc: update release notes for 18.05
  2018-05-30 20:25  7% [dpdk-dev] [PATCH v1] doc: update release notes for 18.05 John McNamara
@ 2018-05-30 20:54 12% ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-05-30 20:54 UTC (permalink / raw)
  To: John McNamara; +Cc: dev

30/05/2018 22:25, John McNamara:
> Fix grammar, spelling and formatting of DPDK 18.05 release notes.
> 
> Signed-off-by: John McNamara <john.mcnamara@intel.com>

Applied with few more changes below, thanks.

--- b/doc/guides/rel_notes/release_18_05.rst
+++ a/doc/guides/rel_notes/release_18_05.rst
@@ -350,7 +350,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* service cores: Service cores no longer marked as experimental.
+* service cores: No longer marked as experimental.
 
   The service cores functions are no longer marked as experimental, and have
   become part of the normal DPDK API and ABI. Any future ABI changes will be
@@ -412,7 +412,7 @@ API Changes
 * ethdev: In struct ``struct rte_eth_dev_info``, field ``rte_pci_device *pci_dev``
   has been replaced with field ``struct rte_device *device``.
 
-* Changes to the semantics of ``rte_eth_dev_configure()`` parameters.
+* ethdev: Changes to the semantics of ``rte_eth_dev_configure()`` parameters.
 
   If both the ``nb_rx_q`` and ``nb_tx_q`` parameters are zero,
   ``rte_eth_dev_configure()`` will now use PMD-recommended queue sizes, or if
@@ -420,7 +420,7 @@ API Changes
   fall-back values. Previously setting both of the parameters to zero would
   have resulted in ``-EINVAL`` being returned.
 
-* Changes to the semantics of ``rte_eth_rx_queue_setup()`` parameters.
+* ethdev: Changes to the semantics of ``rte_eth_rx_queue_setup()`` parameters.
 
   If the ``nb_rx_desc`` parameter is zero, ``rte_eth_rx_queue_setup`` will
   now use the PMD-recommended Rx ring size, or in the case where the PMD
@@ -428,7 +428,7 @@ API Changes
   fall-back value. Previously, setting ``nb_rx_desc`` to zero would have
   resulted in an error.
 
-* Changes to the semantics of ``rte_eth_tx_queue_setup()`` parameters.
+* ethdev: Changes to the semantics of ``rte_eth_tx_queue_setup()`` parameters.
 
    If the ``nb_tx_desc`` parameter is zero, ``rte_eth_tx_queue_setup`` will
    now use the PMD-recommended Tx ring size, or in the case where the PMD
@@ -436,7 +436,7 @@ API Changes
    fall-back value. Previously, setting ``nb_tx_desc`` to zero would have
    resulted in an error.
 
-* ethdev: several changes were made to the flow API.
+* ethdev: Several changes were made to the flow API.
 
   * The unused DUP action was removed.
   * Actions semantics in flow rules: list order now matters ("first
@@ -479,12 +479,12 @@ API Changes
   * ``RTE_FLOW_ACTION_TYPE_MARK`` item type has been added to match a flow against
     a previously marked flow.
 
-* ethdev: change flow APIs regarding count action:
+* ethdev: Change flow APIs regarding count action:
 
   * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
   * ``rte_flow_query()`` API parameter changed from action type to action structure.
 
-* ethdev: changes to offload API
+* ethdev: Changes to offload API
 
    A pure per-port offloading isn't requested to be repeated in [rt]x_conf->offloads to
    ``rte_eth_[rt]x_queue_setup()``. Now any offloading enabled in ``rte_eth_dev_configure()``
@@ -492,7 +492,7 @@ API Changes
    not been enabled in ``rte_eth_dev_configure()`` and is requested to be enabled in
    ``rte_eth_[rt]x_queue_setup()`` must be per-queue type, or otherwise trigger an error log.
 
-* ethdev: runtime queue setup:
+* ethdev: Runtime queue setup
 
   ``rte_eth_rx_queue_setup`` and ``rte_eth_tx_queue_setup`` can be called after
   ``rte_eth_dev_start`` if the device supports runtime queue setup. The device driver can
@@ -520,7 +520,7 @@ ABI Changes
   structure and the offset of the fields remains the same on platforms
   with 64B cache line, but changes on other platforms.
 
-* mempool: Some Ops have changed.
+* mempool: Some ops have changed.
 
   A new callback ``calc_mem_size`` has been added to ``rte_mempool_ops``
   to allow customization of the required memory size calculation.
@@ -532,7 +532,7 @@ ABI Changes
   Callback ``register_memory_area`` has been removed from ``rte_mempool_ops``
   since the new callback ``populate`` may be used instead of it.
 
-* **Additional fields in rte_eth_dev_info.**
+* ethdev: Additional fields in rte_eth_dev_info.
 
   The ``rte_eth_dev_info`` structure has had two extra entries appended to the
   end of it: ``default_rxportconf`` and ``default_txportconf``. Each of these
@@ -553,32 +553,19 @@ ABI Changes
   sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``) and
   new transfer attribute (``struct rte_flow_attr``).
 
-**New parameter added to rte_bbdev_op_cap_turbo_dec.**
+* bbdev: New parameter added to rte_bbdev_op_cap_turbo_dec.
 
   A new parameter ``max_llr_modulus`` has been added to
   ``rte_bbdev_op_cap_turbo_dec`` structure to specify maximal LLR (likelihood
   ratio) absolute value.
 
-* **BBdev Queue Groups split into UL/DL Groups.**
+* bbdev: Queue Groups split into UL/DL Groups.
 
   Queue Groups have been split into UL/DL Groups in the Turbo Software Driver.
   They are independent for Decode/Encode. ``rte_bbdev_driver_info`` reflects
   introduced changes.
 
 
-Removed Items
--------------
-
-.. This section should contain removed items in this release. Sample format:
-
-   * Add a short 1-2 sentence description of the removed item in the past
-     tense.
-
-   This section is a comment. Do not overwrite or remove it.
-   Also, make sure to start the actual text at the margin.
-   =========================================================
-
-
 Known Issues
 ------------
 

^ permalink raw reply	[relevance 12%]

* Re: [dpdk-dev] Compilation of MLX5 driver
  @ 2018-05-31  7:01  4%       ` Nitin Katiyar
  2018-05-31  8:05  0%         ` Nélio Laranjeiro
  0 siblings, 1 reply; 200+ results
From: Nitin Katiyar @ 2018-05-31  7:01 UTC (permalink / raw)
  To: Shahaf Shuler, Nélio Laranjeiro; +Cc: dev

Hi,
It has following files:

arch.h  ib.h  kern-abi.h  mlx4dv.h  mlx5dv.h  opcode.h  sa.h  sa-kern-abi.h  verbs.h

I tried with both MLNX_OFED_LINUX-4.2-1.0.0.0 and MLNX_OFED_LINUX-4.2-1.2.0.0-ubuntu14.04-x86_64

Regards,
Nitin

-----Original Message-----
From: Shahaf Shuler [mailto:shahafs@mellanox.com] 
Sent: Thursday, May 31, 2018 10:51 AM
To: Nitin Katiyar <nitin.katiyar@ericsson.com>; Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: dev@dpdk.org
Subject: RE: [dpdk-dev] Compilation of MLX5 driver

Wednesday, May 30, 2018 7:45 PM, Nitin Katiyar:
> 
> Hi,
> I was compiling 17.05.02.
> Regards,
> Nitin
> 
> -----Original Message-----
> From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> Sent: Wednesday, May 30, 2018 6:42 PM
> To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> 
> Hi,
> 
> On Wed, May 30, 2018 at 11:54:31AM +0000, Nitin Katiyar wrote:
> > Hi,
> > I am trying to compile MLX5 PMD driver by setting
> "CONFIG_RTE_LIBRTE_MLX5_PMD=y" and hitting following compilation 
> error.
> >
> > fatal error: infiniband/mlx5_hw.h: No such file or directory

Can you list the files you have under /usr/include/infiniband ? 

> >
> > I have installed MLNX_OFED _LINUX-4.2-1.2.0 on my Ubuntu 14.04 
> > machine
> but still hitting the same error. Am I missing some other package?
> 
> Which version of DPDK are you using (it is important to help)?
> 
> Regards,
> 
> --
> Nélio Laranjeiro
> 6WIND

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] Compilation of MLX5 driver
  2018-05-31  7:01  4%       ` Nitin Katiyar
@ 2018-05-31  8:05  0%         ` Nélio Laranjeiro
  2018-05-31  9:14  0%           ` Nitin Katiyar
  0 siblings, 1 reply; 200+ results
From: Nélio Laranjeiro @ 2018-05-31  8:05 UTC (permalink / raw)
  To: Nitin Katiyar; +Cc: Shahaf Shuler, dev

On Thu, May 31, 2018 at 07:01:17AM +0000, Nitin Katiyar wrote:
> Hi,
> It has following files:
> 
> arch.h  ib.h  kern-abi.h  mlx4dv.h  mlx5dv.h  opcode.h  sa.h
> sa-kern-abi.h  verbs.h
> 
> I tried with both MLNX_OFED_LINUX-4.2-1.0.0.0 and
> MLNX_OFED_LINUX-4.2-1.2.0.0-ubuntu14.04-x86_64

Did you installed Mellanox OFED with the --dpdk --upstream-libs
arguments for the installation script?

If it is the case, you should not add them for this version, those
options are for DPDK v17.11 and higher.

Regards,

> Regards,
> Nitin
> 
> -----Original Message-----
> From: Shahaf Shuler [mailto:shahafs@mellanox.com] 
> Sent: Thursday, May 31, 2018 10:51 AM
> To: Nitin Katiyar <nitin.katiyar@ericsson.com>; Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] Compilation of MLX5 driver
> 
> Wednesday, May 30, 2018 7:45 PM, Nitin Katiyar:
> > 
> > Hi,
> > I was compiling 17.05.02.
> > Regards,
> > Nitin
> > 
> > -----Original Message-----
> > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > Sent: Wednesday, May 30, 2018 6:42 PM
> > To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> > 
> > Hi,
> > 
> > On Wed, May 30, 2018 at 11:54:31AM +0000, Nitin Katiyar wrote:
> > > Hi,
> > > I am trying to compile MLX5 PMD driver by setting
> > "CONFIG_RTE_LIBRTE_MLX5_PMD=y" and hitting following compilation 
> > error.
> > >
> > > fatal error: infiniband/mlx5_hw.h: No such file or directory
> 
> Can you list the files you have under /usr/include/infiniband ? 
> 
> > >
> > > I have installed MLNX_OFED _LINUX-4.2-1.2.0 on my Ubuntu 14.04 
> > > machine
> > but still hitting the same error. Am I missing some other package?
> > 
> > Which version of DPDK are you using (it is important to help)?
> > 
> > Regards,
> > 
> > --
> > Nélio Laranjeiro
> > 6WIND

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] Compilation of MLX5 driver
  2018-05-31  8:05  0%         ` Nélio Laranjeiro
@ 2018-05-31  9:14  0%           ` Nitin Katiyar
  2018-05-31  9:53  0%             ` Nélio Laranjeiro
  0 siblings, 1 reply; 200+ results
From: Nitin Katiyar @ 2018-05-31  9:14 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: Shahaf Shuler, dev

Yes,I installed it using --dpdk --upstream-libs. What is the way forward now?

Regards,
Nitin

-----Original Message-----
From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com] 
Sent: Thursday, May 31, 2018 1:36 PM
To: Nitin Katiyar <nitin.katiyar@ericsson.com>
Cc: Shahaf Shuler <shahafs@mellanox.com>; dev@dpdk.org
Subject: Re: [dpdk-dev] Compilation of MLX5 driver

On Thu, May 31, 2018 at 07:01:17AM +0000, Nitin Katiyar wrote:
> Hi,
> It has following files:
> 
> arch.h  ib.h  kern-abi.h  mlx4dv.h  mlx5dv.h  opcode.h  sa.h 
> sa-kern-abi.h  verbs.h
> 
> I tried with both MLNX_OFED_LINUX-4.2-1.0.0.0 and
> MLNX_OFED_LINUX-4.2-1.2.0.0-ubuntu14.04-x86_64

Did you installed Mellanox OFED with the --dpdk --upstream-libs arguments for the installation script?

If it is the case, you should not add them for this version, those options are for DPDK v17.11 and higher.

Regards,

> Regards,
> Nitin
> 
> -----Original Message-----
> From: Shahaf Shuler [mailto:shahafs@mellanox.com]
> Sent: Thursday, May 31, 2018 10:51 AM
> To: Nitin Katiyar <nitin.katiyar@ericsson.com>; Nélio Laranjeiro 
> <nelio.laranjeiro@6wind.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] Compilation of MLX5 driver
> 
> Wednesday, May 30, 2018 7:45 PM, Nitin Katiyar:
> > 
> > Hi,
> > I was compiling 17.05.02.
> > Regards,
> > Nitin
> > 
> > -----Original Message-----
> > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > Sent: Wednesday, May 30, 2018 6:42 PM
> > To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> > 
> > Hi,
> > 
> > On Wed, May 30, 2018 at 11:54:31AM +0000, Nitin Katiyar wrote:
> > > Hi,
> > > I am trying to compile MLX5 PMD driver by setting
> > "CONFIG_RTE_LIBRTE_MLX5_PMD=y" and hitting following compilation 
> > error.
> > >
> > > fatal error: infiniband/mlx5_hw.h: No such file or directory
> 
> Can you list the files you have under /usr/include/infiniband ? 
> 
> > >
> > > I have installed MLNX_OFED _LINUX-4.2-1.2.0 on my Ubuntu 14.04 
> > > machine
> > but still hitting the same error. Am I missing some other package?
> > 
> > Which version of DPDK are you using (it is important to help)?
> > 
> > Regards,
> > 
> > --
> > Nélio Laranjeiro
> > 6WIND

--
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] Compilation of MLX5 driver
  2018-05-31  9:14  0%           ` Nitin Katiyar
@ 2018-05-31  9:53  0%             ` Nélio Laranjeiro
  2018-05-31 11:44  0%               ` Nitin Katiyar
  0 siblings, 1 reply; 200+ results
From: Nélio Laranjeiro @ 2018-05-31  9:53 UTC (permalink / raw)
  To: Nitin Katiyar; +Cc: Shahaf Shuler, dev

On Thu, May 31, 2018 at 09:14:03AM +0000, Nitin Katiyar wrote:
> Yes,I installed it using --dpdk --upstream-libs. What is the way
> forward now?

In v17.05 MLX5 PMD is still relying on libibverbs and libmlx5, the way
Those options you used are necessary to select in their package the
installation of libverbs,libmlx5 or rdma-core.
Doing this you have selected rdma-core which is not supported in v17.05
DPDK version.

You need to install Mellanox OFED without those two options to select
libibverbs, libmlx5 to make it work.

Regards,
 
> Regards,
> Nitin
> 
> -----Original Message-----
> From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com] 
> Sent: Thursday, May 31, 2018 1:36 PM
> To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> Cc: Shahaf Shuler <shahafs@mellanox.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> 
> On Thu, May 31, 2018 at 07:01:17AM +0000, Nitin Katiyar wrote:
> > Hi,
> > It has following files:
> > 
> > arch.h  ib.h  kern-abi.h  mlx4dv.h  mlx5dv.h  opcode.h  sa.h 
> > sa-kern-abi.h  verbs.h
> > 
> > I tried with both MLNX_OFED_LINUX-4.2-1.0.0.0 and
> > MLNX_OFED_LINUX-4.2-1.2.0.0-ubuntu14.04-x86_64
> 
> Did you installed Mellanox OFED with the --dpdk --upstream-libs arguments for the installation script?
> 
> If it is the case, you should not add them for this version, those options are for DPDK v17.11 and higher.
> 
> Regards,
> 
> > Regards,
> > Nitin
> > 
> > -----Original Message-----
> > From: Shahaf Shuler [mailto:shahafs@mellanox.com]
> > Sent: Thursday, May 31, 2018 10:51 AM
> > To: Nitin Katiyar <nitin.katiyar@ericsson.com>; Nélio Laranjeiro 
> > <nelio.laranjeiro@6wind.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] Compilation of MLX5 driver
> > 
> > Wednesday, May 30, 2018 7:45 PM, Nitin Katiyar:
> > > 
> > > Hi,
> > > I was compiling 17.05.02.
> > > Regards,
> > > Nitin
> > > 
> > > -----Original Message-----
> > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > Sent: Wednesday, May 30, 2018 6:42 PM
> > > To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> > > 
> > > Hi,
> > > 
> > > On Wed, May 30, 2018 at 11:54:31AM +0000, Nitin Katiyar wrote:
> > > > Hi,
> > > > I am trying to compile MLX5 PMD driver by setting
> > > "CONFIG_RTE_LIBRTE_MLX5_PMD=y" and hitting following compilation 
> > > error.
> > > >
> > > > fatal error: infiniband/mlx5_hw.h: No such file or directory
> > 
> > Can you list the files you have under /usr/include/infiniband ? 
> > 
> > > >
> > > > I have installed MLNX_OFED _LINUX-4.2-1.2.0 on my Ubuntu 14.04 
> > > > machine
> > > but still hitting the same error. Am I missing some other package?
> > > 
> > > Which version of DPDK are you using (it is important to help)?
> > > 
> > > Regards,
> > > 
> > > --
> > > Nélio Laranjeiro
> > > 6WIND
> 
> --
> Nélio Laranjeiro
> 6WIND

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [RFC 0/3] Make device mapping more reliable
@ 2018-05-31 10:57  3% Anatoly Burakov
  0 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-05-31 10:57 UTC (permalink / raw)
  To: dev
  Cc: thomas, hemant.agrawal, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerin.jacob, olivier.matz, stephen, nhorman,
	david.marchand, gowrishankar.m

Currently, memory for device maps is allocated ad-hoc, by calculating
end of VA space allocated for hugepages and crossing fingers in hopes that
those addresses will be free in primary and secondary processes. This leads
to situations such as this:

EAL: Detected 88 lcore(s)
EAL: Detected 2 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket_178323_8af2229603de4
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: PCI device 0000:81:00.0 on NUMA socket 1
EAL:   probe driver: 8086:1563 net_ixgbe
EAL: Cannot mmap device resource file /sys/bus/pci/devices/0000:81:00.0/resource0 to address: 0x7ff7f5800000
EAL: Requested device 0000:81:00.0 cannot be used
EAL: Error - exiting with code: 1
  Cause: No Ethernet ports - bye

As can be seen from the above log, secondary process has initialized
successfully, but device BAR mapping has failed, which resulted in missing ports
in the secondary process.

This patchset is an attempt to fix this problem once and for all, by using
the same method we use for memory to do device mappings as well. That is,
by preallocating all of the device memory in advance, so that initialization
either succeeds and allows for device mappings, or it fails outright (whereas
currently we may be in an in-between kind of situation, where init has
succeeded but device mappings have failed).

This change breaks the ABI, so it is not for this release. However, i'd like
to hear feedback on the approach and whether there are potential problems with
other buses/use cases that i didn't think of.

Anatoly Burakov (3):
  fbarray: allow zero-sized elements
  mem: add device memory reserve/free API
  bus/pci: use the new device memory API for BAR mapping

 drivers/bus/pci/linux/pci_init.h              |   1 -
 drivers/bus/pci/linux/pci_uio.c               |  11 +-
 drivers/bus/pci/linux/pci_vfio.c              |  27 +-
 lib/librte_eal/common/eal_common_fbarray.c    |  10 +-
 lib/librte_eal/common/eal_common_memory.c     | 270 ++++++++++++++++--
 .../common/include/rte_eal_memconfig.h        |  18 ++
 lib/librte_eal/common/include/rte_memory.h    |  40 +++
 lib/librte_pci/Makefile                       |   1 +
 lib/librte_pci/rte_pci.c                      |  20 +-
 9 files changed, 350 insertions(+), 48 deletions(-)

-- 
2.17.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] Compilation of MLX5 driver
  2018-05-31  9:53  0%             ` Nélio Laranjeiro
@ 2018-05-31 11:44  0%               ` Nitin Katiyar
  0 siblings, 0 replies; 200+ results
From: Nitin Katiyar @ 2018-05-31 11:44 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: Shahaf Shuler, dev

Thanks Shahaf, it worked after removing the options you specified.

Regards,
Nitin

-----Original Message-----
From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com] 
Sent: Thursday, May 31, 2018 3:23 PM
To: Nitin Katiyar <nitin.katiyar@ericsson.com>
Cc: Shahaf Shuler <shahafs@mellanox.com>; dev@dpdk.org
Subject: Re: [dpdk-dev] Compilation of MLX5 driver

On Thu, May 31, 2018 at 09:14:03AM +0000, Nitin Katiyar wrote:
> Yes,I installed it using --dpdk --upstream-libs. What is the way 
> forward now?

In v17.05 MLX5 PMD is still relying on libibverbs and libmlx5, the way Those options you used are necessary to select in their package the installation of libverbs,libmlx5 or rdma-core.
Doing this you have selected rdma-core which is not supported in v17.05 DPDK version.

You need to install Mellanox OFED without those two options to select libibverbs, libmlx5 to make it work.

Regards,
 
> Regards,
> Nitin
> 
> -----Original Message-----
> From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> Sent: Thursday, May 31, 2018 1:36 PM
> To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> Cc: Shahaf Shuler <shahafs@mellanox.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> 
> On Thu, May 31, 2018 at 07:01:17AM +0000, Nitin Katiyar wrote:
> > Hi,
> > It has following files:
> > 
> > arch.h  ib.h  kern-abi.h  mlx4dv.h  mlx5dv.h  opcode.h  sa.h 
> > sa-kern-abi.h  verbs.h
> > 
> > I tried with both MLNX_OFED_LINUX-4.2-1.0.0.0 and
> > MLNX_OFED_LINUX-4.2-1.2.0.0-ubuntu14.04-x86_64
> 
> Did you installed Mellanox OFED with the --dpdk --upstream-libs arguments for the installation script?
> 
> If it is the case, you should not add them for this version, those options are for DPDK v17.11 and higher.
> 
> Regards,
> 
> > Regards,
> > Nitin
> > 
> > -----Original Message-----
> > From: Shahaf Shuler [mailto:shahafs@mellanox.com]
> > Sent: Thursday, May 31, 2018 10:51 AM
> > To: Nitin Katiyar <nitin.katiyar@ericsson.com>; Nélio Laranjeiro 
> > <nelio.laranjeiro@6wind.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] Compilation of MLX5 driver
> > 
> > Wednesday, May 30, 2018 7:45 PM, Nitin Katiyar:
> > > 
> > > Hi,
> > > I was compiling 17.05.02.
> > > Regards,
> > > Nitin
> > > 
> > > -----Original Message-----
> > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > Sent: Wednesday, May 30, 2018 6:42 PM
> > > To: Nitin Katiyar <nitin.katiyar@ericsson.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] Compilation of MLX5 driver
> > > 
> > > Hi,
> > > 
> > > On Wed, May 30, 2018 at 11:54:31AM +0000, Nitin Katiyar wrote:
> > > > Hi,
> > > > I am trying to compile MLX5 PMD driver by setting
> > > "CONFIG_RTE_LIBRTE_MLX5_PMD=y" and hitting following compilation 
> > > error.
> > > >
> > > > fatal error: infiniband/mlx5_hw.h: No such file or directory
> > 
> > Can you list the files you have under /usr/include/infiniband ? 
> > 
> > > >
> > > > I have installed MLNX_OFED _LINUX-4.2-1.2.0 on my Ubuntu 14.04 
> > > > machine
> > > but still hitting the same error. Am I missing some other package?
> > > 
> > > Which version of DPDK are you using (it is important to help)?
> > > 
> > > Regards,
> > > 
> > > --
> > > Nélio Laranjeiro
> > > 6WIND
> 
> --
> Nélio Laranjeiro
> 6WIND

--
Nélio Laranjeiro
6WIND

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] eal: move runtime config file to new location
@ 2018-05-31 15:35  5% Anatoly Burakov
  0 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-05-31 15:35 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, John McNamara, Marko Kovacevic, thomas,
	bruce.richardson, harry.van.haaren

As per deprecation notice [1], move DPDK runtime config to default
DPDK runtime data location. Also, remove the deprecation notice.

[1] http://dpdk.org/dev/patchwork/patch/40418/

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   | 10 ----------
 lib/librte_eal/common/eal_filesystem.h | 10 +++-------
 2 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692eac..ff15baa3f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,16 +8,6 @@ API and ABI deprecation notices are to be posted here.
 Deprecation Notices
 -------------------
 
-* eal: DPDK runtime configuration file (located at
-  ``/var/run/.<prefix>_config``) will be moved. The new path will be as follows:
-
-  - if DPDK is running as root, path will be set to
-    ``/var/run/dpdk/<prefix>/config``
-  - if DPDK is not running as root and $XDG_RUNTIME_DIR is set, path will be set
-    to ``$XDG_RUNTIME_DIR/dpdk/<prefix>/config``
-  - if DPDK is not running as root and $XDG_RUNTIME_DIR is not set, path will be
-    set to ``/tmp/dpdk/<prefix>/config``
-
 * eal: both declaring and identifying devices will be streamlined in v18.08.
   New functions will appear to query a specific port from buses, classes of
   device and device drivers. Device declaration will be made coherent with the
diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
index 364f38d13..de05febf4 100644
--- a/lib/librte_eal/common/eal_filesystem.h
+++ b/lib/librte_eal/common/eal_filesystem.h
@@ -12,7 +12,6 @@
 #define EAL_FILESYSTEM_H
 
 /** Path of rte config file. */
-#define RUNTIME_CONFIG_FMT "%s/.%s_config"
 
 #include <stdint.h>
 #include <limits.h>
@@ -30,17 +29,14 @@ eal_create_runtime_dir(void);
 const char *
 eal_get_runtime_dir(void);
 
+#define RUNTIME_CONFIG_FNAME "config"
 static inline const char *
 eal_runtime_config_path(void)
 {
 	static char buffer[PATH_MAX]; /* static so auto-zeroed */
-	const char *directory = "/var/run";
-	const char *home_dir = getenv("HOME");
 
-	if (getuid() != 0 && home_dir != NULL)
-		directory = home_dir;
-	snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT, directory,
-			internal_config.hugefile_prefix);
+	snprintf(buffer, sizeof(buffer) - 1, "%s/%s", eal_get_runtime_dir(),
+			RUNTIME_CONFIG_FNAME);
 	return buffer;
 }
 
-- 
2.17.0

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH] doc: add template release notes for 18.08
@ 2018-05-31 21:11  6% Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-05-31 21:11 UTC (permalink / raw)
  To: dev; +Cc: john.mcnamara, marko.kovacevic

Add template release notes for DPDK 18.08 with inline
comments and explanations of the various sections.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_18_08.rst | 192 +++++++++++++++++++++++++
 2 files changed, 193 insertions(+)
 create mode 100644 doc/guides/rel_notes/release_18_08.rst

diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index eb82a0e06..d125342c3 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -9,6 +9,7 @@ Release Notes
     :numbered:
 
     rel_description
+    release_18_08
     release_18_05
     release_18_02
     release_17_11
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
new file mode 100644
index 000000000..5bc23c537
--- /dev/null
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -0,0 +1,192 @@
+DPDK Release 18.08
+==================
+
+.. **Read this first.**
+
+   The text in the sections below explains how to update the release notes.
+
+   Use proper spelling, capitalization and punctuation in all sections.
+
+   Variable and config names should be quoted as fixed width text:
+   ``LIKE_THIS``.
+
+   Build the docs and view the output file to ensure the changes are correct::
+
+      make doc-guides-html
+
+      xdg-open build/doc/html/guides/rel_notes/release_18_08.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+   Sample format:
+
+   * **Add a title in the past tense with a full stop.**
+
+     Add a short 1-2 sentence description in the past tense.
+     The description should be enough to allow someone scanning
+     the release notes to understand the new feature.
+
+     If the feature adds a lot of sub-features you can use a bullet list
+     like this:
+
+     * Added feature foo to do something.
+     * Enhanced feature bar to do something else.
+
+     Refer to the previous release notes for examples.
+
+     This section is a comment. Do not overwrite or remove it.
+     Also, make sure to start the actual text at the margin.
+     =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+   * Add a short 1-2 sentence description of the API change.
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+   * Add a short 1-2 sentence description of the ABI change
+     that was announced in the previous releases and made in this release.
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item
+     in the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+   and prepend with a ``+`` sign, like this:
+
+     librte_acl.so.2
+   + librte_cfgfile.so.2
+     librte_cmdline.so.2
+
+   This section is a comment. Do not overwrite or remove it.
+   =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     librte_acl.so.2
+     librte_bbdev.so.1
+     librte_bitratestats.so.2
+     librte_bpf.so.1
+     librte_bus_dpaa.so.1
+     librte_bus_fslmc.so.1
+     librte_bus_pci.so.1
+     librte_bus_vdev.so.1
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_common_octeontx.so.1
+     librte_compressdev.so.1
+     librte_cryptodev.so.4
+     librte_distributor.so.1
+     librte_eal.so.7
+     librte_ethdev.so.9
+     librte_eventdev.so.4
+     librte_flow_classify.so.1
+     librte_gro.so.1
+     librte_gso.so.1
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_latencystats.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.4
+     librte_mempool.so.4
+     librte_meter.so.2
+     librte_metrics.so.1
+     librte_net.so.1
+     librte_pci.so.1
+     librte_pdump.so.2
+     librte_pipeline.so.3
+     librte_pmd_bnxt.so.2
+     librte_pmd_bond.so.2
+     librte_pmd_i40e.so.2
+     librte_pmd_ixgbe.so.2
+     librte_pmd_dpaa2_cmdif.so.1
+     librte_pmd_dpaa2_qdma.so.1
+     librte_pmd_ring.so.2
+     librte_pmd_softnic.so.1
+     librte_pmd_vhost.so.2
+     librte_port.so.3
+     librte_power.so.1
+     librte_rawdev.so.1
+     librte_reorder.so.1
+     librte_ring.so.2
+     librte_sched.so.1
+     librte_security.so.1
+     librte_table.so.3
+     librte_timer.so.1
+     librte_vhost.so.3
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+   * **Add title in present tense with full stop.**
+
+     Add a short 1-2 sentence description of the known issue
+     in the present tense. Add information on any known workarounds.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+   with this release.
+
+   The format is:
+
+   * <vendor> platform with <vendor> <type of devices> combinations
+
+     * List of CPU
+     * List of OS
+     * List of devices
+     * Other relevant details...
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
-- 
2.17.1

^ permalink raw reply	[relevance 6%]

* [dpdk-dev] [PATCH 8/9] doc: add deprecation notice for EAL command line options
  @ 2018-06-01 17:15  5% ` Anatoly Burakov
  0 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-06-01 17:15 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, John McNamara, Marko Kovacevic, ray.kinsella,
	kuralamudhan.ramakrishnan, louise.m.daly, bruce.richardson,
	ferruh.yigit, konstantin.ananyev, thomas

Options --no-shconf and --huge-unlink will be removed, and
replaced with --in-memory option, which will be a superset
of these two, and an offially support method to run DPDK
entirely in memory.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---

Notes:
    RFC->v1:
    - Add this patch

 doc/guides/rel_notes/deprecation.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692eac..c8344f42f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,11 @@ API and ABI deprecation notices are to be posted here.
 Deprecation Notices
 -------------------
 
+* eal: command-line options ``--no-shconf`` and ``--huge-unlink`` will be
+    removed, and replaced with a single option ``--in-memory``, which will
+    enable DPDK to operate entirely in memory, without creating any files on any
+    filesystems.
+
 * eal: DPDK runtime configuration file (located at
   ``/var/run/.<prefix>_config``) will be moved. The new path will be as follows:
 
-- 
2.17.0

^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH] doc: add SPDX and copyright to rel notes
  @ 2018-06-05  7:50  4% ` Hemant Agrawal
  2018-06-05  7:50  4% ` [dpdk-dev] [PATCH] doc: add SPDX and copyright to contributing guide Hemant Agrawal
  1 sibling, 0 replies; 200+ results
From: Hemant Agrawal @ 2018-06-05  7:50 UTC (permalink / raw)
  To: dev; +Cc: thomas, john.mcnamara

using "The DPDK Contributors" as decided by techboard.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst   | 3 +++
 doc/guides/rel_notes/release_16_04.rst | 3 +++
 doc/guides/rel_notes/release_16_07.rst | 3 +++
 doc/guides/rel_notes/release_16_11.rst | 3 +++
 doc/guides/rel_notes/release_17_02.rst | 3 +++
 doc/guides/rel_notes/release_17_05.rst | 3 +++
 doc/guides/rel_notes/release_17_08.rst | 3 +++
 doc/guides/rel_notes/release_17_11.rst | 3 +++
 doc/guides/rel_notes/release_18_02.rst | 3 +++
 doc/guides/rel_notes/release_18_05.rst | 3 +++
 doc/guides/rel_notes/release_18_08.rst | 3 +++
 doc/guides/rel_notes/release_2_2.rst   | 2 ++
 12 files changed, 35 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692e..2f46b45 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 ABI and API Deprecation
 =======================
 
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index d0a09ef..e9f1e6f 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2016 The DPDK contributors
+
 DPDK Release 16.04
 ==================
 
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index a8a3fc1..2904aac 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2016 The DPDK contributors
+
 DPDK Release 16.07
 ==================
 
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index 8c9ec65..92e0ec6 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2016 The DPDK contributors
+
 DPDK Release 16.11
 ==================
 
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 357965a..d6c1c56 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2017 The DPDK contributors
+
 DPDK Release 17.02
 ==================
 
diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 6892284..6418240 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2017 The DPDK contributors
+
 DPDK Release 17.05
 ==================
 
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 0bcdfb7..dc62240 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2017 The DPDK contributors
+
 DPDK Release 17.08
 ==================
 
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 5176d69..2a93af3 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2017 The DPDK contributors
+
 DPDK Release 17.11
 ==================
 
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 44b7de5..8e40311 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 DPDK Release 18.02
 ==================
 
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 6b36493..8dc22b0 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 DPDK Release 18.05
 ==================
 
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 5bc23c5..cee2121 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 DPDK Release 18.08
 ==================
 
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index bb7d15a..b8c750b 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -1,3 +1,5 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
 DPDK Release 2.2
 ================
 
-- 
2.7.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] doc: add SPDX and copyright to contributing guide
    2018-06-05  7:50  4% ` [dpdk-dev] [PATCH] doc: add SPDX and copyright to rel notes Hemant Agrawal
@ 2018-06-05  7:50  4% ` Hemant Agrawal
  1 sibling, 0 replies; 200+ results
From: Hemant Agrawal @ 2018-06-05  7:50 UTC (permalink / raw)
  To: dev; +Cc: thomas, john.mcnamara

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/contributing/cheatsheet.rst    | 3 +++
 doc/guides/contributing/coding_style.rst  | 3 +++
 doc/guides/contributing/design.rst        | 3 +++
 doc/guides/contributing/documentation.rst | 3 +++
 doc/guides/contributing/index.rst         | 3 +++
 doc/guides/contributing/patches.rst       | 3 +++
 doc/guides/contributing/stable.rst        | 3 +++
 doc/guides/contributing/versioning.rst    | 3 +++
 8 files changed, 24 insertions(+)

diff --git a/doc/guides/contributing/cheatsheet.rst b/doc/guides/contributing/cheatsheet.rst
index 7bc0771..0debd11 100644
--- a/doc/guides/contributing/cheatsheet.rst
+++ b/doc/guides/contributing/cheatsheet.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 Patch Cheatsheet
 ================
 
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index 2587605..b1bf0d1 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 .. _coding_style:
 
 DPDK Coding Style
diff --git a/doc/guides/contributing/design.rst b/doc/guides/contributing/design.rst
index 88d3a43..651fd22 100644
--- a/doc/guides/contributing/design.rst
+++ b/doc/guides/contributing/design.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 Design
 ======
 
diff --git a/doc/guides/contributing/documentation.rst b/doc/guides/contributing/documentation.rst
index 82f2e1b..6a07555 100644
--- a/doc/guides/contributing/documentation.rst
+++ b/doc/guides/contributing/documentation.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 .. _doc_guidelines:
 
 DPDK Documentation Guidelines
diff --git a/doc/guides/contributing/index.rst b/doc/guides/contributing/index.rst
index 329b678..f90df45 100644
--- a/doc/guides/contributing/index.rst
+++ b/doc/guides/contributing/index.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 Contributor's Guidelines
 ========================
 
diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst
index e4e0cb5..a3d7880 100644
--- a/doc/guides/contributing/patches.rst
+++ b/doc/guides/contributing/patches.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 .. submitting_patches:
 
 Contributing Code to DPDK
diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
index 0f2f1f3..bfc9b10 100644
--- a/doc/guides/contributing/stable.rst
+++ b/doc/guides/contributing/stable.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 .. stable_lts_releases:
 
 DPDK Stable Releases and Long Term Support
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index c495294d..6bd34dd 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -1,3 +1,6 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
 Managing ABI updates
 ====================
 
-- 
2.7.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v7] checkpatches.sh: Add checks for ABI symbol addition
    @ 2018-06-05 12:21  6% ` Neil Horman
  2018-06-14 13:30  6% ` [dpdk-dev] [PATCH v8] " Neil Horman
  2018-06-27 18:01  6% ` [dpdk-dev] [PATCH v9] " Neil Horman
  3 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-06-05 12:21 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, thomas, john.mcnamara, bruce.richardson,
	Ferruh Yigit, Stephen Hemminger

Recently, some additional patches were added to allow for programmatic
marking of C symbols as experimental.  The addition of these markers is
dependent on the manual addition of exported symbols to the EXPERIMENTAL
section of the corresponding libraries version map file.  The consensus
on review is that, in addition to mandating the addition of symbols to
the EXPERIMENTAL version in the map, we need a mechanism to enforce our
documented process of mandating that addition when they are introduced.
To that end, I am proposing this change.  It is an addition to the
checkpatches script, which scan incoming patches for additions and
removals of symbols to the map file, and warns the user appropriately

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: thomas@monjalon.net
CC: john.mcnamara@intel.com
CC: bruce.richardson@intel.com
CC: Ferruh Yigit <ferruh.yigit@intel.com>
CC: Stephen Hemminger <stephen@networkplumber.org>

---
Change notes

v2)
 * Cleaned up and documented awk script (shemminger)
 * fixed sort/uniq usage (shemminger)
 * moved checking to new script (tmonjalon)
 * added maintainer entry (tmonjalon)
 * added license (tmonjalon)

v3)
 * Changed symbol check script name (tmonjalon)
 * Trapped exit to clean temp file (tmonjalon)
 * Honored verbose command (tmonjalon)
 * Cleaned left over debug bits (tmonjalon)
 * Updated location in MAINTAINERS file (tmonjalon)

v4)
 * Updated maintainers file (tmonjalon)

v5)
 * undo V4 (tmojalon)

v6)
 * Cleaning up more nits (tmonjalon)
 * Combining some lines (tmonjalon)
 * Fixing error print condition (tmonjalon)
 * Redirect stdin to a file to allow rewinding for
   Multiple passes on tools (nhorman)

v7)
 * More nits (tmonjalon)
 * consoloidating some common report lines (tmonjalon)
 * move SPDX identifier to line 2 (nhorman)
 * fix some checkpatch errors
---
 MAINTAINERS                     |   1 +
 devtools/check-symbol-change.sh | 145 ++++++++++++++++++++++++++++++++
 devtools/checkpatches.sh        |  50 +++++++++--
 3 files changed, 189 insertions(+), 7 deletions(-)
 create mode 100755 devtools/check-symbol-change.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 7398749d7..da4735c11 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -122,6 +122,7 @@ M: Neil Horman <nhorman@tuxdriver.com>
 F: lib/librte_compat/
 F: doc/guides/rel_notes/deprecation.rst
 F: devtools/validate-abi.sh
+F: devtools/check-symbol-change.sh
 F: buildtools/check-experimental-syms.sh
 
 Driver information
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
new file mode 100755
index 000000000..76d5562b6
--- /dev/null
+++ b/devtools/check-symbol-change.sh
@@ -0,0 +1,145 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
+
+build_map_changes()
+{
+	local fname=$1
+	local mapdb=$2
+
+	cat $fname | filterdiff -i *.map | awk '
+		# Initialize our variables
+		BEGIN {map="";sym="";ar="";sec=""; in_sec=0}
+
+		# Anything that starts with + or -, followed by an a
+		# and ends in the string .map is the name of our map file
+		# This may appear multiple times in a patch if multiple
+		# map files are altered, and all section/symbol names
+		# appearing between a triggering of this rule and the
+		# next trigger of this rule are associated with this file
+		/[-+] a\/.*\.map/ {map=$2}
+
+		# Triggering this rule, which starts a line with a + and ends it
+		# with a { identifies a versioned section.  The section name is
+		# the rest of the line with the + and { symbols remvoed.
+		# Triggering this rule sets in_sec to 1, which actives the
+		# symbol rule below
+		/+.*{/ {gsub("+","");sec=$1; in_sec=1}
+
+		# This rule idenfies the end of a section, and disables the
+		# symbol rule
+		/.*}/ {in_sec=0}
+
+		# This rule matches on a + followed by any characters except a :
+		# (which denotes a global vs local segment), and ends with a ;.
+		# The semicolon is removed and the symbol is printed with its
+		# association file name and version section, along with an
+		# indicator that the symbol is a new addition.  Note this rule
+		# only works if we have found a version section in the rule
+		# above (hence the in_sec check).  Otherwise we flag it as an
+		# unknown section
+		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_sec == 1) {
+				print map " " sym " " sec " add"
+			} else {
+				print map " " sym " unknown add"
+			}
+		}
+
+		# This is the same rule as above, but the rule matches on a
+		# leading - rather than a +, denoting that the symbol is being
+		# removed.
+		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_sec == 1) {
+				print map " " sym " " sec " del"
+			} else {
+				print map " " sym " unknown del"
+			}
+		}' > ./$mapdb
+
+		sort -u $mapdb > ./$mapdb.2
+		mv -f $mapdb.2 $mapdb
+
+}
+
+check_for_rule_violations()
+{
+	local mapdb=$1
+	local mname
+	local symname
+	local secname
+	local ar
+	local ret=0
+
+	while read mname symname secname ar
+	do
+		if [ "$ar" == "add" ]
+		then
+
+			if [ "$secname" == "unknown" ]
+			then
+				# Just inform the user of this occurrence, but
+				# don't flag it as an error
+				echo -n "INFO: symbol $syname is added but "
+				echo -n "patch has insuficient context "
+				echo -n "to determine the section name "
+				echo -n "please ensure the version is "
+				echo "EXPERIMENTAL"
+				continue
+			fi
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Symbols that are getting added in a section
+				# other ithan the experimental section
+				# to be moving from an already supported
+				# section or its a violation
+				grep -q \
+				"$mname $symname [^EXPERIMENTAL] del" $mapdb
+				if [ $? -ne 0 ]
+				then
+					echo -n "ERROR: symbol $symname "
+					echo -n "is added in a section "
+					echo -n "other than the EXPERIMENTAL "
+					echo "section of the version map"
+					ret=1
+				fi
+			fi
+		else
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Just inform users that non-experimenal
+				# symbols need to go through a deprecation
+				# process
+				echo -n "INFO: symbol $symname is being "
+				echo -n "removed, ensure that it has "
+				echo "gone through the deprecation process"
+			fi
+		fi
+	done < $mapdb
+
+	return $ret
+}
+
+trap clean_and_exit_on_sig EXIT
+
+mapfile=`mktemp mapdb.XXXXXX`
+patch=$1
+exit_code=1
+
+clean_and_exit_on_sig()
+{
+	rm -f $mapfile
+	exit $exit_code
+}
+
+build_map_changes $patch $mapfile
+check_for_rule_violations $mapfile
+exit_code=$?
+
+rm -f $mapfile
+
+exit $exit_code
+
+
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 245d5ab10..2e9f30cc8 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -7,6 +7,9 @@
 # - DPDK_CHECKPATCH_LINE_LENGTH
 . $(dirname $(readlink -e $0))/load-devel-config
 
+
+VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
+
 length=${DPDK_CHECKPATCH_LINE_LENGTH:-80}
 
 # override default Linux options
@@ -21,6 +24,15 @@ SPLIT_STRING,LONG_LINE_STRING,\
 LINE_SPACING,PARENTHESIS_ALIGNMENT,NETWORKING_BLOCK_COMMENT_STYLE,\
 NEW_TYPEDEFS,COMPARISON_TO_NULL"
 
+clean_tmp_files() {
+	echo $TMPINPUT | grep -q checkpaches
+	if [ $? -eq 0 ]; then
+		rm -f $TMPINPUT
+	fi
+}
+
+trap "clean_tmp_files" SIGINT
+
 print_usage () {
 	cat <<- END_OF_HELP
 	usage: $(basename $0) [-q] [-v] [-nX|patch1 [patch2] ...]]
@@ -58,19 +70,43 @@ total=0
 status=0
 
 check () { # <patch> <commit> <title>
+	local ret=0
+
 	total=$(($total + 1))
 	! $verbose || printf '\n### %s\n\n' "$3"
 	if [ -n "$1" ] ; then
-		report=$($DPDK_CHECKPATCH_PATH $options "$1" 2>/dev/null)
+		TMPINPUT=$1
 	elif [ -n "$2" ] ; then
-		report=$(git format-patch --find-renames --no-stat --stdout -1 $commit |
-			$DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		TMPINPUT=$(mktemp checkpatches.XXXXXX)
+		git format-patch --find-renames \
+		--no-stat --stdout -1 $commit > ./$TMPINPUT
 	else
-		report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		TMPINPUT=$(mktemp checkpatches.XXXXXX)
+		cat > ./$TMPINPUT
+	fi
+
+	report=$($DPDK_CHECKPATCH_PATH $options $TMPINPUT 2>/dev/null)
+
+	if [ $? -ne 0 ]
+	then
+		$verbose || printf '\n### %s\n\n' "$3"
+		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+		ret=1
+	fi
+
+	! $verbose || printf '\nChecking API additions/removals:\n'
+
+	report=$($VALIDATE_NEW_API "$TMPINPUT")
+
+	if [ $? -ne 0 ]; then
+		printf '%s\n' "$report"
+		ret=1
+	fi
+
+	clean_tmp_files
+	if [ $ret -eq 0 ]; then
+		return 0
 	fi
-	[ $? -ne 0 ] || return 0
-	$verbose || printf '\n### %s\n\n' "$3"
-	printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
 	status=$(($status + 1))
 }
 
-- 
2.17.1

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH] eal: add request to map reserved physical memory
  @ 2018-06-07 12:15  3%           ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-06-07 12:15 UTC (permalink / raw)
  To: Scott Branden, Srinath Mannam; +Cc: Ajit Khaparde, dev

On 06-Jun-18 1:18 AM, Scott Branden wrote:
> Hi Anatoly,
> 
> 
> On 18-04-27 09:49 AM, Burakov, Anatoly wrote:
>> On 27-Apr-18 5:30 PM, Scott Branden wrote:
>>> Hi Anatoly,
>>>
>>> We'd appreciate your input so we can come to a solution of supporting 
>>> the necessary memory allocations?
>>>
>>
>> Hi Scott,
>>
>> I'm currently starting to work on a prototype that will be at least 
>> RFC'd (if not v1'd) during 18.08 timeframe. Basically, the idea is to 
>> create/destroy named malloc heaps dynamically, and allow user to 
>> request memory from them. You may then mmap() whatever you want and 
>> create a malloc heap out of it.
>>
>> Does that sound reasonable?
>>
> Is the plan still to have a patch for 18.08?
> 
> Thanks,
>   Scott
> 
Hi Scott,

The plan is still to submit an RFC during 18.08 timeframe, but since it 
will be an ABI break, it will only be integrated in the next (18.11) 
release.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/3] bpf: add extra information for external symbol definitions
  @ 2018-06-08  8:42  2% ` Konstantin Ananyev
  0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2018-06-08  8:42 UTC (permalink / raw)
  To: dev, dev; +Cc: Konstantin Ananyev

Extend struct rte_bpf_xsym with new fields to provide information about:
 - for variables - type and size
 - for functions - number of arguments and type/size of each argument
   and return value

Such information would allow validate code to perform
more extensive checking on input BPF program and catch
misbehaving BPF code.

That change would cause ABI/API breakage for librte_bpf.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 app/test-pmd/bpf_cmd.c        | 27 ++++++++++++++++++++++--
 lib/librte_bpf/bpf_def.h      |  5 +++++
 lib/librte_bpf/bpf_exec.c     |  2 +-
 lib/librte_bpf/bpf_impl.h     | 14 +++++++++++++
 lib/librte_bpf/bpf_jit_x86.c  | 17 ++-------------
 lib/librte_bpf/bpf_load.c     | 49 ++++++++++++++++++++++++++++++++++++++++++-
 lib/librte_bpf/bpf_load_elf.c |  4 ++--
 lib/librte_bpf/rte_bpf.h      | 21 +++++++++++++++----
 test/test/test_bpf.c          | 19 ++++++++++++++++-
 9 files changed, 132 insertions(+), 26 deletions(-)

diff --git a/app/test-pmd/bpf_cmd.c b/app/test-pmd/bpf_cmd.c
index 584fad908..830bfc13a 100644
--- a/app/test-pmd/bpf_cmd.c
+++ b/app/test-pmd/bpf_cmd.c
@@ -19,12 +19,35 @@ static const struct rte_bpf_xsym bpf_xsym[] = {
 	{
 		.name = RTE_STR(stdout),
 		.type = RTE_BPF_XTYPE_VAR,
-		.var = &stdout,
+		.var = {
+			.val = &stdout,
+			.desc = {
+				.type = RTE_BPF_ARG_PTR,
+				.size = sizeof(stdout),
+			},
+		},
 	},
 	{
 		.name = RTE_STR(rte_pktmbuf_dump),
 		.type = RTE_BPF_XTYPE_FUNC,
-		.func = (void *)rte_pktmbuf_dump,
+		.func = {
+			.val = (void *)rte_pktmbuf_dump,
+			.nb_args = 3,
+			.args = {
+				[0] = {
+					.type = RTE_BPF_ARG_RAW,
+					.size = sizeof(uintptr_t),
+				},
+				[1] = {
+					.type = RTE_BPF_ARG_PTR_MBUF,
+					.size = sizeof(struct rte_mbuf),
+				},
+				[2] = {
+					.type = RTE_BPF_ARG_RAW,
+					.size = sizeof(uint32_t),
+				},
+			},
+		},
 	},
 };
 
diff --git a/lib/librte_bpf/bpf_def.h b/lib/librte_bpf/bpf_def.h
index 6b69de345..c10f3aec4 100644
--- a/lib/librte_bpf/bpf_def.h
+++ b/lib/librte_bpf/bpf_def.h
@@ -131,6 +131,11 @@ struct ebpf_insn {
 	int32_t imm;
 };
 
+/*
+ * eBPF allows functions with R1-R5 as arguments.
+ */
+#define	EBPF_FUNC_MAX_ARGS	(EBPF_REG_6 - EBPF_REG_1)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_bpf/bpf_exec.c b/lib/librte_bpf/bpf_exec.c
index e373b1f3d..6a79139c0 100644
--- a/lib/librte_bpf/bpf_exec.c
+++ b/lib/librte_bpf/bpf_exec.c
@@ -402,7 +402,7 @@ bpf_exec(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM])
 			break;
 		/* call instructions */
 		case (BPF_JMP | EBPF_CALL):
-			reg[EBPF_REG_0] = bpf->prm.xsym[ins->imm].func(
+			reg[EBPF_REG_0] = bpf->prm.xsym[ins->imm].func.val(
 				reg[EBPF_REG_1], reg[EBPF_REG_2],
 				reg[EBPF_REG_3], reg[EBPF_REG_4],
 				reg[EBPF_REG_5]);
diff --git a/lib/librte_bpf/bpf_impl.h b/lib/librte_bpf/bpf_impl.h
index 5d7e65c31..b577e2cbe 100644
--- a/lib/librte_bpf/bpf_impl.h
+++ b/lib/librte_bpf/bpf_impl.h
@@ -34,6 +34,20 @@ extern int rte_bpf_logtype;
 #define	RTE_BPF_LOG(lvl, fmt, args...) \
 	rte_log(RTE_LOG_## lvl, rte_bpf_logtype, fmt, ##args)
 
+static inline size_t
+bpf_size(uint32_t bpf_op_sz)
+{
+	if (bpf_op_sz == BPF_B)
+		return sizeof(uint8_t);
+	else if (bpf_op_sz == BPF_H)
+		return sizeof(uint16_t);
+	else if (bpf_op_sz == BPF_W)
+		return sizeof(uint32_t);
+	else if (bpf_op_sz == EBPF_DW)
+		return sizeof(uint64_t);
+	return 0;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_bpf/bpf_jit_x86.c b/lib/librte_bpf/bpf_jit_x86.c
index 111e028d2..68ea389f2 100644
--- a/lib/librte_bpf/bpf_jit_x86.c
+++ b/lib/librte_bpf/bpf_jit_x86.c
@@ -113,20 +113,6 @@ union bpf_jit_imm {
 	uint8_t u8[4];
 };
 
-static size_t
-bpf_size(uint32_t bpf_op_sz)
-{
-	if (bpf_op_sz == BPF_B)
-		return sizeof(uint8_t);
-	else if (bpf_op_sz == BPF_H)
-		return sizeof(uint16_t);
-	else if (bpf_op_sz == BPF_W)
-		return sizeof(uint32_t);
-	else if (bpf_op_sz == EBPF_DW)
-		return sizeof(uint64_t);
-	return 0;
-}
-
 /*
  * In many cases for imm8 we can produce shorter code.
  */
@@ -1294,7 +1280,8 @@ emit(struct bpf_jit_state *st, const struct rte_bpf *bpf)
 			break;
 		/* call instructions */
 		case (BPF_JMP | EBPF_CALL):
-			emit_call(st, (uintptr_t)bpf->prm.xsym[ins->imm].func);
+			emit_call(st,
+				(uintptr_t)bpf->prm.xsym[ins->imm].func.val);
 			break;
 		/* return instruction */
 		case (BPF_JMP | EBPF_EXIT):
diff --git a/lib/librte_bpf/bpf_load.c b/lib/librte_bpf/bpf_load.c
index d1c9abd7f..2b84fe724 100644
--- a/lib/librte_bpf/bpf_load.c
+++ b/lib/librte_bpf/bpf_load.c
@@ -51,17 +51,64 @@ bpf_load(const struct rte_bpf_prm *prm)
 	return bpf;
 }
 
+/*
+ * Check that user provided external symbol.
+ */
+static int
+bpf_check_xsym(const struct rte_bpf_xsym *xsym)
+{
+	uint32_t i;
+
+	if (xsym->name == NULL)
+		return -EINVAL;
+
+	if (xsym->type == RTE_BPF_XTYPE_VAR) {
+		if (xsym->var.desc.type == RTE_BPF_ARG_UNDEF)
+			return -EINVAL;
+	} else if (xsym->type == RTE_BPF_XTYPE_FUNC) {
+
+		if (xsym->func.nb_args > EBPF_FUNC_MAX_ARGS)
+			return -EINVAL;
+
+		/* check function arguments */
+		for (i = 0; i != xsym->func.nb_args; i++) {
+			if (xsym->func.args[i].type == RTE_BPF_ARG_UNDEF)
+				return -EINVAL;
+		}
+
+		/* check return value info */
+		if (xsym->func.ret.type != RTE_BPF_ARG_UNDEF &&
+				xsym->func.ret.size == 0)
+			return -EINVAL;
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
 __rte_experimental struct rte_bpf *
 rte_bpf_load(const struct rte_bpf_prm *prm)
 {
 	struct rte_bpf *bpf;
 	int32_t rc;
+	uint32_t i;
 
-	if (prm == NULL || prm->ins == NULL) {
+	if (prm == NULL || prm->ins == NULL ||
+			(prm->nb_xsym != 0 && prm->xsym == NULL)) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
 
+	rc = 0;
+	for (i = 0; i != prm->nb_xsym && rc == 0; i++)
+		rc = bpf_check_xsym(prm->xsym + i);
+
+	if (rc != 0) {
+		rte_errno = -rc;
+		RTE_BPF_LOG(ERR, "%s: %d-th xsym is invalid\n", __func__, i);
+		return NULL;
+	}
+
 	bpf = bpf_load(prm);
 	if (bpf == NULL) {
 		rte_errno = ENOMEM;
diff --git a/lib/librte_bpf/bpf_load_elf.c b/lib/librte_bpf/bpf_load_elf.c
index 6ab03d86e..96d3630fe 100644
--- a/lib/librte_bpf/bpf_load_elf.c
+++ b/lib/librte_bpf/bpf_load_elf.c
@@ -81,9 +81,9 @@ resolve_xsym(const char *sn, size_t ofs, struct ebpf_insn *ins, size_t ins_sz,
 		ins[idx].imm = fidx;
 	/* for variable we need to store its absolute address */
 	else {
-		ins[idx].imm = (uintptr_t)prm->xsym[fidx].var;
+		ins[idx].imm = (uintptr_t)prm->xsym[fidx].var.val;
 		ins[idx + 1].imm =
-			(uint64_t)(uintptr_t)prm->xsym[fidx].var >> 32;
+			(uint64_t)(uintptr_t)prm->xsym[fidx].var.val >> 32;
 	}
 
 	return 0;
diff --git a/lib/librte_bpf/rte_bpf.h b/lib/librte_bpf/rte_bpf.h
index 1249a992c..ad62ef2c6 100644
--- a/lib/librte_bpf/rte_bpf.h
+++ b/lib/librte_bpf/rte_bpf.h
@@ -40,7 +40,11 @@ enum rte_bpf_arg_type {
  */
 struct rte_bpf_arg {
 	enum rte_bpf_arg_type type;
-	size_t size;     /**< for pointer types, size of data it points to */
+	/**
+	 * for ptr type - max size of data buffer it points to
+	 * for raw type - the size (in bytes) of the value
+	 */
+	size_t size;
 	size_t buf_size;
 	/**< for mbuf ptr type, max size of rte_mbuf data buffer */
 };
@@ -66,10 +70,19 @@ struct rte_bpf_xsym {
 	const char *name;        /**< name */
 	enum rte_bpf_xtype type; /**< type */
 	union {
-		uint64_t (*func)(uint64_t, uint64_t, uint64_t,
+		struct {
+			uint64_t (*val)(uint64_t, uint64_t, uint64_t,
 				uint64_t, uint64_t);
-		void *var;
-	}; /**< value */
+			uint32_t nb_args;
+			struct rte_bpf_arg args[EBPF_FUNC_MAX_ARGS];
+			/**< Function arguments descriptions. */
+			struct rte_bpf_arg ret; /**< function return value. */
+		} func;
+		struct {
+			void *val; /**< actual memory location */
+			struct rte_bpf_arg desc; /**< type, size, etc. */
+		} var; /**< external variable */
+	};
 };
 
 /**
diff --git a/test/test/test_bpf.c b/test/test/test_bpf.c
index cbd6be63d..1e9caef95 100644
--- a/test/test/test_bpf.c
+++ b/test/test/test_bpf.c
@@ -1530,7 +1530,24 @@ static const struct rte_bpf_xsym test_call1_xsym[] = {
 	{
 		.name = RTE_STR(dummy_func1),
 		.type = RTE_BPF_XTYPE_FUNC,
-		.func = (void *)dummy_func1,
+		.func = {
+			.val = (void *)dummy_func1,
+			.nb_args = 3,
+			.args = {
+				[0] = {
+					.type = RTE_BPF_ARG_PTR,
+					.size = sizeof(struct dummy_offset),
+				},
+				[1] = {
+					.type = RTE_BPF_ARG_PTR,
+					.size = sizeof(uint32_t),
+				},
+				[2] = {
+					.type = RTE_BPF_ARG_PTR,
+					.size = sizeof(uint64_t),
+				},
+			},
+		},
 	},
 };
 
-- 
2.13.6

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH 1/6] cryptodev: replace bus specific struct with generic dev
  @ 2018-06-08 22:02  4% ` Pablo de Lara
  2018-06-08 22:02  1% ` [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions Pablo de Lara
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-08 22:02 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Structure rte_cryptodev_info has currently PCI device
information ("struct rte_pci_device") in it.

This information is not generic to all devices,
so this gets replaced with the generic "rte_device" structure,
compatible with all crypto devices.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/prog_guide/cryptodev_lib.rst  | 2 +-
 doc/guides/rel_notes/deprecation.rst     | 2 --
 doc/guides/rel_notes/release_18_08.rst   | 5 ++++-
 drivers/crypto/qat/qat_crypto.c          | 1 -
 drivers/crypto/virtio/virtio_cryptodev.c | 1 -
 lib/librte_cryptodev/rte_cryptodev.c     | 1 +
 lib/librte_cryptodev/rte_cryptodev.h     | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 30f0bcf7a..d02bb7514 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -269,7 +269,7 @@ relevant information for the device.
     struct rte_cryptodev_info {
         const char *driver_name;
         uint8_t driver_id;
-        struct rte_pci_device *pci_dev;
+        struct rte_device *device;
 
         uint64_t feature_flags;
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692eac..b71080bb8 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -104,8 +104,6 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
-  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
-    structure.
   - Functions ``rte_cryptodev_queue_pair_attach_sym_session()`` and
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 5bc23c537..ba710e845 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -55,6 +55,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
+  has been replaced with field ``struct rte_device *device``.
+
 
 ABI Changes
 -----------
@@ -113,7 +116,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cmdline.so.2
      librte_common_octeontx.so.1
      librte_compressdev.so.1
-     librte_cryptodev.so.4
+   + librte_cryptodev.so.5
      librte_distributor.so.1
      librte_eal.so.7
      librte_ethdev.so.9
diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
index d9ce2a136..768dcbae0 100644
--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -1656,7 +1656,6 @@ void qat_dev_info_get(struct rte_cryptodev *dev,
 		info->capabilities = internals->qat_dev_capabilities;
 		info->sym.max_nb_sessions = internals->max_nb_sessions;
 		info->driver_id = cryptodev_qat_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 	}
 }
 
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index df88953f6..482edea1a 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1409,7 +1409,6 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
 
 	if (info != NULL) {
 		info->driver_id = cryptodev_virtio_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 		info->feature_flags = dev->feature_flags;
 		info->max_nb_queue_pairs = hw->max_dataqueues;
 		info->sym.max_nb_sessions =
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 7e5821246..457ac5670 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -966,6 +966,7 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->driver_name = dev->device->driver->name;
+	dev_info->device = dev->device;
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 92ce6d49a..80cd6b474 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -371,7 +371,7 @@ rte_cryptodev_get_feature_name(uint64_t flag);
 struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	uint8_t driver_id;			/**< Driver identifier */
-	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_device *device;		/**< Generic device information. */
 
 	uint64_t feature_flags;
 	/**< Feature flags exposes HW/SW features for the given device */
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions
    2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 1/6] cryptodev: replace bus specific struct with generic dev Pablo de Lara
@ 2018-06-08 22:02  1% ` Pablo de Lara
  2018-06-12 11:37  0%   ` Tomasz Duszynski
  2018-06-08 22:02  2% ` [dpdk-dev] [PATCH 4/6] cryptodev: remove queue start/stop functions Pablo de Lara
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 200+ results
From: Pablo de Lara @ 2018-06-08 22:02 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Sessions are not created and stored in the crypto device
anymore, since now the session mempool is created
at the application level.

Therefore the limitation of the maximum number of sessions
that can be created should not be dependent of the crypto device.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 config/common_base                               | 12 ------------
 config/rte_config.h                              | 14 --------------
 doc/guides/cryptodevs/aesni_gcm.rst              |  4 +---
 doc/guides/cryptodevs/aesni_mb.rst               |  4 +---
 doc/guides/cryptodevs/armv8.rst                  |  1 -
 doc/guides/cryptodevs/ccp.rst                    |  2 --
 doc/guides/cryptodevs/dpaa2_sec.rst              |  5 -----
 doc/guides/cryptodevs/dpaa_sec.rst               |  5 -----
 doc/guides/cryptodevs/kasumi.rst                 |  4 +---
 doc/guides/cryptodevs/mvsam.rst                  |  1 -
 doc/guides/cryptodevs/null.rst                   |  4 +---
 doc/guides/cryptodevs/openssl.rst                |  1 -
 doc/guides/cryptodevs/scheduler.rst              |  4 ----
 doc/guides/cryptodevs/snow3g.rst                 |  4 +---
 doc/guides/cryptodevs/zuc.rst                    |  4 +---
 doc/guides/prog_guide/cryptodev_lib.rst          |  9 ++-------
 doc/guides/rel_notes/deprecation.rst             |  3 ---
 doc/guides/rel_notes/release_18_08.rst           |  3 ++-
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  5 +----
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |  1 -
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |  2 --
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c       |  5 +----
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c   |  1 -
 .../crypto/aesni_mb/rte_aesni_mb_pmd_private.h   |  2 --
 drivers/crypto/armv8/rte_armv8_pmd.c             |  5 +----
 drivers/crypto/armv8/rte_armv8_pmd_ops.c         |  1 -
 drivers/crypto/armv8/rte_armv8_pmd_private.h     |  2 --
 drivers/crypto/ccp/ccp_pmd_ops.c                 |  1 -
 drivers/crypto/ccp/ccp_pmd_private.h             |  1 -
 drivers/crypto/ccp/rte_ccp_pmd.c                 | 16 +---------------
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c      |  3 ++-
 drivers/crypto/dpaa_sec/dpaa_sec.c               |  1 -
 drivers/crypto/dpaa_sec/dpaa_sec.h               |  1 +
 drivers/crypto/kasumi/rte_kasumi_pmd.c           |  5 +----
 drivers/crypto/kasumi/rte_kasumi_pmd_ops.c       |  1 -
 drivers/crypto/kasumi/rte_kasumi_pmd_private.h   |  2 --
 drivers/crypto/mvsam/rte_mrvl_pmd.c              |  6 ------
 drivers/crypto/mvsam/rte_mrvl_pmd_ops.c          |  1 -
 drivers/crypto/mvsam/rte_mrvl_pmd_private.h      |  1 -
 drivers/crypto/null/null_crypto_pmd.c            |  3 ---
 drivers/crypto/null/null_crypto_pmd_ops.c        |  1 -
 drivers/crypto/null/null_crypto_pmd_private.h    |  1 -
 drivers/crypto/openssl/rte_openssl_pmd.c         |  3 ---
 drivers/crypto/openssl/rte_openssl_pmd_ops.c     |  1 -
 drivers/crypto/openssl/rte_openssl_pmd_private.h |  2 --
 drivers/crypto/qat/qat_crypto.c                  |  1 -
 drivers/crypto/qat/qat_crypto.h                  |  2 --
 drivers/crypto/qat/rte_qat_cryptodev.c           |  4 +---
 drivers/crypto/scheduler/scheduler_pmd.c         | 13 +------------
 drivers/crypto/scheduler/scheduler_pmd_ops.c     |  7 -------
 drivers/crypto/snow3g/rte_snow3g_pmd.c           |  3 ---
 drivers/crypto/snow3g/rte_snow3g_pmd_ops.c       |  1 -
 drivers/crypto/snow3g/rte_snow3g_pmd_private.h   |  2 --
 drivers/crypto/virtio/virtio_cryptodev.c         |  3 ---
 drivers/crypto/zuc/rte_zuc_pmd.c                 |  5 +----
 drivers/crypto/zuc/rte_zuc_pmd_ops.c             |  1 -
 drivers/crypto/zuc/rte_zuc_pmd_private.h         |  2 --
 lib/librte_cryptodev/rte_cryptodev.h             |  5 -----
 lib/librte_cryptodev/rte_cryptodev_pmd.c         | 12 ++----------
 lib/librte_cryptodev/rte_cryptodev_pmd.h         |  4 ----
 test/test/test_cryptodev.c                       | 13 +++++++------
 61 files changed, 30 insertions(+), 206 deletions(-)

diff --git a/config/common_base b/config/common_base
index 6b0d1cbbb..db6dec335 100644
--- a/config/common_base
+++ b/config/common_base
@@ -473,14 +473,12 @@ CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG=n
 # Compile NXP DPAA2 crypto sec driver for CAAM HW
 #
 CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=n
-CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS=2048
 
 #
 # NXP DPAA caam - crypto driver
 #
 CONFIG_RTE_LIBRTE_PMD_DPAA_SEC=n
 CONFIG_RTE_LIBRTE_DPAA_MAX_CRYPTODEV=4
-CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS=2048
 
 #
 # Compile PMD for QuickAssist based devices
@@ -490,11 +488,6 @@ CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
 CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
 CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
-#
-# Number of sessions to create in the session memory pool
-# on a single QuickAssist device.
-#
-CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
 
 #
 # Compile PMD for virtio crypto devices
@@ -504,11 +497,6 @@ CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=y
 # Number of maximum virtio crypto devices
 #
 CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
-#
-# Number of sessions to create in the session memory pool
-# on a single virtio crypto device.
-#
-CONFIG_RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS=1024
 
 #
 # Compile PMD for AESNI backed device
diff --git a/config/rte_config.h b/config/rte_config.h
index a1d01759e..7261d28d6 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -85,23 +85,9 @@
 
 /****** driver defines ********/
 
-/*
- * Number of sessions to create in the session memory pool
- * on a single instance of crypto HW device.
- */
-/* QuickAssist device */
-#define RTE_QAT_PMD_MAX_NB_SESSIONS 2048
-
 /* virtio crypto defines */
-#define RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS 1024
 #define RTE_MAX_VIRTIO_CRYPTO 32
 
-/* DPAA2_SEC */
-#define RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS 2048
-
-/* DPAA_SEC */
-#define RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS 2048
-
 /* DPAA SEC max cryptodev devices*/
 #define RTE_LIBRTE_DPAA_MAX_CRYPTODEV	4
 
diff --git a/doc/guides/cryptodevs/aesni_gcm.rst b/doc/guides/cryptodevs/aesni_gcm.rst
index 01590e850..2cfd1e9f7 100644
--- a/doc/guides/cryptodevs/aesni_gcm.rst
+++ b/doc/guides/cryptodevs/aesni_gcm.rst
@@ -83,11 +83,9 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_gcm,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_gcm,socket_id=0" \
     -- -p 1 --cdev SW --chain AEAD --aead_algo "aes-gcm"
diff --git a/doc/guides/cryptodevs/aesni_mb.rst b/doc/guides/cryptodevs/aesni_mb.rst
index 236828c0a..a0602a10d 100644
--- a/doc/guides/cryptodevs/aesni_mb.rst
+++ b/doc/guides/cryptodevs/aesni_mb.rst
@@ -106,13 +106,11 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_mb,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_mb,socket_id=0" \
     -- -p 1 --cdev SW --chain CIPHER_HASH --cipher_algo "aes-cbc" --auth_algo "sha1-hmac"
 
 Extra notes
diff --git a/doc/guides/cryptodevs/armv8.rst b/doc/guides/cryptodevs/armv8.rst
index 725398daf..4adf3cf40 100644
--- a/doc/guides/cryptodevs/armv8.rst
+++ b/doc/guides/cryptodevs/armv8.rst
@@ -64,7 +64,6 @@ For performance test cryptodev_sw_armv8_perftest can be used.
 Limitations
 -----------
 
-* Maximum number of sessions is 2048.
 * Only chained operations are supported.
 * AES-128-CBC is the only supported cipher variant.
 * Cipher input data has to be a multiple of 16 bytes.
diff --git a/doc/guides/cryptodevs/ccp.rst b/doc/guides/cryptodevs/ccp.rst
index 034d20367..d577d5a1c 100644
--- a/doc/guides/cryptodevs/ccp.rst
+++ b/doc/guides/cryptodevs/ccp.rst
@@ -101,8 +101,6 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device.
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 * ccp_auth_opt: Specify authentication operations to perform on CPU using openssl APIs.
 
 To validate ccp pmd, l2fwd-crypto example can be used with following command:
diff --git a/doc/guides/cryptodevs/dpaa2_sec.rst b/doc/guides/cryptodevs/dpaa2_sec.rst
index 3ea24c8aa..990befeb7 100644
--- a/doc/guides/cryptodevs/dpaa2_sec.rst
+++ b/doc/guides/cryptodevs/dpaa2_sec.rst
@@ -200,11 +200,6 @@ Please note that enabling debugging options may affect system performance.
   By default it is only enabled in defconfig_arm64-dpaa2-* config.
   Toggle compilation of the ``librte_pmd_dpaa2_sec`` driver.
 
-* ``CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS``
-  By default it is set as 2048 in defconfig_arm64-dpaa2-* config.
-  It indicates Number of sessions to create in the session memory pool
-  on a single DPAA2 SEC device.
-
 Installations
 -------------
 To compile the DPAA2_SEC PMD for Linux arm64 gcc target, run the
diff --git a/doc/guides/cryptodevs/dpaa_sec.rst b/doc/guides/cryptodevs/dpaa_sec.rst
index c14d6d7b1..c5097a84f 100644
--- a/doc/guides/cryptodevs/dpaa_sec.rst
+++ b/doc/guides/cryptodevs/dpaa_sec.rst
@@ -145,11 +145,6 @@ Please note that enabling debugging options may affect system performance.
   By default it is only enabled in defconfig_arm64-dpaa-* config.
   Toggle compilation of the ``librte_pmd_dpaa_sec`` driver.
 
-* ``CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS``
-  By default it is set as 2048 in defconfig_arm64-dpaa-* config.
-  It indicates Number of sessions to create in the session memory pool
-  on a single DPAA SEC device.
-
 Installations
 -------------
 To compile the DPAA_SEC PMD for Linux arm64 gcc target, run the
diff --git a/doc/guides/cryptodevs/kasumi.rst b/doc/guides/cryptodevs/kasumi.rst
index 2265eee4e..74bc4d840 100644
--- a/doc/guides/cryptodevs/kasumi.rst
+++ b/doc/guides/cryptodevs/kasumi.rst
@@ -87,13 +87,11 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_kasumi,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_kasumi,socket_id=0" \
     -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "kasumi-f8"
 
 Extra notes on KASUMI F9
diff --git a/doc/guides/cryptodevs/mvsam.rst b/doc/guides/cryptodevs/mvsam.rst
index fd418c264..b91bb0fb6 100644
--- a/doc/guides/cryptodevs/mvsam.rst
+++ b/doc/guides/cryptodevs/mvsam.rst
@@ -115,7 +115,6 @@ loaded:
 The following parameters (all optional) are exported by the driver:
 
 * max_nb_queue_pairs: maximum number of queue pairs in the device (8 by default).
-* max_nb_sessions: maximum number of sessions that can be created (2048 by default).
 * socket_id: socket on which to allocate the device resources on.
 
 l2fwd-crypto example application can be used to verify MVSAM CRYPTO PMD
diff --git a/doc/guides/cryptodevs/null.rst b/doc/guides/cryptodevs/null.rst
index c980e0ac8..ca39fe444 100644
--- a/doc/guides/cryptodevs/null.rst
+++ b/doc/guides/cryptodevs/null.rst
@@ -61,11 +61,9 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_null,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_null,socket_id=0" \
     -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "null"
diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst
index 427fc807c..153ad0657 100644
--- a/doc/guides/cryptodevs/openssl.rst
+++ b/doc/guides/cryptodevs/openssl.rst
@@ -98,7 +98,6 @@ To verify real traffic l2fwd-crypto example can be used with this command:
 Limitations
 -----------
 
-* Maximum number of sessions is 2048.
 * Chained mbufs are supported only for source mbuf (destination must be
   contiguous).
 * Hash only is not supported for GCM and GMAC.
diff --git a/doc/guides/cryptodevs/scheduler.rst b/doc/guides/cryptodevs/scheduler.rst
index d67894d55..e266ec5a3 100644
--- a/doc/guides/cryptodevs/scheduler.rst
+++ b/doc/guides/cryptodevs/scheduler.rst
@@ -58,10 +58,6 @@ two calls:
   to be allocated (by default, socket_id will be the socket where the core
   that is creating the PMD is running on).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be
-  created. This value may be overwritten internally if there are too
-  many devices are attached.
-
 * slave: If a cryptodev has been initialized with specific name, it can be
   attached to the scheduler using this parameter, simply filling the name
   here. Multiple cryptodevs can be attached initially by presenting this
diff --git a/doc/guides/cryptodevs/snow3g.rst b/doc/guides/cryptodevs/snow3g.rst
index 7cba712c1..e0b9a73f7 100644
--- a/doc/guides/cryptodevs/snow3g.rst
+++ b/doc/guides/cryptodevs/snow3g.rst
@@ -79,11 +79,9 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_snow3g,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_snow3g,socket_id=0" \
     -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "snow3g-uea2"
diff --git a/doc/guides/cryptodevs/zuc.rst b/doc/guides/cryptodevs/zuc.rst
index e38989968..7bebbb48b 100644
--- a/doc/guides/cryptodevs/zuc.rst
+++ b/doc/guides/cryptodevs/zuc.rst
@@ -79,11 +79,9 @@ The following parameters (all optional) can be provided in the previous two call
 
 * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
 
-* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
-
 Example:
 
 .. code-block:: console
 
-    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_zuc,socket_id=0,max_nb_sessions=128" \
+    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_zuc,socket_id=0" \
     -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "zuc-eea3"
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index d02bb7514..c83184fe9 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -41,7 +41,7 @@ From the command line using the --vdev EAL option
 
 .. code-block:: console
 
-   --vdev  'crypto_aesni_mb0,max_nb_queue_pairs=2,max_nb_sessions=1024,socket_id=0'
+   --vdev  'crypto_aesni_mb0,max_nb_queue_pairs=2,socket_id=0'
 
 .. Note::
 
@@ -57,12 +57,11 @@ Our using the rte_vdev_init API within the application code.
 .. code-block:: c
 
    rte_vdev_init("crypto_aesni_mb",
-                     "max_nb_queue_pairs=2,max_nb_sessions=1024,socket_id=0")
+                     "max_nb_queue_pairs=2,socket_id=0")
 
 All virtual Crypto devices support the following initialization parameters:
 
 * ``max_nb_queue_pairs`` - maximum number of queue pairs supported by the device.
-* ``max_nb_sessions`` - maximum number of sessions supported by the device
 * ``socket_id`` - socket on which to allocate the device resources on.
 
 
@@ -276,10 +275,6 @@ relevant information for the device.
         const struct rte_cryptodev_capabilities *capabilities;
 
         unsigned max_nb_queue_pairs;
-
-        struct {
-            unsigned max_nb_sessions;
-        } sym;
     };
 
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b71080bb8..dc014da21 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -101,9 +101,6 @@ Deprecation Notices
 * cryptodev: The following changes will be made in the library
   for 18.08:
 
-  - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
-    containing fields not relevant anymore since the session mempool
-    is not internal in the crypto device anymore.
   - Functions ``rte_cryptodev_queue_pair_attach_sym_session()`` and
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index ba710e845..a6f31713a 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -56,7 +56,8 @@ API Changes
    =========================================================
 
 * cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
-  has been replaced with field ``struct rte_device *device``.
+  has been replaced with field ``struct rte_device *device`` and
+  field ``sym`` has been removed.
 
 
 ABI Changes
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index 80360dd9c..cd5b1952b 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -513,7 +513,6 @@ aesni_gcm_create(const char *name,
 	internals->vector_mode = vector_mode;
 
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 }
@@ -525,8 +524,7 @@ aesni_gcm_probe(struct rte_vdev_device *vdev)
 		"",
 		sizeof(struct aesni_gcm_private),
 		rte_socket_id(),
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 	};
 	const char *name;
 	const char *input_args;
@@ -568,7 +566,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_GCM_PMD, aesni_gcm_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_GCM_PMD, cryptodev_aesni_gcm_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_GCM_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(aesni_gcm_crypto_drv, aesni_gcm_pmd_drv.driver,
 		cryptodev_driver_id);
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index 6f542137c..b05122c1b 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -143,7 +143,6 @@ aesni_gcm_pmd_info_get(struct rte_cryptodev *dev,
 		dev_info->capabilities = aesni_gcm_pmd_capabilities;
 
 		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 3d60583b0..b496377dd 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -39,8 +39,6 @@ struct aesni_gcm_private {
 	/**< Vector mode */
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 };
 
 struct aesni_gcm_qp {
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index bb35c66ab..bb647f736 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -885,7 +885,6 @@ cryptodev_aesni_mb_create(const char *name,
 
 	internals->vector_mode = vector_mode;
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 }
@@ -897,8 +896,7 @@ cryptodev_aesni_mb_probe(struct rte_vdev_device *vdev)
 		"",
 		sizeof(struct aesni_mb_private),
 		rte_socket_id(),
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 	};
 	const char *name, *args;
 	int retval;
@@ -947,7 +945,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_MB_PMD, cryptodev_aesni_mb_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_MB_PMD, cryptodev_aesni_mb_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_MB_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(aesni_mb_crypto_drv,
 		cryptodev_aesni_mb_pmd_drv.driver,
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index 01530523f..7c735f5dc 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -387,7 +387,6 @@ aesni_mb_pmd_info_get(struct rte_cryptodev *dev,
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = aesni_mb_pmd_capabilities;
 		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
index a33b2f695..9520cdf9c 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
@@ -124,8 +124,6 @@ struct aesni_mb_private {
 	/**< CPU vector instruction set mode */
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 };
 
 /** AESNI Multi buffer queue pair */
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index fbb08f729..db0d8a2a9 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -779,7 +779,6 @@ cryptodev_armv8_crypto_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 
@@ -800,8 +799,7 @@ cryptodev_armv8_crypto_init(struct rte_vdev_device *vdev)
 		"",
 		sizeof(struct armv8_crypto_private),
 		rte_socket_id(),
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 	};
 	const char *name;
 	const char *input_args;
@@ -848,7 +846,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(armv8_crypto_drv, armv8_crypto_pmd_drv.driver,
 		cryptodev_driver_id);
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index c64aef09f..d31ef7d66 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -154,7 +154,6 @@ armv8_crypto_pmd_info_get(struct rte_cryptodev *dev,
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = armv8_crypto_pmd_capabilities;
 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
index b8966e934..7feb021db 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_private.h
+++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
@@ -106,8 +106,6 @@ typedef void (*crypto_key_sched_t)(uint8_t *, const uint8_t *);
 struct armv8_crypto_private {
 	unsigned int max_nb_qpairs;
 	/**< Max number of queue pairs */
-	unsigned int max_nb_sessions;
-	/**< Max number of sessions */
 };
 
 /** ARMv8 crypto queue pair */
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index 80b75ccb0..7e383feed 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -624,7 +624,6 @@ ccp_pmd_info_get(struct rte_cryptodev *dev,
 		if (internals->auth_opt == 1)
 			dev_info->capabilities = ccp_crypto_cap_complete;
 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/ccp/ccp_pmd_private.h b/drivers/crypto/ccp/ccp_pmd_private.h
index f4498048f..79752f687 100644
--- a/drivers/crypto/ccp/ccp_pmd_private.h
+++ b/drivers/crypto/ccp/ccp_pmd_private.h
@@ -40,7 +40,6 @@
 /* private data structure for each CCP crypto device */
 struct ccp_private {
 	unsigned int max_nb_qpairs;	/**< Max number of queue pairs */
-	unsigned int max_nb_sessions;	/**< Max number of sessions */
 	uint8_t crypto_num_dev;		/**< Number of working crypto devices */
 	bool auth_opt;			/**< Authentication offload option */
 	struct ccp_device *last_dev;	/**< Last working crypto device */
diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c b/drivers/crypto/ccp/rte_ccp_pmd.c
index 2061f465e..d70640f6d 100644
--- a/drivers/crypto/ccp/rte_ccp_pmd.c
+++ b/drivers/crypto/ccp/rte_ccp_pmd.c
@@ -30,14 +30,12 @@ struct ccp_pmd_init_params {
 #define CCP_CRYPTODEV_PARAM_NAME		("name")
 #define CCP_CRYPTODEV_PARAM_SOCKET_ID		("socket_id")
 #define CCP_CRYPTODEV_PARAM_MAX_NB_QP		("max_nb_queue_pairs")
-#define CCP_CRYPTODEV_PARAM_MAX_NB_SESS		("max_nb_sessions")
 #define CCP_CRYPTODEV_PARAM_AUTH_OPT		("ccp_auth_opt")
 
 const char *ccp_pmd_valid_params[] = {
 	CCP_CRYPTODEV_PARAM_NAME,
 	CCP_CRYPTODEV_PARAM_SOCKET_ID,
 	CCP_CRYPTODEV_PARAM_MAX_NB_QP,
-	CCP_CRYPTODEV_PARAM_MAX_NB_SESS,
 	CCP_CRYPTODEV_PARAM_AUTH_OPT,
 };
 
@@ -124,13 +122,6 @@ ccp_pmd_parse_input_args(struct ccp_pmd_init_params *params,
 		if (ret < 0)
 			goto free_kvlist;
 
-		ret = rte_kvargs_process(kvlist,
-					 CCP_CRYPTODEV_PARAM_MAX_NB_SESS,
-					 &parse_integer_arg,
-					 &params->def_p.max_nb_sessions);
-		if (ret < 0)
-			goto free_kvlist;
-
 		ret = rte_kvargs_process(kvlist,
 					 CCP_CRYPTODEV_PARAM_SOCKET_ID,
 					 &parse_integer_arg,
@@ -334,7 +325,6 @@ cryptodev_ccp_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_qpairs = init_params->def_p.max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->def_p.max_nb_sessions;
 	internals->auth_opt = init_params->auth_opt;
 	internals->crypto_num_dev = cryptodev_cnt;
 
@@ -359,8 +349,7 @@ cryptodev_ccp_probe(struct rte_vdev_device *vdev)
 			"",
 			sizeof(struct ccp_private),
 			rte_socket_id(),
-			CCP_PMD_MAX_QUEUE_PAIRS,
-			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+			CCP_PMD_MAX_QUEUE_PAIRS
 		},
 		.auth_opt = CCP_PMD_AUTH_OPT_CCP,
 	};
@@ -382,8 +371,6 @@ cryptodev_ccp_probe(struct rte_vdev_device *vdev)
 		init_params.def_p.socket_id);
 	RTE_LOG(INFO, PMD, "Max number of queue pairs = %d\n",
 		init_params.def_p.max_nb_queue_pairs);
-	RTE_LOG(INFO, PMD, "Max number of sessions = %d\n",
-		init_params.def_p.max_nb_sessions);
 	RTE_LOG(INFO, PMD, "Authentication offload to %s\n",
 		((init_params.auth_opt == 0) ? "CCP" : "CPU"));
 
@@ -404,7 +391,6 @@ static struct cryptodev_driver ccp_crypto_drv;
 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_CCP_PMD, cryptodev_ccp_pmd_drv);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CCP_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int> "
 	"ccp_auth_opt=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(ccp_crypto_drv, cryptodev_ccp_pmd_drv.driver,
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 56fa969d3..16ab0b6a6 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -55,6 +55,8 @@ typedef uint64_t	dma_addr_t;
 #define SEC_FLC_DHR_OUTBOUND	-114
 #define SEC_FLC_DHR_INBOUND	0
 
+#define RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS 2048
+
 enum rta_sec_era rta_sec_era = RTA_SEC_ERA_8;
 
 static uint8_t cryptodev_driver_id;
@@ -2626,7 +2628,6 @@ dpaa2_sec_dev_infos_get(struct rte_cryptodev *dev,
 		info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
 		info->feature_flags = dev->feature_flags;
 		info->capabilities = dpaa2_sec_capabilities;
-		info->sym.max_nb_sessions = internals->max_nb_sessions;
 		info->driver_id = cryptodev_driver_id;
 	}
 }
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index 73cae483b..909583bd0 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -2214,7 +2214,6 @@ dpaa_sec_dev_infos_get(struct rte_cryptodev *dev,
 		info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
 		info->feature_flags = dev->feature_flags;
 		info->capabilities = dpaa_sec_capabilities;
-		info->sym.max_nb_sessions = internals->max_nb_sessions;
 		info->driver_id = cryptodev_driver_id;
 	}
 }
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.h b/drivers/crypto/dpaa_sec/dpaa_sec.h
index e15e373fd..91df68009 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.h
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.h
@@ -137,6 +137,7 @@ struct dpaa_sec_qp {
 };
 
 #define RTE_DPAA_MAX_NB_SEC_QPS 8
+#define RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS 2048
 #define RTE_DPAA_MAX_RX_QUEUE RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS
 #define DPAA_MAX_DEQUEUE_NUM_FRAMES 63
 
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 205dc1de7..65376b211 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -555,7 +555,6 @@ cryptodev_kasumi_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 init_error:
@@ -573,8 +572,7 @@ cryptodev_kasumi_probe(struct rte_vdev_device *vdev)
 		"",
 		sizeof(struct kasumi_private),
 		rte_socket_id(),
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 	};
 	const char *name;
 	const char *input_args;
@@ -617,7 +615,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_KASUMI_PMD, cryptodev_kasumi_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_KASUMI_PMD, cryptodev_kasumi_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_KASUMI_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(kasumi_crypto_drv,
 		cryptodev_kasumi_pmd_drv.driver, cryptodev_driver_id);
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index a388dbb63..284669341 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -126,7 +126,6 @@ kasumi_pmd_info_get(struct rte_cryptodev *dev,
 	if (dev_info != NULL) {
 		dev_info->driver_id = dev->driver_id;
 		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = kasumi_pmd_capabilities;
 	}
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
index a397bee65..2b12818bc 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
@@ -36,8 +36,6 @@
 struct kasumi_private {
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 };
 
 /** KASUMI buffer queue pair */
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd.c b/drivers/crypto/mvsam/rte_mrvl_pmd.c
index 1b6029a56..822b6cac7 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd.c
@@ -719,7 +719,6 @@ cryptodev_mrvl_crypto_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	/*
 	 * ret == -EEXIST is correct, it means DMA
@@ -734,8 +733,6 @@ cryptodev_mrvl_crypto_create(const char *name,
 			"DMA memory has been already initialized by a different driver.");
 	}
 
-	sam_params.max_num_sessions = internals->max_nb_sessions;
-
 	return sam_init(&sam_params);
 
 init_error:
@@ -766,8 +763,6 @@ cryptodev_mrvl_crypto_init(struct rte_vdev_device *vdev)
 
 	init_params.private_data_size = sizeof(struct mrvl_crypto_private);
 	init_params.max_nb_queue_pairs = sam_get_num_inst() * SAM_HW_RING_NUM;
-	init_params.max_nb_sessions =
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS;
 	init_params.socket_id = rte_socket_id();
 
 	ret = rte_cryptodev_pmd_parse_input_args(&init_params, args);
@@ -823,7 +818,6 @@ static struct cryptodev_driver mrvl_crypto_drv;
 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_MRVL_PMD, cryptodev_mrvl_pmd_drv);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_MRVL_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(mrvl_crypto_drv, cryptodev_mrvl_pmd_drv.driver,
 		cryptodev_driver_id);
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 3f8de37b7..944a415cf 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -471,7 +471,6 @@ mrvl_crypto_pmd_info_get(struct rte_cryptodev *dev,
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = mrvl_crypto_pmd_capabilities;
 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
index c16d95b46..bb528493a 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
@@ -51,7 +51,6 @@ enum mrvl_crypto_chain_order {
 /** Private data structure for each crypto device. */
 struct mrvl_crypto_private {
 	unsigned int max_nb_qpairs;	/**< Max number of queue pairs */
-	unsigned int max_nb_sessions;	/**< Max number of sessions */
 };
 
 /** MRVL crypto queue pair structure. */
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 052b6546c..a8499cf94 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -182,7 +182,6 @@ cryptodev_null_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 }
@@ -196,7 +195,6 @@ cryptodev_null_probe(struct rte_vdev_device *dev)
 		sizeof(struct null_crypto_private),
 		rte_socket_id(),
 		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
 	};
 	const char *name, *args;
 	int retval;
@@ -245,7 +243,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_NULL_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(null_crypto_drv, cryptodev_null_pmd_drv.driver,
 		cryptodev_driver_id);
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index f8e5f61f1..3ca1370e8 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -121,7 +121,6 @@ null_crypto_pmd_info_get(struct rte_cryptodev *dev,
 	if (dev_info != NULL) {
 		dev_info->driver_id = dev->driver_id;
 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = null_crypto_pmd_capabilities;
 	}
diff --git a/drivers/crypto/null/null_crypto_pmd_private.h b/drivers/crypto/null/null_crypto_pmd_private.h
index 0fd133625..d7d769f3d 100644
--- a/drivers/crypto/null/null_crypto_pmd_private.h
+++ b/drivers/crypto/null/null_crypto_pmd_private.h
@@ -32,7 +32,6 @@
 /** private data structure for each NULL crypto device */
 struct null_crypto_private {
 	unsigned max_nb_qpairs;		/**< Max number of queue pairs */
-	unsigned max_nb_sessions;	/**< Max number of sessions */
 };
 
 /** NULL crypto queue pair */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 93c6d7e5d..965cab9f2 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1666,7 +1666,6 @@ cryptodev_openssl_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 
@@ -1687,7 +1686,6 @@ cryptodev_openssl_probe(struct rte_vdev_device *vdev)
 		sizeof(struct openssl_private),
 		rte_socket_id(),
 		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
 	};
 	const char *name;
 	const char *input_args;
@@ -1731,7 +1729,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_OPENSSL_PMD,
 	cryptodev_openssl_pmd_drv);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv,
 		cryptodev_openssl_pmd_drv.driver, cryptodev_driver_id);
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 1cb87d59a..485c80e7f 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -547,7 +547,6 @@ openssl_pmd_info_get(struct rte_cryptodev *dev,
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = openssl_pmd_capabilities;
 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 	}
 }
 
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index bc8dc7cdc..02ea81d5c 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -62,8 +62,6 @@ enum openssl_auth_mode {
 struct openssl_private {
 	unsigned int max_nb_qpairs;
 	/**< Max number of queue pairs */
-	unsigned int max_nb_sessions;
-	/**< Max number of sessions */
 };
 
 /** OPENSSL crypto queue pair */
diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
index 768dcbae0..e89d3bc11 100644
--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -1654,7 +1654,6 @@ void qat_dev_info_get(struct rte_cryptodev *dev,
 				ADF_NUM_BUNDLES_PER_DEV;
 		info->feature_flags = dev->feature_flags;
 		info->capabilities = internals->qat_dev_capabilities;
-		info->sym.max_nb_sessions = internals->max_nb_sessions;
 		info->driver_id = cryptodev_qat_driver_id;
 	}
 }
diff --git a/drivers/crypto/qat/qat_crypto.h b/drivers/crypto/qat/qat_crypto.h
index 281a142b9..c84cf669f 100644
--- a/drivers/crypto/qat/qat_crypto.h
+++ b/drivers/crypto/qat/qat_crypto.h
@@ -75,8 +75,6 @@ struct qat_qp {
 struct qat_pmd_private {
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 	enum qat_device_gen qat_dev_gen;
 	/**< QAT device generation */
 	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index c8da07af6..74a903d3a 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -94,7 +94,6 @@ crypto_qat_create(const char *name, struct rte_pci_device *pci_dev,
 			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
 
 	internals = cryptodev->data->dev_private;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 	switch (pci_dev->id.device_id) {
 	case 0x0443:
 		internals->qat_dev_gen = QAT_GEN1;
@@ -131,8 +130,7 @@ static int crypto_qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_cryptodev_pmd_init_params init_params = {
 		.name = "",
 		.socket_id = pci_dev->device.numa_node,
-		.private_data_size = sizeof(struct qat_pmd_private),
-		.max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS
+		.private_data_size = sizeof(struct qat_pmd_private)
 	};
 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
 
diff --git a/drivers/crypto/scheduler/scheduler_pmd.c b/drivers/crypto/scheduler/scheduler_pmd.c
index 25d6409f3..32a19c106 100644
--- a/drivers/crypto/scheduler/scheduler_pmd.c
+++ b/drivers/crypto/scheduler/scheduler_pmd.c
@@ -31,7 +31,6 @@ struct scheduler_init_params {
 #define RTE_CRYPTODEV_VDEV_MODE			("mode")
 #define RTE_CRYPTODEV_VDEV_ORDERING		("ordering")
 #define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG	("max_nb_queue_pairs")
-#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG	("max_nb_sessions")
 #define RTE_CRYPTODEV_VDEV_SOCKET_ID		("socket_id")
 #define RTE_CRYPTODEV_VDEV_COREMASK		("coremask")
 #define RTE_CRYPTODEV_VDEV_CORELIST		("corelist")
@@ -42,7 +41,6 @@ const char *scheduler_valid_params[] = {
 	RTE_CRYPTODEV_VDEV_MODE,
 	RTE_CRYPTODEV_VDEV_ORDERING,
 	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
-	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
 	RTE_CRYPTODEV_VDEV_SOCKET_ID,
 	RTE_CRYPTODEV_VDEV_COREMASK,
 	RTE_CRYPTODEV_VDEV_CORELIST
@@ -406,13 +404,6 @@ scheduler_parse_init_params(struct scheduler_init_params *params,
 		if (ret < 0)
 			goto free_kvlist;
 
-		ret = rte_kvargs_process(kvlist,
-				RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
-				&parse_integer_arg,
-				&params->def_p.max_nb_sessions);
-		if (ret < 0)
-			goto free_kvlist;
-
 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
 				&parse_integer_arg,
 				&params->def_p.socket_id);
@@ -466,8 +457,7 @@ cryptodev_scheduler_probe(struct rte_vdev_device *vdev)
 			"",
 			sizeof(struct scheduler_ctx),
 			rte_socket_id(),
-			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 		},
 		.nb_slaves = 0,
 		.mode = CDEV_SCHED_MODE_NOT_SET,
@@ -500,7 +490,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SCHEDULER_PMD,
 	cryptodev_scheduler_pmd_drv);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SCHEDULER_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int> "
 	"slave=<name>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(scheduler_crypto_drv,
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 147dc51e9..88be72a05 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -321,8 +321,6 @@ scheduler_pmd_info_get(struct rte_cryptodev *dev,
 		struct rte_cryptodev_info *dev_info)
 {
 	struct scheduler_ctx *sched_ctx = dev->data->dev_private;
-	uint32_t max_nb_sessions = sched_ctx->nb_slaves ?
-			UINT32_MAX : RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS;
 	uint32_t i;
 
 	if (!dev_info)
@@ -338,17 +336,12 @@ scheduler_pmd_info_get(struct rte_cryptodev *dev,
 		struct rte_cryptodev_info slave_info;
 
 		rte_cryptodev_info_get(slave_dev_id, &slave_info);
-		max_nb_sessions = slave_info.sym.max_nb_sessions <
-				max_nb_sessions ?
-				slave_info.sym.max_nb_sessions :
-				max_nb_sessions;
 	}
 
 	dev_info->driver_id = dev->driver_id;
 	dev_info->feature_flags = dev->feature_flags;
 	dev_info->capabilities = sched_ctx->capabilities;
 	dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs;
-	dev_info->sym.max_nb_sessions = max_nb_sessions;
 }
 
 /** Release queue pair */
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 72751e35e..fe595abe1 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -555,7 +555,6 @@ cryptodev_snow3g_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 init_error:
@@ -574,7 +573,6 @@ cryptodev_snow3g_probe(struct rte_vdev_device *vdev)
 		sizeof(struct snow3g_private),
 		rte_socket_id(),
 		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
 	};
 	const char *name;
 	const char *input_args;
@@ -617,7 +615,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SNOW3G_PMD, cryptodev_snow3g_pmd_drv);
 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_SNOW3G_PMD, cryptodev_snow3g_pmd);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SNOW3G_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(snow3g_crypto_drv,
 		cryptodev_snow3g_pmd_drv.driver, cryptodev_driver_id);
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index f60b47598..fff4644c0 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -130,7 +130,6 @@ snow3g_pmd_info_get(struct rte_cryptodev *dev,
 	if (dev_info != NULL) {
 		dev_info->driver_id = dev->driver_id;
 		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = snow3g_pmd_capabilities;
 	}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
index eea900e0a..2c6e1a948 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
@@ -36,8 +36,6 @@
 struct snow3g_private {
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 };
 
 /** SNOW 3G buffer queue pair */
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 482edea1a..8395801a4 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1411,8 +1411,6 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
 		info->driver_id = cryptodev_virtio_driver_id;
 		info->feature_flags = dev->feature_flags;
 		info->max_nb_queue_pairs = hw->max_dataqueues;
-		info->sym.max_nb_sessions =
-			RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS;
 		info->capabilities = hw->virtio_dev_capabilities;
 	}
 }
@@ -1426,7 +1424,6 @@ crypto_virtio_pci_probe(
 		.name = "",
 		.socket_id = rte_socket_id(),
 		.private_data_size = sizeof(struct virtio_crypto_hw),
-		.max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS
 	};
 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
 
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index a805b2278..396f25975 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -479,7 +479,6 @@ cryptodev_zuc_create(const char *name,
 	internals = dev->data->dev_private;
 
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
-	internals->max_nb_sessions = init_params->max_nb_sessions;
 
 	return 0;
 init_error:
@@ -497,8 +496,7 @@ cryptodev_zuc_probe(struct rte_vdev_device *vdev)
 		"",
 		sizeof(struct zuc_private),
 		rte_socket_id(),
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
-		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
+		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
 	};
 	const char *name;
 	const char *input_args;
@@ -541,7 +539,6 @@ static struct cryptodev_driver zuc_crypto_drv;
 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ZUC_PMD, cryptodev_zuc_pmd_drv);
 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ZUC_PMD,
 	"max_nb_queue_pairs=<int> "
-	"max_nb_sessions=<int> "
 	"socket_id=<int>");
 RTE_PMD_REGISTER_CRYPTO_DRIVER(zuc_crypto_drv, cryptodev_zuc_pmd_drv.driver,
 		cryptodev_driver_id);
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index 8abac8989..ac509e70d 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -130,7 +130,6 @@ zuc_pmd_info_get(struct rte_cryptodev *dev,
 	if (dev_info != NULL) {
 		dev_info->driver_id = dev->driver_id;
 		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
-		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
 		dev_info->feature_flags = dev->feature_flags;
 		dev_info->capabilities = zuc_pmd_capabilities;
 	}
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_private.h b/drivers/crypto/zuc/rte_zuc_pmd_private.h
index b83c4a047..2bd378ad6 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_private.h
+++ b/drivers/crypto/zuc/rte_zuc_pmd_private.h
@@ -37,8 +37,6 @@
 struct zuc_private {
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
-	unsigned max_nb_sessions;
-	/**< Max number of sessions supported by device */
 };
 
 /** ZUC buffer queue pair */
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a4b8cccc2..78be5bdb8 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -381,11 +381,6 @@ struct rte_cryptodev_info {
 
 	unsigned max_nb_queue_pairs;
 	/**< Maximum number of queues pairs supported by device. */
-
-	struct {
-		unsigned max_nb_sessions;
-		/**< Maximum number of sessions supported by device. */
-	} sym;
 };
 
 #define RTE_CRYPTODEV_DETACHED  (0)
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index f2aac24b7..2088ac3f3 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -65,13 +65,6 @@ rte_cryptodev_pmd_parse_input_args(
 		if (ret < 0)
 			goto free_kvlist;
 
-		ret = rte_kvargs_process(kvlist,
-				RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
-				&rte_cryptodev_pmd_parse_uint_arg,
-				&params->max_nb_sessions);
-		if (ret < 0)
-			goto free_kvlist;
-
 		ret = rte_kvargs_process(kvlist,
 				RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
 				&rte_cryptodev_pmd_parse_uint_arg,
@@ -109,10 +102,9 @@ rte_cryptodev_pmd_create(const char *name,
 			device->driver->name, name);
 
 	CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s,"
-			"socket id: %d, max queue pairs: %u, max sessions: %u",
+			"socket id: %d, max queue pairs: %u",
 			device->driver->name, name,
-			params->socket_id, params->max_nb_queue_pairs,
-			params->max_nb_sessions);
+			params->socket_id, params->max_nb_queue_pairs);
 
 	/* allocate device structure */
 	cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 69d776934..0739ce065 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -59,18 +59,15 @@ extern "C" {
 
 
 #define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS	8
-#define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS	2048
 
 #define RTE_CRYPTODEV_PMD_NAME_ARG			("name")
 #define RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG			("max_nb_queue_pairs")
-#define RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG		("max_nb_sessions")
 #define RTE_CRYPTODEV_PMD_SOCKET_ID_ARG			("socket_id")
 
 
 static const char * const cryptodev_pmd_valid_params[] = {
 	RTE_CRYPTODEV_PMD_NAME_ARG,
 	RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
-	RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
 	RTE_CRYPTODEV_PMD_SOCKET_ID_ARG
 };
 
@@ -83,7 +80,6 @@ struct rte_cryptodev_pmd_init_params {
 	size_t private_data_size;
 	int socket_id;
 	unsigned int max_nb_queue_pairs;
-	unsigned int max_nb_sessions;
 };
 
 /** Global structure used for maintaining state of allocated crypto devices */
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 389f79677..2c687bd7c 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -39,6 +39,7 @@
 #include "test_cryptodev_hmac_test_vectors.h"
 
 #define VDEV_ARGS_SIZE 100
+#define MAX_NB_SESSIONS            4
 
 static int gbl_driver_id;
 
@@ -437,7 +438,7 @@ testsuite_setup(void)
 	 */
 	ts_params->session_mpool = rte_mempool_create(
 				"test_sess_mp",
-				info.sym.max_nb_sessions * 2,
+				MAX_NB_SESSIONS * 2,
 				session_size,
 				0, 0, NULL, NULL, NULL,
 				NULL, SOCKET_ID_ANY,
@@ -6499,10 +6500,10 @@ test_multi_session(void)
 
 	sessions = rte_malloc(NULL,
 			(sizeof(struct rte_cryptodev_sym_session *) *
-			dev_info.sym.max_nb_sessions) + 1, 0);
+			MAX_NB_SESSIONS) + 1, 0);
 
 	/* Create multiple crypto sessions*/
-	for (i = 0; i < dev_info.sym.max_nb_sessions; i++) {
+	for (i = 0; i < MAX_NB_SESSIONS; i++) {
 
 		sessions[i] = rte_cryptodev_sym_session_create(
 				ts_params->session_mpool);
@@ -6551,7 +6552,7 @@ test_multi_session(void)
 	TEST_ASSERT_NULL(sessions[i],
 			"Session creation succeeded unexpectedly!");
 
-	for (i = 0; i < dev_info.sym.max_nb_sessions; i++) {
+	for (i = 0; i < MAX_NB_SESSIONS; i++) {
 		rte_cryptodev_sym_session_clear(ts_params->valid_devs[0],
 				sessions[i]);
 		rte_cryptodev_sym_session_free(sessions[i]);
@@ -6610,7 +6611,7 @@ test_multi_session_random_usage(void)
 
 	sessions = rte_malloc(NULL,
 			(sizeof(struct rte_cryptodev_sym_session *)
-					* dev_info.sym.max_nb_sessions) + 1, 0);
+					* MAX_NB_SESSIONS) + 1, 0);
 
 	for (i = 0; i < MB_SESSION_NUMBER; i++) {
 		sessions[i] = rte_cryptodev_sym_session_create(
@@ -8545,7 +8546,7 @@ test_scheduler_attach_slave_op(void)
 		if (ts_params->session_mpool == NULL) {
 			ts_params->session_mpool = rte_mempool_create(
 					"test_sess_mp",
-					info.sym.max_nb_sessions * 2,
+					MAX_NB_SESSIONS * 2,
 					session_size,
 					0, 0, NULL, NULL, NULL,
 					NULL, SOCKET_ID_ANY,
-- 
2.17.0

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH 4/6] cryptodev: remove queue start/stop functions
    2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 1/6] cryptodev: replace bus specific struct with generic dev Pablo de Lara
  2018-06-08 22:02  1% ` [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions Pablo de Lara
@ 2018-06-08 22:02  2% ` Pablo de Lara
  2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions Pablo de Lara
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-08 22:02 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed cryptodev queue start/stop functions,
as they were marked deprecated in 18.05, since they
were not implemented by any driver.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst          |  4 --
 doc/guides/rel_notes/release_18_08.rst        |  5 +++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c  | 18 --------
 .../crypto/aesni_mb/rte_aesni_mb_pmd_ops.c    | 18 --------
 drivers/crypto/armv8/rte_armv8_pmd_ops.c      | 18 --------
 drivers/crypto/ccp/ccp_pmd_ops.c              | 16 -------
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c   | 22 ----------
 drivers/crypto/dpaa_sec/dpaa_sec.c            | 22 ----------
 drivers/crypto/kasumi/rte_kasumi_pmd_ops.c    | 18 --------
 drivers/crypto/mvsam/rte_mrvl_pmd_ops.c       | 28 ------------
 drivers/crypto/null/null_crypto_pmd_ops.c     | 18 --------
 drivers/crypto/openssl/rte_openssl_pmd_ops.c  | 18 --------
 drivers/crypto/qat/rte_qat_cryptodev.c        |  2 -
 drivers/crypto/scheduler/scheduler_pmd_ops.c  | 18 --------
 drivers/crypto/snow3g/rte_snow3g_pmd_ops.c    | 18 --------
 drivers/crypto/virtio/virtio_cryptodev.c      |  2 -
 drivers/crypto/zuc/rte_zuc_pmd_ops.c          | 18 --------
 lib/librte_cryptodev/rte_cryptodev.c          | 44 -------------------
 lib/librte_cryptodev/rte_cryptodev.h          | 37 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.h      | 26 -----------
 .../rte_cryptodev_version.map                 |  2 -
 21 files changed, 5 insertions(+), 367 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index dc014da21..91592534e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,10 +105,6 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Functions ``rte_cryptodev_queue_pair_start()`` and
-    ``rte_cryptodev_queue_pair_stop()`` will be deprecated from 18.05
-    and removed in 18.08, as there are no drivers doing anything useful
-    with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
   - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index a6f31713a..3fa9a6e68 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -59,6 +59,11 @@ API Changes
   has been replaced with field ``struct rte_device *device`` and
   field ``sym`` has been removed.
 
+* cryptodev: Following functions were deprecated and are removed in 18.08:
+
+  - ``rte_cryptodev_queue_pair_start``
+  - ``rte_cryptodev_queue_pair_stop``
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index b05122c1b..2a3ca4e26 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -241,22 +241,6 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_gcm_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_gcm_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_gcm_pmd_qp_count(struct rte_cryptodev *dev)
@@ -338,8 +322,6 @@ struct rte_cryptodev_ops aesni_gcm_pmd_ops = {
 
 		.queue_pair_setup	= aesni_gcm_pmd_qp_setup,
 		.queue_pair_release	= aesni_gcm_pmd_qp_release,
-		.queue_pair_start	= aesni_gcm_pmd_qp_start,
-		.queue_pair_stop	= aesni_gcm_pmd_qp_stop,
 		.queue_pair_count	= aesni_gcm_pmd_qp_count,
 
 		.session_get_size	= aesni_gcm_pmd_session_get_size,
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index 7c735f5dc..1044946ec 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -507,22 +507,6 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_mb_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_mb_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_mb_pmd_qp_count(struct rte_cryptodev *dev)
@@ -605,8 +589,6 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
 
 		.queue_pair_setup	= aesni_mb_pmd_qp_setup,
 		.queue_pair_release	= aesni_mb_pmd_qp_release,
-		.queue_pair_start	= aesni_mb_pmd_qp_start,
-		.queue_pair_stop	= aesni_mb_pmd_qp_stop,
 		.queue_pair_count	= aesni_mb_pmd_qp_count,
 
 		.session_get_size	= aesni_mb_pmd_session_get_size,
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index d31ef7d66..05217a1a9 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -256,22 +256,6 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-armv8_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-armv8_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -352,8 +336,6 @@ struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
 
 		.queue_pair_setup	= armv8_crypto_pmd_qp_setup,
 		.queue_pair_release	= armv8_crypto_pmd_qp_release,
-		.queue_pair_start	= armv8_crypto_pmd_qp_start,
-		.queue_pair_stop	= armv8_crypto_pmd_qp_stop,
 		.queue_pair_count	= armv8_crypto_pmd_qp_count,
 
 		.session_get_size	= armv8_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index 7e383feed..ff815f6ca 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -746,20 +746,6 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-static int
-ccp_pmd_qp_start(struct rte_cryptodev *dev __rte_unused,
-		 uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
-static int
-ccp_pmd_qp_stop(struct rte_cryptodev *dev __rte_unused,
-		uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
 static uint32_t
 ccp_pmd_qp_count(struct rte_cryptodev *dev)
 {
@@ -835,8 +821,6 @@ struct rte_cryptodev_ops ccp_ops = {
 
 		.queue_pair_setup	= ccp_pmd_qp_setup,
 		.queue_pair_release	= ccp_pmd_qp_release,
-		.queue_pair_start	= ccp_pmd_qp_start,
-		.queue_pair_stop	= ccp_pmd_qp_stop,
 		.queue_pair_count	= ccp_pmd_qp_count,
 
 		.session_get_size	= ccp_pmd_session_get_size,
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 16ab0b6a6..471ad1cbb 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1472,26 +1472,6 @@ dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return retcode;
 }
 
-/** Start queue pair */
-static int
-dpaa2_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			   __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa2_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa2_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2716,8 +2696,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.stats_reset	      = dpaa2_sec_stats_reset,
 	.queue_pair_setup     = dpaa2_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa2_sec_queue_pair_release,
-	.queue_pair_start     = dpaa2_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa2_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa2_sec_queue_pair_count,
 	.session_get_size     = dpaa2_sec_session_get_size,
 	.session_configure    = dpaa2_sec_session_configure,
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index 909583bd0..e7ae33c5e 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1585,26 +1585,6 @@ dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-dpaa_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			 __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2226,8 +2206,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.dev_infos_get        = dpaa_sec_dev_infos_get,
 	.queue_pair_setup     = dpaa_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa_sec_queue_pair_release,
-	.queue_pair_start     = dpaa_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa_sec_queue_pair_count,
 	.session_get_size     = dpaa_sec_session_get_size,
 	.session_configure    = dpaa_sec_session_configure,
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index 284669341..64dba3024 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -227,22 +227,6 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-kasumi_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-kasumi_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 kasumi_pmd_qp_count(struct rte_cryptodev *dev)
@@ -323,8 +307,6 @@ struct rte_cryptodev_ops kasumi_pmd_ops = {
 
 		.queue_pair_setup   = kasumi_pmd_qp_setup,
 		.queue_pair_release = kasumi_pmd_qp_release,
-		.queue_pair_start   = kasumi_pmd_qp_start,
-		.queue_pair_stop    = kasumi_pmd_qp_stop,
 		.queue_pair_count   = kasumi_pmd_qp_count,
 
 		.session_get_size   = kasumi_pmd_session_get_size,
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 944a415cf..c131b40e8 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -594,32 +594,6 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs (PMD ops callback).
  *
  * @param dev Pointer to the device structure.
@@ -737,8 +711,6 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
 
 		.queue_pair_setup	= mrvl_crypto_pmd_qp_setup,
 		.queue_pair_release	= mrvl_crypto_pmd_qp_release,
-		.queue_pair_start	= mrvl_crypto_pmd_qp_start,
-		.queue_pair_stop	= mrvl_crypto_pmd_qp_stop,
 		.queue_pair_count	= mrvl_crypto_pmd_qp_count,
 
 		.session_get_size	= mrvl_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 3ca1370e8..769879136 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -238,22 +238,6 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-null_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-null_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 null_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -334,8 +318,6 @@ struct rte_cryptodev_ops pmd_ops = {
 
 		.queue_pair_setup	= null_crypto_pmd_qp_setup,
 		.queue_pair_release	= null_crypto_pmd_qp_release,
-		.queue_pair_start	= null_crypto_pmd_qp_start,
-		.queue_pair_stop	= null_crypto_pmd_qp_stop,
 		.queue_pair_count	= null_crypto_pmd_qp_count,
 
 		.session_get_size	= null_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 485c80e7f..396a32d73 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -646,22 +646,6 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-openssl_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-openssl_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 openssl_pmd_qp_count(struct rte_cryptodev *dev)
@@ -744,8 +728,6 @@ struct rte_cryptodev_ops openssl_pmd_ops = {
 
 		.queue_pair_setup	= openssl_pmd_qp_setup,
 		.queue_pair_release	= openssl_pmd_qp_release,
-		.queue_pair_start	= openssl_pmd_qp_start,
-		.queue_pair_stop	= openssl_pmd_qp_stop,
 		.queue_pair_count	= openssl_pmd_qp_count,
 
 		.session_get_size	= openssl_pmd_session_get_size,
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 74a903d3a..bb109f8ba 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -38,8 +38,6 @@ static struct rte_cryptodev_ops crypto_qat_ops = {
 		.stats_reset		= qat_crypto_sym_stats_reset,
 		.queue_pair_setup	= qat_crypto_sym_qp_setup,
 		.queue_pair_release	= qat_crypto_sym_qp_release,
-		.queue_pair_start	= NULL,
-		.queue_pair_stop	= NULL,
 		.queue_pair_count	= NULL,
 
 		/* Crypto related operations */
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 88be72a05..c3ad364eb 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -432,22 +432,6 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-scheduler_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-scheduler_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 scheduler_pmd_qp_count(struct rte_cryptodev *dev)
@@ -528,8 +512,6 @@ struct rte_cryptodev_ops scheduler_pmd_ops = {
 
 		.queue_pair_setup	= scheduler_pmd_qp_setup,
 		.queue_pair_release	= scheduler_pmd_qp_release,
-		.queue_pair_start	= scheduler_pmd_qp_start,
-		.queue_pair_stop	= scheduler_pmd_qp_stop,
 		.queue_pair_count	= scheduler_pmd_qp_count,
 
 		.session_get_size	= scheduler_pmd_session_get_size,
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index fff4644c0..63c2e245f 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -229,22 +229,6 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-snow3g_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-snow3g_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 snow3g_pmd_qp_count(struct rte_cryptodev *dev)
@@ -325,8 +309,6 @@ struct rte_cryptodev_ops snow3g_pmd_ops = {
 
 		.queue_pair_setup   = snow3g_pmd_qp_setup,
 		.queue_pair_release = snow3g_pmd_qp_release,
-		.queue_pair_start   = snow3g_pmd_qp_start,
-		.queue_pair_stop    = snow3g_pmd_qp_stop,
 		.queue_pair_count   = snow3g_pmd_qp_count,
 
 		.session_get_size   = snow3g_pmd_session_get_size,
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 8395801a4..1e74f0485 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -515,8 +515,6 @@ static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
 
 	.queue_pair_setup                = virtio_crypto_qp_setup,
 	.queue_pair_release              = virtio_crypto_qp_release,
-	.queue_pair_start                = NULL,
-	.queue_pair_stop                 = NULL,
 	.queue_pair_count                = NULL,
 
 	/* Crypto related operations */
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index ac509e70d..5d0f057de 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -229,22 +229,6 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-zuc_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-zuc_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 zuc_pmd_qp_count(struct rte_cryptodev *dev)
@@ -325,8 +309,6 @@ struct rte_cryptodev_ops zuc_pmd_ops = {
 
 		.queue_pair_setup   = zuc_pmd_qp_setup,
 		.queue_pair_release = zuc_pmd_qp_release,
-		.queue_pair_start   = zuc_pmd_qp_start,
-		.queue_pair_stop    = zuc_pmd_qp_stop,
 		.queue_pair_count   = zuc_pmd_qp_count,
 
 		.session_get_size   = zuc_pmd_session_get_size,
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 457ac5670..a07904fb9 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -702,50 +702,6 @@ rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
 	return 0;
 }
 
-int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_start, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_start(dev, queue_pair_id);
-
-}
-
-int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_stop, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_stop(dev, queue_pair_id);
-
-}
-
 int
 rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 78be5bdb8..90487bffc 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -593,43 +593,6 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
 		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
 		struct rte_mempool *session_pool);
 
-/**
- * @deprecated
- * Start a specified queue pair of a device. It is used
- * when deferred_start flag of the specified queue is true.
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to start. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_crypto_dev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id);
-
-/**
- * @deprecated
- * Stop specified queue pair of a device
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to stop. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_cryptodev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id);
-
 /**
  * Get the number of queue pairs on a specific crypto device
  *
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 0739ce065..b47730eaf 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -211,28 +211,6 @@ typedef void (*cryptodev_stats_reset_t)(struct rte_cryptodev *dev);
 typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
 				struct rte_cryptodev_info *dev_info);
 
-/**
- * Start queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_start_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
-/**
- * Stop queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_stop_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
 /**
  * Setup a queue pair for a device.
  *
@@ -371,10 +349,6 @@ struct rte_cryptodev_ops {
 	/**< Set up a device queue pair. */
 	cryptodev_queue_pair_release_t queue_pair_release;
 	/**< Release a queue pair. */
-	cryptodev_queue_pair_start_t queue_pair_start;
-	/**< Start a queue pair. */
-	cryptodev_queue_pair_stop_t queue_pair_stop;
-	/**< Stop a queue pair. */
 	cryptodev_queue_pair_count_t queue_pair_count;
 	/**< Get count of the queue pairs. */
 
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index be8f4c1a7..020b45754 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -22,8 +22,6 @@ DPDK_16.04 {
 	rte_cryptodev_stop;
 	rte_cryptodev_queue_pair_count;
 	rte_cryptodev_queue_pair_setup;
-	rte_cryptodev_queue_pair_start;
-	rte_cryptodev_queue_pair_stop;
 	rte_crypto_op_pool_create;
 
 	local: *;
-- 
2.17.0

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
                     ` (2 preceding siblings ...)
  2018-06-08 22:02  2% ` [dpdk-dev] [PATCH 4/6] cryptodev: remove queue start/stop functions Pablo de Lara
@ 2018-06-08 22:02  4% ` Pablo de Lara
  2018-06-21 12:59  0%   ` Akhil Goyal
  2018-06-08 22:02  3% ` [dpdk-dev] [PATCH 6/6] cryptodev: replace mbuf scatter gather flag Pablo de Lara
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 200+ results
From: Pablo de Lara @ 2018-06-08 22:02 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed rte_cryptodev_get_header_session_size
and rte_cryptodev_get_private_session_size functions,
as they have been substituted with functions
specific for symmetric operations, with _sym_ word
after "rte_cryptodev_".

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  6 ------
 doc/guides/rel_notes/release_18_08.rst         |  8 ++++++++
 lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
 lib/librte_cryptodev/rte_cryptodev.h           | 11 -----------
 lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
 5 files changed, 8 insertions(+), 25 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 91592534e..9a73b1d8e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -107,9 +107,3 @@ Deprecation Notices
     with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
-  - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_header_session_size()``.
-    It will be removed in 18.08.
-  - Function ``rte_cryptodev_get_private_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_private_session_size()``.
-    It will be removed in 18.08.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 3fa9a6e68..0624f3701 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -64,6 +64,14 @@ API Changes
   - ``rte_cryptodev_queue_pair_start``
   - ``rte_cryptodev_queue_pair_stop``
 
+* cryptodev: Following functions were deprecated and are replaced by
+  other functions in 18.08:
+
+  - ``rte_cryptodev_get_header_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_header_session_size``
+  - ``rte_cryptodev_get_private_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_private_session_size``
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a07904fb9..40e249e79 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
 	return 0;
 }
 
-unsigned int
-rte_cryptodev_get_header_session_size(void)
-{
-	return rte_cryptodev_sym_get_header_session_size();
-}
-
 unsigned int
 rte_cryptodev_sym_get_header_session_size(void)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 90487bffc..8e8a59522 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -925,17 +925,6 @@ int
 rte_cryptodev_sym_session_clear(uint8_t dev_id,
 			struct rte_cryptodev_sym_session *sess);
 
-/**
- * @deprecated
- * Get the size of the header session, for all registered drivers.
- *
- * @return
- *   Size of the header session.
- */
-__rte_deprecated
-unsigned int
-rte_cryptodev_get_header_session_size(void);
-
 /**
  * @deprecated
  * Get the size of the private session data for a device.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 020b45754..0ab6d5195 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -63,8 +63,6 @@ DPDK_17.08 {
 	rte_cryptodev_driver_id_get;
 	rte_cryptodev_driver_name_get;
 	rte_cryptodev_get_aead_algo_enum;
-	rte_cryptodev_get_header_session_size;
-	rte_cryptodev_get_private_session_size;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 6/6] cryptodev: replace mbuf scatter gather flag
                     ` (3 preceding siblings ...)
  2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions Pablo de Lara
@ 2018-06-08 22:02  3% ` Pablo de Lara
      6 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-08 22:02 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

The current mbuf scatter gatter feature flag is
too ambiguous, as it is not clear if input and/or output
buffers can be scatter gather mbufs or not.

Therefore, two new flags will replace this flag:
RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN and
RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst        |  2 -
 doc/guides/rel_notes/release_18_08.rst      |  4 ++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c    |  2 +-
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c |  2 +-
 drivers/crypto/dpaa_sec/dpaa_sec.c          |  3 +-
 drivers/crypto/null/null_crypto_pmd.c       |  3 +-
 drivers/crypto/openssl/rte_openssl_pmd.c    |  2 +-
 drivers/crypto/qat/rte_qat_cryptodev.c      |  3 +-
 lib/librte_cryptodev/rte_cryptodev.c        |  6 ++-
 lib/librte_cryptodev/rte_cryptodev.h        | 12 +++---
 test/test/test_cryptodev.c                  | 41 ++++++++++++++-------
 test/test/test_cryptodev_blockcipher.c      | 11 ++++--
 12 files changed, 59 insertions(+), 32 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9a73b1d8e..62d635b74 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,5 +105,3 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
-    so some will be replaced by more explicit flags.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 0624f3701..89b84846c 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -72,6 +72,10 @@ API Changes
   - ``rte_cryptodev_get_private_session_size`` is replaced with
     ``rte_cryptodev_sym_get_private_session_size``
 
+* cryptodev: Feature flag ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` is
+  replaced with the more explicit``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN``
+  and ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT`` flags.
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index cd5b1952b..aa795cbbc 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -492,7 +492,7 @@ aesni_gcm_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN;
 
 	switch (vector_mode) {
 	case RTE_AESNI_GCM_SSE:
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 471ad1cbb..cadfeddeb 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -2762,7 +2762,7 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN;
 
 	internals = cryptodev->data->dev_private;
 	internals->max_nb_sessions = RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS;
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index e7ae33c5e..54540d7f6 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -2270,7 +2270,8 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT;
 
 	internals = cryptodev->data->dev_private;
 	internals->max_nb_queue_pairs = RTE_DPAA_MAX_NB_SEC_QPS;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index a8499cf94..d9dc22e0f 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -177,7 +177,8 @@ cryptodev_null_create(const char *name,
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT;
 
 	internals = dev->data->dev_private;
 
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 965cab9f2..6878baa4c 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1660,7 +1660,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN;
 
 	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index bb109f8ba..4f1ba5f30 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -89,7 +89,8 @@ crypto_qat_create(const char *name, struct rte_pci_device *pci_dev,
 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT;
 
 	internals = cryptodev->data->dev_private;
 	switch (pci_dev->id.device_id) {
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 40e249e79..b180d4c84 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -361,8 +361,10 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 		return "CPU_AESNI";
 	case RTE_CRYPTODEV_FF_HW_ACCELERATED:
 		return "HW_ACCELERATED";
-	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER:
-		return "MBUF_SCATTER_GATHER";
+	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN:
+		return "MBUF_INPUT_SCATTER_GATHER";
+	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT:
+		return "MBUF_OUTPUT_SCATTER_GATHER";
 	case RTE_CRYPTODEV_FF_CPU_NEON:
 		return "CPU_NEON";
 	case RTE_CRYPTODEV_FF_CPU_ARM_CE:
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8e8a59522..bfb52e7f2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -345,13 +345,15 @@ rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
 /**< Operations are off-loaded to an external hardware accelerator */
 #define	RTE_CRYPTODEV_FF_CPU_AVX512		(1ULL << 8)
 /**< Utilises CPU SIMD AVX512 instructions */
-#define	RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER	(1ULL << 9)
-/**< Scatter-gather mbufs are supported */
-#define	RTE_CRYPTODEV_FF_CPU_NEON		(1ULL << 10)
+#define	RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN	(1ULL << 9)
+/**< Scatter-gather input mbufs are supported */
+#define RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT (1ULL << 10)
+/**< Scatter-gather output mbufs are supported */
+#define	RTE_CRYPTODEV_FF_CPU_NEON		(1ULL << 11)
 /**< Utilises CPU NEON instructions */
-#define	RTE_CRYPTODEV_FF_CPU_ARM_CE		(1ULL << 11)
+#define	RTE_CRYPTODEV_FF_CPU_ARM_CE		(1ULL << 12)
 /**< Utilises ARM CPU Cryptographic Extensions */
-#define	RTE_CRYPTODEV_FF_SECURITY		(1ULL << 12)
+#define	RTE_CRYPTODEV_FF_SECURITY		(1ULL << 13)
 /**< Support Security Protocol Processing */
 
 
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 2c687bd7c..627c3b1b3 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -3152,9 +3152,13 @@ test_kasumi_encryption_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
-				"Test Skipped.\n");
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN) ||
+			!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT)) {
+		printf("Device doesn't support scatter-gather in both input "
+				"and output mbufs. Test Skipped.\n");
 		return 0;
 	}
 
@@ -3300,9 +3304,12 @@ test_kasumi_encryption_oop_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
-				"Test Skipped.\n");
+
+	uint64_t feat_flags = dev_info.feature_flags;
+	if (!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN) ||
+			!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT)) {
+		printf("Device doesn't support scatter-gather in both input "
+				"and output mbufs. Test Skipped.\n");
 		return 0;
 	}
 
@@ -3651,9 +3658,13 @@ test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
-				"Test Skipped.\n");
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN) ||
+			!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT)) {
+		printf("Device doesn't support scatter-gather in both input "
+				"and output mbufs. Test Skipped.\n");
 		return 0;
 	}
 
@@ -4485,10 +4496,14 @@ test_zuc_encryption_sgl(const struct wireless_test_data *tdata)
 		return -ENOTSUP;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
-				"Test Skipped.\n");
-		return -ENOTSUP;
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN) ||
+			!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT)) {
+		printf("Device doesn't support scatter-gather in both input "
+				"and output mbufs. Test Skipped.\n");
+		return 0;
 	}
 
 	plaintext_len = ceil_byte_length(tdata->plaintext.len);
diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c
index 256a7daa2..7a56171e9 100644
--- a/test/test/test_cryptodev_blockcipher.c
+++ b/test/test/test_cryptodev_blockcipher.c
@@ -77,10 +77,13 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 
 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
 		rte_cryptodev_info_get(dev_id, &dev_info);
-		if (!(dev_info.feature_flags &
-				RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-			printf("Device doesn't support scatter-gather. "
-					"Test Skipped.\n");
+		uint64_t feat_flags = dev_info.feature_flags;
+
+		if (!(feat_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_IN) ||
+				!(feat_flags &
+					RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER_OUT)) {
+			printf("Device doesn't support scatter-gather in both input "
+				"and output mbufs. Test Skipped.\n");
 			return 0;
 		}
 		nb_segs = 3;
-- 
2.17.0

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions
  2018-06-08 22:02  1% ` [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions Pablo de Lara
@ 2018-06-12 11:37  0%   ` Tomasz Duszynski
  0 siblings, 0 replies; 200+ results
From: Tomasz Duszynski @ 2018-06-12 11:37 UTC (permalink / raw)
  To: Pablo de Lara
  Cc: declan.doherty, akhil.goyal, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou, dev

Hello Pablo,

On Fri, Jun 08, 2018 at 11:02:31PM +0100, Pablo de Lara wrote:
> Sessions are not created and stored in the crypto device
> anymore, since now the session mempool is created
> at the application level.
>
> Therefore the limitation of the maximum number of sessions
> that can be created should not be dependent of the crypto device.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
>  config/common_base                               | 12 ------------
>  config/rte_config.h                              | 14 --------------
>  doc/guides/cryptodevs/aesni_gcm.rst              |  4 +---
>  doc/guides/cryptodevs/aesni_mb.rst               |  4 +---
>  doc/guides/cryptodevs/armv8.rst                  |  1 -
>  doc/guides/cryptodevs/ccp.rst                    |  2 --
>  doc/guides/cryptodevs/dpaa2_sec.rst              |  5 -----
>  doc/guides/cryptodevs/dpaa_sec.rst               |  5 -----
>  doc/guides/cryptodevs/kasumi.rst                 |  4 +---
>  doc/guides/cryptodevs/mvsam.rst                  |  1 -
>  doc/guides/cryptodevs/null.rst                   |  4 +---
>  doc/guides/cryptodevs/openssl.rst                |  1 -
>  doc/guides/cryptodevs/scheduler.rst              |  4 ----
>  doc/guides/cryptodevs/snow3g.rst                 |  4 +---
>  doc/guides/cryptodevs/zuc.rst                    |  4 +---
>  doc/guides/prog_guide/cryptodev_lib.rst          |  9 ++-------
>  doc/guides/rel_notes/deprecation.rst             |  3 ---
>  doc/guides/rel_notes/release_18_08.rst           |  3 ++-
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  5 +----
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |  1 -
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |  2 --
>  drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c       |  5 +----
>  drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c   |  1 -
>  .../crypto/aesni_mb/rte_aesni_mb_pmd_private.h   |  2 --
>  drivers/crypto/armv8/rte_armv8_pmd.c             |  5 +----
>  drivers/crypto/armv8/rte_armv8_pmd_ops.c         |  1 -
>  drivers/crypto/armv8/rte_armv8_pmd_private.h     |  2 --
>  drivers/crypto/ccp/ccp_pmd_ops.c                 |  1 -
>  drivers/crypto/ccp/ccp_pmd_private.h             |  1 -
>  drivers/crypto/ccp/rte_ccp_pmd.c                 | 16 +---------------
>  drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c      |  3 ++-
>  drivers/crypto/dpaa_sec/dpaa_sec.c               |  1 -
>  drivers/crypto/dpaa_sec/dpaa_sec.h               |  1 +
>  drivers/crypto/kasumi/rte_kasumi_pmd.c           |  5 +----
>  drivers/crypto/kasumi/rte_kasumi_pmd_ops.c       |  1 -
>  drivers/crypto/kasumi/rte_kasumi_pmd_private.h   |  2 --
>  drivers/crypto/mvsam/rte_mrvl_pmd.c              |  6 ------
>  drivers/crypto/mvsam/rte_mrvl_pmd_ops.c          |  1 -
>  drivers/crypto/mvsam/rte_mrvl_pmd_private.h      |  1 -
>  drivers/crypto/null/null_crypto_pmd.c            |  3 ---
>  drivers/crypto/null/null_crypto_pmd_ops.c        |  1 -
>  drivers/crypto/null/null_crypto_pmd_private.h    |  1 -
>  drivers/crypto/openssl/rte_openssl_pmd.c         |  3 ---
>  drivers/crypto/openssl/rte_openssl_pmd_ops.c     |  1 -
>  drivers/crypto/openssl/rte_openssl_pmd_private.h |  2 --
>  drivers/crypto/qat/qat_crypto.c                  |  1 -
>  drivers/crypto/qat/qat_crypto.h                  |  2 --
>  drivers/crypto/qat/rte_qat_cryptodev.c           |  4 +---
>  drivers/crypto/scheduler/scheduler_pmd.c         | 13 +------------
>  drivers/crypto/scheduler/scheduler_pmd_ops.c     |  7 -------
>  drivers/crypto/snow3g/rte_snow3g_pmd.c           |  3 ---
>  drivers/crypto/snow3g/rte_snow3g_pmd_ops.c       |  1 -
>  drivers/crypto/snow3g/rte_snow3g_pmd_private.h   |  2 --
>  drivers/crypto/virtio/virtio_cryptodev.c         |  3 ---
>  drivers/crypto/zuc/rte_zuc_pmd.c                 |  5 +----
>  drivers/crypto/zuc/rte_zuc_pmd_ops.c             |  1 -
>  drivers/crypto/zuc/rte_zuc_pmd_private.h         |  2 --
>  lib/librte_cryptodev/rte_cryptodev.h             |  5 -----
>  lib/librte_cryptodev/rte_cryptodev_pmd.c         | 12 ++----------
>  lib/librte_cryptodev/rte_cryptodev_pmd.h         |  4 ----
>  test/test/test_cryptodev.c                       | 13 +++++++------
>  61 files changed, 30 insertions(+), 206 deletions(-)
>
> diff --git a/config/common_base b/config/common_base
> index 6b0d1cbbb..db6dec335 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -473,14 +473,12 @@ CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG=n
>  # Compile NXP DPAA2 crypto sec driver for CAAM HW
>  #
>  CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=n
> -CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS=2048
>
>  #
>  # NXP DPAA caam - crypto driver
>  #
>  CONFIG_RTE_LIBRTE_PMD_DPAA_SEC=n
>  CONFIG_RTE_LIBRTE_DPAA_MAX_CRYPTODEV=4
> -CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS=2048
>
>  #
>  # Compile PMD for QuickAssist based devices
> @@ -490,11 +488,6 @@ CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
>  CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=n
>  CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=n
>  CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
> -#
> -# Number of sessions to create in the session memory pool
> -# on a single QuickAssist device.
> -#
> -CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
>
>  #
>  # Compile PMD for virtio crypto devices
> @@ -504,11 +497,6 @@ CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=y
>  # Number of maximum virtio crypto devices
>  #
>  CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
> -#
> -# Number of sessions to create in the session memory pool
> -# on a single virtio crypto device.
> -#
> -CONFIG_RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS=1024
>
>  #
>  # Compile PMD for AESNI backed device
> diff --git a/config/rte_config.h b/config/rte_config.h
> index a1d01759e..7261d28d6 100644
> --- a/config/rte_config.h
> +++ b/config/rte_config.h
> @@ -85,23 +85,9 @@
>
>  /****** driver defines ********/
>
> -/*
> - * Number of sessions to create in the session memory pool
> - * on a single instance of crypto HW device.
> - */
> -/* QuickAssist device */
> -#define RTE_QAT_PMD_MAX_NB_SESSIONS 2048
> -
>  /* virtio crypto defines */
> -#define RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS 1024
>  #define RTE_MAX_VIRTIO_CRYPTO 32
>
> -/* DPAA2_SEC */
> -#define RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS 2048
> -
> -/* DPAA_SEC */
> -#define RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS 2048
> -
>  /* DPAA SEC max cryptodev devices*/
>  #define RTE_LIBRTE_DPAA_MAX_CRYPTODEV	4
>
> diff --git a/doc/guides/cryptodevs/aesni_gcm.rst b/doc/guides/cryptodevs/aesni_gcm.rst
> index 01590e850..2cfd1e9f7 100644
> --- a/doc/guides/cryptodevs/aesni_gcm.rst
> +++ b/doc/guides/cryptodevs/aesni_gcm.rst
> @@ -83,11 +83,9 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_gcm,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_gcm,socket_id=0" \
>      -- -p 1 --cdev SW --chain AEAD --aead_algo "aes-gcm"
> diff --git a/doc/guides/cryptodevs/aesni_mb.rst b/doc/guides/cryptodevs/aesni_mb.rst
> index 236828c0a..a0602a10d 100644
> --- a/doc/guides/cryptodevs/aesni_mb.rst
> +++ b/doc/guides/cryptodevs/aesni_mb.rst
> @@ -106,13 +106,11 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_mb,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_aesni_mb,socket_id=0" \
>      -- -p 1 --cdev SW --chain CIPHER_HASH --cipher_algo "aes-cbc" --auth_algo "sha1-hmac"
>
>  Extra notes
> diff --git a/doc/guides/cryptodevs/armv8.rst b/doc/guides/cryptodevs/armv8.rst
> index 725398daf..4adf3cf40 100644
> --- a/doc/guides/cryptodevs/armv8.rst
> +++ b/doc/guides/cryptodevs/armv8.rst
> @@ -64,7 +64,6 @@ For performance test cryptodev_sw_armv8_perftest can be used.
>  Limitations
>  -----------
>
> -* Maximum number of sessions is 2048.
>  * Only chained operations are supported.
>  * AES-128-CBC is the only supported cipher variant.
>  * Cipher input data has to be a multiple of 16 bytes.
> diff --git a/doc/guides/cryptodevs/ccp.rst b/doc/guides/cryptodevs/ccp.rst
> index 034d20367..d577d5a1c 100644
> --- a/doc/guides/cryptodevs/ccp.rst
> +++ b/doc/guides/cryptodevs/ccp.rst
> @@ -101,8 +101,6 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device.
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  * ccp_auth_opt: Specify authentication operations to perform on CPU using openssl APIs.
>
>  To validate ccp pmd, l2fwd-crypto example can be used with following command:
> diff --git a/doc/guides/cryptodevs/dpaa2_sec.rst b/doc/guides/cryptodevs/dpaa2_sec.rst
> index 3ea24c8aa..990befeb7 100644
> --- a/doc/guides/cryptodevs/dpaa2_sec.rst
> +++ b/doc/guides/cryptodevs/dpaa2_sec.rst
> @@ -200,11 +200,6 @@ Please note that enabling debugging options may affect system performance.
>    By default it is only enabled in defconfig_arm64-dpaa2-* config.
>    Toggle compilation of the ``librte_pmd_dpaa2_sec`` driver.
>
> -* ``CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS``
> -  By default it is set as 2048 in defconfig_arm64-dpaa2-* config.
> -  It indicates Number of sessions to create in the session memory pool
> -  on a single DPAA2 SEC device.
> -
>  Installations
>  -------------
>  To compile the DPAA2_SEC PMD for Linux arm64 gcc target, run the
> diff --git a/doc/guides/cryptodevs/dpaa_sec.rst b/doc/guides/cryptodevs/dpaa_sec.rst
> index c14d6d7b1..c5097a84f 100644
> --- a/doc/guides/cryptodevs/dpaa_sec.rst
> +++ b/doc/guides/cryptodevs/dpaa_sec.rst
> @@ -145,11 +145,6 @@ Please note that enabling debugging options may affect system performance.
>    By default it is only enabled in defconfig_arm64-dpaa-* config.
>    Toggle compilation of the ``librte_pmd_dpaa_sec`` driver.
>
> -* ``CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS``
> -  By default it is set as 2048 in defconfig_arm64-dpaa-* config.
> -  It indicates Number of sessions to create in the session memory pool
> -  on a single DPAA SEC device.
> -
>  Installations
>  -------------
>  To compile the DPAA_SEC PMD for Linux arm64 gcc target, run the
> diff --git a/doc/guides/cryptodevs/kasumi.rst b/doc/guides/cryptodevs/kasumi.rst
> index 2265eee4e..74bc4d840 100644
> --- a/doc/guides/cryptodevs/kasumi.rst
> +++ b/doc/guides/cryptodevs/kasumi.rst
> @@ -87,13 +87,11 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_kasumi,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_kasumi,socket_id=0" \
>      -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "kasumi-f8"
>
>  Extra notes on KASUMI F9
> diff --git a/doc/guides/cryptodevs/mvsam.rst b/doc/guides/cryptodevs/mvsam.rst
> index fd418c264..b91bb0fb6 100644
> --- a/doc/guides/cryptodevs/mvsam.rst
> +++ b/doc/guides/cryptodevs/mvsam.rst
> @@ -115,7 +115,6 @@ loaded:
>  The following parameters (all optional) are exported by the driver:
>
>  * max_nb_queue_pairs: maximum number of queue pairs in the device (8 by default).
> -* max_nb_sessions: maximum number of sessions that can be created (2048 by default).
>  * socket_id: socket on which to allocate the device resources on.
>
>  l2fwd-crypto example application can be used to verify MVSAM CRYPTO PMD
> diff --git a/doc/guides/cryptodevs/null.rst b/doc/guides/cryptodevs/null.rst
> index c980e0ac8..ca39fe444 100644
> --- a/doc/guides/cryptodevs/null.rst
> +++ b/doc/guides/cryptodevs/null.rst
> @@ -61,11 +61,9 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_null,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_null,socket_id=0" \
>      -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "null"
> diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst
> index 427fc807c..153ad0657 100644
> --- a/doc/guides/cryptodevs/openssl.rst
> +++ b/doc/guides/cryptodevs/openssl.rst
> @@ -98,7 +98,6 @@ To verify real traffic l2fwd-crypto example can be used with this command:
>  Limitations
>  -----------
>
> -* Maximum number of sessions is 2048.
>  * Chained mbufs are supported only for source mbuf (destination must be
>    contiguous).
>  * Hash only is not supported for GCM and GMAC.
> diff --git a/doc/guides/cryptodevs/scheduler.rst b/doc/guides/cryptodevs/scheduler.rst
> index d67894d55..e266ec5a3 100644
> --- a/doc/guides/cryptodevs/scheduler.rst
> +++ b/doc/guides/cryptodevs/scheduler.rst
> @@ -58,10 +58,6 @@ two calls:
>    to be allocated (by default, socket_id will be the socket where the core
>    that is creating the PMD is running on).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be
> -  created. This value may be overwritten internally if there are too
> -  many devices are attached.
> -
>  * slave: If a cryptodev has been initialized with specific name, it can be
>    attached to the scheduler using this parameter, simply filling the name
>    here. Multiple cryptodevs can be attached initially by presenting this
> diff --git a/doc/guides/cryptodevs/snow3g.rst b/doc/guides/cryptodevs/snow3g.rst
> index 7cba712c1..e0b9a73f7 100644
> --- a/doc/guides/cryptodevs/snow3g.rst
> +++ b/doc/guides/cryptodevs/snow3g.rst
> @@ -79,11 +79,9 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_snow3g,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_snow3g,socket_id=0" \
>      -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "snow3g-uea2"
> diff --git a/doc/guides/cryptodevs/zuc.rst b/doc/guides/cryptodevs/zuc.rst
> index e38989968..7bebbb48b 100644
> --- a/doc/guides/cryptodevs/zuc.rst
> +++ b/doc/guides/cryptodevs/zuc.rst
> @@ -79,11 +79,9 @@ The following parameters (all optional) can be provided in the previous two call
>
>  * max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).
>
> -* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).
> -
>  Example:
>
>  .. code-block:: console
>
> -    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_zuc,socket_id=0,max_nb_sessions=128" \
> +    ./l2fwd-crypto -l 1 -n 4 --vdev="crypto_zuc,socket_id=0" \
>      -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "zuc-eea3"
> diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
> index d02bb7514..c83184fe9 100644
> --- a/doc/guides/prog_guide/cryptodev_lib.rst
> +++ b/doc/guides/prog_guide/cryptodev_lib.rst
> @@ -41,7 +41,7 @@ From the command line using the --vdev EAL option
>
>  .. code-block:: console
>
> -   --vdev  'crypto_aesni_mb0,max_nb_queue_pairs=2,max_nb_sessions=1024,socket_id=0'
> +   --vdev  'crypto_aesni_mb0,max_nb_queue_pairs=2,socket_id=0'
>
>  .. Note::
>
> @@ -57,12 +57,11 @@ Our using the rte_vdev_init API within the application code.
>  .. code-block:: c
>
>     rte_vdev_init("crypto_aesni_mb",
> -                     "max_nb_queue_pairs=2,max_nb_sessions=1024,socket_id=0")
> +                     "max_nb_queue_pairs=2,socket_id=0")
>
>  All virtual Crypto devices support the following initialization parameters:
>
>  * ``max_nb_queue_pairs`` - maximum number of queue pairs supported by the device.
> -* ``max_nb_sessions`` - maximum number of sessions supported by the device
>  * ``socket_id`` - socket on which to allocate the device resources on.
>
>
> @@ -276,10 +275,6 @@ relevant information for the device.
>          const struct rte_cryptodev_capabilities *capabilities;
>
>          unsigned max_nb_queue_pairs;
> -
> -        struct {
> -            unsigned max_nb_sessions;
> -        } sym;
>      };
>
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index b71080bb8..dc014da21 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -101,9 +101,6 @@ Deprecation Notices
>  * cryptodev: The following changes will be made in the library
>    for 18.08:
>
> -  - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
> -    containing fields not relevant anymore since the session mempool
> -    is not internal in the crypto device anymore.
>    - Functions ``rte_cryptodev_queue_pair_attach_sym_session()`` and
>      ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
>      18.05 and removed in 18.08, as there are no drivers doing anything useful
> diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
> index ba710e845..a6f31713a 100644
> --- a/doc/guides/rel_notes/release_18_08.rst
> +++ b/doc/guides/rel_notes/release_18_08.rst
> @@ -56,7 +56,8 @@ API Changes
>     =========================================================
>
>  * cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
> -  has been replaced with field ``struct rte_device *device``.
> +  has been replaced with field ``struct rte_device *device`` and
> +  field ``sym`` has been removed.
>
>
>  ABI Changes
> diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> index 80360dd9c..cd5b1952b 100644
> --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> @@ -513,7 +513,6 @@ aesni_gcm_create(const char *name,
>  	internals->vector_mode = vector_mode;
>
>  	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  }
> @@ -525,8 +524,7 @@ aesni_gcm_probe(struct rte_vdev_device *vdev)
>  		"",
>  		sizeof(struct aesni_gcm_private),
>  		rte_socket_id(),
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -568,7 +566,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_GCM_PMD, aesni_gcm_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_GCM_PMD, cryptodev_aesni_gcm_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_GCM_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(aesni_gcm_crypto_drv, aesni_gcm_pmd_drv.driver,
>  		cryptodev_driver_id);
> diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
> index 6f542137c..b05122c1b 100644
> --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
> +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
> @@ -143,7 +143,6 @@ aesni_gcm_pmd_info_get(struct rte_cryptodev *dev,
>  		dev_info->capabilities = aesni_gcm_pmd_capabilities;
>
>  		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
> index 3d60583b0..b496377dd 100644
> --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
> +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
> @@ -39,8 +39,6 @@ struct aesni_gcm_private {
>  	/**< Vector mode */
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  };
>
>  struct aesni_gcm_qp {
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> index bb35c66ab..bb647f736 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> @@ -885,7 +885,6 @@ cryptodev_aesni_mb_create(const char *name,
>
>  	internals->vector_mode = vector_mode;
>  	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  }
> @@ -897,8 +896,7 @@ cryptodev_aesni_mb_probe(struct rte_vdev_device *vdev)
>  		"",
>  		sizeof(struct aesni_mb_private),
>  		rte_socket_id(),
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  	};
>  	const char *name, *args;
>  	int retval;
> @@ -947,7 +945,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_MB_PMD, cryptodev_aesni_mb_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_MB_PMD, cryptodev_aesni_mb_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_MB_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(aesni_mb_crypto_drv,
>  		cryptodev_aesni_mb_pmd_drv.driver,
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
> index 01530523f..7c735f5dc 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
> @@ -387,7 +387,6 @@ aesni_mb_pmd_info_get(struct rte_cryptodev *dev,
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = aesni_mb_pmd_capabilities;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> index a33b2f695..9520cdf9c 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
> @@ -124,8 +124,6 @@ struct aesni_mb_private {
>  	/**< CPU vector instruction set mode */
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  };
>
>  /** AESNI Multi buffer queue pair */
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
> index fbb08f729..db0d8a2a9 100644
> --- a/drivers/crypto/armv8/rte_armv8_pmd.c
> +++ b/drivers/crypto/armv8/rte_armv8_pmd.c
> @@ -779,7 +779,6 @@ cryptodev_armv8_crypto_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>
> @@ -800,8 +799,7 @@ cryptodev_armv8_crypto_init(struct rte_vdev_device *vdev)
>  		"",
>  		sizeof(struct armv8_crypto_private),
>  		rte_socket_id(),
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -848,7 +846,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(armv8_crypto_drv, armv8_crypto_pmd_drv.driver,
>  		cryptodev_driver_id);
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> index c64aef09f..d31ef7d66 100644
> --- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> @@ -154,7 +154,6 @@ armv8_crypto_pmd_info_get(struct rte_cryptodev *dev,
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = armv8_crypto_pmd_capabilities;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
> index b8966e934..7feb021db 100644
> --- a/drivers/crypto/armv8/rte_armv8_pmd_private.h
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
> @@ -106,8 +106,6 @@ typedef void (*crypto_key_sched_t)(uint8_t *, const uint8_t *);
>  struct armv8_crypto_private {
>  	unsigned int max_nb_qpairs;
>  	/**< Max number of queue pairs */
> -	unsigned int max_nb_sessions;
> -	/**< Max number of sessions */
>  };
>
>  /** ARMv8 crypto queue pair */
> diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
> index 80b75ccb0..7e383feed 100644
> --- a/drivers/crypto/ccp/ccp_pmd_ops.c
> +++ b/drivers/crypto/ccp/ccp_pmd_ops.c
> @@ -624,7 +624,6 @@ ccp_pmd_info_get(struct rte_cryptodev *dev,
>  		if (internals->auth_opt == 1)
>  			dev_info->capabilities = ccp_crypto_cap_complete;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/ccp/ccp_pmd_private.h b/drivers/crypto/ccp/ccp_pmd_private.h
> index f4498048f..79752f687 100644
> --- a/drivers/crypto/ccp/ccp_pmd_private.h
> +++ b/drivers/crypto/ccp/ccp_pmd_private.h
> @@ -40,7 +40,6 @@
>  /* private data structure for each CCP crypto device */
>  struct ccp_private {
>  	unsigned int max_nb_qpairs;	/**< Max number of queue pairs */
> -	unsigned int max_nb_sessions;	/**< Max number of sessions */
>  	uint8_t crypto_num_dev;		/**< Number of working crypto devices */
>  	bool auth_opt;			/**< Authentication offload option */
>  	struct ccp_device *last_dev;	/**< Last working crypto device */
> diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c b/drivers/crypto/ccp/rte_ccp_pmd.c
> index 2061f465e..d70640f6d 100644
> --- a/drivers/crypto/ccp/rte_ccp_pmd.c
> +++ b/drivers/crypto/ccp/rte_ccp_pmd.c
> @@ -30,14 +30,12 @@ struct ccp_pmd_init_params {
>  #define CCP_CRYPTODEV_PARAM_NAME		("name")
>  #define CCP_CRYPTODEV_PARAM_SOCKET_ID		("socket_id")
>  #define CCP_CRYPTODEV_PARAM_MAX_NB_QP		("max_nb_queue_pairs")
> -#define CCP_CRYPTODEV_PARAM_MAX_NB_SESS		("max_nb_sessions")
>  #define CCP_CRYPTODEV_PARAM_AUTH_OPT		("ccp_auth_opt")
>
>  const char *ccp_pmd_valid_params[] = {
>  	CCP_CRYPTODEV_PARAM_NAME,
>  	CCP_CRYPTODEV_PARAM_SOCKET_ID,
>  	CCP_CRYPTODEV_PARAM_MAX_NB_QP,
> -	CCP_CRYPTODEV_PARAM_MAX_NB_SESS,
>  	CCP_CRYPTODEV_PARAM_AUTH_OPT,
>  };
>
> @@ -124,13 +122,6 @@ ccp_pmd_parse_input_args(struct ccp_pmd_init_params *params,
>  		if (ret < 0)
>  			goto free_kvlist;
>
> -		ret = rte_kvargs_process(kvlist,
> -					 CCP_CRYPTODEV_PARAM_MAX_NB_SESS,
> -					 &parse_integer_arg,
> -					 &params->def_p.max_nb_sessions);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
>  		ret = rte_kvargs_process(kvlist,
>  					 CCP_CRYPTODEV_PARAM_SOCKET_ID,
>  					 &parse_integer_arg,
> @@ -334,7 +325,6 @@ cryptodev_ccp_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_qpairs = init_params->def_p.max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->def_p.max_nb_sessions;
>  	internals->auth_opt = init_params->auth_opt;
>  	internals->crypto_num_dev = cryptodev_cnt;
>
> @@ -359,8 +349,7 @@ cryptodev_ccp_probe(struct rte_vdev_device *vdev)
>  			"",
>  			sizeof(struct ccp_private),
>  			rte_socket_id(),
> -			CCP_PMD_MAX_QUEUE_PAIRS,
> -			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +			CCP_PMD_MAX_QUEUE_PAIRS
>  		},
>  		.auth_opt = CCP_PMD_AUTH_OPT_CCP,
>  	};
> @@ -382,8 +371,6 @@ cryptodev_ccp_probe(struct rte_vdev_device *vdev)
>  		init_params.def_p.socket_id);
>  	RTE_LOG(INFO, PMD, "Max number of queue pairs = %d\n",
>  		init_params.def_p.max_nb_queue_pairs);
> -	RTE_LOG(INFO, PMD, "Max number of sessions = %d\n",
> -		init_params.def_p.max_nb_sessions);
>  	RTE_LOG(INFO, PMD, "Authentication offload to %s\n",
>  		((init_params.auth_opt == 0) ? "CCP" : "CPU"));
>
> @@ -404,7 +391,6 @@ static struct cryptodev_driver ccp_crypto_drv;
>  RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_CCP_PMD, cryptodev_ccp_pmd_drv);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CCP_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int> "
>  	"ccp_auth_opt=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(ccp_crypto_drv, cryptodev_ccp_pmd_drv.driver,
> diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
> index 56fa969d3..16ab0b6a6 100644
> --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
> +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
> @@ -55,6 +55,8 @@ typedef uint64_t	dma_addr_t;
>  #define SEC_FLC_DHR_OUTBOUND	-114
>  #define SEC_FLC_DHR_INBOUND	0
>
> +#define RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS 2048
> +
>  enum rta_sec_era rta_sec_era = RTA_SEC_ERA_8;
>
>  static uint8_t cryptodev_driver_id;
> @@ -2626,7 +2628,6 @@ dpaa2_sec_dev_infos_get(struct rte_cryptodev *dev,
>  		info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
>  		info->feature_flags = dev->feature_flags;
>  		info->capabilities = dpaa2_sec_capabilities;
> -		info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		info->driver_id = cryptodev_driver_id;
>  	}
>  }
> diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
> index 73cae483b..909583bd0 100644
> --- a/drivers/crypto/dpaa_sec/dpaa_sec.c
> +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
> @@ -2214,7 +2214,6 @@ dpaa_sec_dev_infos_get(struct rte_cryptodev *dev,
>  		info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
>  		info->feature_flags = dev->feature_flags;
>  		info->capabilities = dpaa_sec_capabilities;
> -		info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		info->driver_id = cryptodev_driver_id;
>  	}
>  }
> diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.h b/drivers/crypto/dpaa_sec/dpaa_sec.h
> index e15e373fd..91df68009 100644
> --- a/drivers/crypto/dpaa_sec/dpaa_sec.h
> +++ b/drivers/crypto/dpaa_sec/dpaa_sec.h
> @@ -137,6 +137,7 @@ struct dpaa_sec_qp {
>  };
>
>  #define RTE_DPAA_MAX_NB_SEC_QPS 8
> +#define RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS 2048
>  #define RTE_DPAA_MAX_RX_QUEUE RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS
>  #define DPAA_MAX_DEQUEUE_NUM_FRAMES 63
>
> diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
> index 205dc1de7..65376b211 100644
> --- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
> +++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
> @@ -555,7 +555,6 @@ cryptodev_kasumi_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  init_error:
> @@ -573,8 +572,7 @@ cryptodev_kasumi_probe(struct rte_vdev_device *vdev)
>  		"",
>  		sizeof(struct kasumi_private),
>  		rte_socket_id(),
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -617,7 +615,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_KASUMI_PMD, cryptodev_kasumi_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_KASUMI_PMD, cryptodev_kasumi_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_KASUMI_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(kasumi_crypto_drv,
>  		cryptodev_kasumi_pmd_drv.driver, cryptodev_driver_id);
> diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
> index a388dbb63..284669341 100644
> --- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
> +++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
> @@ -126,7 +126,6 @@ kasumi_pmd_info_get(struct rte_cryptodev *dev,
>  	if (dev_info != NULL) {
>  		dev_info->driver_id = dev->driver_id;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = kasumi_pmd_capabilities;
>  	}
> diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
> index a397bee65..2b12818bc 100644
> --- a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
> +++ b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
> @@ -36,8 +36,6 @@
>  struct kasumi_private {
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  };
>
>  /** KASUMI buffer queue pair */
> diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd.c b/drivers/crypto/mvsam/rte_mrvl_pmd.c
> index 1b6029a56..822b6cac7 100644
> --- a/drivers/crypto/mvsam/rte_mrvl_pmd.c
> +++ b/drivers/crypto/mvsam/rte_mrvl_pmd.c
> @@ -719,7 +719,6 @@ cryptodev_mrvl_crypto_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	/*
>  	 * ret == -EEXIST is correct, it means DMA
> @@ -734,8 +733,6 @@ cryptodev_mrvl_crypto_create(const char *name,
>  			"DMA memory has been already initialized by a different driver.");
>  	}
>
> -	sam_params.max_num_sessions = internals->max_nb_sessions;

This will not fly since library maintains separate list of sessions.
We have to initialize this number to something sane. Since we cannot
get it from userspace perhaps make that compile-time configurable
by adding separate CONFIG_?

> -
>  	return sam_init(&sam_params);
>
>  init_error:
> @@ -766,8 +763,6 @@ cryptodev_mrvl_crypto_init(struct rte_vdev_device *vdev)
>
>  	init_params.private_data_size = sizeof(struct mrvl_crypto_private);
>  	init_params.max_nb_queue_pairs = sam_get_num_inst() * SAM_HW_RING_NUM;
> -	init_params.max_nb_sessions =
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS;
>  	init_params.socket_id = rte_socket_id();
>
>  	ret = rte_cryptodev_pmd_parse_input_args(&init_params, args);
> @@ -823,7 +818,6 @@ static struct cryptodev_driver mrvl_crypto_drv;
>  RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_MRVL_PMD, cryptodev_mrvl_pmd_drv);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_MRVL_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(mrvl_crypto_drv, cryptodev_mrvl_pmd_drv.driver,
>  		cryptodev_driver_id);
> diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
> index 3f8de37b7..944a415cf 100644
> --- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
> +++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
> @@ -471,7 +471,6 @@ mrvl_crypto_pmd_info_get(struct rte_cryptodev *dev,
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = mrvl_crypto_pmd_capabilities;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
> index c16d95b46..bb528493a 100644
> --- a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
> +++ b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
> @@ -51,7 +51,6 @@ enum mrvl_crypto_chain_order {
>  /** Private data structure for each crypto device. */
>  struct mrvl_crypto_private {
>  	unsigned int max_nb_qpairs;	/**< Max number of queue pairs */
> -	unsigned int max_nb_sessions;	/**< Max number of sessions */
>  };
>
>  /** MRVL crypto queue pair structure. */
> diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
> index 052b6546c..a8499cf94 100644
> --- a/drivers/crypto/null/null_crypto_pmd.c
> +++ b/drivers/crypto/null/null_crypto_pmd.c
> @@ -182,7 +182,6 @@ cryptodev_null_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  }
> @@ -196,7 +195,6 @@ cryptodev_null_probe(struct rte_vdev_device *dev)
>  		sizeof(struct null_crypto_private),
>  		rte_socket_id(),
>  		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
>  	};
>  	const char *name, *args;
>  	int retval;
> @@ -245,7 +243,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_NULL_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(null_crypto_drv, cryptodev_null_pmd_drv.driver,
>  		cryptodev_driver_id);
> diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
> index f8e5f61f1..3ca1370e8 100644
> --- a/drivers/crypto/null/null_crypto_pmd_ops.c
> +++ b/drivers/crypto/null/null_crypto_pmd_ops.c
> @@ -121,7 +121,6 @@ null_crypto_pmd_info_get(struct rte_cryptodev *dev,
>  	if (dev_info != NULL) {
>  		dev_info->driver_id = dev->driver_id;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = null_crypto_pmd_capabilities;
>  	}
> diff --git a/drivers/crypto/null/null_crypto_pmd_private.h b/drivers/crypto/null/null_crypto_pmd_private.h
> index 0fd133625..d7d769f3d 100644
> --- a/drivers/crypto/null/null_crypto_pmd_private.h
> +++ b/drivers/crypto/null/null_crypto_pmd_private.h
> @@ -32,7 +32,6 @@
>  /** private data structure for each NULL crypto device */
>  struct null_crypto_private {
>  	unsigned max_nb_qpairs;		/**< Max number of queue pairs */
> -	unsigned max_nb_sessions;	/**< Max number of sessions */
>  };
>
>  /** NULL crypto queue pair */
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
> index 93c6d7e5d..965cab9f2 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> @@ -1666,7 +1666,6 @@ cryptodev_openssl_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>
> @@ -1687,7 +1686,6 @@ cryptodev_openssl_probe(struct rte_vdev_device *vdev)
>  		sizeof(struct openssl_private),
>  		rte_socket_id(),
>  		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -1731,7 +1729,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_OPENSSL_PMD,
>  	cryptodev_openssl_pmd_drv);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv,
>  		cryptodev_openssl_pmd_drv.driver, cryptodev_driver_id);
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> index 1cb87d59a..485c80e7f 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> @@ -547,7 +547,6 @@ openssl_pmd_info_get(struct rte_cryptodev *dev,
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = openssl_pmd_capabilities;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  	}
>  }
>
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
> index bc8dc7cdc..02ea81d5c 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
> +++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
> @@ -62,8 +62,6 @@ enum openssl_auth_mode {
>  struct openssl_private {
>  	unsigned int max_nb_qpairs;
>  	/**< Max number of queue pairs */
> -	unsigned int max_nb_sessions;
> -	/**< Max number of sessions */
>  };
>
>  /** OPENSSL crypto queue pair */
> diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
> index 768dcbae0..e89d3bc11 100644
> --- a/drivers/crypto/qat/qat_crypto.c
> +++ b/drivers/crypto/qat/qat_crypto.c
> @@ -1654,7 +1654,6 @@ void qat_dev_info_get(struct rte_cryptodev *dev,
>  				ADF_NUM_BUNDLES_PER_DEV;
>  		info->feature_flags = dev->feature_flags;
>  		info->capabilities = internals->qat_dev_capabilities;
> -		info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		info->driver_id = cryptodev_qat_driver_id;
>  	}
>  }
> diff --git a/drivers/crypto/qat/qat_crypto.h b/drivers/crypto/qat/qat_crypto.h
> index 281a142b9..c84cf669f 100644
> --- a/drivers/crypto/qat/qat_crypto.h
> +++ b/drivers/crypto/qat/qat_crypto.h
> @@ -75,8 +75,6 @@ struct qat_qp {
>  struct qat_pmd_private {
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  	enum qat_device_gen qat_dev_gen;
>  	/**< QAT device generation */
>  	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
> diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
> index c8da07af6..74a903d3a 100644
> --- a/drivers/crypto/qat/rte_qat_cryptodev.c
> +++ b/drivers/crypto/qat/rte_qat_cryptodev.c
> @@ -94,7 +94,6 @@ crypto_qat_create(const char *name, struct rte_pci_device *pci_dev,
>  			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
>
>  	internals = cryptodev->data->dev_private;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>  	switch (pci_dev->id.device_id) {
>  	case 0x0443:
>  		internals->qat_dev_gen = QAT_GEN1;
> @@ -131,8 +130,7 @@ static int crypto_qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
>  	struct rte_cryptodev_pmd_init_params init_params = {
>  		.name = "",
>  		.socket_id = pci_dev->device.numa_node,
> -		.private_data_size = sizeof(struct qat_pmd_private),
> -		.max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS
> +		.private_data_size = sizeof(struct qat_pmd_private)
>  	};
>  	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
>
> diff --git a/drivers/crypto/scheduler/scheduler_pmd.c b/drivers/crypto/scheduler/scheduler_pmd.c
> index 25d6409f3..32a19c106 100644
> --- a/drivers/crypto/scheduler/scheduler_pmd.c
> +++ b/drivers/crypto/scheduler/scheduler_pmd.c
> @@ -31,7 +31,6 @@ struct scheduler_init_params {
>  #define RTE_CRYPTODEV_VDEV_MODE			("mode")
>  #define RTE_CRYPTODEV_VDEV_ORDERING		("ordering")
>  #define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG	("max_nb_queue_pairs")
> -#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG	("max_nb_sessions")
>  #define RTE_CRYPTODEV_VDEV_SOCKET_ID		("socket_id")
>  #define RTE_CRYPTODEV_VDEV_COREMASK		("coremask")
>  #define RTE_CRYPTODEV_VDEV_CORELIST		("corelist")
> @@ -42,7 +41,6 @@ const char *scheduler_valid_params[] = {
>  	RTE_CRYPTODEV_VDEV_MODE,
>  	RTE_CRYPTODEV_VDEV_ORDERING,
>  	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
> -	RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
>  	RTE_CRYPTODEV_VDEV_SOCKET_ID,
>  	RTE_CRYPTODEV_VDEV_COREMASK,
>  	RTE_CRYPTODEV_VDEV_CORELIST
> @@ -406,13 +404,6 @@ scheduler_parse_init_params(struct scheduler_init_params *params,
>  		if (ret < 0)
>  			goto free_kvlist;
>
> -		ret = rte_kvargs_process(kvlist,
> -				RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
> -				&parse_integer_arg,
> -				&params->def_p.max_nb_sessions);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
>  		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
>  				&parse_integer_arg,
>  				&params->def_p.socket_id);
> @@ -466,8 +457,7 @@ cryptodev_scheduler_probe(struct rte_vdev_device *vdev)
>  			"",
>  			sizeof(struct scheduler_ctx),
>  			rte_socket_id(),
> -			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  		},
>  		.nb_slaves = 0,
>  		.mode = CDEV_SCHED_MODE_NOT_SET,
> @@ -500,7 +490,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SCHEDULER_PMD,
>  	cryptodev_scheduler_pmd_drv);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SCHEDULER_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int> "
>  	"slave=<name>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(scheduler_crypto_drv,
> diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
> index 147dc51e9..88be72a05 100644
> --- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
> +++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
> @@ -321,8 +321,6 @@ scheduler_pmd_info_get(struct rte_cryptodev *dev,
>  		struct rte_cryptodev_info *dev_info)
>  {
>  	struct scheduler_ctx *sched_ctx = dev->data->dev_private;
> -	uint32_t max_nb_sessions = sched_ctx->nb_slaves ?
> -			UINT32_MAX : RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS;
>  	uint32_t i;
>
>  	if (!dev_info)
> @@ -338,17 +336,12 @@ scheduler_pmd_info_get(struct rte_cryptodev *dev,
>  		struct rte_cryptodev_info slave_info;
>
>  		rte_cryptodev_info_get(slave_dev_id, &slave_info);
> -		max_nb_sessions = slave_info.sym.max_nb_sessions <
> -				max_nb_sessions ?
> -				slave_info.sym.max_nb_sessions :
> -				max_nb_sessions;
>  	}
>
>  	dev_info->driver_id = dev->driver_id;
>  	dev_info->feature_flags = dev->feature_flags;
>  	dev_info->capabilities = sched_ctx->capabilities;
>  	dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs;
> -	dev_info->sym.max_nb_sessions = max_nb_sessions;
>  }
>
>  /** Release queue pair */
> diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
> index 72751e35e..fe595abe1 100644
> --- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
> +++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
> @@ -555,7 +555,6 @@ cryptodev_snow3g_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  init_error:
> @@ -574,7 +573,6 @@ cryptodev_snow3g_probe(struct rte_vdev_device *vdev)
>  		sizeof(struct snow3g_private),
>  		rte_socket_id(),
>  		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -617,7 +615,6 @@ RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SNOW3G_PMD, cryptodev_snow3g_pmd_drv);
>  RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_SNOW3G_PMD, cryptodev_snow3g_pmd);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SNOW3G_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(snow3g_crypto_drv,
>  		cryptodev_snow3g_pmd_drv.driver, cryptodev_driver_id);
> diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
> index f60b47598..fff4644c0 100644
> --- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
> +++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
> @@ -130,7 +130,6 @@ snow3g_pmd_info_get(struct rte_cryptodev *dev,
>  	if (dev_info != NULL) {
>  		dev_info->driver_id = dev->driver_id;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = snow3g_pmd_capabilities;
>  	}
> diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
> index eea900e0a..2c6e1a948 100644
> --- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
> +++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
> @@ -36,8 +36,6 @@
>  struct snow3g_private {
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  };
>
>  /** SNOW 3G buffer queue pair */
> diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
> index 482edea1a..8395801a4 100644
> --- a/drivers/crypto/virtio/virtio_cryptodev.c
> +++ b/drivers/crypto/virtio/virtio_cryptodev.c
> @@ -1411,8 +1411,6 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
>  		info->driver_id = cryptodev_virtio_driver_id;
>  		info->feature_flags = dev->feature_flags;
>  		info->max_nb_queue_pairs = hw->max_dataqueues;
> -		info->sym.max_nb_sessions =
> -			RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS;
>  		info->capabilities = hw->virtio_dev_capabilities;
>  	}
>  }
> @@ -1426,7 +1424,6 @@ crypto_virtio_pci_probe(
>  		.name = "",
>  		.socket_id = rte_socket_id(),
>  		.private_data_size = sizeof(struct virtio_crypto_hw),
> -		.max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS
>  	};
>  	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
>
> diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
> index a805b2278..396f25975 100644
> --- a/drivers/crypto/zuc/rte_zuc_pmd.c
> +++ b/drivers/crypto/zuc/rte_zuc_pmd.c
> @@ -479,7 +479,6 @@ cryptodev_zuc_create(const char *name,
>  	internals = dev->data->dev_private;
>
>  	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
> -	internals->max_nb_sessions = init_params->max_nb_sessions;
>
>  	return 0;
>  init_error:
> @@ -497,8 +496,7 @@ cryptodev_zuc_probe(struct rte_vdev_device *vdev)
>  		"",
>  		sizeof(struct zuc_private),
>  		rte_socket_id(),
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
> -		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS
> +		RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
>  	};
>  	const char *name;
>  	const char *input_args;
> @@ -541,7 +539,6 @@ static struct cryptodev_driver zuc_crypto_drv;
>  RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ZUC_PMD, cryptodev_zuc_pmd_drv);
>  RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ZUC_PMD,
>  	"max_nb_queue_pairs=<int> "
> -	"max_nb_sessions=<int> "
>  	"socket_id=<int>");
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(zuc_crypto_drv, cryptodev_zuc_pmd_drv.driver,
>  		cryptodev_driver_id);
> diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
> index 8abac8989..ac509e70d 100644
> --- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
> +++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
> @@ -130,7 +130,6 @@ zuc_pmd_info_get(struct rte_cryptodev *dev,
>  	if (dev_info != NULL) {
>  		dev_info->driver_id = dev->driver_id;
>  		dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
> -		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
>  		dev_info->feature_flags = dev->feature_flags;
>  		dev_info->capabilities = zuc_pmd_capabilities;
>  	}
> diff --git a/drivers/crypto/zuc/rte_zuc_pmd_private.h b/drivers/crypto/zuc/rte_zuc_pmd_private.h
> index b83c4a047..2bd378ad6 100644
> --- a/drivers/crypto/zuc/rte_zuc_pmd_private.h
> +++ b/drivers/crypto/zuc/rte_zuc_pmd_private.h
> @@ -37,8 +37,6 @@
>  struct zuc_private {
>  	unsigned max_nb_queue_pairs;
>  	/**< Max number of queue pairs supported by device */
> -	unsigned max_nb_sessions;
> -	/**< Max number of sessions supported by device */
>  };
>
>  /** ZUC buffer queue pair */
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> index a4b8cccc2..78be5bdb8 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -381,11 +381,6 @@ struct rte_cryptodev_info {
>
>  	unsigned max_nb_queue_pairs;
>  	/**< Maximum number of queues pairs supported by device. */
> -
> -	struct {
> -		unsigned max_nb_sessions;
> -		/**< Maximum number of sessions supported by device. */
> -	} sym;
>  };
>
>  #define RTE_CRYPTODEV_DETACHED  (0)
> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> index f2aac24b7..2088ac3f3 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> @@ -65,13 +65,6 @@ rte_cryptodev_pmd_parse_input_args(
>  		if (ret < 0)
>  			goto free_kvlist;
>
> -		ret = rte_kvargs_process(kvlist,
> -				RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
> -				&rte_cryptodev_pmd_parse_uint_arg,
> -				&params->max_nb_sessions);
> -		if (ret < 0)
> -			goto free_kvlist;
> -
>  		ret = rte_kvargs_process(kvlist,
>  				RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
>  				&rte_cryptodev_pmd_parse_uint_arg,
> @@ -109,10 +102,9 @@ rte_cryptodev_pmd_create(const char *name,
>  			device->driver->name, name);
>
>  	CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s,"
> -			"socket id: %d, max queue pairs: %u, max sessions: %u",
> +			"socket id: %d, max queue pairs: %u",
>  			device->driver->name, name,
> -			params->socket_id, params->max_nb_queue_pairs,
> -			params->max_nb_sessions);
> +			params->socket_id, params->max_nb_queue_pairs);
>
>  	/* allocate device structure */
>  	cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> index 69d776934..0739ce065 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> @@ -59,18 +59,15 @@ extern "C" {
>
>
>  #define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS	8
> -#define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS	2048
>
>  #define RTE_CRYPTODEV_PMD_NAME_ARG			("name")
>  #define RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG			("max_nb_queue_pairs")
> -#define RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG		("max_nb_sessions")
>  #define RTE_CRYPTODEV_PMD_SOCKET_ID_ARG			("socket_id")
>
>
>  static const char * const cryptodev_pmd_valid_params[] = {
>  	RTE_CRYPTODEV_PMD_NAME_ARG,
>  	RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
> -	RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
>  	RTE_CRYPTODEV_PMD_SOCKET_ID_ARG
>  };
>
> @@ -83,7 +80,6 @@ struct rte_cryptodev_pmd_init_params {
>  	size_t private_data_size;
>  	int socket_id;
>  	unsigned int max_nb_queue_pairs;
> -	unsigned int max_nb_sessions;
>  };
>
>  /** Global structure used for maintaining state of allocated crypto devices */
> diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
> index 389f79677..2c687bd7c 100644
> --- a/test/test/test_cryptodev.c
> +++ b/test/test/test_cryptodev.c
> @@ -39,6 +39,7 @@
>  #include "test_cryptodev_hmac_test_vectors.h"
>
>  #define VDEV_ARGS_SIZE 100
> +#define MAX_NB_SESSIONS            4
>
>  static int gbl_driver_id;
>
> @@ -437,7 +438,7 @@ testsuite_setup(void)
>  	 */
>  	ts_params->session_mpool = rte_mempool_create(
>  				"test_sess_mp",
> -				info.sym.max_nb_sessions * 2,
> +				MAX_NB_SESSIONS * 2,
>  				session_size,
>  				0, 0, NULL, NULL, NULL,
>  				NULL, SOCKET_ID_ANY,
> @@ -6499,10 +6500,10 @@ test_multi_session(void)
>
>  	sessions = rte_malloc(NULL,
>  			(sizeof(struct rte_cryptodev_sym_session *) *
> -			dev_info.sym.max_nb_sessions) + 1, 0);
> +			MAX_NB_SESSIONS) + 1, 0);
>
>  	/* Create multiple crypto sessions*/
> -	for (i = 0; i < dev_info.sym.max_nb_sessions; i++) {
> +	for (i = 0; i < MAX_NB_SESSIONS; i++) {
>
>  		sessions[i] = rte_cryptodev_sym_session_create(
>  				ts_params->session_mpool);
> @@ -6551,7 +6552,7 @@ test_multi_session(void)
>  	TEST_ASSERT_NULL(sessions[i],
>  			"Session creation succeeded unexpectedly!");
>
> -	for (i = 0; i < dev_info.sym.max_nb_sessions; i++) {
> +	for (i = 0; i < MAX_NB_SESSIONS; i++) {
>  		rte_cryptodev_sym_session_clear(ts_params->valid_devs[0],
>  				sessions[i]);
>  		rte_cryptodev_sym_session_free(sessions[i]);
> @@ -6610,7 +6611,7 @@ test_multi_session_random_usage(void)
>
>  	sessions = rte_malloc(NULL,
>  			(sizeof(struct rte_cryptodev_sym_session *)
> -					* dev_info.sym.max_nb_sessions) + 1, 0);
> +					* MAX_NB_SESSIONS) + 1, 0);
>
>  	for (i = 0; i < MB_SESSION_NUMBER; i++) {
>  		sessions[i] = rte_cryptodev_sym_session_create(
> @@ -8545,7 +8546,7 @@ test_scheduler_attach_slave_op(void)
>  		if (ts_params->session_mpool == NULL) {
>  			ts_params->session_mpool = rte_mempool_create(
>  					"test_sess_mp",
> -					info.sym.max_nb_sessions * 2,
> +					MAX_NB_SESSIONS * 2,
>  					session_size,
>  					0, 0, NULL, NULL, NULL,
>  					NULL, SOCKET_ID_ANY,
> --
> 2.17.0
>

--
- Tomasz Duszyński

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] cryptodev: fix ABI breakage
@ 2018-06-13  9:36  8% Pablo de Lara
  2018-06-13  9:50  4% ` Ananyev, Konstantin
  2018-06-13 10:00  4% ` Gujjar, Abhinandan S
  0 siblings, 2 replies; 200+ results
From: Pablo de Lara @ 2018-06-13  9:36 UTC (permalink / raw)
  To: declan.doherty, abhinandan.gujjar; +Cc: dev, Pablo de Lara, stable

In 17.08, the crypto operation was restructured,
and some reserved bytes (5) were added  to have the mempool
pointer aligned to 64 bits, since the structure is expected
to be aligned to 64 bits, allowing future additions with no
ABI breakage needed.

In 18.05, a new 2-byte field was added, so the reserved bytes
were reduced to 3. However, this field was added after the first 3 bytes
of the structure, causing it to be placed in an offset of 4 bytes,
and therefore, forcing the mempool pointer to be placed after 16 bytes,
instead of a 8 bytes, causing unintentionally the ABI breakage.

This commit fixes the breakage, by swapping the reserved bytes
and the private_data_offset field, so the latter is aligned to 2 bytes
and the offset of the mempool pointer returns to its original offset,
8 bytes.

Fixes: 54c836846603 ("cryptodev: set private data for session-less mode")
Cc: stable@dpdk.org

Reported-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 lib/librte_cryptodev/rte_crypto.h | 51 +++++++++++++++++++------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
index 25404264b..a16be656d 100644
--- a/lib/librte_cryptodev/rte_crypto.h
+++ b/lib/librte_cryptodev/rte_crypto.h
@@ -73,26 +73,37 @@ enum rte_crypto_op_sess_type {
  * rte_cryptodev_enqueue_burst() / rte_cryptodev_dequeue_burst() .
  */
 struct rte_crypto_op {
-	uint8_t type;
-	/**< operation type */
-	uint8_t status;
-	/**<
-	 * operation status - this is reset to
-	 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation from mempool and
-	 * will be set to RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation
-	 * is successfully processed by a crypto PMD
-	 */
-	uint8_t sess_type;
-	/**< operation session type */
-	uint16_t private_data_offset;
-	/**< Offset to indicate start of private data (if any). The offset
-	 * is counted from the start of the rte_crypto_op including IV.
-	 * The private data may be used by the application to store
-	 * information which should remain untouched in the library/driver
-	 */
-
-	uint8_t reserved[3];
-	/**< Reserved bytes to fill 64 bits for future additions */
+	__extension__
+	union {
+		uint64_t raw;
+		__extension__
+		struct {
+			uint8_t type;
+			/**< operation type */
+			uint8_t status;
+			/**<
+			 * operation status - this is reset to
+			 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation
+			 * from mempool and will be set to
+			 * RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation
+			 * is successfully processed by a crypto PMD
+			 */
+			uint8_t sess_type;
+			/**< operation session type */
+			uint8_t reserved[3];
+			/**< Reserved bytes to fill 64 bits for
+			 * future additions
+			 */
+			uint16_t private_data_offset;
+			/**< Offset to indicate start of private data (if any).
+			 * The offset is counted from the start of the
+			 * rte_crypto_op including IV.
+			 * The private data may be used by the application
+			 * to store information which should remain untouched
+			 * in the library/driver
+			 */
+		};
+	};
 	struct rte_mempool *mempool;
 	/**< crypto operation mempool which operation is allocated from */
 
-- 
2.17.0

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH] cryptodev: fix ABI breakage
  2018-06-13  9:36  8% [dpdk-dev] [PATCH] cryptodev: fix ABI breakage Pablo de Lara
@ 2018-06-13  9:50  4% ` Ananyev, Konstantin
  2018-06-13 10:00  4% ` Gujjar, Abhinandan S
  1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2018-06-13  9:50 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Doherty, Declan, Gujjar, Abhinandan S
  Cc: dev, De Lara Guarch, Pablo, stable



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pablo de Lara
> Sent: Wednesday, June 13, 2018 10:37 AM
> To: Doherty, Declan <declan.doherty@intel.com>; Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; stable@dpdk.org
> Subject: [dpdk-dev] [PATCH] cryptodev: fix ABI breakage
> 
> In 17.08, the crypto operation was restructured,
> and some reserved bytes (5) were added  to have the mempool
> pointer aligned to 64 bits, since the structure is expected
> to be aligned to 64 bits, allowing future additions with no
> ABI breakage needed.
> 
> In 18.05, a new 2-byte field was added, so the reserved bytes
> were reduced to 3. However, this field was added after the first 3 bytes
> of the structure, causing it to be placed in an offset of 4 bytes,
> and therefore, forcing the mempool pointer to be placed after 16 bytes,
> instead of a 8 bytes, causing unintentionally the ABI breakage.
> 
> This commit fixes the breakage, by swapping the reserved bytes
> and the private_data_offset field, so the latter is aligned to 2 bytes
> and the offset of the mempool pointer returns to its original offset,
> 8 bytes.
> 
> Fixes: 54c836846603 ("cryptodev: set private data for session-less mode")
> Cc: stable@dpdk.org
> 
> Reported-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
>  lib/librte_cryptodev/rte_crypto.h | 51 +++++++++++++++++++------------
>  1 file changed, 31 insertions(+), 20 deletions(-)
> 
> diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
> index 25404264b..a16be656d 100644
> --- a/lib/librte_cryptodev/rte_crypto.h
> +++ b/lib/librte_cryptodev/rte_crypto.h
> @@ -73,26 +73,37 @@ enum rte_crypto_op_sess_type {
>   * rte_cryptodev_enqueue_burst() / rte_cryptodev_dequeue_burst() .
>   */
>  struct rte_crypto_op {
> -	uint8_t type;
> -	/**< operation type */
> -	uint8_t status;
> -	/**<
> -	 * operation status - this is reset to
> -	 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation from mempool and
> -	 * will be set to RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation
> -	 * is successfully processed by a crypto PMD
> -	 */
> -	uint8_t sess_type;
> -	/**< operation session type */
> -	uint16_t private_data_offset;
> -	/**< Offset to indicate start of private data (if any). The offset
> -	 * is counted from the start of the rte_crypto_op including IV.
> -	 * The private data may be used by the application to store
> -	 * information which should remain untouched in the library/driver
> -	 */
> -
> -	uint8_t reserved[3];
> -	/**< Reserved bytes to fill 64 bits for future additions */
> +	__extension__
> +	union {
> +		uint64_t raw;
> +		__extension__
> +		struct {
> +			uint8_t type;
> +			/**< operation type */
> +			uint8_t status;
> +			/**<
> +			 * operation status - this is reset to
> +			 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation
> +			 * from mempool and will be set to
> +			 * RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation
> +			 * is successfully processed by a crypto PMD
> +			 */
> +			uint8_t sess_type;
> +			/**< operation session type */
> +			uint8_t reserved[3];
> +			/**< Reserved bytes to fill 64 bits for
> +			 * future additions
> +			 */
> +			uint16_t private_data_offset;
> +			/**< Offset to indicate start of private data (if any).
> +			 * The offset is counted from the start of the
> +			 * rte_crypto_op including IV.
> +			 * The private data may be used by the application
> +			 * to store information which should remain untouched
> +			 * in the library/driver
> +			 */
> +		};
> +	};
>  	struct rte_mempool *mempool;
>  	/**< crypto operation mempool which operation is allocated from */
> 
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> 2.17.0

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] cryptodev: fix ABI breakage
  2018-06-13  9:36  8% [dpdk-dev] [PATCH] cryptodev: fix ABI breakage Pablo de Lara
  2018-06-13  9:50  4% ` Ananyev, Konstantin
@ 2018-06-13 10:00  4% ` Gujjar, Abhinandan S
  2018-06-27 21:14  4%   ` De Lara Guarch, Pablo
  1 sibling, 1 reply; 200+ results
From: Gujjar, Abhinandan S @ 2018-06-13 10:00 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Doherty, Declan; +Cc: dev, stable



> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Wednesday, June 13, 2018 3:07 PM
> To: Doherty, Declan <declan.doherty@intel.com>; Gujjar, Abhinandan S
> <abhinandan.gujjar@intel.com>
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>;
> stable@dpdk.org
> Subject: [PATCH] cryptodev: fix ABI breakage
> 
> In 17.08, the crypto operation was restructured, and some reserved bytes (5)
> were added  to have the mempool pointer aligned to 64 bits, since the structure
> is expected to be aligned to 64 bits, allowing future additions with no ABI
> breakage needed.
> 
> In 18.05, a new 2-byte field was added, so the reserved bytes were reduced to 3.
> However, this field was added after the first 3 bytes of the structure, causing it
> to be placed in an offset of 4 bytes, and therefore, forcing the mempool pointer
> to be placed after 16 bytes, instead of a 8 bytes, causing unintentionally the ABI
> breakage.
> 
> This commit fixes the breakage, by swapping the reserved bytes and the
> private_data_offset field, so the latter is aligned to 2 bytes and the offset of the
> mempool pointer returns to its original offset,
> 8 bytes.
> 
> Fixes: 54c836846603 ("cryptodev: set private data for session-less mode")
> Cc: stable@dpdk.org
> 
> Reported-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
>  lib/librte_cryptodev/rte_crypto.h | 51 +++++++++++++++++++------------
>  1 file changed, 31 insertions(+), 20 deletions(-)
> 
> diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
> index 25404264b..a16be656d 100644
> --- a/lib/librte_cryptodev/rte_crypto.h
> +++ b/lib/librte_cryptodev/rte_crypto.h
> @@ -73,26 +73,37 @@ enum rte_crypto_op_sess_type {
>   * rte_cryptodev_enqueue_burst() / rte_cryptodev_dequeue_burst() .
>   */
>  struct rte_crypto_op {
> -	uint8_t type;
> -	/**< operation type */
> -	uint8_t status;
> -	/**<
> -	 * operation status - this is reset to
> -	 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation from
> mempool and
> -	 * will be set to RTE_CRYPTO_OP_STATUS_SUCCESS after crypto
> operation
> -	 * is successfully processed by a crypto PMD
> -	 */
> -	uint8_t sess_type;
> -	/**< operation session type */
> -	uint16_t private_data_offset;
> -	/**< Offset to indicate start of private data (if any). The offset
> -	 * is counted from the start of the rte_crypto_op including IV.
> -	 * The private data may be used by the application to store
> -	 * information which should remain untouched in the library/driver
> -	 */
> -
> -	uint8_t reserved[3];
> -	/**< Reserved bytes to fill 64 bits for future additions */
> +	__extension__
> +	union {
> +		uint64_t raw;
> +		__extension__
> +		struct {
> +			uint8_t type;
> +			/**< operation type */
> +			uint8_t status;
> +			/**<
> +			 * operation status - this is reset to
> +			 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on
> allocation
> +			 * from mempool and will be set to
> +			 * RTE_CRYPTO_OP_STATUS_SUCCESS after crypto
> operation
> +			 * is successfully processed by a crypto PMD
> +			 */
> +			uint8_t sess_type;
> +			/**< operation session type */
> +			uint8_t reserved[3];
> +			/**< Reserved bytes to fill 64 bits for
> +			 * future additions
> +			 */
> +			uint16_t private_data_offset;
> +			/**< Offset to indicate start of private data (if any).
> +			 * The offset is counted from the start of the
> +			 * rte_crypto_op including IV.
> +			 * The private data may be used by the application
> +			 * to store information which should remain untouched
> +			 * in the library/driver
> +			 */
> +		};
> +	};
>  	struct rte_mempool *mempool;
>  	/**< crypto operation mempool which operation is allocated from */
> 
> --

Acked-by: Abhinandan Gujjar <Abhinandan.gujjar@intel.com>

> 2.17.0

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v8] checkpatches.sh: Add checks for ABI symbol addition
      2018-06-05 12:21  6% ` [dpdk-dev] [PATCH v7] " Neil Horman
@ 2018-06-14 13:30  6% ` Neil Horman
  2018-06-25 23:04  4%   ` Thomas Monjalon
  2018-06-27 18:01  6% ` [dpdk-dev] [PATCH v9] " Neil Horman
  3 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-06-14 13:30 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, thomas, john.mcnamara, bruce.richardson,
	Ferruh Yigit, Stephen Hemminger

Recently, some additional patches were added to allow for programmatic
marking of C symbols as experimental.  The addition of these markers is
dependent on the manual addition of exported symbols to the EXPERIMENTAL
section of the corresponding libraries version map file.  The consensus
on review is that, in addition to mandating the addition of symbols to
the EXPERIMENTAL version in the map, we need a mechanism to enforce our
documented process of mandating that addition when they are introduced.
To that end, I am proposing this change.  It is an addition to the
checkpatches script, which scan incoming patches for additions and
removals of symbols to the map file, and warns the user appropriately

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: thomas@monjalon.net
CC: john.mcnamara@intel.com
CC: bruce.richardson@intel.com
CC: Ferruh Yigit <ferruh.yigit@intel.com>
CC: Stephen Hemminger <stephen@networkplumber.org>

---
Change notes

v2)
 * Cleaned up and documented awk script (shemminger)
 * fixed sort/uniq usage (shemminger)
 * moved checking to new script (tmonjalon)
 * added maintainer entry (tmonjalon)
 * added license (tmonjalon)

v3)
 * Changed symbol check script name (tmonjalon)
 * Trapped exit to clean temp file (tmonjalon)
 * Honored verbose command (tmonjalon)
 * Cleaned left over debug bits (tmonjalon)
 * Updated location in MAINTAINERS file (tmonjalon)

v4)
 * Updated maintainers file (tmonjalon)

v5)
 * undo V4 (tmojalon)

v6)
 * Cleaning up more nits (tmonjalon)
 * Combining some lines (tmonjalon)
 * Fixing error print condition (tmonjalon)
 * Redirect stdin to a file to allow rewinding for
   Multiple passes on tools (nhorman)

v7)
 * More nits (tmonjalon)
 * consoloidating some common report lines (tmonjalon)
 * move SPDX identifier to line 2 (nhorman)
 * fix some checkpatch errors

v8)
 * spelling fix (nhorman)
 * found a way to eliminate the use of filterdiff (new awk rules)
---
 MAINTAINERS                     |   1 +
 devtools/check-symbol-change.sh | 161 ++++++++++++++++++++++++++++++++
 devtools/checkpatches.sh        |  50 ++++++++--
 3 files changed, 205 insertions(+), 7 deletions(-)
 create mode 100755 devtools/check-symbol-change.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 4667fa7fb..7b1180fe0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -122,6 +122,7 @@ M: Neil Horman <nhorman@tuxdriver.com>
 F: lib/librte_compat/
 F: doc/guides/rel_notes/deprecation.rst
 F: devtools/validate-abi.sh
+F: devtools/check-symbol-change.sh
 F: buildtools/check-experimental-syms.sh
 
 Driver information
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
new file mode 100755
index 000000000..6d7d83db4
--- /dev/null
+++ b/devtools/check-symbol-change.sh
@@ -0,0 +1,161 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
+
+build_map_changes()
+{
+	local fname=$1
+	local mapdb=$2
+
+	cat $fname | awk '
+		# Initialize our variables
+		BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
+
+		# Anything that starts with + or -, followed by an a
+		# and ends in the string .map is the name of our map file
+		# This may appear multiple times in a patch if multiple
+		# map files are altered, and all section/symbol names
+		# appearing between a triggering of this rule and the
+		# next trigger of this rule are associated with this file
+		/[-+] a\/.*\.map/ {map=$2; in_map=1}
+
+		# Same pattern as above, only it matches on anything that
+		# doesnt end in 'map', indicating we have left the map chunk.
+		# When we hit this, turn off the in_map variable, which
+		# supresses the subordonate rules below
+		/[-+] a\/.*\.^(map)/ {in_map=0}
+
+		# Triggering this rule, which starts a line with a + and ends it
+		# with a { identifies a versioned section.  The section name is
+		# the rest of the line with the + and { symbols remvoed.
+		# Triggering this rule sets in_sec to 1, which actives the
+		# symbol rule below
+		/+.*{/ {gsub("+","");
+			if (in_map == 1) {
+				sec=$1; in_sec=1;
+			}
+		}
+
+		# This rule idenfies the end of a section, and disables the
+		# symbol rule
+		/.*}/ {in_sec=0}
+
+		# This rule matches on a + followed by any characters except a :
+		# (which denotes a global vs local segment), and ends with a ;.
+		# The semicolon is removed and the symbol is printed with its
+		# association file name and version section, along with an
+		# indicator that the symbol is a new addition.  Note this rule
+		# only works if we have found a version section in the rule
+		# above (hence the in_sec check) And found a map file (the
+		# in_map check).  If we are not in a map chunk, do nothing.  If
+		# we are in a map chunk but not a section chunk, record it as
+		# unknown.
+		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " add"
+				} else {
+					print map " " sym " unknown add"
+				}
+			}
+		}
+
+		# This is the same rule as above, but the rule matches on a
+		# leading - rather than a +, denoting that the symbol is being
+		# removed.
+		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " del"
+				} else {
+					print map " " sym " unknown del"
+				}
+			}
+		}' > ./$mapdb
+
+		sort -u $mapdb > ./$mapdb.2
+		mv -f $mapdb.2 $mapdb
+
+}
+
+check_for_rule_violations()
+{
+	local mapdb=$1
+	local mname
+	local symname
+	local secname
+	local ar
+	local ret=0
+
+	while read mname symname secname ar
+	do
+		if [ "$ar" == "add" ]
+		then
+
+			if [ "$secname" == "unknown" ]
+			then
+				# Just inform the user of this occurrence, but
+				# don't flag it as an error
+				echo -n "INFO: symbol $syname is added but "
+				echo -n "patch has insuficient context "
+				echo -n "to determine the section name "
+				echo -n "please ensure the version is "
+				echo "EXPERIMENTAL"
+				continue
+			fi
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Symbols that are getting added in a section
+				# other than the experimental section
+				# to be moving from an already supported
+				# section or its a violation
+				grep -q \
+				"$mname $symname [^EXPERIMENTAL] del" $mapdb
+				if [ $? -ne 0 ]
+				then
+					echo -n "ERROR: symbol $symname "
+					echo -n "is added in a section "
+					echo -n "other than the EXPERIMENTAL "
+					echo "section of the version map"
+					ret=1
+				fi
+			fi
+		else
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Just inform users that non-experimenal
+				# symbols need to go through a deprecation
+				# process
+				echo -n "INFO: symbol $symname is being "
+				echo -n "removed, ensure that it has "
+				echo "gone through the deprecation process"
+			fi
+		fi
+	done < $mapdb
+
+	return $ret
+}
+
+trap clean_and_exit_on_sig EXIT
+
+mapfile=`mktemp mapdb.XXXXXX`
+patch=$1
+exit_code=1
+
+clean_and_exit_on_sig()
+{
+	rm -f $mapfile
+	exit $exit_code
+}
+
+build_map_changes $patch $mapfile
+check_for_rule_violations $mapfile
+exit_code=$?
+
+rm -f $mapfile
+
+exit $exit_code
+
+
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 663b7c426..10ba35340 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -7,6 +7,9 @@
 # - DPDK_CHECKPATCH_LINE_LENGTH
 . $(dirname $(readlink -e $0))/load-devel-config
 
+
+VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
+
 length=${DPDK_CHECKPATCH_LINE_LENGTH:-80}
 
 # override default Linux options
@@ -21,6 +24,15 @@ SPLIT_STRING,LONG_LINE_STRING,\
 LINE_SPACING,PARENTHESIS_ALIGNMENT,NETWORKING_BLOCK_COMMENT_STYLE,\
 NEW_TYPEDEFS,COMPARISON_TO_NULL"
 
+clean_tmp_files() {
+	echo $TMPINPUT | grep -q checkpaches
+	if [ $? -eq 0 ]; then
+		rm -f $TMPINPUT
+	fi
+}
+
+trap "clean_tmp_files" SIGINT
+
 print_usage () {
 	cat <<- END_OF_HELP
 	usage: $(basename $0) [-q] [-v] [-nX|patch1 [patch2] ...]]
@@ -58,19 +70,43 @@ total=0
 status=0
 
 check () { # <patch> <commit> <title>
+	local ret=0
+
 	total=$(($total + 1))
 	! $verbose || printf '\n### %s\n\n' "$3"
 	if [ -n "$1" ] ; then
-		report=$($DPDK_CHECKPATCH_PATH $options "$1" 2>/dev/null)
+		TMPINPUT=$1
 	elif [ -n "$2" ] ; then
-		report=$(git format-patch --find-renames --no-stat --stdout -1 $commit |
-			$DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		TMPINPUT=$(mktemp checkpatches.XXXXXX)
+		git format-patch --find-renames \
+		--no-stat --stdout -1 $commit > ./$TMPINPUT
 	else
-		report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		TMPINPUT=$(mktemp checkpatches.XXXXXX)
+		cat > ./$TMPINPUT
+	fi
+
+	report=$($DPDK_CHECKPATCH_PATH $options $TMPINPUT 2>/dev/null)
+
+	if [ $? -ne 0 ]
+	then
+		$verbose || printf '\n### %s\n\n' "$3"
+		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+		ret=1
+	fi
+
+	! $verbose || printf '\nChecking API additions/removals:\n'
+
+	report=$($VALIDATE_NEW_API "$TMPINPUT")
+
+	if [ $? -ne 0 ]; then
+		printf '%s\n' "$report"
+		ret=1
+	fi
+
+	clean_tmp_files
+	if [ $ret -eq 0 ]; then
+		return 0
 	fi
-	[ $? -ne 0 ] || return 0
-	$verbose || printf '\n### %s\n\n' "$3"
-	printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
 	status=$(($status + 1))
 }
 
-- 
2.17.1

^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH v2 01/22] eal: introduce one device scan
  @ 2018-06-21  7:56  3%     ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-06-21  7:56 UTC (permalink / raw)
  To: Qi Zhang, thomas
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati

On 21-Jun-18 3:00 AM, Qi Zhang wrote:
> When hot plug a new device, it is not necessary to scan everything
> on the bus since the devname and devargs are already there. So new
> rte_bus ops "scan_one" is introduced, bus driver can implement this
> function to simplify the hotplug process.
> 
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
> 

<snip>

> +/**
>    * Implementation specific probe function which is responsible for linking
>    * devices on that bus with applicable drivers.
>    *
> @@ -204,6 +219,7 @@ struct rte_bus {
>   	TAILQ_ENTRY(rte_bus) next;   /**< Next bus object in linked list */
>   	const char *name;            /**< Name of the bus */
>   	rte_bus_scan_t scan;         /**< Scan for devices attached to bus */
> +	rte_bus_scan_one_t scan_one; /**< Scan one device using devargs */
>   	rte_bus_probe_t probe;       /**< Probe devices on bus */
>   	rte_bus_find_device_t find_device; /**< Find a device on the bus */
>   	rte_bus_plug_t plug;         /**< Probe single device for drivers */
> 

Does this break ABI for bus?

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 03/22] ethdev: add function to release port in local process
  @ 2018-06-21  8:06  3%     ` Burakov, Anatoly
  2018-06-21  8:21  4%       ` Thomas Monjalon
  2018-06-21  8:21  0%       ` Zhang, Qi Z
  0 siblings, 2 replies; 200+ results
From: Burakov, Anatoly @ 2018-06-21  8:06 UTC (permalink / raw)
  To: Qi Zhang, thomas
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati

On 21-Jun-18 3:00 AM, Qi Zhang wrote:
> Add driver API rte_eth_release_port_private to support the
> requirement that an ethdev only be released on secondary process,
> so only local state be set to unused , share data will not be
> reset so primary process can still use it.
> 
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---

<snip>

>   
>   /**
>    * @internal
> + * Release the specified ethdev port in local process, only set to ethdev
> + * state to unused, but not reset share data since it assume other process
> + * is still using it, typically it is called by secondary process.
> + *
> + * @param eth_dev
> + * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
> + * @return
> + *   - 0 on success, negative on error
> + */
> +int rte_eth_dev_release_port_private(struct rte_eth_dev *eth_dev);
> +

As far as i can tell, even though the function is marked as internal, it 
should still be exported in the .map file (see rte_eth_dev_allocate() 
for example).

Thomas and others, does this count as new API? Should this be marked as 
__rte_experimental? Presumably, we guarantee ABI stability for internal 
functions too, so my expectation would be yes.

> +/**
> + * @internal
>    * Release device queues and clear its configuration to force the user
>    * application to reconfigure it. It is for internal use only.
>    *
> 


-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 03/22] ethdev: add function to release port in local process
  2018-06-21  8:06  3%     ` Burakov, Anatoly
@ 2018-06-21  8:21  4%       ` Thomas Monjalon
  2018-06-21  8:21  0%       ` Zhang, Qi Z
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-06-21  8:21 UTC (permalink / raw)
  To: Burakov, Anatoly, Qi Zhang
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati

21/06/2018 10:06, Burakov, Anatoly:
> On 21-Jun-18 3:00 AM, Qi Zhang wrote:
> > Add driver API rte_eth_release_port_private to support the
> > requirement that an ethdev only be released on secondary process,
> > so only local state be set to unused , share data will not be
> > reset so primary process can still use it.
> > 
> > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > ---
> 
> <snip>
> 
> >   
> >   /**
> >    * @internal
> > + * Release the specified ethdev port in local process, only set to ethdev
> > + * state to unused, but not reset share data since it assume other process
> > + * is still using it, typically it is called by secondary process.
> > + *
> > + * @param eth_dev
> > + * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
> > + * @return
> > + *   - 0 on success, negative on error
> > + */
> > +int rte_eth_dev_release_port_private(struct rte_eth_dev *eth_dev);
> > +
> 
> As far as i can tell, even though the function is marked as internal, it 
> should still be exported in the .map file (see rte_eth_dev_allocate() 
> for example).
> 
> Thomas and others, does this count as new API? Should this be marked as 
> __rte_experimental? Presumably, we guarantee ABI stability for internal 
> functions too, so my expectation would be yes.

You know the A in ABI stands for Application :)
If it is not called by application, it has no impact on ABI.

However, I am not sure about having this function at all.
Who is calling it?

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 03/22] ethdev: add function to release port in local process
  2018-06-21  8:06  3%     ` Burakov, Anatoly
  2018-06-21  8:21  4%       ` Thomas Monjalon
@ 2018-06-21  8:21  0%       ` Zhang, Qi Z
  1 sibling, 0 replies; 200+ results
From: Zhang, Qi Z @ 2018-06-21  8:21 UTC (permalink / raw)
  To: Burakov, Anatoly, thomas
  Cc: Ananyev, Konstantin, dev, Richardson, Bruce, Yigit, Ferruh,
	Shelton, Benjamin H, Vangati, Narender



> -----Original Message-----
> From: Burakov, Anatoly
> Sent: Thursday, June 21, 2018 4:06 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; thomas@monjalon.net
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org;
> Richardson, Bruce <bruce.richardson@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; Shelton, Benjamin H
> <benjamin.h.shelton@intel.com>; Vangati, Narender
> <narender.vangati@intel.com>
> Subject: Re: [PATCH v2 03/22] ethdev: add function to release port in local
> process
> 
> On 21-Jun-18 3:00 AM, Qi Zhang wrote:
> > Add driver API rte_eth_release_port_private to support the requirement
> > that an ethdev only be released on secondary process, so only local
> > state be set to unused , share data will not be reset so primary
> > process can still use it.
> >
> > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > ---
> 
> <snip>
> 
> >
> >   /**
> >    * @internal
> > + * Release the specified ethdev port in local process, only set to
> > +ethdev
> > + * state to unused, but not reset share data since it assume other
> > +process
> > + * is still using it, typically it is called by secondary process.
> > + *
> > + * @param eth_dev
> > + * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
> > + * @return
> > + *   - 0 on success, negative on error
> > + */
> > +int rte_eth_dev_release_port_private(struct rte_eth_dev *eth_dev);
> > +
> 
> As far as i can tell, even though the function is marked as internal, it should still
> be exported in the .map file (see rte_eth_dev_allocate() for example).
> 
> Thomas and others, does this count as new API? Should this be marked as
> __rte_experimental? Presumably, we guarantee ABI stability for internal
> functions too, so my expectation would be yes.

Sorry, I not intent to mark this as experimental, I must forgot to remove this
It should rte_eth_dev_attach/detach_private and rte_eth_dev_lock/unlock .

I guess internal API is not necessary to have this.
I will remove it in v3

Thanks
Qi

> 
> > +/**
> > + * @internal
> >    * Release device queues and clear its configuration to force the user
> >    * application to reconfigure it. It is for internal use only.
> >    *
> >
> 
> 
> --
> Thanks,
> Anatoly

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
  2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions Pablo de Lara
@ 2018-06-21 12:59  0%   ` Akhil Goyal
  2018-06-22 17:02  0%     ` Verma, Shally
  0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2018-06-21 12:59 UTC (permalink / raw)
  To: Pablo de Lara, declan.doherty, ravi1.kumar, jerin.jacob,
	roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev

Hi Pablo,


On 6/9/2018 3:32 AM, Pablo de Lara wrote:
> Removed rte_cryptodev_get_header_session_size
> and rte_cryptodev_get_private_session_size functions,
> as they have been substituted with functions
> specific for symmetric operations, with _sym_ word
> after "rte_cryptodev_".
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> ---
>   doc/guides/rel_notes/deprecation.rst           |  6 ------
>   doc/guides/rel_notes/release_18_08.rst         |  8 ++++++++
>   lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
>   lib/librte_cryptodev/rte_cryptodev.h           | 11 -----------
>   lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
>   5 files changed, 8 insertions(+), 25 deletions(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 91592534e..9a73b1d8e 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -107,9 +107,3 @@ Deprecation Notices
>       with them.
>     - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
>       so some will be replaced by more explicit flags.
> -  - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
> -    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_header_session_size()``.
> -    It will be removed in 18.08.
> -  - Function ``rte_cryptodev_get_private_session_size()`` will be deprecated
> -    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_private_session_size()``.
> -    It will be removed in 18.08.
> diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
> index 3fa9a6e68..0624f3701 100644
> --- a/doc/guides/rel_notes/release_18_08.rst
> +++ b/doc/guides/rel_notes/release_18_08.rst
> @@ -64,6 +64,14 @@ API Changes
>     - ``rte_cryptodev_queue_pair_start``
>     - ``rte_cryptodev_queue_pair_stop``
>   
> +* cryptodev: Following functions were deprecated and are replaced by
> +  other functions in 18.08:
> +
> +  - ``rte_cryptodev_get_header_session_size`` is replaced with
> +    ``rte_cryptodev_sym_get_header_session_size``
> +  - ``rte_cryptodev_get_private_session_size`` is replaced with
> +    ``rte_cryptodev_sym_get_private_session_size``
> +
rte_cryptodev_get_private_session_size is not removed in this patch. I 
think you missed it in your patch.

-Akhil
>   
>   ABI Changes
>   -----------
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
> index a07904fb9..40e249e79 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
>   	return 0;
>   }
>   
> -unsigned int
> -rte_cryptodev_get_header_session_size(void)
> -{
> -	return rte_cryptodev_sym_get_header_session_size();
> -}
> -
>   unsigned int
>   rte_cryptodev_sym_get_header_session_size(void)
>   {
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> index 90487bffc..8e8a59522 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -925,17 +925,6 @@ int
>   rte_cryptodev_sym_session_clear(uint8_t dev_id,
>   			struct rte_cryptodev_sym_session *sess);
>   
> -/**
> - * @deprecated
> - * Get the size of the header session, for all registered drivers.
> - *
> - * @return
> - *   Size of the header session.
> - */
> -__rte_deprecated
> -unsigned int
> -rte_cryptodev_get_header_session_size(void);
> -
>   /**
>    * @deprecated
>    * Get the size of the private session data for a device.
> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
> index 020b45754..0ab6d5195 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
> @@ -63,8 +63,6 @@ DPDK_17.08 {
>   	rte_cryptodev_driver_id_get;
>   	rte_cryptodev_driver_name_get;
>   	rte_cryptodev_get_aead_algo_enum;
> -	rte_cryptodev_get_header_session_size;
> -	rte_cryptodev_get_private_session_size;
>   	rte_cryptodev_sym_capability_check_aead;
>   	rte_cryptodev_sym_session_init;
>   	rte_cryptodev_sym_session_clear;

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 1/2] cryptodev: add min headroom and tailroom requirement
  @ 2018-06-22  6:52  3%     ` Joseph, Anoob
  2018-06-22 10:03  0%       ` Akhil Goyal
  0 siblings, 1 reply; 200+ results
From: Joseph, Anoob @ 2018-06-22  6:52 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Ankur Dwivedi, Jerin Jacob, Narayana Prasad, dev

Hi Akhil,

The change adds couple of entries in cryptodev_info structure. I was 
under the impression this will be an ABI change and would need one 
release cycle. If we can get this through in 18.08, it would be great. 
Do you want me to revise the patch stating it that way?

Thanks,
Anoob
On 21-06-2018 19:54, Akhil Goyal wrote:
>
> On 6/19/2018 11:56 AM, Anoob Joseph wrote:
>> Enabling crypto devs to specify the minimum headroom and tailroom it
>> expects in the mbuf. For net PMDs, standard headroom has to be honoured
>> by applications, which is not strictly followed for crypto devs. This
>> prevents crypto devs from using free space in mbuf (available as
>> head/tailroom) for internal requirements in crypto operations. Addition
>> of head/tailroom requirement will help PMDs to communicate such
>> requirements to the application.
>>
>> The availability and use of head/tailroom is an optimization if the
>> hardware supports use of head/tailroom for crypto-op info. For devices
>> that do not support using the head/tailroom, they can continue to 
>> operate
>> without any performance-drop.
>>
>> Signed-off-by: Anoob Joseph <anoob.joseph@caviumnetworks.com>
>> ---
>>   doc/guides/rel_notes/deprecation.rst | 4 ++++
>>   lib/librte_cryptodev/rte_cryptodev.h | 6 ++++++
>>   2 files changed, 10 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst 
>> b/doc/guides/rel_notes/deprecation.rst
>> index 1ce692e..a547289 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -122,3 +122,7 @@ Deprecation Notices
>>     - Function ``rte_cryptodev_get_private_session_size()`` will be 
>> deprecated
>>       in 18.05, and it gets replaced with 
>> ``rte_cryptodev_sym_get_private_session_size()``.
>>       It will be removed in 18.08.
>> +  - New field, ``min_headroom_req``, added in ``rte_cryptodev_info`` 
>> structure. It will be
>> +    added in 18.11.
>> +  - New field, ``min_tailroom_req``, added in ``rte_cryptodev_info`` 
>> structure. It will be
>> +    added in 18.11.
>
> Is this targeted for 18.08 or 18.11?
>
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h 
>> b/lib/librte_cryptodev/rte_cryptodev.h
>> index 92ce6d4..fa944b8 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>> @@ -382,6 +382,12 @@ struct rte_cryptodev_info {
>>       unsigned max_nb_queue_pairs;
>>       /**< Maximum number of queues pairs supported by device. */
>>
>> +     uint32_t min_headroom_req;
>> +     /**< Minimum mbuf headroom required by device */
>> +
>> +     uint32_t min_tailroom_req;
>> +     /**< Minimum mbuf tailroom required by device */
>> +
>>       struct {
>>               unsigned max_nb_sessions;
>>               /**< Maximum number of sessions supported by device. */
>

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 1/2] cryptodev: add min headroom and tailroom requirement
  2018-06-22  6:52  3%     ` Joseph, Anoob
@ 2018-06-22 10:03  0%       ` Akhil Goyal
  0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2018-06-22 10:03 UTC (permalink / raw)
  To: Joseph, Anoob, Declan Doherty, Pablo de Lara
  Cc: Ankur Dwivedi, Jerin Jacob, Narayana Prasad, dev

Hi Anoob,


On 6/22/2018 12:22 PM, Joseph, Anoob wrote:
> Hi Akhil,
>
> The change adds couple of entries in cryptodev_info structure. I was 
> under the impression this will be an ABI change and would need one 
> release cycle. If we can get this through in 18.08, it would be great. 
> Do you want me to revise the patch stating it that way?

If you are adding a deprecation notice for next release, then you cannot add code in that release.

To add this in current release, I think Pablo can take a decision on this.


>
> Thanks,
> Anoob
> On 21-06-2018 19:54, Akhil Goyal wrote:
>>
>> On 6/19/2018 11:56 AM, Anoob Joseph wrote:
>>> Enabling crypto devs to specify the minimum headroom and tailroom it
>>> expects in the mbuf. For net PMDs, standard headroom has to be honoured
>>> by applications, which is not strictly followed for crypto devs. This
>>> prevents crypto devs from using free space in mbuf (available as
>>> head/tailroom) for internal requirements in crypto operations. Addition
>>> of head/tailroom requirement will help PMDs to communicate such
>>> requirements to the application.
>>>
>>> The availability and use of head/tailroom is an optimization if the
>>> hardware supports use of head/tailroom for crypto-op info. For devices
>>> that do not support using the head/tailroom, they can continue to 
>>> operate
>>> without any performance-drop.
>>>
>>> Signed-off-by: Anoob Joseph <anoob.joseph@caviumnetworks.com>
>>> ---
>>>   doc/guides/rel_notes/deprecation.rst | 4 ++++
>>>   lib/librte_cryptodev/rte_cryptodev.h | 6 ++++++
>>>   2 files changed, 10 insertions(+)
>>>
>>> diff --git a/doc/guides/rel_notes/deprecation.rst 
>>> b/doc/guides/rel_notes/deprecation.rst
>>> index 1ce692e..a547289 100644
>>> --- a/doc/guides/rel_notes/deprecation.rst
>>> +++ b/doc/guides/rel_notes/deprecation.rst
>>> @@ -122,3 +122,7 @@ Deprecation Notices
>>>     - Function ``rte_cryptodev_get_private_session_size()`` will be 
>>> deprecated
>>>       in 18.05, and it gets replaced with 
>>> ``rte_cryptodev_sym_get_private_session_size()``.
>>>       It will be removed in 18.08.
>>> +  - New field, ``min_headroom_req``, added in 
>>> ``rte_cryptodev_info`` structure. It will be
>>> +    added in 18.11.
>>> +  - New field, ``min_tailroom_req``, added in 
>>> ``rte_cryptodev_info`` structure. It will be
>>> +    added in 18.11.
>>
>> Is this targeted for 18.08 or 18.11?
>>
>>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h 
>>> b/lib/librte_cryptodev/rte_cryptodev.h
>>> index 92ce6d4..fa944b8 100644
>>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>>> @@ -382,6 +382,12 @@ struct rte_cryptodev_info {
>>>       unsigned max_nb_queue_pairs;
>>>       /**< Maximum number of queues pairs supported by device. */
>>>
>>> +     uint32_t min_headroom_req;
>>> +     /**< Minimum mbuf headroom required by device */
>>> +
>>> +     uint32_t min_tailroom_req;
>>> +     /**< Minimum mbuf tailroom required by device */
>>> +
>>>       struct {
>>>               unsigned max_nb_sessions;
>>>               /**< Maximum number of sessions supported by device. */
>>
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
  2018-06-21 12:59  0%   ` Akhil Goyal
@ 2018-06-22 17:02  0%     ` Verma, Shally
  2018-06-25 16:40  0%       ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 200+ results
From: Verma, Shally @ 2018-06-22 17:02 UTC (permalink / raw)
  To: Akhil Goyal, Pablo de Lara, declan.doherty, ravi1.kumar, Jacob,
	 Jerin, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev

Hi Pablo

>-----Original Message-----
>From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
>Sent: 21 June 2018 18:29
>To: Pablo de Lara <pablo.de.lara.guarch@intel.com>; declan.doherty@intel.com; ravi1.kumar@amd.com; Jacob, Jerin
><Jerin.JacobKollanukkaran@cavium.com>; roy.fan.zhang@intel.com; fiona.trahe@intel.com; tdu@semihalf.com;
>jianjay.zhou@huawei.com
>Cc: dev@dpdk.org
>Subject: Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
>
>External Email
>
>Hi Pablo,
>
>
>On 6/9/2018 3:32 AM, Pablo de Lara wrote:
>> Removed rte_cryptodev_get_header_session_size
>> and rte_cryptodev_get_private_session_size functions,
>> as they have been substituted with functions
>> specific for symmetric operations, with _sym_ word
>> after "rte_cryptodev_".
>>
>> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
>> ---
>>   doc/guides/rel_notes/deprecation.rst           |  6 ------
>>   doc/guides/rel_notes/release_18_08.rst         |  8 ++++++++
>>   lib/librte_cryptodev/rte_cryptodev.c           |  6 ------
>>   lib/librte_cryptodev/rte_cryptodev.h           | 11 -----------
>>   lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
>>   5 files changed, 8 insertions(+), 25 deletions(-)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>> index 91592534e..9a73b1d8e 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -107,9 +107,3 @@ Deprecation Notices
>>       with them.
>>     - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
>>       so some will be replaced by more explicit flags.
>> -  - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
>> -    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_header_session_size()``.
>> -    It will be removed in 18.08.
>> -  - Function ``rte_cryptodev_get_private_session_size()`` will be deprecated
>> -    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_private_session_size()``.
>> -    It will be removed in 18.08.
>> diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
>> index 3fa9a6e68..0624f3701 100644
>> --- a/doc/guides/rel_notes/release_18_08.rst
>> +++ b/doc/guides/rel_notes/release_18_08.rst
>> @@ -64,6 +64,14 @@ API Changes
>>     - ``rte_cryptodev_queue_pair_start``
>>     - ``rte_cryptodev_queue_pair_stop``
>>
>> +* cryptodev: Following functions were deprecated and are replaced by
>> +  other functions in 18.08:
>> +
>> +  - ``rte_cryptodev_get_header_session_size`` is replaced with
>> +    ``rte_cryptodev_sym_get_header_session_size``
>> +  - ``rte_cryptodev_get_private_session_size`` is replaced with
>> +    ``rte_cryptodev_sym_get_private_session_size``
>> +
>rte_cryptodev_get_private_session_size is not removed in this patch. I
>think you missed it in your patch.
>
>-Akhil
>>
>>   ABI Changes
>>   -----------
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
>> index a07904fb9..40e249e79 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>> @@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
>>       return 0;
>>   }
>>
>> -unsigned int
>> -rte_cryptodev_get_header_session_size(void)
>> -{
>> -     return rte_cryptodev_sym_get_header_session_size();
>> -}
>> -
>>   unsigned int
>>   rte_cryptodev_sym_get_header_session_size(void)
>>   {

[Shally] I missed this before. I think this implementation either should change to use nb_drivers which support symmetric or else I am not seeing a need for separate sym specific API for header_size since it will always be same for both sym and asym.

Thanks
Shally

>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
>> index 90487bffc..8e8a59522 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>> @@ -925,17 +925,6 @@ int
>>   rte_cryptodev_sym_session_clear(uint8_t dev_id,
>>                       struct rte_cryptodev_sym_session *sess);
>>
>> -/**
>> - * @deprecated
>> - * Get the size of the header session, for all registered drivers.
>> - *
>> - * @return
>> - *   Size of the header session.
>> - */
>> -__rte_deprecated
>> -unsigned int
>> -rte_cryptodev_get_header_session_size(void);
>> -
>>   /**
>>    * @deprecated
>>    * Get the size of the private session data for a device.
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
>> index 020b45754..0ab6d5195 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>> @@ -63,8 +63,6 @@ DPDK_17.08 {
>>       rte_cryptodev_driver_id_get;
>>       rte_cryptodev_driver_name_get;
>>       rte_cryptodev_get_aead_algo_enum;
>> -     rte_cryptodev_get_header_session_size;
>> -     rte_cryptodev_get_private_session_size;
>>       rte_cryptodev_sym_capability_check_aead;
>>       rte_cryptodev_sym_session_init;
>>       rte_cryptodev_sym_session_clear;


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
  2018-06-22 17:02  0%     ` Verma, Shally
@ 2018-06-25 16:40  0%       ` De Lara Guarch, Pablo
  2018-06-26  5:28  0%         ` Verma, Shally
  0 siblings, 1 reply; 200+ results
From: De Lara Guarch, Pablo @ 2018-06-25 16:40 UTC (permalink / raw)
  To: Verma, Shally, Akhil Goyal, Doherty, Declan, ravi1.kumar, Jacob,
	 Jerin, Zhang, Roy Fan, Trahe, Fiona, tdu, jianjay.zhou
  Cc: dev



> -----Original Message-----
> From: Verma, Shally [mailto:Shally.Verma@cavium.com]
> Sent: Friday, June 22, 2018 6:02 PM
> To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Doherty, Declan
> <declan.doherty@intel.com>; ravi1.kumar@amd.com; Jacob, Jerin
> <Jerin.JacobKollanukkaran@cavium.com>; Zhang, Roy Fan
> <roy.fan.zhang@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> tdu@semihalf.com; jianjay.zhou@huawei.com
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size
> functions
> 
> Hi Pablo
> 
> >-----Original Message-----
> >From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
> >Sent: 21 June 2018 18:29
> >To: Pablo de Lara <pablo.de.lara.guarch@intel.com>;
> >declan.doherty@intel.com; ravi1.kumar@amd.com; Jacob, Jerin
> ><Jerin.JacobKollanukkaran@cavium.com>; roy.fan.zhang@intel.com;
> >fiona.trahe@intel.com; tdu@semihalf.com; jianjay.zhou@huawei.com
> >Cc: dev@dpdk.org
> >Subject: Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session
> >size functions
> >
> >External Email
> >
> >Hi Pablo,
> >
> >
> >On 6/9/2018 3:32 AM, Pablo de Lara wrote:
> >> Removed rte_cryptodev_get_header_session_size
> >> and rte_cryptodev_get_private_session_size functions, as they have
> >> been substituted with functions specific for symmetric operations,
> >> with _sym_ word after "rte_cryptodev_".
> >>
> >> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> >> ---

...

> >> +
> >> +  - ``rte_cryptodev_get_header_session_size`` is replaced with
> >> +    ``rte_cryptodev_sym_get_header_session_size``
> >> +  - ``rte_cryptodev_get_private_session_size`` is replaced with
> >> +    ``rte_cryptodev_sym_get_private_session_size``
> >> +
> >rte_cryptodev_get_private_session_size is not removed in this patch. I
> >think you missed it in your patch.

Right Akhil, thanks for spotting this. Will fix in next version.

> >
> >-Akhil
> >>
> >>   ABI Changes
> >>   -----------
> >> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> >> b/lib/librte_cryptodev/rte_cryptodev.c
> >> index a07904fb9..40e249e79 100644
> >> --- a/lib/librte_cryptodev/rte_cryptodev.c
> >> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> >> @@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct
> rte_cryptodev_sym_session *sess)
> >>       return 0;
> >>   }
> >>
> >> -unsigned int
> >> -rte_cryptodev_get_header_session_size(void)
> >> -{
> >> -     return rte_cryptodev_sym_get_header_session_size();
> >> -}
> >> -
> >>   unsigned int
> >>   rte_cryptodev_sym_get_header_session_size(void)
> >>   {
> 
> [Shally] I missed this before. I think this implementation either should change to
> use nb_drivers which support symmetric or else I am not seeing a need for
> separate sym specific API for header_size since it will always be same for both
> sym and asym.

The implementation is already using nb_drivers to calculate the size, right?
Anyway, I understand that the way asymmetric sessions are done, the API
will be the same, but this could change in the future and since we have already deprecated the
generic function (get_header_session_size), I think we should continue and have both _sym and _asym_ functions.

Thanks,
Pablo


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2 01/15] cryptodev: replace bus specific struct with generic dev
  @ 2018-06-25  8:48  4%   ` Pablo de Lara
  2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 08/15] cryptodev: define value for unlimited sessions Pablo de Lara
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-25  8:48 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Structure rte_cryptodev_info has currently PCI device
information ("struct rte_pci_device") in it.

This information is not generic to all devices,
so this gets replaced with the generic "rte_device" structure,
compatible with all crypto devices.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/prog_guide/cryptodev_lib.rst  | 2 +-
 doc/guides/rel_notes/deprecation.rst     | 2 --
 doc/guides/rel_notes/release_18_08.rst   | 5 ++++-
 drivers/crypto/qat/qat_sym_pmd.c         | 1 -
 drivers/crypto/virtio/virtio_cryptodev.c | 1 -
 lib/librte_cryptodev/rte_cryptodev.c     | 1 +
 lib/librte_cryptodev/rte_cryptodev.h     | 6 +++---
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 30f0bcf7a..d02bb7514 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -269,7 +269,7 @@ relevant information for the device.
     struct rte_cryptodev_info {
         const char *driver_name;
         uint8_t driver_id;
-        struct rte_pci_device *pci_dev;
+        struct rte_device *device;
 
         uint64_t feature_flags;
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692eac..b71080bb8 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -104,8 +104,6 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
-  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
-    structure.
   - Functions ``rte_cryptodev_queue_pair_attach_sym_session()`` and
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..6bf53dc31 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -60,6 +60,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
+  has been replaced with field ``struct rte_device *device``.
+
 
 ABI Changes
 -----------
@@ -118,7 +121,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cmdline.so.2
      librte_common_octeontx.so.1
      librte_compressdev.so.1
-     librte_cryptodev.so.4
+   + librte_cryptodev.so.5
      librte_distributor.so.1
      librte_eal.so.7
      librte_ethdev.so.9
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index 115639089..0bc042a75 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -74,7 +74,6 @@ static void qat_sym_dev_info_get(struct rte_cryptodev *dev,
 		info->capabilities = internals->qat_dev_capabilities;
 		info->sym.max_nb_sessions = QAT_SYM_PMD_MAX_NB_SESSIONS;
 		info->driver_id = cryptodev_qat_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 	}
 }
 
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index df88953f6..482edea1a 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1409,7 +1409,6 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
 
 	if (info != NULL) {
 		info->driver_id = cryptodev_virtio_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 		info->feature_flags = dev->feature_flags;
 		info->max_nb_queue_pairs = hw->max_dataqueues;
 		info->sym.max_nb_sessions =
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 7e5821246..457ac5670 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -966,6 +966,7 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->driver_name = dev->device->driver->name;
+	dev_info->device = dev->device;
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 92ce6d49a..9a49f9d86 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -369,9 +369,9 @@ rte_cryptodev_get_feature_name(uint64_t flag);
 
 /**  Crypto device information */
 struct rte_cryptodev_info {
-	const char *driver_name;		/**< Driver name. */
-	uint8_t driver_id;			/**< Driver identifier */
-	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	const char *driver_name;	/**< Driver name. */
+	uint8_t driver_id;		/**< Driver identifier */
+	struct rte_device *device;	/**< Generic device information. */
 
 	uint64_t feature_flags;
 	/**< Feature flags exposes HW/SW features for the given device */
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 08/15] cryptodev: define value for unlimited sessions
    2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 01/15] cryptodev: replace bus specific struct with generic dev Pablo de Lara
@ 2018-06-25  8:48  4%   ` Pablo de Lara
  2018-06-25  8:48  2%   ` [dpdk-dev] [PATCH v2 11/15] cryptodev: remove queue start/stop functions Pablo de Lara
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-25  8:48 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Currently, the info structure contains the maximum number
of sessions that a device can manage.
This field was useful when the session mempool was created inside
each device, but now it is created at the application level.

Most PMDs do not have a limitation on the sessions managed,
but a few do, therefore this field must remain in the structure.
However, a new value, 0, can be used to indicate that
a device does not have an actual maximum of sessions.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 app/test-crypto-perf/main.c            | 2 +-
 doc/guides/rel_notes/release_18_08.rst | 2 ++
 examples/ipsec-secgw/ipsec-secgw.c     | 2 +-
 lib/librte_cryptodev/rte_cryptodev.h   | 5 ++++-
 test/test/test_cryptodev.c             | 6 ++++--
 5 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index b02d3f597..87aaba0ce 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -169,7 +169,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
 		 * A single session is required per queue pair
 		 * in each device
 		 */
-		if (dev_max_nb_sess < opts->nb_qps) {
+		if (dev_max_nb_sess != 0 && dev_max_nb_sess < opts->nb_qps) {
 			RTE_LOG(ERR, USER1,
 				"Device does not support at least "
 				"%u sessions\n", opts->nb_qps);
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 6bf53dc31..2b994ee78 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -62,6 +62,8 @@ API Changes
 
 * cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
   has been replaced with field ``struct rte_device *device``.
+  Value 0 is accepted in ``sym.max_nb_sessions``, meaning that a device
+  supports an unlimited number of sessions.
 
 
 ABI Changes
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 2582dcb6e..dacf323c9 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1441,7 +1441,7 @@ cryptodevs_init(void)
 		dev_conf.nb_queue_pairs = qp;
 
 		uint32_t dev_max_sess = cdev_info.sym.max_nb_sessions;
-		if (dev_max_sess < (CDEV_MP_NB_OBJS / 2))
+		if (dev_max_sess != 0 && dev_max_sess < (CDEV_MP_NB_OBJS / 2))
 			rte_exit(EXIT_FAILURE,
 				"Device does not support at least %u "
 				"sessions", CDEV_MP_NB_OBJS / 2);
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 0a4dd39b1..64ffbafca 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -384,7 +384,10 @@ struct rte_cryptodev_info {
 
 	struct {
 		unsigned max_nb_sessions;
-		/**< Maximum number of sessions supported by device. */
+		/**< Maximum number of sessions supported by device.
+		 * If 0, the device does not have any limitation in
+		 * number of sessions that can be used.
+		 */
 	} sym;
 };
 
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 5c906cfae..73aadaced 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -436,7 +436,8 @@ testsuite_setup(void)
 	 * Create mempool with maximum number of sessions * 2,
 	 * to include the session headers
 	 */
-	if (info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
+	if (info.sym.max_nb_sessions != 0 &&
+			info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
 		RTE_LOG(ERR, USER1, "Device does not support "
 				"at least %u sessions\n",
 				MAX_NB_SESSIONS);
@@ -8546,7 +8547,8 @@ test_scheduler_attach_slave_op(void)
 		unsigned int session_size =
 			rte_cryptodev_sym_get_private_session_size(i);
 
-		if (info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
+		if (info.sym.max_nb_sessions != 0 &&
+				info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
 			RTE_LOG(ERR, USER1,
 					"Device does not support "
 					"at least %u sessions\n",
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 11/15] cryptodev: remove queue start/stop functions
    2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 01/15] cryptodev: replace bus specific struct with generic dev Pablo de Lara
  2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 08/15] cryptodev: define value for unlimited sessions Pablo de Lara
@ 2018-06-25  8:48  2%   ` Pablo de Lara
  2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 12/15] cryptodev: remove old get session size functions Pablo de Lara
  2018-06-25  8:48  3%   ` [dpdk-dev] [PATCH v2 13/15] cryptodev: replace mbuf scatter gather flag Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-25  8:48 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed cryptodev queue start/stop functions,
as they were marked deprecated in 18.05, since they
were not implemented by any driver.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst           |  4 ---
 doc/guides/rel_notes/release_18_08.rst         |  5 +++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c   | 18 -----------
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 18 -----------
 drivers/crypto/armv8/rte_armv8_pmd_ops.c       | 18 -----------
 drivers/crypto/ccp/ccp_pmd_ops.c               | 16 ----------
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c    | 22 -------------
 drivers/crypto/dpaa_sec/dpaa_sec.c             | 22 -------------
 drivers/crypto/kasumi/rte_kasumi_pmd_ops.c     | 18 -----------
 drivers/crypto/mvsam/rte_mrvl_pmd_ops.c        | 28 ----------------
 drivers/crypto/null/null_crypto_pmd_ops.c      | 18 -----------
 drivers/crypto/openssl/rte_openssl_pmd_ops.c   | 18 -----------
 drivers/crypto/qat/qat_sym_pmd.c               |  2 --
 drivers/crypto/scheduler/scheduler_pmd_ops.c   | 18 -----------
 drivers/crypto/snow3g/rte_snow3g_pmd_ops.c     | 18 -----------
 drivers/crypto/virtio/virtio_cryptodev.c       |  2 --
 drivers/crypto/zuc/rte_zuc_pmd_ops.c           | 18 -----------
 lib/librte_cryptodev/rte_cryptodev.c           | 44 --------------------------
 lib/librte_cryptodev/rte_cryptodev.h           | 37 ----------------------
 lib/librte_cryptodev/rte_cryptodev_pmd.h       | 26 ---------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
 21 files changed, 5 insertions(+), 367 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index dc014da21..91592534e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,10 +105,6 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Functions ``rte_cryptodev_queue_pair_start()`` and
-    ``rte_cryptodev_queue_pair_stop()`` will be deprecated from 18.05
-    and removed in 18.08, as there are no drivers doing anything useful
-    with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
   - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 2b994ee78..cfb2885a1 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -65,6 +65,11 @@ API Changes
   Value 0 is accepted in ``sym.max_nb_sessions``, meaning that a device
   supports an unlimited number of sessions.
 
+* cryptodev: Following functions were deprecated and are removed in 18.08:
+
+  - ``rte_cryptodev_queue_pair_start``
+  - ``rte_cryptodev_queue_pair_stop``
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index 796ccdbd8..e24453a7e 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -243,22 +243,6 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_gcm_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_gcm_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_gcm_pmd_qp_count(struct rte_cryptodev *dev)
@@ -340,8 +324,6 @@ struct rte_cryptodev_ops aesni_gcm_pmd_ops = {
 
 		.queue_pair_setup	= aesni_gcm_pmd_qp_setup,
 		.queue_pair_release	= aesni_gcm_pmd_qp_release,
-		.queue_pair_start	= aesni_gcm_pmd_qp_start,
-		.queue_pair_stop	= aesni_gcm_pmd_qp_stop,
 		.queue_pair_count	= aesni_gcm_pmd_qp_count,
 
 		.session_get_size	= aesni_gcm_pmd_session_get_size,
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index 101fdc5c6..6eb37a5bf 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -509,22 +509,6 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_mb_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_mb_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_mb_pmd_qp_count(struct rte_cryptodev *dev)
@@ -607,8 +591,6 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
 
 		.queue_pair_setup	= aesni_mb_pmd_qp_setup,
 		.queue_pair_release	= aesni_mb_pmd_qp_release,
-		.queue_pair_start	= aesni_mb_pmd_qp_start,
-		.queue_pair_stop	= aesni_mb_pmd_qp_stop,
 		.queue_pair_count	= aesni_mb_pmd_qp_count,
 
 		.session_get_size	= aesni_mb_pmd_session_get_size,
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index b654f7528..5e8a5a292 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -258,22 +258,6 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-armv8_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-armv8_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -354,8 +338,6 @@ struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
 
 		.queue_pair_setup	= armv8_crypto_pmd_qp_setup,
 		.queue_pair_release	= armv8_crypto_pmd_qp_release,
-		.queue_pair_start	= armv8_crypto_pmd_qp_start,
-		.queue_pair_stop	= armv8_crypto_pmd_qp_stop,
 		.queue_pair_count	= armv8_crypto_pmd_qp_count,
 
 		.session_get_size	= armv8_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index dbe545c10..1cb944406 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -748,20 +748,6 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-static int
-ccp_pmd_qp_start(struct rte_cryptodev *dev __rte_unused,
-		 uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
-static int
-ccp_pmd_qp_stop(struct rte_cryptodev *dev __rte_unused,
-		uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
 static uint32_t
 ccp_pmd_qp_count(struct rte_cryptodev *dev)
 {
@@ -837,8 +823,6 @@ struct rte_cryptodev_ops ccp_ops = {
 
 		.queue_pair_setup	= ccp_pmd_qp_setup,
 		.queue_pair_release	= ccp_pmd_qp_release,
-		.queue_pair_start	= ccp_pmd_qp_start,
-		.queue_pair_stop	= ccp_pmd_qp_stop,
 		.queue_pair_count	= ccp_pmd_qp_count,
 
 		.session_get_size	= ccp_pmd_session_get_size,
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index bc091c560..1b1c30d85 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1470,26 +1470,6 @@ dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return retcode;
 }
 
-/** Start queue pair */
-static int
-dpaa2_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			   __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa2_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa2_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2716,8 +2696,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.stats_reset	      = dpaa2_sec_stats_reset,
 	.queue_pair_setup     = dpaa2_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa2_sec_queue_pair_release,
-	.queue_pair_start     = dpaa2_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa2_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa2_sec_queue_pair_count,
 	.session_get_size     = dpaa2_sec_session_get_size,
 	.session_configure    = dpaa2_sec_session_configure,
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index 73cae483b..b96552c57 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1585,26 +1585,6 @@ dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-dpaa_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			 __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2227,8 +2207,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.dev_infos_get        = dpaa_sec_dev_infos_get,
 	.queue_pair_setup     = dpaa_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa_sec_queue_pair_release,
-	.queue_pair_start     = dpaa_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa_sec_queue_pair_count,
 	.session_get_size     = dpaa_sec_session_get_size,
 	.session_configure    = dpaa_sec_session_configure,
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index e72f2ae0b..4174f1f80 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -229,22 +229,6 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-kasumi_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-kasumi_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 kasumi_pmd_qp_count(struct rte_cryptodev *dev)
@@ -325,8 +309,6 @@ struct rte_cryptodev_ops kasumi_pmd_ops = {
 
 		.queue_pair_setup   = kasumi_pmd_qp_setup,
 		.queue_pair_release = kasumi_pmd_qp_release,
-		.queue_pair_start   = kasumi_pmd_qp_start,
-		.queue_pair_stop    = kasumi_pmd_qp_stop,
 		.queue_pair_count   = kasumi_pmd_qp_count,
 
 		.session_get_size   = kasumi_pmd_session_get_size,
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 07850098b..8710ba3b7 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -596,32 +596,6 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs (PMD ops callback).
  *
  * @param dev Pointer to the device structure.
@@ -739,8 +713,6 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
 
 		.queue_pair_setup	= mrvl_crypto_pmd_qp_setup,
 		.queue_pair_release	= mrvl_crypto_pmd_qp_release,
-		.queue_pair_start	= mrvl_crypto_pmd_qp_start,
-		.queue_pair_stop	= mrvl_crypto_pmd_qp_stop,
 		.queue_pair_count	= mrvl_crypto_pmd_qp_count,
 
 		.session_get_size	= mrvl_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 2842498af..e43fba7db 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -240,22 +240,6 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-null_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-null_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 null_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -336,8 +320,6 @@ struct rte_cryptodev_ops pmd_ops = {
 
 		.queue_pair_setup	= null_crypto_pmd_qp_setup,
 		.queue_pair_release	= null_crypto_pmd_qp_release,
-		.queue_pair_start	= null_crypto_pmd_qp_start,
-		.queue_pair_stop	= null_crypto_pmd_qp_stop,
 		.queue_pair_count	= null_crypto_pmd_qp_count,
 
 		.session_get_size	= null_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index d194e3657..554177d20 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -648,22 +648,6 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-openssl_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-openssl_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 openssl_pmd_qp_count(struct rte_cryptodev *dev)
@@ -746,8 +730,6 @@ struct rte_cryptodev_ops openssl_pmd_ops = {
 
 		.queue_pair_setup	= openssl_pmd_qp_setup,
 		.queue_pair_release	= openssl_pmd_qp_release,
-		.queue_pair_start	= openssl_pmd_qp_start,
-		.queue_pair_stop	= openssl_pmd_qp_stop,
 		.queue_pair_count	= openssl_pmd_qp_count,
 
 		.session_get_size	= openssl_pmd_session_get_size,
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index 84dd5bec8..ee8633b85 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -202,8 +202,6 @@ static struct rte_cryptodev_ops crypto_qat_ops = {
 		.stats_reset		= qat_sym_stats_reset,
 		.queue_pair_setup	= qat_sym_qp_setup,
 		.queue_pair_release	= qat_sym_qp_release,
-		.queue_pair_start	= NULL,
-		.queue_pair_stop	= NULL,
 		.queue_pair_count	= NULL,
 
 		/* Crypto related operations */
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 16a8021c8..f363e3257 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -439,22 +439,6 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-scheduler_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-scheduler_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 scheduler_pmd_qp_count(struct rte_cryptodev *dev)
@@ -535,8 +519,6 @@ struct rte_cryptodev_ops scheduler_pmd_ops = {
 
 		.queue_pair_setup	= scheduler_pmd_qp_setup,
 		.queue_pair_release	= scheduler_pmd_qp_release,
-		.queue_pair_start	= scheduler_pmd_qp_start,
-		.queue_pair_stop	= scheduler_pmd_qp_stop,
 		.queue_pair_count	= scheduler_pmd_qp_count,
 
 		.session_get_size	= scheduler_pmd_session_get_size,
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index 6f8b9e2c6..fe882c366 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -231,22 +231,6 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-snow3g_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-snow3g_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 snow3g_pmd_qp_count(struct rte_cryptodev *dev)
@@ -327,8 +311,6 @@ struct rte_cryptodev_ops snow3g_pmd_ops = {
 
 		.queue_pair_setup   = snow3g_pmd_qp_setup,
 		.queue_pair_release = snow3g_pmd_qp_release,
-		.queue_pair_start   = snow3g_pmd_qp_start,
-		.queue_pair_stop    = snow3g_pmd_qp_stop,
 		.queue_pair_count   = snow3g_pmd_qp_count,
 
 		.session_get_size   = snow3g_pmd_session_get_size,
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 1da4ae871..0be435c8c 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -515,8 +515,6 @@ static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
 
 	.queue_pair_setup                = virtio_crypto_qp_setup,
 	.queue_pair_release              = virtio_crypto_qp_release,
-	.queue_pair_start                = NULL,
-	.queue_pair_stop                 = NULL,
 	.queue_pair_count                = NULL,
 
 	/* Crypto related operations */
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index b39e35b9f..79326d8f5 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -231,22 +231,6 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-zuc_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-zuc_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 zuc_pmd_qp_count(struct rte_cryptodev *dev)
@@ -327,8 +311,6 @@ struct rte_cryptodev_ops zuc_pmd_ops = {
 
 		.queue_pair_setup   = zuc_pmd_qp_setup,
 		.queue_pair_release = zuc_pmd_qp_release,
-		.queue_pair_start   = zuc_pmd_qp_start,
-		.queue_pair_stop    = zuc_pmd_qp_stop,
 		.queue_pair_count   = zuc_pmd_qp_count,
 
 		.session_get_size   = zuc_pmd_session_get_size,
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 457ac5670..a07904fb9 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -702,50 +702,6 @@ rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
 	return 0;
 }
 
-int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_start, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_start(dev, queue_pair_id);
-
-}
-
-int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_stop, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_stop(dev, queue_pair_id);
-
-}
-
 int
 rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 64ffbafca..0d994397d 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -601,43 +601,6 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
 		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
 		struct rte_mempool *session_pool);
 
-/**
- * @deprecated
- * Start a specified queue pair of a device. It is used
- * when deferred_start flag of the specified queue is true.
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to start. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_crypto_dev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id);
-
-/**
- * @deprecated
- * Stop specified queue pair of a device
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to stop. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_cryptodev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id);
-
 /**
  * Get the number of queue pairs on a specific crypto device
  *
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 0739ce065..b47730eaf 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -211,28 +211,6 @@ typedef void (*cryptodev_stats_reset_t)(struct rte_cryptodev *dev);
 typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
 				struct rte_cryptodev_info *dev_info);
 
-/**
- * Start queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_start_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
-/**
- * Stop queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_stop_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
 /**
  * Setup a queue pair for a device.
  *
@@ -371,10 +349,6 @@ struct rte_cryptodev_ops {
 	/**< Set up a device queue pair. */
 	cryptodev_queue_pair_release_t queue_pair_release;
 	/**< Release a queue pair. */
-	cryptodev_queue_pair_start_t queue_pair_start;
-	/**< Start a queue pair. */
-	cryptodev_queue_pair_stop_t queue_pair_stop;
-	/**< Stop a queue pair. */
 	cryptodev_queue_pair_count_t queue_pair_count;
 	/**< Get count of the queue pairs. */
 
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index be8f4c1a7..020b45754 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -22,8 +22,6 @@ DPDK_16.04 {
 	rte_cryptodev_stop;
 	rte_cryptodev_queue_pair_count;
 	rte_cryptodev_queue_pair_setup;
-	rte_cryptodev_queue_pair_start;
-	rte_cryptodev_queue_pair_stop;
 	rte_crypto_op_pool_create;
 
 	local: *;
-- 
2.14.4

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v2 12/15] cryptodev: remove old get session size functions
                       ` (2 preceding siblings ...)
  2018-06-25  8:48  2%   ` [dpdk-dev] [PATCH v2 11/15] cryptodev: remove queue start/stop functions Pablo de Lara
@ 2018-06-25  8:48  4%   ` Pablo de Lara
  2018-06-25  8:48  3%   ` [dpdk-dev] [PATCH v2 13/15] cryptodev: replace mbuf scatter gather flag Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-25  8:48 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed rte_cryptodev_get_header_session_size
and rte_cryptodev_get_private_session_size functions,
as they have been substituted with functions
specific for symmetric operations, with _sym_ word
after "rte_cryptodev_".

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  6 ------
 doc/guides/rel_notes/release_18_08.rst         |  8 ++++++++
 lib/librte_cryptodev/rte_cryptodev.c           | 12 ------------
 lib/librte_cryptodev/rte_cryptodev.h           | 25 -------------------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
 5 files changed, 8 insertions(+), 45 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 91592534e..9a73b1d8e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -107,9 +107,3 @@ Deprecation Notices
     with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
-  - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_header_session_size()``.
-    It will be removed in 18.08.
-  - Function ``rte_cryptodev_get_private_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_private_session_size()``.
-    It will be removed in 18.08.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index cfb2885a1..e482d3d5f 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -70,6 +70,14 @@ API Changes
   - ``rte_cryptodev_queue_pair_start``
   - ``rte_cryptodev_queue_pair_stop``
 
+* cryptodev: Following functions were deprecated and are replaced by
+  other functions in 18.08:
+
+  - ``rte_cryptodev_get_header_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_header_session_size``
+  - ``rte_cryptodev_get_private_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_private_session_size``
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a07904fb9..381330f3d 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
 	return 0;
 }
 
-unsigned int
-rte_cryptodev_get_header_session_size(void)
-{
-	return rte_cryptodev_sym_get_header_session_size();
-}
-
 unsigned int
 rte_cryptodev_sym_get_header_session_size(void)
 {
@@ -1198,12 +1192,6 @@ rte_cryptodev_sym_get_header_session_size(void)
 	return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
 }
 
-unsigned int
-rte_cryptodev_get_private_session_size(uint8_t dev_id)
-{
-	return rte_cryptodev_sym_get_private_session_size(dev_id);
-}
-
 unsigned int
 rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 0d994397d..a60eb38e4 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -933,31 +933,6 @@ int
 rte_cryptodev_sym_session_clear(uint8_t dev_id,
 			struct rte_cryptodev_sym_session *sess);
 
-/**
- * @deprecated
- * Get the size of the header session, for all registered drivers.
- *
- * @return
- *   Size of the header session.
- */
-__rte_deprecated
-unsigned int
-rte_cryptodev_get_header_session_size(void);
-
-/**
- * @deprecated
- * Get the size of the private session data for a device.
- *
- * @param	dev_id		The device identifier.
- *
- * @return
- *   - Size of the private data, if successful
- *   - 0 if device is invalid or does not have private session
- */
-__rte_deprecated
-unsigned int
-rte_cryptodev_get_private_session_size(uint8_t dev_id);
-
 /**
  * Get the size of the header session, for all registered drivers.
  *
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 020b45754..0ab6d5195 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -63,8 +63,6 @@ DPDK_17.08 {
 	rte_cryptodev_driver_id_get;
 	rte_cryptodev_driver_name_get;
 	rte_cryptodev_get_aead_algo_enum;
-	rte_cryptodev_get_header_session_size;
-	rte_cryptodev_get_private_session_size;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 13/15] cryptodev: replace mbuf scatter gather flag
                       ` (3 preceding siblings ...)
  2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 12/15] cryptodev: remove old get session size functions Pablo de Lara
@ 2018-06-25  8:48  3%   ` Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-25  8:48 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

The current mbuf scatter gatter feature flag is
too ambiguous, as it is not clear if input and/or output
buffers can be scatter gather mbufs or not, plus
if in-place and/or out-of-place is supported.

Therefore, five new flags will replace this flag:
- RTE_CRYPTODEV_FF_IN_PLACE_SGL
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst        |  2 --
 doc/guides/rel_notes/release_18_08.rst      |  8 +++++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c    |  2 +-
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c |  6 +++-
 drivers/crypto/dpaa_sec/dpaa_sec.c          |  6 +++-
 drivers/crypto/null/null_crypto_pmd.c       |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c    |  2 +-
 drivers/crypto/qat/qat_sym_pmd.c            |  6 +++-
 lib/librte_cryptodev/rte_cryptodev.c        | 12 ++++++--
 lib/librte_cryptodev/rte_cryptodev.h        | 46 +++++++++++++++++++----------
 test/test/test_cryptodev.c                  | 31 +++++++++++++------
 test/test/test_cryptodev_blockcipher.c      | 21 ++++++++++---
 12 files changed, 106 insertions(+), 38 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9a73b1d8e..62d635b74 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,5 +105,3 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
-    so some will be replaced by more explicit flags.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index e482d3d5f..2a136d88c 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -78,6 +78,14 @@ API Changes
   - ``rte_cryptodev_get_private_session_size`` is replaced with
     ``rte_cryptodev_sym_get_private_session_size``
 
+* cryptodev: Feature flag ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` is
+  replaced with the following more explicit flags:
+  - ``RTE_CRYPTODEV_FF_IN_PLACE_SGL``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT``
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index cd5b1952b..03917f220 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -492,7 +492,7 @@ aesni_gcm_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
 
 	switch (vector_mode) {
 	case RTE_AESNI_GCM_SSE:
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 1b1c30d85..4daee5f59 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -2762,7 +2762,11 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index b96552c57..8ad25f2be 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -2271,7 +2271,11 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 	internals->max_nb_queue_pairs = RTE_DPAA_MAX_NB_SEC_QPS;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 478ac0b62..224ba7233 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -177,7 +177,7 @@ cryptodev_null_create(const char *name,
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL;
 
 	internals = dev->data->dev_private;
 
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 972e2adfe..94b6e2de9 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1660,7 +1660,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
 
 	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index ee8633b85..629904e2f 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -274,7 +274,11 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev)
 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 	internals->qat_dev = qat_pci_dev;
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 381330f3d..15110661b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -361,8 +361,16 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 		return "CPU_AESNI";
 	case RTE_CRYPTODEV_FF_HW_ACCELERATED:
 		return "HW_ACCELERATED";
-	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER:
-		return "MBUF_SCATTER_GATHER";
+	case RTE_CRYPTODEV_FF_IN_PLACE_SGL:
+		return "IN_PLACE_SGL";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT:
+		return "OUT_OF_PLACE_SGL_IN_SGL_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT:
+		return "OUT_OF_PLACE_SGL_IN_FB_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT:
+		return "OUT_OF_PLACE_FB_IN_SGL_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT:
+		return "OUT_OF_PLACE_FB_IN_FB_OUT";
 	case RTE_CRYPTODEV_FF_CPU_NEON:
 		return "CPU_NEON";
 	case RTE_CRYPTODEV_FF_CPU_ARM_CE:
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a60eb38e4..c897dc6e2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -327,31 +327,47 @@ rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
  *
  * Keep these flags synchronised with rte_cryptodev_get_feature_name()
  */
-#define	RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO	(1ULL << 0)
+#define	RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO		(1ULL << 0)
 /**< Symmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO	(1ULL << 1)
+#define	RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO		(1ULL << 1)
 /**< Asymmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING	(1ULL << 2)
+#define	RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING		(1ULL << 2)
 /**< Chaining symmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_CPU_SSE		(1ULL << 3)
+#define	RTE_CRYPTODEV_FF_CPU_SSE			(1ULL << 3)
 /**< Utilises CPU SIMD SSE instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AVX		(1ULL << 4)
+#define	RTE_CRYPTODEV_FF_CPU_AVX			(1ULL << 4)
 /**< Utilises CPU SIMD AVX instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AVX2		(1ULL << 5)
+#define	RTE_CRYPTODEV_FF_CPU_AVX2			(1ULL << 5)
 /**< Utilises CPU SIMD AVX2 instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AESNI		(1ULL << 6)
+#define	RTE_CRYPTODEV_FF_CPU_AESNI			(1ULL << 6)
 /**< Utilises CPU AES-NI instructions */
-#define	RTE_CRYPTODEV_FF_HW_ACCELERATED		(1ULL << 7)
-/**< Operations are off-loaded to an external hardware accelerator */
-#define	RTE_CRYPTODEV_FF_CPU_AVX512		(1ULL << 8)
+#define	RTE_CRYPTODEV_FF_HW_ACCELERATED			(1ULL << 7)
+/**< Operations are off-loaded to an
+ * external hardware accelerator
+ */
+#define	RTE_CRYPTODEV_FF_CPU_AVX512			(1ULL << 8)
 /**< Utilises CPU SIMD AVX512 instructions */
-#define	RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER	(1ULL << 9)
-/**< Scatter-gather mbufs are supported */
-#define	RTE_CRYPTODEV_FF_CPU_NEON		(1ULL << 10)
+#define	RTE_CRYPTODEV_FF_IN_PLACE_SGL			(1ULL << 9)
+/**< In-place Scatter-gather (SGL) mbufs are supported */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT	(1ULL << 10)
+/**< Out-of-place Scatter-gather (SGL) mbufs are
+ * supported in input and output
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT	(1ULL << 11)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in input, but only flat buffers (FB) are supported in output
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT	(1ULL << 12)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in output, but only flat buffers (FB) are supported in input
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT	(1ULL << 13)
+/**< Only flat buffers (FB) are supported in input and output */
+#define	RTE_CRYPTODEV_FF_CPU_NEON			(1ULL << 14)
 /**< Utilises CPU NEON instructions */
-#define	RTE_CRYPTODEV_FF_CPU_ARM_CE		(1ULL << 11)
+#define	RTE_CRYPTODEV_FF_CPU_ARM_CE			(1ULL << 15)
 /**< Utilises ARM CPU Cryptographic Extensions */
-#define	RTE_CRYPTODEV_FF_SECURITY		(1ULL << 12)
+#define	RTE_CRYPTODEV_FF_SECURITY			(1ULL << 16)
 /**< Support Security Protocol Processing */
 
 
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 73aadaced..84fcf0651 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -3160,8 +3160,11 @@ test_kasumi_encryption_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+		printf("Device doesn't support in-place scatter-gather. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -3308,8 +3311,11 @@ test_kasumi_encryption_oop_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+	if (!(feat_flags & RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT)) {
+		printf("Device doesn't support out-of-place scatter-gather "
+				"in both input and output mbufs. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -3659,8 +3665,12 @@ test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT)) {
+		printf("Device doesn't support out-of-place scatter-gather "
+				"in both input and output mbufs. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -4493,10 +4503,13 @@ test_zuc_encryption_sgl(const struct wireless_test_data *tdata)
 		return -ENOTSUP;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+		printf("Device doesn't support in-place scatter-gather. "
 				"Test Skipped.\n");
-		return -ENOTSUP;
+		return 0;
 	}
 
 	plaintext_len = ceil_byte_length(tdata->plaintext.len);
diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c
index 256a7daa2..7a11b3af8 100644
--- a/test/test/test_cryptodev_blockcipher.c
+++ b/test/test/test_cryptodev_blockcipher.c
@@ -77,12 +77,25 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 
 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
 		rte_cryptodev_info_get(dev_id, &dev_info);
-		if (!(dev_info.feature_flags &
-				RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-			printf("Device doesn't support scatter-gather. "
+		uint64_t feat_flags = dev_info.feature_flags;
+		uint64_t oop_flag = RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
+
+		if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) {
+			if (!(feat_flags & oop_flag)) {
+				printf("Device doesn't support out-of-place "
+					"scatter-gather in input mbuf. "
+					"Test Skipped.\n");
+				return 0;
+			}
+		} else {
+			if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+				printf("Device doesn't support in-place "
+					"scatter-gather mbufs. "
 					"Test Skipped.\n");
-			return 0;
+				return 0;
+			}
 		}
+
 		nb_segs = 3;
 	}
 
-- 
2.14.4

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v8] checkpatches.sh: Add checks for ABI symbol addition
  2018-06-14 13:30  6% ` [dpdk-dev] [PATCH v8] " Neil Horman
@ 2018-06-25 23:04  4%   ` Thomas Monjalon
  2018-06-27 17:58  4%     ` Neil Horman
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-06-25 23:04 UTC (permalink / raw)
  To: Neil Horman
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

14/06/2018 15:30, Neil Horman:
>  * found a way to eliminate the use of filterdiff (new awk rules)

Thanks a lot for not requiring filterdiff dependency.

[...]
> +				# Just inform the user of this occurrence, but
> +				# don't flag it as an error
> +				echo -n "INFO: symbol $syname is added but "
> +				echo -n "patch has insuficient context "
> +				echo -n "to determine the section name "
> +				echo -n "please ensure the version is "
> +				echo "EXPERIMENTAL"

For info, I think nowadays "printf" is preferred over "echo -n"
But if you prefer "echo -n" for any reason, no problem.

[...]
> +exit $exit_code
> +
> +

Ironically, this patch doesn't pass checkpatch test because of
the trailing new lines.

[...]
> +clean_tmp_files() {
> +	echo $TMPINPUT | grep -q checkpaches

Two comments here.

Since TMPINPUT is not supposed to be overwritten by environment,
I think it is better to make it lowercase (kind of convention).

What the grep is supposed to match?
(side note, there is a typo: checkpaches -> checkpatches)
Is it to remove file only in case of mktemp?
I think it is a risky pattern matching. I suggest '^checkpatches\.'

> +	if [ $? -eq 0 ]; then

Could be easier to read if combining "if" and "grep":
	if echo $tmpinput | grep -q '^checkpatches\.' ; then

> +		rm -f $TMPINPUT
> +	fi
> +}

[...]
> +		TMPINPUT=$(mktemp checkpatches.XXXXXX)

Open to discussion: do we prefer local dir or /tmp?
Some tools are using /tmp.

[...]
> +	report=$($DPDK_CHECKPATCH_PATH $options $TMPINPUT 2>/dev/null)
> +

Please, no blank line between command and test.

> +	if [ $? -ne 0 ]
> +	then
> +		$verbose || printf '\n### %s\n\n' "$3"
> +		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
> +		ret=1
> +	fi
> +
> +	! $verbose || printf '\nChecking API additions/removals:\n'
> +
> +	report=$($VALIDATE_NEW_API "$TMPINPUT")
> +

Same comments about blank lines.

> +	if [ $? -ne 0 ]; then
> +		printf '%s\n' "$report"
> +		ret=1
> +	fi
> +
> +	clean_tmp_files
> +	if [ $ret -eq 0 ]; then
> +		return 0
>  	fi
> -	[ $? -ne 0 ] || return 0

Why replacing this oneliner by a longer "if" block?

After this review, I think I won't have any more comment.
Thanks Neil

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
  2018-06-25 16:40  0%       ` De Lara Guarch, Pablo
@ 2018-06-26  5:28  0%         ` Verma, Shally
  2018-06-26  8:17  0%           ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 200+ results
From: Verma, Shally @ 2018-06-26  5:28 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Akhil Goyal, Doherty, Declan, ravi1.kumar,
	Jacob,  Jerin, Zhang, Roy Fan, Trahe, Fiona, tdu, jianjay.zhou
  Cc: dev



>-----Original Message-----
>From: De Lara Guarch, Pablo [mailto:pablo.de.lara.guarch@intel.com]
>Sent: 25 June 2018 22:10
>To: Verma, Shally <Shally.Verma@cavium.com>; Akhil Goyal <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>;
>ravi1.kumar@amd.com; Jacob, Jerin <Jerin.JacobKollanukkaran@cavium.com>; Zhang, Roy Fan <roy.fan.zhang@intel.com>; Trahe,
>Fiona <fiona.trahe@intel.com>; tdu@semihalf.com; jianjay.zhou@huawei.com
>Cc: dev@dpdk.org
>Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
>
>External Email
>
>> -----Original Message-----
>> From: Verma, Shally [mailto:Shally.Verma@cavium.com]
>> Sent: Friday, June 22, 2018 6:02 PM
>> To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
>> <pablo.de.lara.guarch@intel.com>; Doherty, Declan
>> <declan.doherty@intel.com>; ravi1.kumar@amd.com; Jacob, Jerin
>> <Jerin.JacobKollanukkaran@cavium.com>; Zhang, Roy Fan
>> <roy.fan.zhang@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
>> tdu@semihalf.com; jianjay.zhou@huawei.com
>> Cc: dev@dpdk.org
>> Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size
>> functions
>>
>> Hi Pablo
>>
>> >-----Original Message-----
>> >From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
>> >Sent: 21 June 2018 18:29
>> >To: Pablo de Lara <pablo.de.lara.guarch@intel.com>;
>> >declan.doherty@intel.com; ravi1.kumar@amd.com; Jacob, Jerin
>> ><Jerin.JacobKollanukkaran@cavium.com>; roy.fan.zhang@intel.com;
>> >fiona.trahe@intel.com; tdu@semihalf.com; jianjay.zhou@huawei.com
>> >Cc: dev@dpdk.org
>> >Subject: Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session
>> >size functions
>> >
>> >External Email
>> >
>> >Hi Pablo,
>> >
>> >
>> >On 6/9/2018 3:32 AM, Pablo de Lara wrote:
>> >> Removed rte_cryptodev_get_header_session_size
>> >> and rte_cryptodev_get_private_session_size functions, as they have
>> >> been substituted with functions specific for symmetric operations,
>> >> with _sym_ word after "rte_cryptodev_".
>> >>
>> >> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
>> >> ---
>
>...
>
>> >> +
>> >> +  - ``rte_cryptodev_get_header_session_size`` is replaced with
>> >> +    ``rte_cryptodev_sym_get_header_session_size``
>> >> +  - ``rte_cryptodev_get_private_session_size`` is replaced with
>> >> +    ``rte_cryptodev_sym_get_private_session_size``
>> >> +
>> >rte_cryptodev_get_private_session_size is not removed in this patch. I
>> >think you missed it in your patch.
>
>Right Akhil, thanks for spotting this. Will fix in next version.
>
>> >
>> >-Akhil
>> >>
>> >>   ABI Changes
>> >>   -----------
>> >> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
>> >> b/lib/librte_cryptodev/rte_cryptodev.c
>> >> index a07904fb9..40e249e79 100644
>> >> --- a/lib/librte_cryptodev/rte_cryptodev.c
>> >> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>> >> @@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct
>> rte_cryptodev_sym_session *sess)
>> >>       return 0;
>> >>   }
>> >>
>> >> -unsigned int
>> >> -rte_cryptodev_get_header_session_size(void)
>> >> -{
>> >> -     return rte_cryptodev_sym_get_header_session_size();
>> >> -}
>> >> -
>> >>   unsigned int
>> >>   rte_cryptodev_sym_get_header_session_size(void)
>> >>   {
>>
>> [Shally] I missed this before. I think this implementation either should change to
>> use nb_drivers which support symmetric or else I am not seeing a need for
>> separate sym specific API for header_size since it will always be same for both
>> sym and asym.
>
>The implementation is already using nb_drivers to calculate the size, right?
[Shally] I meant change it to nb_sym_drivers, where nb_sym_drivers = number of drivers that have symmetric capability

>Anyway, I understand that the way asymmetric sessions are done, the API
>will be the same, but this could change in the future and since we have already deprecated the
>generic function (get_header_session_size), I think we should continue and have both _sym and _asym_ functions.
>
[Shally] Ok.
>Thanks,
>Pablo


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions
  2018-06-26  5:28  0%         ` Verma, Shally
@ 2018-06-26  8:17  0%           ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2018-06-26  8:17 UTC (permalink / raw)
  To: Verma, Shally, Akhil Goyal, Doherty, Declan, ravi1.kumar, Jacob,
	 Jerin, Zhang, Roy Fan, Trahe, Fiona, tdu, jianjay.zhou
  Cc: dev



> -----Original Message-----
> From: Verma, Shally [mailto:Shally.Verma@cavium.com]
> Sent: Tuesday, June 26, 2018 6:28 AM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>;
> ravi1.kumar@amd.com; Jacob, Jerin <Jerin.JacobKollanukkaran@cavium.com>;
> Zhang, Roy Fan <roy.fan.zhang@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; tdu@semihalf.com; jianjay.zhou@huawei.com
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size
> functions
> 
> 
> 
> >-----Original Message-----
> >From: De Lara Guarch, Pablo [mailto:pablo.de.lara.guarch@intel.com]
> >Sent: 25 June 2018 22:10
> >To: Verma, Shally <Shally.Verma@cavium.com>; Akhil Goyal
> ><akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>;
> >ravi1.kumar@amd.com; Jacob, Jerin
> ><Jerin.JacobKollanukkaran@cavium.com>; Zhang, Roy Fan
> ><roy.fan.zhang@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> >tdu@semihalf.com; jianjay.zhou@huawei.com
> >Cc: dev@dpdk.org
> >Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session
> >size functions
> >
> >External Email
> >
> >> -----Original Message-----
> >> From: Verma, Shally [mailto:Shally.Verma@cavium.com]
> >> Sent: Friday, June 22, 2018 6:02 PM
> >> To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> >> <pablo.de.lara.guarch@intel.com>; Doherty, Declan
> >> <declan.doherty@intel.com>; ravi1.kumar@amd.com; Jacob, Jerin
> >> <Jerin.JacobKollanukkaran@cavium.com>; Zhang, Roy Fan
> >> <roy.fan.zhang@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> >> tdu@semihalf.com; jianjay.zhou@huawei.com
> >> Cc: dev@dpdk.org
> >> Subject: RE: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session
> >> size functions
> >>
> >> Hi Pablo
> >>
> >> >-----Original Message-----
> >> >From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
> >> >Sent: 21 June 2018 18:29
> >> >To: Pablo de Lara <pablo.de.lara.guarch@intel.com>;
> >> >declan.doherty@intel.com; ravi1.kumar@amd.com; Jacob, Jerin
> >> ><Jerin.JacobKollanukkaran@cavium.com>; roy.fan.zhang@intel.com;
> >> >fiona.trahe@intel.com; tdu@semihalf.com; jianjay.zhou@huawei.com
> >> >Cc: dev@dpdk.org
> >> >Subject: Re: [dpdk-dev] [PATCH 5/6] cryptodev: remove old get
> >> >session size functions
> >> >
> >> >External Email
> >> >
> >> >Hi Pablo,
> >> >
> >> >
> >> >On 6/9/2018 3:32 AM, Pablo de Lara wrote:
> >> >> Removed rte_cryptodev_get_header_session_size
> >> >> and rte_cryptodev_get_private_session_size functions, as they have
> >> >> been substituted with functions specific for symmetric operations,
> >> >> with _sym_ word after "rte_cryptodev_".
> >> >>
> >> >> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> >> >> ---
> >
> >...
> >
> >> >> +
> >> >> +  - ``rte_cryptodev_get_header_session_size`` is replaced with
> >> >> +    ``rte_cryptodev_sym_get_header_session_size``
> >> >> +  - ``rte_cryptodev_get_private_session_size`` is replaced with
> >> >> +    ``rte_cryptodev_sym_get_private_session_size``
> >> >> +
> >> >rte_cryptodev_get_private_session_size is not removed in this patch.
> >> >I think you missed it in your patch.
> >
> >Right Akhil, thanks for spotting this. Will fix in next version.
> >
> >> >
> >> >-Akhil
> >> >>
> >> >>   ABI Changes
> >> >>   -----------
> >> >> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> >> >> b/lib/librte_cryptodev/rte_cryptodev.c
> >> >> index a07904fb9..40e249e79 100644
> >> >> --- a/lib/librte_cryptodev/rte_cryptodev.c
> >> >> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> >> >> @@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct
> >> rte_cryptodev_sym_session *sess)
> >> >>       return 0;
> >> >>   }
> >> >>
> >> >> -unsigned int
> >> >> -rte_cryptodev_get_header_session_size(void)
> >> >> -{
> >> >> -     return rte_cryptodev_sym_get_header_session_size();
> >> >> -}
> >> >> -
> >> >>   unsigned int
> >> >>   rte_cryptodev_sym_get_header_session_size(void)
> >> >>   {
> >>
> >> [Shally] I missed this before. I think this implementation either
> >> should change to use nb_drivers which support symmetric or else I am
> >> not seeing a need for separate sym specific API for header_size since
> >> it will always be same for both sym and asym.
> >
> >The implementation is already using nb_drivers to calculate the size, right?
> [Shally] I meant change it to nb_sym_drivers, where nb_sym_drivers = number
> of drivers that have symmetric capability

Ok, I see now. Well, this will overcomplicate things, rte_cryptodev_allocate_driver
would need to be changed to two functions,
one for symmetric and another for asymmetric, causing an API breakage.
I think as long as the session creation/initialization functions check if a PMD supports
symmetric and/or asymmetric, we should be OK.

We might need some changes in the current symmetric implementation to peform those checks
and in the new asymmetric implementation.

Thanks,
Pablo

> 
> >Anyway, I understand that the way asymmetric sessions are done, the API
> >will be the same, but this could change in the future and since we have
> >already deprecated the generic function (get_header_session_size), I think we
> should continue and have both _sym and _asym_ functions.
> >
> [Shally] Ok.
> >Thanks,
> >Pablo


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan
  @ 2018-06-26 11:47  3%     ` Burakov, Anatoly
  2018-06-26 12:26  0%       ` Zhang, Qi Z
  0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-06-26 11:47 UTC (permalink / raw)
  To: Qi Zhang, thomas
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati

On 26-Jun-18 8:08 AM, Qi Zhang wrote:
> When hot plug a new device, it is not necessary to scan everything
> on the bus since the devname and devargs are already there. So new
> rte_bus ops "scan_one" is introduced, bus driver can implement this
> function to simplify the hotplug process.
> 
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
> 

<snip>

> + *	NULL for unsuccessful scan
> + */
> +typedef struct rte_device *(*rte_bus_scan_one_t)(struct rte_devargs *devargs);
> +
> +/**
>    * Implementation specific probe function which is responsible for linking
>    * devices on that bus with applicable drivers.
>    *
> @@ -204,6 +219,7 @@ struct rte_bus {
>   	TAILQ_ENTRY(rte_bus) next;   /**< Next bus object in linked list */
>   	const char *name;            /**< Name of the bus */
>   	rte_bus_scan_t scan;         /**< Scan for devices attached to bus */
> +	rte_bus_scan_one_t scan_one; /**< Scan one device using devargs */
>   	rte_bus_probe_t probe;       /**< Probe devices on bus */
>   	rte_bus_find_device_t find_device; /**< Find a device on the bus */
>   	rte_bus_plug_t plug;         /**< Probe single device for drivers */
> 

Does changing this structure break ABI for bus drivers?

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan
  2018-06-26 11:47  3%     ` Burakov, Anatoly
@ 2018-06-26 12:26  0%       ` Zhang, Qi Z
  2018-06-26 16:33  4%         ` Gaëtan Rivet
  0 siblings, 1 reply; 200+ results
From: Zhang, Qi Z @ 2018-06-26 12:26 UTC (permalink / raw)
  To: Burakov, Anatoly, thomas
  Cc: Ananyev, Konstantin, dev, Richardson, Bruce, Yigit, Ferruh,
	Shelton, Benjamin H, Vangati, Narender



> -----Original Message-----
> From: Burakov, Anatoly
> Sent: Tuesday, June 26, 2018 7:48 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; thomas@monjalon.net
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org;
> Richardson, Bruce <bruce.richardson@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; Shelton, Benjamin H
> <benjamin.h.shelton@intel.com>; Vangati, Narender
> <narender.vangati@intel.com>
> Subject: Re: [PATCH v4 01/24] eal: introduce one device scan
> 
> On 26-Jun-18 8:08 AM, Qi Zhang wrote:
> > When hot plug a new device, it is not necessary to scan everything on
> > the bus since the devname and devargs are already there. So new
> > rte_bus ops "scan_one" is introduced, bus driver can implement this
> > function to simplify the hotplug process.
> >
> > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > ---
> >
> 
> <snip>
> 
> > + *	NULL for unsuccessful scan
> > + */
> > +typedef struct rte_device *(*rte_bus_scan_one_t)(struct rte_devargs
> > +*devargs);
> > +
> > +/**
> >    * Implementation specific probe function which is responsible for linking
> >    * devices on that bus with applicable drivers.
> >    *
> > @@ -204,6 +219,7 @@ struct rte_bus {
> >   	TAILQ_ENTRY(rte_bus) next;   /**< Next bus object in linked list */
> >   	const char *name;            /**< Name of the bus */
> >   	rte_bus_scan_t scan;         /**< Scan for devices attached to
> bus */
> > +	rte_bus_scan_one_t scan_one; /**< Scan one device using devargs */
> >   	rte_bus_probe_t probe;       /**< Probe devices on bus */
> >   	rte_bus_find_device_t find_device; /**< Find a device on the bus */
> >   	rte_bus_plug_t plug;         /**< Probe single device for drivers
> */
> >
> 
> Does changing this structure break ABI for bus drivers?

For bus driver, I think yes, but I'm not sure what I should do for this, since this is not for application


> 
> --
> Thanks,
> Anatoly

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] cmdline: rework as a wrapper to libedit
  @ 2018-06-26 13:21  0%   ` Olivier Matz
  2018-06-27 10:36  0%     ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2018-06-26 13:21 UTC (permalink / raw)
  To: Adrien Mazarguil
  Cc: dev, Keith Wiles, Jingjing Wu, Thomas Monjalon, Ferruh Yigit,
	Jim Thompson, Anatoly Burakov

Hi Adrien,

Better late than never, please find below some comments
about your patch.

On Thu, Apr 19, 2018 at 05:13:53PM +0200, Adrien Mazarguil wrote:
> Disclaimer: this patch must not be confused with the CLI library [1]
> (work in progress) that will eventually supersede librte_cmdline itself
> with a different API.
> 
> Rather, it modifies librte_cmdline to delegate all the heavy lifting
> (terminal and history handling), strips unused features and re-implements
> what remains of its public API as a wrapper to the editline library (also
> known as libedit) [2], a well-known, BSD-licensed and widely available
> library used by many projects which does everything needed and more [3].
> 
> This approach was chosen because converting librte_cmdline as a wrapper to
> a more capable library was easier and faster than addressing its
> shortcomings and results in much less code to maintain in DPDK.
> 
> It also provides a drop-in solution for applications that rely on
> librte_cmdline. They benefit from greatly improved command line handling
> without a meaningful impact on their code base.
> 
> The main motivation behind this patch is testpmd's flow (rte_flow) command,
> which requires support for dynamic tokens and very long lines that must be
> broken down when displayed. This is not supported by librte_cmdline's
> limited terminal handling capabilities, resulting in a rather frustrating
> user experience.
> 
> It had to be addressed given the importance of testpmd as one of the
> primary tool used by PMD developers.
> 
> This rework results in the following changes:
> 
> - Removed circular buffer management interface for command history
>   (cmdline_cirbuf.c), command history being handled by libedit.
> - Removed raw command-line interpreter (cmdline_rdline.c).
> - Removed raw terminal handler (cmdline_vt100.c).
> - Removed all test/example code for the above.
> - Re-implemented high level interactive and non-interactive command-line
>   handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
>   native interface, not its readline compatibility layer.
> - Made struct cmdline opaque so that applications relying on librte_cmdline
>   do not need to include any libedit headers.
> - Applications do not need to include cmdline_rdline.h anymore.
> - Terminal resizing is now automatically handled.
> - New external dependency for applications relying on librte_cmdline.
> - Major version bump due to the ABI impact of these changes.
> 
> [1] http://dpdk.org/browse/draft/dpdk-draft-cli/
> [2] http://thrysoee.dk/editline/
> [3] http://netbsd.gw.com/cgi-bin/man-cgi?editline++NetBSD-current
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Cc: Olivier Matz <olivier.matz@6wind.com>
> Cc: Keith Wiles <keith.wiles@intel.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: Jim Thompson <jim@netgate.com>
> Cc: Anatoly Burakov <anatoly.burakov@intel.com>
> 
> --
> 
> v2 changes:
> 
> - Replaced an instance of snprintf() with rte_strlcpy() [5].
> - Rebased patch.
> 
> [5] http://dpdk.org/ml/archives/dev/2018-April/097721.html
> 
> v1 changes:
> 
> No fundamental change since the original RFC [4], except it's been rebased
> several times and Meson build support was added in the meantime. Commit log
> was also shortened a bit.
> 
> I'm re-sending this because I think it's useful, at least to me (duh). As
> the maintainer of rte_flow, I spend most of my time typing flow commands in
> testpmd and libedit makes that a pleasant experience.
> 
> Try it out! And don't hesitate to send your acked-by line to get this in
> time for 18.05 :)
> 
> [4] http://dpdk.org/ml/archives/dev/2017-November/081605.html

Re-saying what I said the first time: I think this is a very good
improvement, removing lots of dpdk code that is better implemented in
well-known libraries.


The compilation with shared libraries fail. Please try for instance:
./devtools/test-build.sh -j4 x86_64-native-linuxapp-clang+shared+debug

I suggest to add in lib/librte_cmdline/Makefile:

  LDLIBS += $(shell pkg-config --libs libedit)


I also think something should be added in
/doc/guides/linux_gsg/sys_reqs.rst to highlight the new build
dependency.


I noticed a bad behavior change (in addition to many good ones):
ctrl-c now quits the application, and this was not the case before.
I often use ctrl-c to delete the line I'm currently editing. Please
see at the end a proposition to restore this feature.


Finally, the patch removes some functions, so it should be announced
with a deprecation notice.


[...]

> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 0b442c3a6..6b4d9dbfd 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -48,7 +48,6 @@
>  #include <rte_flow.h>
>  #include <rte_gro.h>
>  
> -#include <cmdline_rdline.h>
>  #include <cmdline_parse.h>
>  #include <cmdline_parse_num.h>
>  #include <cmdline_parse_string.h>

FYI, after rebase, same hunk is also required in
examples/vhost_crypto/main.c

[...]

> diff --git a/lib/librte_cmdline/cmdline.c b/lib/librte_cmdline/cmdline.c
> index 591b78b0f..1c45cd9ff 100644
> --- a/lib/librte_cmdline/cmdline.c
> +++ b/lib/librte_cmdline/cmdline.c
> @@ -4,79 +4,183 @@
>   * All rights reserved.
>   */
>  
> +#include <ctype.h>
> +#include <histedit.h>

histedit.h would be better after system includes.


[...]

> @@ -207,48 +317,49 @@ cmdline_poll(struct cmdline *cl)
>  {
>  	struct pollfd pfd;
>  	int status;
> -	ssize_t read_status;
> -	char c;
> +	int read_status;
> +	int flags;
>  
>  	if (!cl)
>  		return -EINVAL;
> -	else if (cl->rdl.status == RDLINE_EXITED)
> +	else if (cl->error)
> +		return RDLINE_ERROR;
> +	else if (cl->eof)
>  		return RDLINE_EXITED;
>  
> -	pfd.fd = cl->s_in;
> +	pfd.fd = fileno(cl->f_in);
>  	pfd.events = POLLIN;
>  	pfd.revents = 0;
>  
>  	status = poll(&pfd, 1, 0);
>  	if (status < 0)
> -		return status;
> -	else if (status > 0) {
> -		c = -1;
> -		read_status = read(cl->s_in, &c, 1);
> -		if (read_status < 0)
> -			return read_status;
> -
> -		status = cmdline_in(cl, &c, 1);
> -		if (status < 0 && cl->rdl.status != RDLINE_EXITED)
> -			return status;
> -	}
> -
> -	return cl->rdl.status;
> +		return RDLINE_ERROR;
> +	if (!status)
> +		return RDLINE_RUNNING;
> +	flags = fcntl(pfd.fd, F_GETFL);
> +	if (!(flags & O_NONBLOCK))
> +		fcntl(pfd.fd, F_SETFL, flags | O_NONBLOCK);

We just checked that fd is readable, what is the purpose of
adding the O_NONBLOCK flag?


> +	if (!el_gets(cl->el, &read_status) && read_status == -1)
> +		cl->error = 1;

Either from documentation or libedit code, I don't think it is
possible that read_status is set to -1. Am I missing something?


> +	if (!(flags & O_NONBLOCK))
> +		fcntl(pfd.fd, F_SETFL, flags);
> +	return cl->error ? RDLINE_ERROR :
> +		cl->eof ? RDLINE_EXITED :
> +		RDLINE_RUNNING;
>  }
>  
>  void
>  cmdline_interact(struct cmdline *cl)
>  {
> -	char c;
> -
>  	if (!cl)
>  		return;
>  
> -	c = -1;
> -	while (1) {
> -		if (read(cl->s_in, &c, 1) <= 0)
> -			break;
> -		if (cmdline_in(cl, &c, 1) < 0)
> -			break;
> +	while (!cl->error && !cl->eof) {
> +		int read_status;
> +
> +		if (el_gets(cl->el, &read_status))
> +			continue;
> +		if (read_status == -1)
> +			cl->error = 1;

Same comment here about read_status.


Thanks
Olivier

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan
  2018-06-26 12:26  0%       ` Zhang, Qi Z
@ 2018-06-26 16:33  4%         ` Gaëtan Rivet
  2018-06-27 12:32  3%           ` Zhang, Qi Z
  0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2018-06-26 16:33 UTC (permalink / raw)
  To: Zhang, Qi Z
  Cc: Burakov, Anatoly, thomas, Ananyev, Konstantin, dev, Richardson,
	Bruce, Yigit, Ferruh, Shelton, Benjamin H, Vangati, Narender

On Tue, Jun 26, 2018 at 12:26:05PM +0000, Zhang, Qi Z wrote:
> 
> 
> > -----Original Message-----
> > From: Burakov, Anatoly
> > Sent: Tuesday, June 26, 2018 7:48 PM
> > To: Zhang, Qi Z <qi.z.zhang@intel.com>; thomas@monjalon.net
> > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org;
> > Richardson, Bruce <bruce.richardson@intel.com>; Yigit, Ferruh
> > <ferruh.yigit@intel.com>; Shelton, Benjamin H
> > <benjamin.h.shelton@intel.com>; Vangati, Narender
> > <narender.vangati@intel.com>
> > Subject: Re: [PATCH v4 01/24] eal: introduce one device scan
> > 
> > On 26-Jun-18 8:08 AM, Qi Zhang wrote:
> > > When hot plug a new device, it is not necessary to scan everything on
> > > the bus since the devname and devargs are already there. So new
> > > rte_bus ops "scan_one" is introduced, bus driver can implement this
> > > function to simplify the hotplug process.
> > >
> > > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > > ---
> > >
> > 
> > <snip>
> > 
> > > + *	NULL for unsuccessful scan
> > > + */
> > > +typedef struct rte_device *(*rte_bus_scan_one_t)(struct rte_devargs
> > > +*devargs);
> > > +
> > > +/**
> > >    * Implementation specific probe function which is responsible for linking
> > >    * devices on that bus with applicable drivers.
> > >    *
> > > @@ -204,6 +219,7 @@ struct rte_bus {
> > >   	TAILQ_ENTRY(rte_bus) next;   /**< Next bus object in linked list */
> > >   	const char *name;            /**< Name of the bus */
> > >   	rte_bus_scan_t scan;         /**< Scan for devices attached to
> > bus */
> > > +	rte_bus_scan_one_t scan_one; /**< Scan one device using devargs */
> > >   	rte_bus_probe_t probe;       /**< Probe devices on bus */
> > >   	rte_bus_find_device_t find_device; /**< Find a device on the bus */
> > >   	rte_bus_plug_t plug;         /**< Probe single device for drivers
> > */
> > >
> > 
> > Does changing this structure break ABI for bus drivers?
> 
> For bus driver, I think yes, but I'm not sure what I should do for this, since this is not for application
> 
> 

This should be appropriately announced in advance, in general.
However, it seems there is some leeway if the new field will not move
the others and not make the structure grow (i.e. replace a padding).

There is an ABI check script that can be used.

This however breaks the bus ABI, which breaks the EAL ABI.
This is usually an issue.

More generally, I was in favor of changing the whole bus scan process to a
per-device iteration. I was shut down on this when adding hotplug.
As a result, bus->scan() process was made to require the operation to be
idempotent.

Adding a new ops adds noise to the bus API. It should be kept as clean
as possible. This new one seems unnecessary, now that all bus scans are
idempotent (when supporting hotplug).

Regards,
-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4 fragmentation
  @ 2018-06-27  2:28  3%       ` Hu, Jiayu
  2018-06-27  5:05  3%         ` Hu, Jiayu
  0 siblings, 1 reply; 200+ results
From: Hu, Jiayu @ 2018-06-27  2:28 UTC (permalink / raw)
  To: Ophir Munk, dev
  Cc: Wang, Xiao W, Ananyev, Konstantin, Zhang, Yuwei1, Iremonger,
	Bernard, Thomas Monjalon

Hi Ophir,

Replies are inline.

> -----Original Message-----
> From: Ophir Munk [mailto:ophirmu@mellanox.com]
> Sent: Wednesday, June 27, 2018 7:59 AM
> To: Hu, Jiayu <jiayu.hu@intel.com>; dev@dpdk.org
> Cc: Wang, Xiao W <xiao.w.wang@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Zhang, Yuwei1
> <yuwei1.zhang@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: RE: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4
> fragmentation
> 
> Hi,
> Please find some comments below.
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jiayu Hu
> > Sent: Friday, June 22, 2018 8:54 AM
> > To: dev@dpdk.org
> > Cc: xiao.w.wang@intel.com; konstantin.ananyev@intel.com;
> > yuwei1.zhang@intel.com; bernard.iremonger@intel.com; Thomas
> Monjalon
> > <thomas@monjalon.net>; Jiayu Hu <jiayu.hu@intel.com>
> > Subject: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4 fragmentation
> >
> > This patch adds GSO support for UDP/IPv4 packets. Supported packets
> may
> > include a single VLAN tag. UDP/IPv4 GSO doesn't check if input packets
> have
> > correct checksums, and doesn't update checksums for output packets (the
> > responsibility for this lies with the application).
> > Additionally, UDP/IPv4 GSO doesn't process IP fragmented packets.
> >
> > UDP/IPv4 GSO uses two chained MBUFs, one direct MBUF and one indrect
> > MBUF, to organize an output packet. The direct MBUF stores the packet
> > header, while the indirect mbuf simply points to a location within the
> original
> > packet's payload. Consequently, use of UDP GSO requires multi-segment
> > MBUF support in the TX functions of the NIC driver.
> >
> > If a packet is GSO'd, UDP/IPv4 GSO reduces its MBUF refcnt by 1. As a
> result,
> > when all of its GSOed segments are freed, the packet is freed
> automatically.
> >
> > Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> > ---
> >  lib/librte_gso/Makefile     |  1 +
> >  lib/librte_gso/gso_common.h |  3 ++
> >  lib/librte_gso/gso_udp4.c   | 81
> > +++++++++++++++++++++++++++++++++++++++++++++
> >  lib/librte_gso/gso_udp4.h   | 42 +++++++++++++++++++++++
> >  lib/librte_gso/meson.build  |  2 +-
> >  lib/librte_gso/rte_gso.c    | 24 +++++++++++---
> >  lib/librte_gso/rte_gso.h    |  6 +++-
> >  7 files changed, 152 insertions(+), 7 deletions(-)  create mode 100644
> > lib/librte_gso/gso_udp4.c  create mode 100644 lib/librte_gso/gso_udp4.h
> >
> > diff --git a/lib/librte_gso/Makefile b/lib/librte_gso/Makefile index
> > 3648ec0..1fac53a 100644
> > --- a/lib/librte_gso/Makefile
> > +++ b/lib/librte_gso/Makefile
> > @@ -19,6 +19,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_GSO) += rte_gso.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_common.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_tcp4.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_tunnel_tcp4.c
> > +SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_udp4.c
> >
> >  # install this header file
> >  SYMLINK-$(CONFIG_RTE_LIBRTE_GSO)-include += rte_gso.h diff --git
> > a/lib/librte_gso/gso_common.h b/lib/librte_gso/gso_common.h index
> > 5ca5974..6cd764f 100644
> > --- a/lib/librte_gso/gso_common.h
> > +++ b/lib/librte_gso/gso_common.h
> > @@ -31,6 +31,9 @@
> >  		(PKT_TX_TCP_SEG | PKT_TX_IPV4 | PKT_TX_OUTER_IPV4 |
> \
> >  		 PKT_TX_TUNNEL_GRE))
> >
> > +#define IS_IPV4_UDP(flag) (((flag) & (PKT_TX_UDP_SEG | PKT_TX_IPV4))
> ==
> > \
> > +		(PKT_TX_UDP_SEG | PKT_TX_IPV4))
> > +
> >  /**
> >   * Internal function which updates the UDP header of a packet, following
> >   * segmentation. This is required to update the header's datagram length
> > field.
> > diff --git a/lib/librte_gso/gso_udp4.c b/lib/librte_gso/gso_udp4.c new file
> > mode 100644 index 0000000..927dee1
> > --- /dev/null
> > +++ b/lib/librte_gso/gso_udp4.c
> 
> File gso_upd4.c could be very similar to file gso_tcp4.c and that would
> avoid code duplication.
> In a unified file you could use a tcp vs. udp flag to distinguish between them
> when necessary.
> The files are short (~75 lines) so it is not a critical issue.

The function gso_tcp4_segment and gso_udp4_segment have different prototype,
and their GSO rules are different. They are two different basic GSO types.

The GSO library gives each GSO type (TCP, tunnel) an internal .c and .h file, and their name
represents their content. The rte_gso_segment calls different function according to the GSO type.
This style is very clear for developers or users to understand. In addition, as you said, the code
is short. So I think it's better to keep this style for UDP/IPv4 GSO.

> 
> > @@ -0,0 +1,81 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Intel Corporation
> > + */
> > +
> > +#include "gso_common.h"
> > +#include "gso_udp4.h"
> > +
> > +#define IPV4_HDR_MF_BIT (1U << 13)
> > +
> > +static inline void
> > +update_ipv4_udp_headers(struct rte_mbuf *pkt, struct rte_mbuf **segs,
> > +		uint16_t nb_segs)
> > +{
> > +	struct ipv4_hdr *ipv4_hdr;
> > +	uint16_t frag_offset = 0, is_mf;
> > +	uint16_t l2_hdrlen = pkt->l2_len, l3_hdrlen = pkt->l3_len;
> > +	uint16_t tail_idx = nb_segs - 1, length, i;
> > +
> > +	/*
> > +	 * Update IP header fields for output segments. Specifically,
> > +	 * keep the same IP id, update fragment offset and total
> > +	 * length.
> > +	 */
> > +	for (i = 0; i < nb_segs; i++) {
> > +		ipv4_hdr = rte_pktmbuf_mtod_offset(segs[i], struct
> ipv4_hdr
> > *,
> > +			l2_hdrlen);
> > +		length = segs[i]->pkt_len - l2_hdrlen;
> > +		ipv4_hdr->total_length = rte_cpu_to_be_16(length);
> > +
> > +		is_mf = i < tail_idx ? IPV4_HDR_MF_BIT : 0;
> > +		ipv4_hdr->fragment_offset =
> > +			rte_cpu_to_be_16(frag_offset | is_mf);
> > +		frag_offset += ((length - l3_hdrlen) >> 3);
> > +	}
> > +}
> > +
> > +int
> > +gso_udp4_segment(struct rte_mbuf *pkt,
> > +		uint16_t gso_size,
> > +		struct rte_mempool *direct_pool,
> > +		struct rte_mempool *indirect_pool,
> > +		struct rte_mbuf **pkts_out,
> > +		uint16_t nb_pkts_out)
> > +{
> > +	struct ipv4_hdr *ipv4_hdr;
> > +	uint16_t pyld_unit_size, hdr_offset;
> > +	uint16_t frag_off;
> > +	int ret;
> > +
> > +	/* Don't process the fragmented packet */
> > +	ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
> > +			pkt->l2_len);
> > +	frag_off = rte_be_to_cpu_16(ipv4_hdr->fragment_offset);
> > +	if (unlikely(IS_FRAGMENTED(frag_off))) {
> > +		pkts_out[0] = pkt;
> > +		return 1;
> > +	}
> > +
> > +	/*
> > +	 * UDP fragmentation is the same as IP fragmentation.
> > +	 * Except the first one, other output packets just have l2
> > +	 * and l3 headers.
> > +	 */
> > +	hdr_offset = pkt->l2_len + pkt->l3_len;
> > +
> > +	/* Don't process the packet without data. */
> > +	if (unlikely(hdr_offset + pkt->l4_len >= pkt->pkt_len)) {
> > +		pkts_out[0] = pkt;
> > +		return 1;
> > +	}
> > +
> > +	pyld_unit_size = gso_size - hdr_offset;
> > +
> > +	/* Segment the payload */
> > +	ret = gso_do_segment(pkt, hdr_offset, pyld_unit_size, direct_pool,
> > +			indirect_pool, pkts_out, nb_pkts_out);
> > +	if (ret > 1)
> > +		update_ipv4_udp_headers(pkt, pkts_out, ret);
> > +
> > +	return ret;
> > +}
> > diff --git a/lib/librte_gso/gso_udp4.h b/lib/librte_gso/gso_udp4.h new file
> > mode 100644 index 0000000..b2a2908
> 
> File gso_upd4.h is almost identical to file gso_tcp4.h so both files (although
> short ~40 lines) could have been unified into one file.

Ditto.

> 
> > --- /dev/null
> > +++ b/lib/librte_gso/gso_udp4.h
> > @@ -0,0 +1,42 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Intel Corporation
> > + */
> > +
> > +#ifndef _GSO_UDP4_H_
> > +#define _GSO_UDP4_H_
> > +
> > +#include <stdint.h>
> > +#include <rte_mbuf.h>
> > +
> > +/**
> > + * Segment an UDP/IPv4 packet. This function doesn't check if the input
> > + * packet has correct checksums, and doesn't update checksums for
> > +output
> > + * GSO segments. Furthermore, it doesn't process IP fragment packets.
> > + *
> > + * @param pkt
> > + *  The packet mbuf to segment.
> > + * @param gso_size
> > + *  The max length of a GSO segment, measured in bytes.
> > + * @param direct_pool
> > + *  MBUF pool used for allocating direct buffers for output segments.
> > + * @param indirect_pool
> > + *  MBUF pool used for allocating indirect buffers for output segments.
> > + * @param pkts_out
> > + *  Pointer array used to store the MBUF addresses of output GSO
> > + *  segments, when the function succeeds. If the memory space in
> > + *  pkts_out is insufficient, it fails and returns -EINVAL.
> > + * @param nb_pkts_out
> > + *  The max number of items that 'pkts_out' can keep.
> > + *
> > + * @return
> > + *   - The number of GSO segments filled in pkts_out on success.
> > + *   - Return -ENOMEM if run out of memory in MBUF pools.
> > + *   - Return -EINVAL for invalid parameters.
> > + */
> > +int gso_udp4_segment(struct rte_mbuf *pkt,
> > +		uint16_t gso_size,
> > +		struct rte_mempool *direct_pool,
> > +		struct rte_mempool *indirect_pool,
> > +		struct rte_mbuf **pkts_out,
> > +		uint16_t nb_pkts_out);
> > +#endif
> > diff --git a/lib/librte_gso/meson.build b/lib/librte_gso/meson.build index
> > 056534f..ad8dd85 100644
> > --- a/lib/librte_gso/meson.build
> > +++ b/lib/librte_gso/meson.build
> > @@ -1,7 +1,7 @@
> >  # SPDX-License-Identifier: BSD-3-Clause  # Copyright(c) 2017 Intel
> > Corporation
> >
> > -sources = files('gso_common.c', 'gso_tcp4.c',
> > +sources = files('gso_common.c', 'gso_tcp4.c', 'gso_udp4.c',
> >   		'gso_tunnel_tcp4.c', 'rte_gso.c')
> >  headers = files('rte_gso.h')
> >  deps += ['ethdev']
> > diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c index
> > a44e3d4..751b5b6 100644
> > --- a/lib/librte_gso/rte_gso.c
> > +++ b/lib/librte_gso/rte_gso.c
> > @@ -11,6 +11,17 @@
> >  #include "gso_common.h"
> >  #include "gso_tcp4.h"
> >  #include "gso_tunnel_tcp4.h"
> > +#include "gso_udp4.h"
> > +
> > +#define ILLEGAL_UDP_GSO_CTX(ctx) \
> > +	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) == 0) || \
> > +	 (ctx)->gso_size < RTE_GSO_UDP_SEG_SIZE_MIN)
> > +
> > +#define ILLEGAL_TCP_GSO_CTX(ctx) \
> > +	((((ctx)->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | \
> > +		DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
> > +		DEV_TX_OFFLOAD_GRE_TNL_TSO)) == 0) || \
> > +		(ctx)->gso_size < RTE_GSO_SEG_SIZE_MIN)
> 
> Can you please explain why it is correct that the min len for VXLAN_TNL or
> GRE_TNL is that of TCP MIN size (RTE_GSO_SEG_SIZE_MIN)

The logic here is a little complicated. First, we have two GSO types, i.e. TCP and UDP,
and they have different requirements for min lengths and gso_types flags. In the code,
we use ILLEGAL_UDP_GSO_CTX() and ILLEGAL_TCP_GSO_CTX() to check if the input packet
doesn't meet the requirements. Rte_gso_segment() starts to process the input packet only
when it meets UDP or TCP requirement. In other words, rte_gso_segment() stops if the
packet doesn't meet both requirements at the same time. This is why I use
" ILLEGAL_UDP_GSO_CTX(gso_ctx) && ILLEGAL_TCP_GSO_CTX(gso_ctx))" as the exit
condition.

RTE_GSO_SEG_SIZE_MIN is not used to decide if input tunnel packets meet length
requirement, but just checks a min length. In fact, we cannot decide a real correct min
length for a packet type, since it may have vlan header or not. The original GSO code
leverages this macro for tunnel packets to do a minimal check, so I think we can keep it
here.

> 
> >
> 
> To make the macros above and their usage below clearer:
> 
> 1. I would change the || with &&. and == with !=
> 
> #define ILLEGAL_UDP_GSO_CTX(ctx) \
> 	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) != 0) && \
> 	 (ctx)->gso_size < RTE_GSO_UDP_SEG_SIZE_MIN)

This macro doesn't check all conditions for illegal UDP GSO. For example,
if we input a UDP/IPv4 packet with setting gso_size to 1500 and without setting
DEV_TX_OFFLOAD_UDP_TSO in gso_types, this macro returns 0, which means
it's a legal UDP GSO packet.

If you mean we'd better use LEGAL rather than ILLEGAL as the check in the code,
the exit condition should be: 

#define LEGAL_UDP_GSO_CTX(ctx) \
	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) != 0) && \
	(ctx)->gso_size >= RTE_GSO_UDP_SEG_SIZE_MIN)

if (~(LEGAL_UDP_GSO_CTX(..) || LEGAL_TCP_GSO_CTX(..)))
	return -EINVAL;

But in fact, it's the same as current implementation. I can add some
explanations to the code for users to better understand the logic, if you
think it's OK.

> 
> #define ILLEGAL_TCP_GSO_CTX(ctx) \
> 	((((ctx)->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | \
> 		DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
> 		DEV_TX_OFFLOAD_GRE_TNL_TSO)) != 0) && \
> 		(ctx)->gso_size < RTE_GSO_SEG_SIZE_MIN)
> 

Ditto.

> 2. Then later I would change the && with ||
> 
> Changing original:
> 			(ILLEGAL_UDP_GSO_CTX(gso_ctx) &&
> 			 ILLEGAL_TCP_GSO_CTX(gso_ctx)))
> 
> With this:
> 			ILLEGAL_UDP_GSO_CTX(gso_ctx) ||
> 			 ILLEGAL_TCP_GSO_CTX(gso_ctx))

Ditto.

> 
> 
> >  int
> >  rte_gso_segment(struct rte_mbuf *pkt,
> > @@ -27,14 +38,12 @@ rte_gso_segment(struct rte_mbuf *pkt,
> >
> >  	if (pkt == NULL || pkts_out == NULL || gso_ctx == NULL ||
> >  			nb_pkts_out < 1 ||
> > -			gso_ctx->gso_size < RTE_GSO_SEG_SIZE_MIN ||
> > -			((gso_ctx->gso_types &
> > (DEV_TX_OFFLOAD_TCP_TSO |
> > -			DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
> > -			DEV_TX_OFFLOAD_GRE_TNL_TSO)) == 0))
> > +			(ILLEGAL_UDP_GSO_CTX(gso_ctx) &&
> > +			 ILLEGAL_TCP_GSO_CTX(gso_ctx)))
> >  		return -EINVAL;
> >
> >  	if (gso_ctx->gso_size >= pkt->pkt_len) {
> > -		pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> > +		pkt->ol_flags &= (~(PKT_TX_TCP_SEG | PKT_TX_UDP_SEG));
> >  		pkts_out[0] = pkt;
> >  		return 1;
> >  	}
> > @@ -59,6 +68,11 @@ rte_gso_segment(struct rte_mbuf *pkt,
> >  		ret = gso_tcp4_segment(pkt, gso_size, ipid_delta,
> >  				direct_pool, indirect_pool,
> >  				pkts_out, nb_pkts_out);
> > +	} else if (IS_IPV4_UDP(pkt->ol_flags) &&
> > +			(gso_ctx->gso_types &
> > DEV_TX_OFFLOAD_UDP_TSO)) {
> > +		pkt->ol_flags &= (~PKT_TX_UDP_SEG);
> > +		ret = gso_udp4_segment(pkt, gso_size, direct_pool,
> > +				indirect_pool, pkts_out, nb_pkts_out);
> >  	} else {
> >  		/* unsupported packet, skip */
> >  		pkts_out[0] = pkt;
> > diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h index
> > f4abd61..a626a11 100644
> > --- a/lib/librte_gso/rte_gso.h
> > +++ b/lib/librte_gso/rte_gso.h
> > @@ -17,10 +17,14 @@ extern "C" {
> >  #include <stdint.h>
> >  #include <rte_mbuf.h>
> >
> > -/* Minimum GSO segment size. */
> > +/* Minimum GSO segment size for TCP based packets. */
> >  #define RTE_GSO_SEG_SIZE_MIN (sizeof(struct ether_hdr) + \
> >  		sizeof(struct ipv4_hdr) + sizeof(struct tcp_hdr) + 1)
> 
> RTE_GSO_SEG_SIZE_MIN is actually TCP min size. Can you name this macro
> as
> RTE_GSO_TCP_SEG_SIZE_MIN (symmetrically to the UDP macro below)?
> 

Yes, you are right. The name is not good. But I don't know if changing name
will introduce ABI change, so I select this name as a workaround.

Thanks,
Jiayu

> >
> > +/* Minimum GSO segment size for UDP based packets. */ #define
> > +RTE_GSO_UDP_SEG_SIZE_MIN (sizeof(struct ether_hdr) + \
> > +		sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr) + 1)
> > +
> >  /* GSO flags for rte_gso_ctx. */
> >  #define RTE_GSO_FLAG_IPID_FIXED (1ULL << 0)  /**< Use fixed IP ids for
> > output GSO segments. Setting
> > --
> > 2.7.4

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4 fragmentation
  2018-06-27  2:28  3%       ` Hu, Jiayu
@ 2018-06-27  5:05  3%         ` Hu, Jiayu
  0 siblings, 0 replies; 200+ results
From: Hu, Jiayu @ 2018-06-27  5:05 UTC (permalink / raw)
  To: 'Ophir Munk', 'dev@dpdk.org'
  Cc: Wang, Xiao W, Ananyev, Konstantin, Zhang, Yuwei1, Iremonger,
	Bernard, 'Thomas Monjalon'



> -----Original Message-----
> From: Hu, Jiayu
> Sent: Wednesday, June 27, 2018 10:29 AM
> To: Ophir Munk <ophirmu@mellanox.com>; dev@dpdk.org
> Cc: Wang, Xiao W <xiao.w.wang@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Zhang, Yuwei1
> <yuwei1.zhang@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: RE: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4
> fragmentation
> 
> Hi Ophir,
> 
> Replies are inline.
> 
> > -----Original Message-----
> > From: Ophir Munk [mailto:ophirmu@mellanox.com]
> > Sent: Wednesday, June 27, 2018 7:59 AM
> > To: Hu, Jiayu <jiayu.hu@intel.com>; dev@dpdk.org
> > Cc: Wang, Xiao W <xiao.w.wang@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; Zhang, Yuwei1
> > <yuwei1.zhang@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; Thomas Monjalon
> > <thomas@monjalon.net>
> > Subject: RE: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4
> > fragmentation
> >
> > Hi,
> > Please find some comments below.
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jiayu Hu
> > > Sent: Friday, June 22, 2018 8:54 AM
> > > To: dev@dpdk.org
> > > Cc: xiao.w.wang@intel.com; konstantin.ananyev@intel.com;
> > > yuwei1.zhang@intel.com; bernard.iremonger@intel.com; Thomas
> > Monjalon
> > > <thomas@monjalon.net>; Jiayu Hu <jiayu.hu@intel.com>
> > > Subject: [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4
> fragmentation
> > >
> > > This patch adds GSO support for UDP/IPv4 packets. Supported packets
> > may
> > > include a single VLAN tag. UDP/IPv4 GSO doesn't check if input packets
> > have
> > > correct checksums, and doesn't update checksums for output packets
> (the
> > > responsibility for this lies with the application).
> > > Additionally, UDP/IPv4 GSO doesn't process IP fragmented packets.
> > >
> > > UDP/IPv4 GSO uses two chained MBUFs, one direct MBUF and one
> indrect
> > > MBUF, to organize an output packet. The direct MBUF stores the packet
> > > header, while the indirect mbuf simply points to a location within the
> > original
> > > packet's payload. Consequently, use of UDP GSO requires multi-segment
> > > MBUF support in the TX functions of the NIC driver.
> > >
> > > If a packet is GSO'd, UDP/IPv4 GSO reduces its MBUF refcnt by 1. As a
> > result,
> > > when all of its GSOed segments are freed, the packet is freed
> > automatically.
> > >
> > > Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> > > ---
> > >  lib/librte_gso/Makefile     |  1 +
> > >  lib/librte_gso/gso_common.h |  3 ++
> > >  lib/librte_gso/gso_udp4.c   | 81
> > > +++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/librte_gso/gso_udp4.h   | 42 +++++++++++++++++++++++
> > >  lib/librte_gso/meson.build  |  2 +-
> > >  lib/librte_gso/rte_gso.c    | 24 +++++++++++---
> > >  lib/librte_gso/rte_gso.h    |  6 +++-
> > >  7 files changed, 152 insertions(+), 7 deletions(-)  create mode 100644
> > > lib/librte_gso/gso_udp4.c  create mode 100644
> lib/librte_gso/gso_udp4.h
> > >
> > > diff --git a/lib/librte_gso/Makefile b/lib/librte_gso/Makefile index
> > > 3648ec0..1fac53a 100644
> > > --- a/lib/librte_gso/Makefile
> > > +++ b/lib/librte_gso/Makefile
> > > @@ -19,6 +19,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_GSO) += rte_gso.c
> > >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_common.c
> > >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_tcp4.c
> > >  SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_tunnel_tcp4.c
> > > +SRCS-$(CONFIG_RTE_LIBRTE_GSO) += gso_udp4.c
> > >
> > >  # install this header file
> > >  SYMLINK-$(CONFIG_RTE_LIBRTE_GSO)-include += rte_gso.h diff --git
> > > a/lib/librte_gso/gso_common.h b/lib/librte_gso/gso_common.h index
> > > 5ca5974..6cd764f 100644
> > > --- a/lib/librte_gso/gso_common.h
> > > +++ b/lib/librte_gso/gso_common.h
> > > @@ -31,6 +31,9 @@
> > >  		(PKT_TX_TCP_SEG | PKT_TX_IPV4 | PKT_TX_OUTER_IPV4 |
> > \
> > >  		 PKT_TX_TUNNEL_GRE))
> > >
> > > +#define IS_IPV4_UDP(flag) (((flag) & (PKT_TX_UDP_SEG | PKT_TX_IPV4))
> > ==
> > > \
> > > +		(PKT_TX_UDP_SEG | PKT_TX_IPV4))
> > > +
> > >  /**
> > >   * Internal function which updates the UDP header of a packet,
> following
> > >   * segmentation. This is required to update the header's datagram
> length
> > > field.
> > > diff --git a/lib/librte_gso/gso_udp4.c b/lib/librte_gso/gso_udp4.c new
> file
> > > mode 100644 index 0000000..927dee1
> > > --- /dev/null
> > > +++ b/lib/librte_gso/gso_udp4.c
> >
> > File gso_upd4.c could be very similar to file gso_tcp4.c and that would
> > avoid code duplication.
> > In a unified file you could use a tcp vs. udp flag to distinguish between
> them
> > when necessary.
> > The files are short (~75 lines) so it is not a critical issue.
> 
> The function gso_tcp4_segment and gso_udp4_segment have different
> prototype,
> and their GSO rules are different. They are two different basic GSO types.
> 
> The GSO library gives each GSO type (TCP, tunnel) an internal .c and .h file,
> and their name
> represents their content. The rte_gso_segment calls different function
> according to the GSO type.
> This style is very clear for developers or users to understand. In addition, as
> you said, the code
> is short. So I think it's better to keep this style for UDP/IPv4 GSO.
> 
> >
> > > @@ -0,0 +1,81 @@
> > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > + * Copyright(c) 2018 Intel Corporation
> > > + */
> > > +
> > > +#include "gso_common.h"
> > > +#include "gso_udp4.h"
> > > +
> > > +#define IPV4_HDR_MF_BIT (1U << 13)
> > > +
> > > +static inline void
> > > +update_ipv4_udp_headers(struct rte_mbuf *pkt, struct rte_mbuf
> **segs,
> > > +		uint16_t nb_segs)
> > > +{
> > > +	struct ipv4_hdr *ipv4_hdr;
> > > +	uint16_t frag_offset = 0, is_mf;
> > > +	uint16_t l2_hdrlen = pkt->l2_len, l3_hdrlen = pkt->l3_len;
> > > +	uint16_t tail_idx = nb_segs - 1, length, i;
> > > +
> > > +	/*
> > > +	 * Update IP header fields for output segments. Specifically,
> > > +	 * keep the same IP id, update fragment offset and total
> > > +	 * length.
> > > +	 */
> > > +	for (i = 0; i < nb_segs; i++) {
> > > +		ipv4_hdr = rte_pktmbuf_mtod_offset(segs[i], struct
> > ipv4_hdr
> > > *,
> > > +			l2_hdrlen);
> > > +		length = segs[i]->pkt_len - l2_hdrlen;
> > > +		ipv4_hdr->total_length = rte_cpu_to_be_16(length);
> > > +
> > > +		is_mf = i < tail_idx ? IPV4_HDR_MF_BIT : 0;
> > > +		ipv4_hdr->fragment_offset =
> > > +			rte_cpu_to_be_16(frag_offset | is_mf);
> > > +		frag_offset += ((length - l3_hdrlen) >> 3);
> > > +	}
> > > +}
> > > +
> > > +int
> > > +gso_udp4_segment(struct rte_mbuf *pkt,
> > > +		uint16_t gso_size,
> > > +		struct rte_mempool *direct_pool,
> > > +		struct rte_mempool *indirect_pool,
> > > +		struct rte_mbuf **pkts_out,
> > > +		uint16_t nb_pkts_out)
> > > +{
> > > +	struct ipv4_hdr *ipv4_hdr;
> > > +	uint16_t pyld_unit_size, hdr_offset;
> > > +	uint16_t frag_off;
> > > +	int ret;
> > > +
> > > +	/* Don't process the fragmented packet */
> > > +	ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
> > > +			pkt->l2_len);
> > > +	frag_off = rte_be_to_cpu_16(ipv4_hdr->fragment_offset);
> > > +	if (unlikely(IS_FRAGMENTED(frag_off))) {
> > > +		pkts_out[0] = pkt;
> > > +		return 1;
> > > +	}
> > > +
> > > +	/*
> > > +	 * UDP fragmentation is the same as IP fragmentation.
> > > +	 * Except the first one, other output packets just have l2
> > > +	 * and l3 headers.
> > > +	 */
> > > +	hdr_offset = pkt->l2_len + pkt->l3_len;
> > > +
> > > +	/* Don't process the packet without data. */
> > > +	if (unlikely(hdr_offset + pkt->l4_len >= pkt->pkt_len)) {
> > > +		pkts_out[0] = pkt;
> > > +		return 1;
> > > +	}
> > > +
> > > +	pyld_unit_size = gso_size - hdr_offset;
> > > +
> > > +	/* Segment the payload */
> > > +	ret = gso_do_segment(pkt, hdr_offset, pyld_unit_size, direct_pool,
> > > +			indirect_pool, pkts_out, nb_pkts_out);
> > > +	if (ret > 1)
> > > +		update_ipv4_udp_headers(pkt, pkts_out, ret);
> > > +
> > > +	return ret;
> > > +}
> > > diff --git a/lib/librte_gso/gso_udp4.h b/lib/librte_gso/gso_udp4.h new
> file
> > > mode 100644 index 0000000..b2a2908
> >
> > File gso_upd4.h is almost identical to file gso_tcp4.h so both files
> (although
> > short ~40 lines) could have been unified into one file.
> 
> Ditto.
> 
> >
> > > --- /dev/null
> > > +++ b/lib/librte_gso/gso_udp4.h
> > > @@ -0,0 +1,42 @@
> > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > + * Copyright(c) 2018 Intel Corporation
> > > + */
> > > +
> > > +#ifndef _GSO_UDP4_H_
> > > +#define _GSO_UDP4_H_
> > > +
> > > +#include <stdint.h>
> > > +#include <rte_mbuf.h>
> > > +
> > > +/**
> > > + * Segment an UDP/IPv4 packet. This function doesn't check if the
> input
> > > + * packet has correct checksums, and doesn't update checksums for
> > > +output
> > > + * GSO segments. Furthermore, it doesn't process IP fragment packets.
> > > + *
> > > + * @param pkt
> > > + *  The packet mbuf to segment.
> > > + * @param gso_size
> > > + *  The max length of a GSO segment, measured in bytes.
> > > + * @param direct_pool
> > > + *  MBUF pool used for allocating direct buffers for output segments.
> > > + * @param indirect_pool
> > > + *  MBUF pool used for allocating indirect buffers for output segments.
> > > + * @param pkts_out
> > > + *  Pointer array used to store the MBUF addresses of output GSO
> > > + *  segments, when the function succeeds. If the memory space in
> > > + *  pkts_out is insufficient, it fails and returns -EINVAL.
> > > + * @param nb_pkts_out
> > > + *  The max number of items that 'pkts_out' can keep.
> > > + *
> > > + * @return
> > > + *   - The number of GSO segments filled in pkts_out on success.
> > > + *   - Return -ENOMEM if run out of memory in MBUF pools.
> > > + *   - Return -EINVAL for invalid parameters.
> > > + */
> > > +int gso_udp4_segment(struct rte_mbuf *pkt,
> > > +		uint16_t gso_size,
> > > +		struct rte_mempool *direct_pool,
> > > +		struct rte_mempool *indirect_pool,
> > > +		struct rte_mbuf **pkts_out,
> > > +		uint16_t nb_pkts_out);
> > > +#endif
> > > diff --git a/lib/librte_gso/meson.build b/lib/librte_gso/meson.build
> index
> > > 056534f..ad8dd85 100644
> > > --- a/lib/librte_gso/meson.build
> > > +++ b/lib/librte_gso/meson.build
> > > @@ -1,7 +1,7 @@
> > >  # SPDX-License-Identifier: BSD-3-Clause  # Copyright(c) 2017 Intel
> > > Corporation
> > >
> > > -sources = files('gso_common.c', 'gso_tcp4.c',
> > > +sources = files('gso_common.c', 'gso_tcp4.c', 'gso_udp4.c',
> > >   		'gso_tunnel_tcp4.c', 'rte_gso.c')
> > >  headers = files('rte_gso.h')
> > >  deps += ['ethdev']
> > > diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c index
> > > a44e3d4..751b5b6 100644
> > > --- a/lib/librte_gso/rte_gso.c
> > > +++ b/lib/librte_gso/rte_gso.c
> > > @@ -11,6 +11,17 @@
> > >  #include "gso_common.h"
> > >  #include "gso_tcp4.h"
> > >  #include "gso_tunnel_tcp4.h"
> > > +#include "gso_udp4.h"
> > > +
> > > +#define ILLEGAL_UDP_GSO_CTX(ctx) \
> > > +	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) == 0) || \
> > > +	 (ctx)->gso_size < RTE_GSO_UDP_SEG_SIZE_MIN)
> > > +
> > > +#define ILLEGAL_TCP_GSO_CTX(ctx) \
> > > +	((((ctx)->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | \
> > > +		DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
> > > +		DEV_TX_OFFLOAD_GRE_TNL_TSO)) == 0) || \
> > > +		(ctx)->gso_size < RTE_GSO_SEG_SIZE_MIN)
> >
> > Can you please explain why it is correct that the min len for VXLAN_TNL
> or
> > GRE_TNL is that of TCP MIN size (RTE_GSO_SEG_SIZE_MIN)
> 
> The logic here is a little complicated. First, we have two GSO types, i.e. TCP
> and UDP,
> and they have different requirements for min lengths and gso_types flags.
> In the code,
> we use ILLEGAL_UDP_GSO_CTX() and ILLEGAL_TCP_GSO_CTX() to check if
> the input packet
> doesn't meet the requirements. Rte_gso_segment() starts to process the
> input packet only
> when it meets UDP or TCP requirement. In other words, rte_gso_segment()
> stops if the
> packet doesn't meet both requirements at the same time. This is why I use
> " ILLEGAL_UDP_GSO_CTX(gso_ctx) && ILLEGAL_TCP_GSO_CTX(gso_ctx))"
> as the exit
> condition.
> 
> RTE_GSO_SEG_SIZE_MIN is not used to decide if input tunnel packets meet
> length
> requirement, but just checks a min length. In fact, we cannot decide a real
> correct min
> length for a packet type, since it may have vlan header or not. The original
> GSO code
> leverages this macro for tunnel packets to do a minimal check, so I think we
> can keep it
> here.
> 
> >
> > >
> >
> > To make the macros above and their usage below clearer:
> >
> > 1. I would change the || with &&. and == with !=
> >
> > #define ILLEGAL_UDP_GSO_CTX(ctx) \
> > 	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) != 0) && \
> > 	 (ctx)->gso_size < RTE_GSO_UDP_SEG_SIZE_MIN)
> 
> This macro doesn't check all conditions for illegal UDP GSO. For example,
> if we input a UDP/IPv4 packet with setting gso_size to 1500 and without
> setting
> DEV_TX_OFFLOAD_UDP_TSO in gso_types, this macro returns 0, which
> means
> it's a legal UDP GSO packet.
> 
> If you mean we'd better use LEGAL rather than ILLEGAL as the check in the
> code,
> the exit condition should be:
> 
> #define LEGAL_UDP_GSO_CTX(ctx) \
> 	((((ctx)->gso_types & DEV_TX_OFFLOAD_UDP_TSO) != 0) && \
> 	(ctx)->gso_size >= RTE_GSO_UDP_SEG_SIZE_MIN)
> 
> if (~(LEGAL_UDP_GSO_CTX(..) || LEGAL_TCP_GSO_CTX(..)))
> 	return -EINVAL;
> 
> But in fact, it's the same as current implementation. I can add some
> explanations to the code for users to better understand the logic, if you
> think it's OK.
> 
> >
> > #define ILLEGAL_TCP_GSO_CTX(ctx) \
> > 	((((ctx)->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | \
> > 		DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
> > 		DEV_TX_OFFLOAD_GRE_TNL_TSO)) != 0) && \
> > 		(ctx)->gso_size < RTE_GSO_SEG_SIZE_MIN)
> >
> 
> Ditto.
> 
> > 2. Then later I would change the && with ||
> >
> > Changing original:
> > 			(ILLEGAL_UDP_GSO_CTX(gso_ctx) &&
> > 			 ILLEGAL_TCP_GSO_CTX(gso_ctx)))
> >
> > With this:
> > 			ILLEGAL_UDP_GSO_CTX(gso_ctx) ||
> > 			 ILLEGAL_TCP_GSO_CTX(gso_ctx))
> 
> Ditto.
> 
> >
> >
> > >  int
> > >  rte_gso_segment(struct rte_mbuf *pkt,
> > > @@ -27,14 +38,12 @@ rte_gso_segment(struct rte_mbuf *pkt,
> > >
> > >  	if (pkt == NULL || pkts_out == NULL || gso_ctx == NULL ||
> > >  			nb_pkts_out < 1 ||
> > > -			gso_ctx->gso_size < RTE_GSO_SEG_SIZE_MIN ||
> > > -			((gso_ctx->gso_types &
> > > (DEV_TX_OFFLOAD_TCP_TSO |
> > > -			DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
> > > -			DEV_TX_OFFLOAD_GRE_TNL_TSO)) == 0))
> > > +			(ILLEGAL_UDP_GSO_CTX(gso_ctx) &&
> > > +			 ILLEGAL_TCP_GSO_CTX(gso_ctx)))
> > >  		return -EINVAL;
> > >
> > >  	if (gso_ctx->gso_size >= pkt->pkt_len) {
> > > -		pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> > > +		pkt->ol_flags &= (~(PKT_TX_TCP_SEG | PKT_TX_UDP_SEG));
> > >  		pkts_out[0] = pkt;
> > >  		return 1;
> > >  	}
> > > @@ -59,6 +68,11 @@ rte_gso_segment(struct rte_mbuf *pkt,
> > >  		ret = gso_tcp4_segment(pkt, gso_size, ipid_delta,
> > >  				direct_pool, indirect_pool,
> > >  				pkts_out, nb_pkts_out);
> > > +	} else if (IS_IPV4_UDP(pkt->ol_flags) &&
> > > +			(gso_ctx->gso_types &
> > > DEV_TX_OFFLOAD_UDP_TSO)) {
> > > +		pkt->ol_flags &= (~PKT_TX_UDP_SEG);
> > > +		ret = gso_udp4_segment(pkt, gso_size, direct_pool,
> > > +				indirect_pool, pkts_out, nb_pkts_out);
> > >  	} else {
> > >  		/* unsupported packet, skip */
> > >  		pkts_out[0] = pkt;
> > > diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h index
> > > f4abd61..a626a11 100644
> > > --- a/lib/librte_gso/rte_gso.h
> > > +++ b/lib/librte_gso/rte_gso.h
> > > @@ -17,10 +17,14 @@ extern "C" {
> > >  #include <stdint.h>
> > >  #include <rte_mbuf.h>
> > >
> > > -/* Minimum GSO segment size. */
> > > +/* Minimum GSO segment size for TCP based packets. */
> > >  #define RTE_GSO_SEG_SIZE_MIN (sizeof(struct ether_hdr) + \
> > >  		sizeof(struct ipv4_hdr) + sizeof(struct tcp_hdr) + 1)
> >
> > RTE_GSO_SEG_SIZE_MIN is actually TCP min size. Can you name this
> macro
> > as
> > RTE_GSO_TCP_SEG_SIZE_MIN (symmetrically to the UDP macro below)?
> >
> 
> Yes, you are right. The name is not good. But I don't know if changing name
> will introduce ABI change, so I select this name as a workaround.

Sorry, it will not cause ABI change but will influence the applications
which have already used the GSO library, if we rename RTE_GSO_SEG_SIZE_MIN.
This is because this macro is an external macro. From my perspective, I prefer to
 introduce a new macro for UDP based GSO, instead of renaming it.

Jiayu
> 
> Thanks,
> Jiayu
> 
> > >
> > > +/* Minimum GSO segment size for UDP based packets. */ #define
> > > +RTE_GSO_UDP_SEG_SIZE_MIN (sizeof(struct ether_hdr) + \
> > > +		sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr) + 1)
> > > +
> > >  /* GSO flags for rte_gso_ctx. */
> > >  #define RTE_GSO_FLAG_IPID_FIXED (1ULL << 0)  /**< Use fixed IP ids
> for
> > > output GSO segments. Setting
> > > --
> > > 2.7.4

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] cmdline: rework as a wrapper to libedit
  2018-06-26 13:21  0%   ` Olivier Matz
@ 2018-06-27 10:36  0%     ` Bruce Richardson
  2018-06-27 11:35  0%       ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2018-06-27 10:36 UTC (permalink / raw)
  To: Olivier Matz
  Cc: Adrien Mazarguil, dev, Keith Wiles, Jingjing Wu, Thomas Monjalon,
	Ferruh Yigit, Jim Thompson, Anatoly Burakov

On Tue, Jun 26, 2018 at 03:21:21PM +0200, Olivier Matz wrote:
> Hi Adrien,
> 
> Better late than never, please find below some comments
> about your patch.
> 
> On Thu, Apr 19, 2018 at 05:13:53PM +0200, Adrien Mazarguil wrote:
> > Disclaimer: this patch must not be confused with the CLI library [1]
> > (work in progress) that will eventually supersede librte_cmdline itself
> > with a different API.
> > 
> > Rather, it modifies librte_cmdline to delegate all the heavy lifting
> > (terminal and history handling), strips unused features and re-implements
> > what remains of its public API as a wrapper to the editline library (also
> > known as libedit) [2], a well-known, BSD-licensed and widely available
> > library used by many projects which does everything needed and more [3].
> > 
> > This approach was chosen because converting librte_cmdline as a wrapper to
> > a more capable library was easier and faster than addressing its
> > shortcomings and results in much less code to maintain in DPDK.
> > 
> > It also provides a drop-in solution for applications that rely on
> > librte_cmdline. They benefit from greatly improved command line handling
> > without a meaningful impact on their code base.
> > 
> > The main motivation behind this patch is testpmd's flow (rte_flow) command,
> > which requires support for dynamic tokens and very long lines that must be
> > broken down when displayed. This is not supported by librte_cmdline's
> > limited terminal handling capabilities, resulting in a rather frustrating
> > user experience.
> > 
> > It had to be addressed given the importance of testpmd as one of the
> > primary tool used by PMD developers.
> > 
> > This rework results in the following changes:
> > 
> > - Removed circular buffer management interface for command history
> >   (cmdline_cirbuf.c), command history being handled by libedit.
> > - Removed raw command-line interpreter (cmdline_rdline.c).
> > - Removed raw terminal handler (cmdline_vt100.c).
> > - Removed all test/example code for the above.
> > - Re-implemented high level interactive and non-interactive command-line
> >   handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
> >   native interface, not its readline compatibility layer.
> > - Made struct cmdline opaque so that applications relying on librte_cmdline
> >   do not need to include any libedit headers.
> > - Applications do not need to include cmdline_rdline.h anymore.
> > - Terminal resizing is now automatically handled.
> > - New external dependency for applications relying on librte_cmdline.
> > - Major version bump due to the ABI impact of these changes.
> > 
> > [1] http://dpdk.org/browse/draft/dpdk-draft-cli/
> > [2] http://thrysoee.dk/editline/
> > [3] http://netbsd.gw.com/cgi-bin/man-cgi?editline++NetBSD-current
> > 
> > Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > Cc: Olivier Matz <olivier.matz@6wind.com>
> > Cc: Keith Wiles <keith.wiles@intel.com>
> > Cc: Jingjing Wu <jingjing.wu@intel.com>
> > Cc: Thomas Monjalon <thomas@monjalon.net>
> > Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> > Cc: Jim Thompson <jim@netgate.com>
> > Cc: Anatoly Burakov <anatoly.burakov@intel.com>
> > 
> > --
> > 
> > v2 changes:
> > 
> > - Replaced an instance of snprintf() with rte_strlcpy() [5].
> > - Rebased patch.
> > 
> > [5] http://dpdk.org/ml/archives/dev/2018-April/097721.html
> > 
> > v1 changes:
> > 
> > No fundamental change since the original RFC [4], except it's been rebased
> > several times and Meson build support was added in the meantime. Commit log
> > was also shortened a bit.
> > 
> > I'm re-sending this because I think it's useful, at least to me (duh). As
> > the maintainer of rte_flow, I spend most of my time typing flow commands in
> > testpmd and libedit makes that a pleasant experience.
> > 
> > Try it out! And don't hesitate to send your acked-by line to get this in
> > time for 18.05 :)
> > 
> > [4] http://dpdk.org/ml/archives/dev/2017-November/081605.html
> 
> Re-saying what I said the first time: I think this is a very good
> improvement, removing lots of dpdk code that is better implemented in
> well-known libraries.
> 
> 
> The compilation with shared libraries fail. Please try for instance:
> ./devtools/test-build.sh -j4 x86_64-native-linuxapp-clang+shared+debug
> 
> I suggest to add in lib/librte_cmdline/Makefile:
> 
>   LDLIBS += $(shell pkg-config --libs libedit)
> 
> 
> I also think something should be added in
> /doc/guides/linux_gsg/sys_reqs.rst to highlight the new build
> dependency.
> 
> 
> I noticed a bad behavior change (in addition to many good ones):
> ctrl-c now quits the application, and this was not the case before.
> I often use ctrl-c to delete the line I'm currently editing. Please
> see at the end a proposition to restore this feature.
> 

I 100% disagree, please set things up that "ctrl-c" quits the application.

Having our DPDK testpmd and auto-test apps fail to close on ctrl-c is just
awful from a usability perspective IMHO! If there is ever a problem with
the app and you need to kill it quickly, e.g. you want to stop one of those
long-running autotests, the lack of ctrl-c is a pain.

For me, the only valid use-case for a command-line app to catch the signal
from ctrl-c is to allow the app to do some cleanup before it quits.

/Bruce

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] cmdline: rework as a wrapper to libedit
  2018-06-27 10:36  0%     ` Bruce Richardson
@ 2018-06-27 11:35  0%       ` Olivier Matz
  0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2018-06-27 11:35 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Adrien Mazarguil, dev, Keith Wiles, Jingjing Wu, Thomas Monjalon,
	Ferruh Yigit, Jim Thompson, Anatoly Burakov

On Wed, Jun 27, 2018 at 11:36:28AM +0100, Bruce Richardson wrote:
> On Tue, Jun 26, 2018 at 03:21:21PM +0200, Olivier Matz wrote:
> > Hi Adrien,
> > 
> > Better late than never, please find below some comments
> > about your patch.
> > 
> > On Thu, Apr 19, 2018 at 05:13:53PM +0200, Adrien Mazarguil wrote:
> > > Disclaimer: this patch must not be confused with the CLI library [1]
> > > (work in progress) that will eventually supersede librte_cmdline itself
> > > with a different API.
> > > 
> > > Rather, it modifies librte_cmdline to delegate all the heavy lifting
> > > (terminal and history handling), strips unused features and re-implements
> > > what remains of its public API as a wrapper to the editline library (also
> > > known as libedit) [2], a well-known, BSD-licensed and widely available
> > > library used by many projects which does everything needed and more [3].
> > > 
> > > This approach was chosen because converting librte_cmdline as a wrapper to
> > > a more capable library was easier and faster than addressing its
> > > shortcomings and results in much less code to maintain in DPDK.
> > > 
> > > It also provides a drop-in solution for applications that rely on
> > > librte_cmdline. They benefit from greatly improved command line handling
> > > without a meaningful impact on their code base.
> > > 
> > > The main motivation behind this patch is testpmd's flow (rte_flow) command,
> > > which requires support for dynamic tokens and very long lines that must be
> > > broken down when displayed. This is not supported by librte_cmdline's
> > > limited terminal handling capabilities, resulting in a rather frustrating
> > > user experience.
> > > 
> > > It had to be addressed given the importance of testpmd as one of the
> > > primary tool used by PMD developers.
> > > 
> > > This rework results in the following changes:
> > > 
> > > - Removed circular buffer management interface for command history
> > >   (cmdline_cirbuf.c), command history being handled by libedit.
> > > - Removed raw command-line interpreter (cmdline_rdline.c).
> > > - Removed raw terminal handler (cmdline_vt100.c).
> > > - Removed all test/example code for the above.
> > > - Re-implemented high level interactive and non-interactive command-line
> > >   handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
> > >   native interface, not its readline compatibility layer.
> > > - Made struct cmdline opaque so that applications relying on librte_cmdline
> > >   do not need to include any libedit headers.
> > > - Applications do not need to include cmdline_rdline.h anymore.
> > > - Terminal resizing is now automatically handled.
> > > - New external dependency for applications relying on librte_cmdline.
> > > - Major version bump due to the ABI impact of these changes.
> > > 
> > > [1] http://dpdk.org/browse/draft/dpdk-draft-cli/
> > > [2] http://thrysoee.dk/editline/
> > > [3] http://netbsd.gw.com/cgi-bin/man-cgi?editline++NetBSD-current
> > > 
> > > Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > > Cc: Olivier Matz <olivier.matz@6wind.com>
> > > Cc: Keith Wiles <keith.wiles@intel.com>
> > > Cc: Jingjing Wu <jingjing.wu@intel.com>
> > > Cc: Thomas Monjalon <thomas@monjalon.net>
> > > Cc: Ferruh Yigit <ferruh.yigit@intel.com>
> > > Cc: Jim Thompson <jim@netgate.com>
> > > Cc: Anatoly Burakov <anatoly.burakov@intel.com>
> > > 
> > > --
> > > 
> > > v2 changes:
> > > 
> > > - Replaced an instance of snprintf() with rte_strlcpy() [5].
> > > - Rebased patch.
> > > 
> > > [5] http://dpdk.org/ml/archives/dev/2018-April/097721.html
> > > 
> > > v1 changes:
> > > 
> > > No fundamental change since the original RFC [4], except it's been rebased
> > > several times and Meson build support was added in the meantime. Commit log
> > > was also shortened a bit.
> > > 
> > > I'm re-sending this because I think it's useful, at least to me (duh). As
> > > the maintainer of rte_flow, I spend most of my time typing flow commands in
> > > testpmd and libedit makes that a pleasant experience.
> > > 
> > > Try it out! And don't hesitate to send your acked-by line to get this in
> > > time for 18.05 :)
> > > 
> > > [4] http://dpdk.org/ml/archives/dev/2017-November/081605.html
> > 
> > Re-saying what I said the first time: I think this is a very good
> > improvement, removing lots of dpdk code that is better implemented in
> > well-known libraries.
> > 
> > 
> > The compilation with shared libraries fail. Please try for instance:
> > ./devtools/test-build.sh -j4 x86_64-native-linuxapp-clang+shared+debug
> > 
> > I suggest to add in lib/librte_cmdline/Makefile:
> > 
> >   LDLIBS += $(shell pkg-config --libs libedit)
> > 
> > 
> > I also think something should be added in
> > /doc/guides/linux_gsg/sys_reqs.rst to highlight the new build
> > dependency.
> > 
> > 
> > I noticed a bad behavior change (in addition to many good ones):
> > ctrl-c now quits the application, and this was not the case before.
> > I often use ctrl-c to delete the line I'm currently editing. Please
> > see at the end a proposition to restore this feature.
> > 
> 
> I 100% disagree, please set things up that "ctrl-c" quits the application.
> 
> Having our DPDK testpmd and auto-test apps fail to close on ctrl-c is just
> awful from a usability perspective IMHO! If there is ever a problem with
> the app and you need to kill it quickly, e.g. you want to stop one of those
> long-running autotests, the lack of ctrl-c is a pain.

Well, this is a good argument.

It looks that ctrl-u can do the job, so I may just need to change my
habits :)

Olivier

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan
  2018-06-26 16:33  4%         ` Gaëtan Rivet
@ 2018-06-27 12:32  3%           ` Zhang, Qi Z
  0 siblings, 0 replies; 200+ results
From: Zhang, Qi Z @ 2018-06-27 12:32 UTC (permalink / raw)
  To: Gaëtan Rivet
  Cc: Burakov, Anatoly, thomas, Ananyev, Konstantin, dev, Richardson,
	Bruce, Yigit, Ferruh, Shelton, Benjamin H, Vangati, Narender



> -----Original Message-----
> From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> Sent: Wednesday, June 27, 2018 12:34 AM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>
> Cc: Burakov, Anatoly <anatoly.burakov@intel.com>; thomas@monjalon.net;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org;
> Richardson, Bruce <bruce.richardson@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; Shelton, Benjamin H
> <benjamin.h.shelton@intel.com>; Vangati, Narender
> <narender.vangati@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan
> 
> On Tue, Jun 26, 2018 at 12:26:05PM +0000, Zhang, Qi Z wrote:
> >
> >
> > > -----Original Message-----
> > > From: Burakov, Anatoly
> > > Sent: Tuesday, June 26, 2018 7:48 PM
> > > To: Zhang, Qi Z <qi.z.zhang@intel.com>; thomas@monjalon.net
> > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>;
> > > dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>; Yigit,
> > > Ferruh <ferruh.yigit@intel.com>; Shelton, Benjamin H
> > > <benjamin.h.shelton@intel.com>; Vangati, Narender
> > > <narender.vangati@intel.com>
> > > Subject: Re: [PATCH v4 01/24] eal: introduce one device scan
> > >
> > > On 26-Jun-18 8:08 AM, Qi Zhang wrote:
> > > > When hot plug a new device, it is not necessary to scan everything
> > > > on the bus since the devname and devargs are already there. So new
> > > > rte_bus ops "scan_one" is introduced, bus driver can implement
> > > > this function to simplify the hotplug process.
> > > >
> > > > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > > > ---
> > > >
> > >
> > > <snip>
> > >
> > > > + *	NULL for unsuccessful scan
> > > > + */
> > > > +typedef struct rte_device *(*rte_bus_scan_one_t)(struct
> > > > +rte_devargs *devargs);
> > > > +
> > > > +/**
> > > >    * Implementation specific probe function which is responsible for
> linking
> > > >    * devices on that bus with applicable drivers.
> > > >    *
> > > > @@ -204,6 +219,7 @@ struct rte_bus {
> > > >   	TAILQ_ENTRY(rte_bus) next;   /**< Next bus object in linked list */
> > > >   	const char *name;            /**< Name of the bus */
> > > >   	rte_bus_scan_t scan;         /**< Scan for devices attached to
> > > bus */
> > > > +	rte_bus_scan_one_t scan_one; /**< Scan one device using devargs
> > > > +*/
> > > >   	rte_bus_probe_t probe;       /**< Probe devices on bus */
> > > >   	rte_bus_find_device_t find_device; /**< Find a device on the bus */
> > > >   	rte_bus_plug_t plug;         /**< Probe single device for drivers
> > > */
> > > >
> > >
> > > Does changing this structure break ABI for bus drivers?
> >
> > For bus driver, I think yes, but I'm not sure what I should do for
> > this, since this is not for application
> >
> >
> 
> This should be appropriately announced in advance, in general.
> However, it seems there is some leeway if the new field will not move the
> others and not make the structure grow (i.e. replace a padding).
> 
> There is an ABI check script that can be used.
> 
> This however breaks the bus ABI, which breaks the EAL ABI.
> This is usually an issue.


OK, since we are able to invoke IPC request in a separate thread and also with below
fix, there is no issue on the vdev->scan during hotplug on secondary.
https://patches.dpdk.org/patch/41647/

ABI break is not necessary, I will withdraw patch 1 and 2. 

Thanks
Qi


> 
> More generally, I was in favor of changing the whole bus scan process to a
> per-device iteration. I was shut down on this when adding hotplug.
> As a result, bus->scan() process was made to require the operation to be
> idempotent.
> 
> Adding a new ops adds noise to the bus API. It should be kept as clean as
> possible. This new one seems unnecessary, now that all bus scans are
> idempotent (when supporting hotplug).
> 
> Regards,
> --
> Gaëtan Rivet
> 6WIND

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/2] compressdev: replace mbuf scatter gather flag
@ 2018-06-27  5:50  4% Pablo de Lara
  2018-06-27 12:16  4% ` [dpdk-dev] [PATCH v2 " Pablo de Lara
  0 siblings, 1 reply; 200+ results
From: Pablo de Lara @ 2018-06-27  5:50 UTC (permalink / raw)
  To: fiona.trahe, ashish.gupta, lee.daly; +Cc: dev, Pablo de Lara

The current mbuf scatter gatter feature flag is
too ambiguous, as it is not clear if input and/or output
buffers can be scatter gather mbufs or not.

Therefore, three new flags will replace this flag:
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT

Note that out-of-place flat buffers is supported by default
and in-place is not supported by the library.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/release_18_08.rst |  6 ++++++
 lib/librte_compressdev/rte_comp.c      |  8 ++++++--
 lib/librte_compressdev/rte_comp.h      | 30 ++++++++++++++++++++----------
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..1fc38418a 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -60,6 +60,12 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* compressdev: Feature flag ``RTE_COMP_FF_MBUF_SCATTER_GATHER`` is
+  replaced with the following more explicit flags:
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT``
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_compressdev/rte_comp.c b/lib/librte_compressdev/rte_comp.c
index d596ba872..ea7692ae7 100644
--- a/lib/librte_compressdev/rte_comp.c
+++ b/lib/librte_compressdev/rte_comp.c
@@ -14,8 +14,12 @@ rte_comp_get_feature_name(uint64_t flag)
 		return "STATEFUL_COMPRESSION";
 	case RTE_COMP_FF_STATEFUL_DECOMPRESSION:
 		return "STATEFUL_DECOMPRESSION";
-	case RTE_COMP_FF_MBUF_SCATTER_GATHER:
-		return "MBUF_SCATTER_GATHER";
+	case RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT:
+		return "OUT_OF_PLACE_SGL_IN_SGL_OUT";
+	case RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT:
+		return "OUT_OF_PLACE_SGL_IN_FB_OUT";
+	case RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT:
+		return "OUT_OF_PLACE_FB_IN_SGL_OUT";
 	case RTE_COMP_FF_MULTI_PKT_CHECKSUM:
 		return "MULTI_PKT_CHECKSUM";
 	case RTE_COMP_FF_ADLER32_CHECKSUM:
diff --git a/lib/librte_compressdev/rte_comp.h b/lib/librte_compressdev/rte_comp.h
index 5b513c77e..3ce6a80e1 100644
--- a/lib/librte_compressdev/rte_comp.h
+++ b/lib/librte_compressdev/rte_comp.h
@@ -30,23 +30,33 @@ extern "C" {
 /**< Stateful compression is supported */
 #define RTE_COMP_FF_STATEFUL_DECOMPRESSION	(1ULL << 1)
 /**< Stateful decompression is supported */
-#define	RTE_COMP_FF_MBUF_SCATTER_GATHER		(1ULL << 2)
-/**< Scatter-gather mbufs are supported */
-#define RTE_COMP_FF_ADLER32_CHECKSUM		(1ULL << 3)
+#define RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT	(1ULL << 2)
+/**< Out-of-place Scatter-gather (SGL) mbufs are
+ * supported in input and output
+ */
+#define RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT	(1ULL << 3)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in input, but only flat buffers (FB) are supported in output
+ */
+#define RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT	(1ULL << 4)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in output, but only flat buffers (FB) are supported in input
+ */
+#define RTE_COMP_FF_ADLER32_CHECKSUM		(1ULL << 5)
 /**< Adler-32 Checksum is supported */
-#define RTE_COMP_FF_CRC32_CHECKSUM		(1ULL << 4)
+#define RTE_COMP_FF_CRC32_CHECKSUM		(1ULL << 6)
 /**< CRC32 Checksum is supported */
-#define RTE_COMP_FF_CRC32_ADLER32_CHECKSUM	(1ULL << 5)
+#define RTE_COMP_FF_CRC32_ADLER32_CHECKSUM	(1ULL << 7)
 /**< Adler-32/CRC32 Checksum is supported */
-#define RTE_COMP_FF_MULTI_PKT_CHECKSUM		(1ULL << 6)
+#define RTE_COMP_FF_MULTI_PKT_CHECKSUM		(1ULL << 8)
 /**< Generation of checksum across multiple stateless packets is supported */
-#define RTE_COMP_FF_SHA1_HASH			(1ULL << 7)
+#define RTE_COMP_FF_SHA1_HASH			(1ULL << 9)
 /**< SHA1 Hash is supported */
-#define RTE_COMP_FF_SHA2_SHA256_HASH		(1ULL << 8)
+#define RTE_COMP_FF_SHA2_SHA256_HASH		(1ULL << 10)
 /**< SHA256 Hash of SHA2 family is supported */
-#define RTE_COMP_FF_NONCOMPRESSED_BLOCKS	(1ULL << 9)
+#define RTE_COMP_FF_NONCOMPRESSED_BLOCKS	(1ULL << 11)
 /**< Creation of non-compressed blocks using RTE_COMP_LEVEL_NONE is supported */
-#define RTE_COMP_FF_SHAREABLE_PRIV_XFORM	(1ULL << 10)
+#define RTE_COMP_FF_SHAREABLE_PRIV_XFORM	(1ULL << 12)
 /**< Private xforms created by the PMD can be shared
  * across multiple stateless operations. If not set, then app needs
  * to create as many priv_xforms as it expects to have stateless
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v8] checkpatches.sh: Add checks for ABI symbol addition
  2018-06-25 23:04  4%   ` Thomas Monjalon
@ 2018-06-27 17:58  4%     ` Neil Horman
  0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-06-27 17:58 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit, Stephen Hemminger

On Tue, Jun 26, 2018 at 01:04:16AM +0200, Thomas Monjalon wrote:
> 14/06/2018 15:30, Neil Horman:
> >  * found a way to eliminate the use of filterdiff (new awk rules)
> 
> Thanks a lot for not requiring filterdiff dependency.
> 
> [...]
> > +				# Just inform the user of this occurrence, but
> > +				# don't flag it as an error
> > +				echo -n "INFO: symbol $syname is added but "
> > +				echo -n "patch has insuficient context "
> > +				echo -n "to determine the section name "
> > +				echo -n "please ensure the version is "
> > +				echo "EXPERIMENTAL"
> 
> For info, I think nowadays "printf" is preferred over "echo -n"
> But if you prefer "echo -n" for any reason, no problem.
> 
I prefer echo, just because its what I've always used.  I'm open to changing it
if there is a compelling reason to do so.

> [...]
> > +exit $exit_code
> > +
> > +
> 
> Ironically, this patch doesn't pass checkpatch test because of
> the trailing new lines.
> 
Patchwork reports only a single error:
https://patches.dpdk.org/patch/41139/

Is the CI checkpatch different from the checkpatch we provide here?  If so, why?

> [...]
> > +clean_tmp_files() {
> > +	echo $TMPINPUT | grep -q checkpaches
> 
> Two comments here.
> 
> Since TMPINPUT is not supposed to be overwritten by environment,
> I think it is better to make it lowercase (kind of convention).
> 
Sure

> What the grep is supposed to match?
The name of the temp file created.  TMPINPUT can take on two classes of values:
1) The name of a passed in patch file
2) The name of a temp file created to hold a patch streamed in on stdin

when we clean up on exit, we want to delete class 2, but never class 1, so we
match on the temp file root name 'checkpatch'

> (side note, there is a typo: checkpaches -> checkpatches)
will fix

> Is it to remove file only in case of mktemp?
yes

> I think it is a risky pattern matching. I suggest '^checkpatches\.'
fine

> 
> > +	if [ $? -eq 0 ]; then
> 
> Could be easier to read if combining "if" and "grep":
> 	if echo $tmpinput | grep -q '^checkpatches\.' ; then
That seems fairly out of line with the style of the rest of the file

> 
> > +		rm -f $TMPINPUT
> > +	fi
> > +}
> 
> [...]
> > +		TMPINPUT=$(mktemp checkpatches.XXXXXX)
> 
> Open to discussion: do we prefer local dir or /tmp?
> Some tools are using /tmp.
> 
I don't think thats our call.  If an end user wants to specify the location of
temp files, they can do so by setting $TMPDIR.  We don't need to mandate it.

> [...]
> > +	report=$($DPDK_CHECKPATCH_PATH $options $TMPINPUT 2>/dev/null)
> > +
> 
> Please, no blank line between command and test.
> 
very well

> > +	if [ $? -ne 0 ]
> > +	then
> > +		$verbose || printf '\n### %s\n\n' "$3"
> > +		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
> > +		ret=1
> > +	fi
> > +
> > +	! $verbose || printf '\nChecking API additions/removals:\n'
> > +
> > +	report=$($VALIDATE_NEW_API "$TMPINPUT")
> > +
> 
> Same comments about blank lines.
> 
> > +	if [ $? -ne 0 ]; then
> > +		printf '%s\n' "$report"
> > +		ret=1
> > +	fi
> > +
> > +	clean_tmp_files
> > +	if [ $ret -eq 0 ]; then
> > +		return 0
> >  	fi
> > -	[ $? -ne 0 ] || return 0
> 
> Why replacing this oneliner by a longer "if" block?
> 
Because it was in keeping with the style that I was working with.  I can revert
it

> After this review, I think I won't have any more comment.
> Thanks Neil
> 
> 
> 

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v9] checkpatches.sh: Add checks for ABI symbol addition
                     ` (2 preceding siblings ...)
  2018-06-14 13:30  6% ` [dpdk-dev] [PATCH v8] " Neil Horman
@ 2018-06-27 18:01  6% ` Neil Horman
  3 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-06-27 18:01 UTC (permalink / raw)
  To: dev
  Cc: Neil Horman, thomas, john.mcnamara, bruce.richardson,
	Ferruh Yigit, Stephen Hemminger

Recently, some additional patches were added to allow for programmatic
marking of C symbols as experimental.  The addition of these markers is
dependent on the manual addition of exported symbols to the EXPERIMENTAL
section of the corresponding libraries version map file.  The consensus
on review is that, in addition to mandating the addition of symbols to
the EXPERIMENTAL version in the map, we need a mechanism to enforce our
documented process of mandating that addition when they are introduced.
To that end, I am proposing this change.  It is an addition to the
checkpatches script, which scan incoming patches for additions and
removals of symbols to the map file, and warns the user appropriately

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: thomas@monjalon.net
CC: john.mcnamara@intel.com
CC: bruce.richardson@intel.com
CC: Ferruh Yigit <ferruh.yigit@intel.com>
CC: Stephen Hemminger <stephen@networkplumber.org>

---
Change notes

v2)
 * Cleaned up and documented awk script (shemminger)
 * fixed sort/uniq usage (shemminger)
 * moved checking to new script (tmonjalon)
 * added maintainer entry (tmonjalon)
 * added license (tmonjalon)

v3)
 * Changed symbol check script name (tmonjalon)
 * Trapped exit to clean temp file (tmonjalon)
 * Honored verbose command (tmonjalon)
 * Cleaned left over debug bits (tmonjalon)
 * Updated location in MAINTAINERS file (tmonjalon)

v4)
 * Updated maintainers file (tmonjalon)

v5)
 * undo V4 (tmojalon)

v6)
 * Cleaning up more nits (tmonjalon)
 * Combining some lines (tmonjalon)
 * Fixing error print condition (tmonjalon)
 * Redirect stdin to a file to allow rewinding for
   Multiple passes on tools (nhorman)

v7)
 * More nits (tmonjalon)
 * consoloidating some common report lines (tmonjalon)
 * move SPDX identifier to line 2 (nhorman)
 * fix some checkpatch errors

v8)
 * spelling fix (nhorman)
 * found a way to eliminate the use of filterdiff (new awk rules)

v9)
 * various nits
---
 MAINTAINERS                     |   1 +
 devtools/check-symbol-change.sh | 159 ++++++++++++++++++++++++++++++++
 devtools/checkpatches.sh        |  47 ++++++++--
 3 files changed, 200 insertions(+), 7 deletions(-)
 create mode 100755 devtools/check-symbol-change.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 4667fa7fb..7b1180fe0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -122,6 +122,7 @@ M: Neil Horman <nhorman@tuxdriver.com>
 F: lib/librte_compat/
 F: doc/guides/rel_notes/deprecation.rst
 F: devtools/validate-abi.sh
+F: devtools/check-symbol-change.sh
 F: buildtools/check-experimental-syms.sh
 
 Driver information
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
new file mode 100755
index 000000000..17d123cf4
--- /dev/null
+++ b/devtools/check-symbol-change.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
+
+build_map_changes()
+{
+	local fname=$1
+	local mapdb=$2
+
+	cat $fname | awk '
+		# Initialize our variables
+		BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
+
+		# Anything that starts with + or -, followed by an a
+		# and ends in the string .map is the name of our map file
+		# This may appear multiple times in a patch if multiple
+		# map files are altered, and all section/symbol names
+		# appearing between a triggering of this rule and the
+		# next trigger of this rule are associated with this file
+		/[-+] a\/.*\.map/ {map=$2; in_map=1}
+
+		# Same pattern as above, only it matches on anything that
+		# doesnt end in 'map', indicating we have left the map chunk.
+		# When we hit this, turn off the in_map variable, which
+		# supresses the subordonate rules below
+		/[-+] a\/.*\.^(map)/ {in_map=0}
+
+		# Triggering this rule, which starts a line with a + and ends it
+		# with a { identifies a versioned section.  The section name is
+		# the rest of the line with the + and { symbols remvoed.
+		# Triggering this rule sets in_sec to 1, which actives the
+		# symbol rule below
+		/+.*{/ {gsub("+","");
+			if (in_map == 1) {
+				sec=$1; in_sec=1;
+			}
+		}
+
+		# This rule idenfies the end of a section, and disables the
+		# symbol rule
+		/.*}/ {in_sec=0}
+
+		# This rule matches on a + followed by any characters except a :
+		# (which denotes a global vs local segment), and ends with a ;.
+		# The semicolon is removed and the symbol is printed with its
+		# association file name and version section, along with an
+		# indicator that the symbol is a new addition.  Note this rule
+		# only works if we have found a version section in the rule
+		# above (hence the in_sec check) And found a map file (the
+		# in_map check).  If we are not in a map chunk, do nothing.  If
+		# we are in a map chunk but not a section chunk, record it as
+		# unknown.
+		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " add"
+				} else {
+					print map " " sym " unknown add"
+				}
+			}
+		}
+
+		# This is the same rule as above, but the rule matches on a
+		# leading - rather than a +, denoting that the symbol is being
+		# removed.
+		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " del"
+				} else {
+					print map " " sym " unknown del"
+				}
+			}
+		}' > ./$mapdb
+
+		sort -u $mapdb > ./$mapdb.2
+		mv -f $mapdb.2 $mapdb
+
+}
+
+check_for_rule_violations()
+{
+	local mapdb=$1
+	local mname
+	local symname
+	local secname
+	local ar
+	local ret=0
+
+	while read mname symname secname ar
+	do
+		if [ "$ar" == "add" ]
+		then
+
+			if [ "$secname" == "unknown" ]
+			then
+				# Just inform the user of this occurrence, but
+				# don't flag it as an error
+				echo -n "INFO: symbol $syname is added but "
+				echo -n "patch has insuficient context "
+				echo -n "to determine the section name "
+				echo -n "please ensure the version is "
+				echo "EXPERIMENTAL"
+				continue
+			fi
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Symbols that are getting added in a section
+				# other than the experimental section
+				# to be moving from an already supported
+				# section or its a violation
+				grep -q \
+				"$mname $symname [^EXPERIMENTAL] del" $mapdb
+				if [ $? -ne 0 ]
+				then
+					echo -n "ERROR: symbol $symname "
+					echo -n "is added in a section "
+					echo -n "other than the EXPERIMENTAL "
+					echo "section of the version map"
+					ret=1
+				fi
+			fi
+		else
+
+			if [ "$secname" != "EXPERIMENTAL" ]
+			then
+				# Just inform users that non-experimenal
+				# symbols need to go through a deprecation
+				# process
+				echo -n "INFO: symbol $symname is being "
+				echo -n "removed, ensure that it has "
+				echo "gone through the deprecation process"
+			fi
+		fi
+	done < $mapdb
+
+	return $ret
+}
+
+trap clean_and_exit_on_sig EXIT
+
+mapfile=`mktemp mapdb.XXXXXX`
+patch=$1
+exit_code=1
+
+clean_and_exit_on_sig()
+{
+	rm -f $mapfile
+	exit $exit_code
+}
+
+build_map_changes $patch $mapfile
+check_for_rule_violations $mapfile
+exit_code=$?
+
+rm -f $mapfile
+
+exit $exit_code
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 663b7c426..c6c7bfae1 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -7,6 +7,9 @@
 # - DPDK_CHECKPATCH_LINE_LENGTH
 . $(dirname $(readlink -e $0))/load-devel-config
 
+
+VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
+
 length=${DPDK_CHECKPATCH_LINE_LENGTH:-80}
 
 # override default Linux options
@@ -21,6 +24,15 @@ SPLIT_STRING,LONG_LINE_STRING,\
 LINE_SPACING,PARENTHESIS_ALIGNMENT,NETWORKING_BLOCK_COMMENT_STYLE,\
 NEW_TYPEDEFS,COMPARISON_TO_NULL"
 
+clean_tmp_files() {
+	echo $tmpinput | grep -q '^checkpatches\.'
+	if [ $? -eq 0 ]; then
+		rm -f $tmpinput
+	fi
+}
+
+trap "clean_tmp_files" SIGINT
+
 print_usage () {
 	cat <<- END_OF_HELP
 	usage: $(basename $0) [-q] [-v] [-nX|patch1 [patch2] ...]]
@@ -58,19 +70,40 @@ total=0
 status=0
 
 check () { # <patch> <commit> <title>
+	local ret=0
+
 	total=$(($total + 1))
 	! $verbose || printf '\n### %s\n\n' "$3"
 	if [ -n "$1" ] ; then
-		report=$($DPDK_CHECKPATCH_PATH $options "$1" 2>/dev/null)
+		tmpinput=$1
 	elif [ -n "$2" ] ; then
-		report=$(git format-patch --find-renames --no-stat --stdout -1 $commit |
-			$DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		tmpinput=$(mktemp checkpatches.XXXXXX)
+		git format-patch --find-renames \
+		--no-stat --stdout -1 $commit > ./$tmpinput
 	else
-		report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
+		tmpinput=$(mktemp checkpatches.XXXXXX)
+		cat > ./$tmpinput
 	fi
-	[ $? -ne 0 ] || return 0
-	$verbose || printf '\n### %s\n\n' "$3"
-	printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+
+	report=$($DPDK_CHECKPATCH_PATH $options $tmpinput 2>/dev/null)
+	if [ $? -ne 0 ]
+	then
+		$verbose || printf '\n### %s\n\n' "$3"
+		printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+		ret=1
+	fi
+
+	! $verbose || printf '\nChecking API additions/removals:\n'
+
+	report=$($VALIDATE_NEW_API "$tmpinput")
+	if [ $? -ne 0 ]; then
+		printf '%s\n' "$report"
+		ret=1
+	fi
+
+	clean_tmp_files
+	[ $ret -eq 0 ] && return 0
+
 	status=$(($status + 1))
 }
 
-- 
2.17.1

^ permalink raw reply	[relevance 6%]

* [dpdk-dev] [PATCH v2 1/2] compressdev: replace mbuf scatter gather flag
  2018-06-27  5:50  4% [dpdk-dev] [PATCH 1/2] compressdev: replace mbuf scatter gather flag Pablo de Lara
@ 2018-06-27 12:16  4% ` Pablo de Lara
  0 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-27 12:16 UTC (permalink / raw)
  To: fiona.trahe, ashish.gupta, lee.daly; +Cc: dev, Pablo de Lara

The current mbuf scatter gather feature flag is
too ambiguous, as it is not clear if input and/or output
buffers can be scatter gather mbufs or not.

Therefore, three new flags will replace this flag:
- RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT
- RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT
- RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT

Note that out-of-place flat buffers is supported by default
and in-place is not supported by the library.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---

Changes in v2:
- Fixed typos
- Rephrased comments

 doc/guides/rel_notes/release_18_08.rst |  6 ++++++
 lib/librte_compressdev/rte_comp.c      |  8 ++++++--
 lib/librte_compressdev/rte_comp.h      | 30 ++++++++++++++++++++----------
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..18c8b4bd1 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -60,6 +60,12 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* compressdev: Feature flag ``RTE_COMP_FF_MBUF_SCATTER_GATHER`` is
+  replaced with the following more explicit flags:
+  - ``RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT``
+  - ``RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT``
+  - ``RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT``
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_compressdev/rte_comp.c b/lib/librte_compressdev/rte_comp.c
index d596ba872..ea7692ae7 100644
--- a/lib/librte_compressdev/rte_comp.c
+++ b/lib/librte_compressdev/rte_comp.c
@@ -14,8 +14,12 @@ rte_comp_get_feature_name(uint64_t flag)
 		return "STATEFUL_COMPRESSION";
 	case RTE_COMP_FF_STATEFUL_DECOMPRESSION:
 		return "STATEFUL_DECOMPRESSION";
-	case RTE_COMP_FF_MBUF_SCATTER_GATHER:
-		return "MBUF_SCATTER_GATHER";
+	case RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT:
+		return "OUT_OF_PLACE_SGL_IN_SGL_OUT";
+	case RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT:
+		return "OUT_OF_PLACE_SGL_IN_FB_OUT";
+	case RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT:
+		return "OUT_OF_PLACE_FB_IN_SGL_OUT";
 	case RTE_COMP_FF_MULTI_PKT_CHECKSUM:
 		return "MULTI_PKT_CHECKSUM";
 	case RTE_COMP_FF_ADLER32_CHECKSUM:
diff --git a/lib/librte_compressdev/rte_comp.h b/lib/librte_compressdev/rte_comp.h
index 5b513c77e..f3742dafb 100644
--- a/lib/librte_compressdev/rte_comp.h
+++ b/lib/librte_compressdev/rte_comp.h
@@ -30,23 +30,33 @@ extern "C" {
 /**< Stateful compression is supported */
 #define RTE_COMP_FF_STATEFUL_DECOMPRESSION	(1ULL << 1)
 /**< Stateful decompression is supported */
-#define	RTE_COMP_FF_MBUF_SCATTER_GATHER		(1ULL << 2)
-/**< Scatter-gather mbufs are supported */
-#define RTE_COMP_FF_ADLER32_CHECKSUM		(1ULL << 3)
+#define RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT	(1ULL << 2)
+/**< Out-of-place Scatter-gather (SGL) mbufs are
+ * supported in input and output
+ */
+#define RTE_COMP_FF_OUT_OF_PLACE_SGL_IN_FB_OUT	(1ULL << 3)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in input, combined with flat buffers (FB) in output
+ */
+#define RTE_COMP_FF_OUT_OF_PLACE_FB_IN_SGL_OUT	(1ULL << 4)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in output, combined with flat buffers (FB) in input
+ */
+#define RTE_COMP_FF_ADLER32_CHECKSUM		(1ULL << 5)
 /**< Adler-32 Checksum is supported */
-#define RTE_COMP_FF_CRC32_CHECKSUM		(1ULL << 4)
+#define RTE_COMP_FF_CRC32_CHECKSUM		(1ULL << 6)
 /**< CRC32 Checksum is supported */
-#define RTE_COMP_FF_CRC32_ADLER32_CHECKSUM	(1ULL << 5)
+#define RTE_COMP_FF_CRC32_ADLER32_CHECKSUM	(1ULL << 7)
 /**< Adler-32/CRC32 Checksum is supported */
-#define RTE_COMP_FF_MULTI_PKT_CHECKSUM		(1ULL << 6)
+#define RTE_COMP_FF_MULTI_PKT_CHECKSUM		(1ULL << 8)
 /**< Generation of checksum across multiple stateless packets is supported */
-#define RTE_COMP_FF_SHA1_HASH			(1ULL << 7)
+#define RTE_COMP_FF_SHA1_HASH			(1ULL << 9)
 /**< SHA1 Hash is supported */
-#define RTE_COMP_FF_SHA2_SHA256_HASH		(1ULL << 8)
+#define RTE_COMP_FF_SHA2_SHA256_HASH		(1ULL << 10)
 /**< SHA256 Hash of SHA2 family is supported */
-#define RTE_COMP_FF_NONCOMPRESSED_BLOCKS	(1ULL << 9)
+#define RTE_COMP_FF_NONCOMPRESSED_BLOCKS	(1ULL << 11)
 /**< Creation of non-compressed blocks using RTE_COMP_LEVEL_NONE is supported */
-#define RTE_COMP_FF_SHAREABLE_PRIV_XFORM	(1ULL << 10)
+#define RTE_COMP_FF_SHAREABLE_PRIV_XFORM	(1ULL << 12)
 /**< Private xforms created by the PMD can be shared
  * across multiple stateless operations. If not set, then app needs
  * to create as many priv_xforms as it expects to have stateless
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] cryptodev: fix ABI breakage
  2018-06-13 10:00  4% ` Gujjar, Abhinandan S
@ 2018-06-27 21:14  4%   ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2018-06-27 21:14 UTC (permalink / raw)
  To: Gujjar, Abhinandan S, Doherty, Declan; +Cc: dev, stable



> -----Original Message-----
> From: Gujjar, Abhinandan S
> Sent: Wednesday, June 13, 2018 11:01 AM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Doherty, Declan
> <declan.doherty@intel.com>
> Cc: dev@dpdk.org; stable@dpdk.org
> Subject: RE: [PATCH] cryptodev: fix ABI breakage
> 
> 
> 
> > -----Original Message-----
> > From: De Lara Guarch, Pablo
> > Sent: Wednesday, June 13, 2018 3:07 PM
> > To: Doherty, Declan <declan.doherty@intel.com>; Gujjar, Abhinandan S
> > <abhinandan.gujjar@intel.com>
> > Cc: dev@dpdk.org; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; stable@dpdk.org
> > Subject: [PATCH] cryptodev: fix ABI breakage
> >
> > In 17.08, the crypto operation was restructured, and some reserved
> > bytes (5) were added  to have the mempool pointer aligned to 64 bits,
> > since the structure is expected to be aligned to 64 bits, allowing
> > future additions with no ABI breakage needed.
> >
> > In 18.05, a new 2-byte field was added, so the reserved bytes were reduced to
> 3.
> > However, this field was added after the first 3 bytes of the
> > structure, causing it to be placed in an offset of 4 bytes, and
> > therefore, forcing the mempool pointer to be placed after 16 bytes,
> > instead of a 8 bytes, causing unintentionally the ABI breakage.
> >
> > This commit fixes the breakage, by swapping the reserved bytes and the
> > private_data_offset field, so the latter is aligned to 2 bytes and the
> > offset of the mempool pointer returns to its original offset,
> > 8 bytes.
> >
> > Fixes: 54c836846603 ("cryptodev: set private data for session-less
> > mode")
> > Cc: stable@dpdk.org
> >
> > Reported-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

...

> Acked-by: Abhinandan Gujjar <Abhinandan.gujjar@intel.com>
> 
> > 2.17.0

Applied to dpdk-next-crypto.

Pablo

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v5 00/24] enable hotplug on multi-process
      @ 2018-06-28  1:49  1% ` Qi Zhang
  2018-06-28  1:50  4%   ` [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug Qi Zhang
  2018-06-28  1:52  1% ` [dpdk-dev] [PATCH v6 00/19] enable hotplug on multi-process Qi Zhang
  3 siblings, 1 reply; 200+ results
From: Qi Zhang @ 2018-06-28  1:49 UTC (permalink / raw)
  To: thomas, anatoly.burakov
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati, Qi Zhang

v6:
- remove bus->scan_one, since ABI break is not necessary.
- remove patch for failsafe PMD since it will not support secondary.
- fix wrong implemenation on ixgbe.
- add rte_eth_dev_release_port_private into rte_eth_dev_pci_generic_remove for
  secondary process, so we don't need to patch on PMD if PMD use the
  default remove function.
- add release notes update.

v5:
- since we will keep mp thread separate from interrupt thread,
  it is not necessary to use temporary thread, we use rte_eal_alarm_set.
- remove the change in rte_eth_dev_release_port, since there is a better
  way to prevent rte_eth_dev_release_port be called after
  rte_eth_dev_release_port_private.
- fix the issue that lock does not take effect on secondary due to
  previous re-work
- fix the issue when the first attached device is a private device from
  secondary. (patch 8/24)
- work around for reply a sync request in separate thread, this is still
  an open and in discussion as below.
  https://mails.dpdk.org/archives/dev/2018-June/105359.html

v4:
- since mp thread will be merged to interrupt thread, the fix on v3
  for sync IPC deadlock will not work. the new version enable the
  machanism to invoke a mp action callback in a temporary thread to
  avoid the IPC deadlock, with this, secondary to primary request
  impelemtation also be simplified, since we can use sync request
  directly in a separate thread.

v3:
- enable mp init callback register to help non-eal module to initialize
  mp channel during rte_eal_init
- fix when attach share device from secondary.
  1) dead lock due to sync IPC be invoked in rte_malloc in primary
     process when handle secondary request to attach device, the
     solution is primary process to issue share device attach/detach
     in interrupt thread.
  2) return port_id not correct.
- check nb_sent and nb_received in sync IPC.
- fix memory leak duirng error handling at attach_on_secondary.
- improve clean_lock_callback to only lock/unlock spinlock once
- improve error code return in check-reply during async IPC.
- remove rte_ prefix of internal function in ethdev_mp.c
- sample code improvement.
  1) rename sample to "hotplug_mp", and move to example/multi-process.
  2) cleanup header include.
  3) call rte_eal_cleanup before exit.

v2:
- rename rte_ethdev_mp.* to ethdev_mp.*
- rename rte_ethdev_lock.* to ethdev_lock.*
- move internal funciton to ethdev_private.h
- separate rte_eth_dev_[un]lock into rte_eth_dev_[un]lock and
  rte_eth_dev_[un]lock_with_callback
- lock callbacks will be removed automatically after device is detached.
- add experimental tag for all new APIs.
- fix coding style issue.
- fix wrong lisence header in sample code.
- fix spelling 
- fix meson.build.
- improve comments. 

Background:
===========

Currently secondary process will only sync ethdev from primary
process at init stage, but it will not be aware if device
is attached/detached on primary process at runtime.

While there is the requirement from application that take
primary-secondary process model. The primary process work as a
resource management process, it will create/destroy virtual device
at runtime, while the secondary process deal with the network stuff
with these devices.

Solution:
=========

So the orignial intention is to fix this gap, but beyond that
the patch set provide a more comprehesive solution to handle
different hotplug cases in multi-process situation, it cover below
scenario:

1. Attach a share device from primary
2. Detach a share device from primary
3. Attach a share device from secondary
4. Detach a share device from secondary
5. Attach a private device from secondary
6. Detach a private device from secondary
7. Detach a share device from secondary privately
8. Attach a share device from secondary privately

In primary-secondary process model, we assume ethernet devices are
shared by default. that means attach or detach a device on any process
will broadcast to all other processes through mp channel then device
information will be synchronized on all processes.

Any failure during attaching process will cause inconsistent status
between processes, so proper rollback action should be considered.
Also, it is not safe to detach a share device when other process still
use it, so a handshake mechanism is introduced.

Scenario for Case 1, 2:

attach device from primary
a) primary attach the new device if failed goto h).
b) primary send attach sync request to all secondary.
c) secondary receive request and attach device and send reply.
d) primary check the reply if all success go to i).
e) primary send attach rollback sync request to all secondary.
f) secondary receive the request and detach device and send reply.
g) primary receive the reply and detach device as rollback action.
h) attach fail
i) attach success

detach device from primary
a) primary perform pre-detach check, if device is locked, goto i).
b) primary send pre-detach sync request to all secondary.
c) secondary perform pre-detach check and send reply.
d) primary check the reply if any fail goto i).
e) primary send detach sync request to all secondary
f) secondary detach the device and send reply (assume no fail)
g) primary detach the device.
h) detach success
i) detach failed

Scenario for case 3, 4:

attach device from secondary:
a) seconary send asycn request to primary and wait on a condition
   which will be released by matched response from primary.
b) primary receive the request and attach the new device if failed
   goto i).
c) primary forward attach request to all secondary as async request
   (because this in mp thread context, use sync request will deadlock,
    same reason for all following async request.)
d) secondary receive request and attach device and send reply.
e) primary check the reply if all success go to j).
f) primary send attach rollback async request to all secondary.
g) secondary receive the request and detach device and send reply.
h) primary receive the reply and detach device as rollback action.
i) send fail response to secondary, goto k).
j) send success response to secondary.
k) secondary process receive response and return.
 
detach device from secondary:
a) secondary send async request to primary and wait on a condition
   which will be released by matched response from primary.
b) primary receive the request and  perform pre-detach check, if device
   is locked, goto j).
c) primary send pre-detach async request to all secondary.
d) secondary perform pre-detach check and send reply.
e) primary check the reply if any fail goto j).
f) primary send detach async request to all secondary
g) secondary detach the device and send reply
h) primary detach the device.
i) send success response to secondary, goto k).
j) send fail response to secondary.
k) secondary process receive response and return.

Case 5, 6:
Secondary process can attach private device which only visible to
itself, in this case no IPC is involved, primary process is not allowed
to have private device so far.

Case 7, 8:
Secondary process can also temporally to detach a share device
"privately" then attach it back later, this action also not impact other
processes.

APIs chenages:
==============

rte_eth_dev_attach and rte_eth_dev_attach are extended to support
share device attach/detach in primary-secondary process model, it will
be called in case 1,2,3,4.

New API rte_eth_dev_attach_private and rte_eth_dev_detach_private are
introduced to cover case 5,6,7,8, this API can only be invoked in
secondary process.

New API rte_eth_dev_lock and rte_eth_dev_unlock are introduced to let
application lock or unlock on specific ethdev, a locked device
can't be detached. This help applicaiton to prevent unexpected
device detaching, especially in multi-process envrionment.
Aslo the new API let application to register a callback function
which will be invoked before a device is going to be detached,
the return value of the function will decide if device will continue
be detached or not, this support application to do condition check
at runtime.

PMD Impact:
===========

Currently device removing is not handled well in secondary process on
most pmd drivers, rte_eth_dev_relase_port will be invoked and will mess up
primary process since it reset all shared data. So we introduced new API
rte_eth_dev_release_port_local which only reset ethdev's state to unsued
but not touch shared data so other process will not be impacted.
Since not all device driver is target to support primary-secondary
process model, so the patch set only fix this on all Intel devices and
vdev, it can be refereneced by other driver when equevalent fix is
required

Limitation:
===========

1. The solution does not cover the case that primary process exit while
   secondary processes still be active. Though this is not a typial use
   case, but if this happens:
   a. secondary process can't attach / detach any shared device since no
      primary exist.
   b. secondary process still can attach / detach private device.
   c. secondary process still can detach a share device privately but may
      not attach it back, that ethdev slot will become zombie slot.

2. So for, for PCI bus, case 5,6 is not supported. PCI bus scan/probe
   mechanism can be improved to support attach private device on secondary
   process, but this is not the scope of this patchset.

Example:
========

The patchset also contains a example to demonstrate device hotplug
in multi-process model, below are detail instructions.

/* start sample code as primary then secondary */
./hotplug_mp --proc-type=auto

Command Line Example:

>help
>list

/* attach a af_packet vdev */
>attach net_af_packet,iface=eth0

/* detach port 0 */
>detach 0

/* attach a private af_packet vdev (secondary process only)*/
>attachp net_af_packet,iface=eth0

/* detach a private device (secondary process only) */
>detachp 0

/* lock port 0 */
>lock 0

/* unlock port 0 */
>unlock 0

Qi Zhang (19):
  ethdev: add function to release port in local process
  eal: enable multi process init callback
  ethdev: enable hotplug on multi-process
  ethdev: introduce device lock
  ethdev: support attach or detach share device from secondary
  ethdev: support attach private device as first
  net/i40e: enable port detach on secondary process
  net/ixgbe: enable port detach on secondary process
  net/af_packet: enable port detach on secondary process
  net/bonding: enable port detach on secondary process
  net/kni: enable port detach on secondary process
  net/null: enable port detach on secondary process
  net/octeontx: enable port detach on secondary process
  net/pcap: enable port detach on secondary process
  net/softnic: enable port detach on secondary process
  net/tap: enable port detach on secondary process
  net/vhost: enable port detach on secondary process
  examples/multi_process: add hotplug sample
  doc: update release notes for multi process hotplug

 doc/guides/rel_notes/release_18_08.rst       |  21 ++
 drivers/net/af_packet/rte_eth_af_packet.c    |  11 +
 drivers/net/bonding/rte_eth_bond_pmd.c       |  11 +
 drivers/net/i40e/i40e_ethdev.c               |   2 +
 drivers/net/ixgbe/ixgbe_ethdev.c             |   3 +
 drivers/net/kni/rte_eth_kni.c                |  11 +
 drivers/net/null/rte_eth_null.c              |  16 +-
 drivers/net/octeontx/octeontx_ethdev.c       |  16 ++
 drivers/net/pcap/rte_eth_pcap.c              |  15 +-
 drivers/net/softnic/rte_eth_softnic.c        |  19 +-
 drivers/net/tap/rte_eth_tap.c                |  17 +-
 drivers/net/vhost/rte_eth_vhost.c            |  11 +
 examples/multi_process/Makefile              |   1 +
 examples/multi_process/hotplug_mp/Makefile   |  23 ++
 examples/multi_process/hotplug_mp/commands.c | 356 +++++++++++++++++++++++
 examples/multi_process/hotplug_mp/commands.h |  10 +
 examples/multi_process/hotplug_mp/main.c     |  41 +++
 lib/librte_eal/common/eal_common_proc.c      |  51 +++-
 lib/librte_eal/common/eal_private.h          |   5 +
 lib/librte_eal/common/include/rte_eal.h      |  34 +++
 lib/librte_eal/linuxapp/eal/eal.c            |   2 +
 lib/librte_ethdev/Makefile                   |   2 +
 lib/librte_ethdev/ethdev_lock.c              | 140 +++++++++
 lib/librte_ethdev/ethdev_lock.h              |  31 ++
 lib/librte_ethdev/ethdev_mp.c                | 415 +++++++++++++++++++++++++++
 lib/librte_ethdev/ethdev_mp.h                |  42 +++
 lib/librte_ethdev/ethdev_private.h           |  42 +++
 lib/librte_ethdev/meson.build                |   2 +
 lib/librte_ethdev/rte_ethdev.c               | 312 ++++++++++++++++++--
 lib/librte_ethdev/rte_ethdev.h               | 169 +++++++++++
 lib/librte_ethdev/rte_ethdev_core.h          |   5 +
 lib/librte_ethdev/rte_ethdev_driver.h        |  13 +
 lib/librte_ethdev/rte_ethdev_pci.h           |   3 +
 33 files changed, 1815 insertions(+), 37 deletions(-)
 create mode 100644 examples/multi_process/hotplug_mp/Makefile
 create mode 100644 examples/multi_process/hotplug_mp/commands.c
 create mode 100644 examples/multi_process/hotplug_mp/commands.h
 create mode 100644 examples/multi_process/hotplug_mp/main.c
 create mode 100644 lib/librte_ethdev/ethdev_lock.c
 create mode 100644 lib/librte_ethdev/ethdev_lock.h
 create mode 100644 lib/librte_ethdev/ethdev_mp.c
 create mode 100644 lib/librte_ethdev/ethdev_mp.h
 create mode 100644 lib/librte_ethdev/ethdev_private.h

-- 
2.13.6

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug
  2018-06-28  1:49  1% ` [dpdk-dev] [PATCH v5 00/24] enable hotplug on multi-process Qi Zhang
@ 2018-06-28  1:50  4%   ` Qi Zhang
  0 siblings, 0 replies; 200+ results
From: Qi Zhang @ 2018-06-28  1:50 UTC (permalink / raw)
  To: thomas, anatoly.burakov
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati, Qi Zhang

Update release notes for the new multi process hotplug feature.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 doc/guides/rel_notes/release_18_08.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..fc4736814 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -46,6 +46,20 @@ New Features
   Flow API support has been added to CXGBE Poll Mode Driver to offload
   flows to Chelsio T5/T6 NICs.
 
+* **Support ethernet device hotplug for primary-secondary model.**
+
+  In primary-secondary process model, ethernet devices are regarded as shared
+  by default, attach or detach a device on any process will broadcast to
+  other processes through mp channel then device information will be
+  synchronzied on all processes. While secondary process can still attach
+  or detach a private device (vdev only) with specific API.
+
+* **Support ethernet device lock.**
+
+  An ethernet device can be directly or conditionally locked. A directly
+  locked device can't be detached, while when try to detach a conditionally
+  locked device a pre-registered callback will be invoked to perform condition
+  check and decide if it can be detached or not.
 
 API Changes
 -----------
@@ -60,6 +74,13 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: scope of rte_eth_dev_attach and rte_eth_dev_detach is extended.
+
+  In primary-secondary process model, ``rte_eth_dev_attach`` will guarantee that
+  device be attached on all processes, if any process failed to attach, it will
+  rollback to orignal status. ``rte_eth_dev_detach`` also guarantee device be
+  detached on all processes, if device is locked by any process, it will roll
+  back to original status.
 
 ABI Changes
 -----------
-- 
2.13.6

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v6 00/19] enable hotplug on multi-process
                     ` (2 preceding siblings ...)
  2018-06-28  1:49  1% ` [dpdk-dev] [PATCH v5 00/24] enable hotplug on multi-process Qi Zhang
@ 2018-06-28  1:52  1% ` Qi Zhang
  2018-06-28  1:52  4%   ` [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug Qi Zhang
  3 siblings, 1 reply; 200+ results
From: Qi Zhang @ 2018-06-28  1:52 UTC (permalink / raw)
  To: thomas, anatoly.burakov
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati, Qi Zhang

v6:
- remove bus->scan_one, since ABI break is not necessary.
- remove patch for failsafe PMD since it will not support secondary.
- fix wrong implemenation on ixgbe.
- add rte_eth_dev_release_port_private into rte_eth_dev_pci_generic_remove for
  secondary process, so we don't need to patch on PMD if PMD use the
  default remove function.
- add release notes update.

v5:
- since we will keep mp thread separate from interrupt thread,
  it is not necessary to use temporary thread, we use rte_eal_alarm_set.
- remove the change in rte_eth_dev_release_port, since there is a better
  way to prevent rte_eth_dev_release_port be called after
  rte_eth_dev_release_port_private.
- fix the issue that lock does not take effect on secondary due to
  previous re-work
- fix the issue when the first attached device is a private device from
  secondary. (patch 8/24)
- work around for reply a sync request in separate thread, this is still
  an open and in discussion as below.
  https://mails.dpdk.org/archives/dev/2018-June/105359.html

v4:
- since mp thread will be merged to interrupt thread, the fix on v3
  for sync IPC deadlock will not work. the new version enable the
  machanism to invoke a mp action callback in a temporary thread to
  avoid the IPC deadlock, with this, secondary to primary request
  impelemtation also be simplified, since we can use sync request
  directly in a separate thread.

v3:
- enable mp init callback register to help non-eal module to initialize
  mp channel during rte_eal_init
- fix when attach share device from secondary.
  1) dead lock due to sync IPC be invoked in rte_malloc in primary
     process when handle secondary request to attach device, the
     solution is primary process to issue share device attach/detach
     in interrupt thread.
  2) return port_id not correct.
- check nb_sent and nb_received in sync IPC.
- fix memory leak duirng error handling at attach_on_secondary.
- improve clean_lock_callback to only lock/unlock spinlock once
- improve error code return in check-reply during async IPC.
- remove rte_ prefix of internal function in ethdev_mp.c
- sample code improvement.
  1) rename sample to "hotplug_mp", and move to example/multi-process.
  2) cleanup header include.
  3) call rte_eal_cleanup before exit.

v2:
- rename rte_ethdev_mp.* to ethdev_mp.*
- rename rte_ethdev_lock.* to ethdev_lock.*
- move internal funciton to ethdev_private.h
- separate rte_eth_dev_[un]lock into rte_eth_dev_[un]lock and
  rte_eth_dev_[un]lock_with_callback
- lock callbacks will be removed automatically after device is detached.
- add experimental tag for all new APIs.
- fix coding style issue.
- fix wrong lisence header in sample code.
- fix spelling 
- fix meson.build.
- improve comments. 

Background:
===========

Currently secondary process will only sync ethdev from primary
process at init stage, but it will not be aware if device
is attached/detached on primary process at runtime.

While there is the requirement from application that take
primary-secondary process model. The primary process work as a
resource management process, it will create/destroy virtual device
at runtime, while the secondary process deal with the network stuff
with these devices.

Solution:
=========

So the orignial intention is to fix this gap, but beyond that
the patch set provide a more comprehesive solution to handle
different hotplug cases in multi-process situation, it cover below
scenario:

1. Attach a share device from primary
2. Detach a share device from primary
3. Attach a share device from secondary
4. Detach a share device from secondary
5. Attach a private device from secondary
6. Detach a private device from secondary
7. Detach a share device from secondary privately
8. Attach a share device from secondary privately

In primary-secondary process model, we assume ethernet devices are
shared by default. that means attach or detach a device on any process
will broadcast to all other processes through mp channel then device
information will be synchronized on all processes.

Any failure during attaching process will cause inconsistent status
between processes, so proper rollback action should be considered.
Also, it is not safe to detach a share device when other process still
use it, so a handshake mechanism is introduced.

Scenario for Case 1, 2:

attach device from primary
a) primary attach the new device if failed goto h).
b) primary send attach sync request to all secondary.
c) secondary receive request and attach device and send reply.
d) primary check the reply if all success go to i).
e) primary send attach rollback sync request to all secondary.
f) secondary receive the request and detach device and send reply.
g) primary receive the reply and detach device as rollback action.
h) attach fail
i) attach success

detach device from primary
a) primary perform pre-detach check, if device is locked, goto i).
b) primary send pre-detach sync request to all secondary.
c) secondary perform pre-detach check and send reply.
d) primary check the reply if any fail goto i).
e) primary send detach sync request to all secondary
f) secondary detach the device and send reply (assume no fail)
g) primary detach the device.
h) detach success
i) detach failed

Scenario for case 3, 4:

attach device from secondary:
a) seconary send asycn request to primary and wait on a condition
   which will be released by matched response from primary.
b) primary receive the request and attach the new device if failed
   goto i).
c) primary forward attach request to all secondary as async request
   (because this in mp thread context, use sync request will deadlock,
    same reason for all following async request.)
d) secondary receive request and attach device and send reply.
e) primary check the reply if all success go to j).
f) primary send attach rollback async request to all secondary.
g) secondary receive the request and detach device and send reply.
h) primary receive the reply and detach device as rollback action.
i) send fail response to secondary, goto k).
j) send success response to secondary.
k) secondary process receive response and return.
 
detach device from secondary:
a) secondary send async request to primary and wait on a condition
   which will be released by matched response from primary.
b) primary receive the request and  perform pre-detach check, if device
   is locked, goto j).
c) primary send pre-detach async request to all secondary.
d) secondary perform pre-detach check and send reply.
e) primary check the reply if any fail goto j).
f) primary send detach async request to all secondary
g) secondary detach the device and send reply
h) primary detach the device.
i) send success response to secondary, goto k).
j) send fail response to secondary.
k) secondary process receive response and return.

Case 5, 6:
Secondary process can attach private device which only visible to
itself, in this case no IPC is involved, primary process is not allowed
to have private device so far.

Case 7, 8:
Secondary process can also temporally to detach a share device
"privately" then attach it back later, this action also not impact other
processes.

APIs chenages:
==============

rte_eth_dev_attach and rte_eth_dev_attach are extended to support
share device attach/detach in primary-secondary process model, it will
be called in case 1,2,3,4.

New API rte_eth_dev_attach_private and rte_eth_dev_detach_private are
introduced to cover case 5,6,7,8, this API can only be invoked in
secondary process.

New API rte_eth_dev_lock and rte_eth_dev_unlock are introduced to let
application lock or unlock on specific ethdev, a locked device
can't be detached. This help applicaiton to prevent unexpected
device detaching, especially in multi-process envrionment.
Aslo the new API let application to register a callback function
which will be invoked before a device is going to be detached,
the return value of the function will decide if device will continue
be detached or not, this support application to do condition check
at runtime.

PMD Impact:
===========

Currently device removing is not handled well in secondary process on
most pmd drivers, rte_eth_dev_relase_port will be invoked and will mess up
primary process since it reset all shared data. So we introduced new API
rte_eth_dev_release_port_local which only reset ethdev's state to unsued
but not touch shared data so other process will not be impacted.
Since not all device driver is target to support primary-secondary
process model, so the patch set only fix this on all Intel devices and
vdev, it can be refereneced by other driver when equevalent fix is
required

Limitation:
===========

1. The solution does not cover the case that primary process exit while
   secondary processes still be active. Though this is not a typial use
   case, but if this happens:
   a. secondary process can't attach / detach any shared device since no
      primary exist.
   b. secondary process still can attach / detach private device.
   c. secondary process still can detach a share device privately but may
      not attach it back, that ethdev slot will become zombie slot.

2. So for, for PCI bus, case 5,6 is not supported. PCI bus scan/probe
   mechanism can be improved to support attach private device on secondary
   process, but this is not the scope of this patchset.

Example:
========

The patchset also contains a example to demonstrate device hotplug
in multi-process model, below are detail instructions.

/* start sample code as primary then secondary */
./hotplug_mp --proc-type=auto

Command Line Example:

>help
>list

/* attach a af_packet vdev */
>attach net_af_packet,iface=eth0

/* detach port 0 */
>detach 0

/* attach a private af_packet vdev (secondary process only)*/
>attachp net_af_packet,iface=eth0

/* detach a private device (secondary process only) */
>detachp 0

/* lock port 0 */
>lock 0

/* unlock port 0 */
>unlock 0

Qi Zhang (19):
  ethdev: add function to release port in local process
  eal: enable multi process init callback
  ethdev: enable hotplug on multi-process
  ethdev: introduce device lock
  ethdev: support attach or detach share device from secondary
  ethdev: support attach private device as first
  net/i40e: enable port detach on secondary process
  net/ixgbe: enable port detach on secondary process
  net/af_packet: enable port detach on secondary process
  net/bonding: enable port detach on secondary process
  net/kni: enable port detach on secondary process
  net/null: enable port detach on secondary process
  net/octeontx: enable port detach on secondary process
  net/pcap: enable port detach on secondary process
  net/softnic: enable port detach on secondary process
  net/tap: enable port detach on secondary process
  net/vhost: enable port detach on secondary process
  examples/multi_process: add hotplug sample
  doc: update release notes for multi process hotplug

 doc/guides/rel_notes/release_18_08.rst       |  21 ++
 drivers/net/af_packet/rte_eth_af_packet.c    |  11 +
 drivers/net/bonding/rte_eth_bond_pmd.c       |  11 +
 drivers/net/i40e/i40e_ethdev.c               |   2 +
 drivers/net/ixgbe/ixgbe_ethdev.c             |   3 +
 drivers/net/kni/rte_eth_kni.c                |  11 +
 drivers/net/null/rte_eth_null.c              |  16 +-
 drivers/net/octeontx/octeontx_ethdev.c       |  16 ++
 drivers/net/pcap/rte_eth_pcap.c              |  15 +-
 drivers/net/softnic/rte_eth_softnic.c        |  19 +-
 drivers/net/tap/rte_eth_tap.c                |  17 +-
 drivers/net/vhost/rte_eth_vhost.c            |  11 +
 examples/multi_process/Makefile              |   1 +
 examples/multi_process/hotplug_mp/Makefile   |  23 ++
 examples/multi_process/hotplug_mp/commands.c | 356 +++++++++++++++++++++++
 examples/multi_process/hotplug_mp/commands.h |  10 +
 examples/multi_process/hotplug_mp/main.c     |  41 +++
 lib/librte_eal/common/eal_common_proc.c      |  51 +++-
 lib/librte_eal/common/eal_private.h          |   5 +
 lib/librte_eal/common/include/rte_eal.h      |  34 +++
 lib/librte_eal/linuxapp/eal/eal.c            |   2 +
 lib/librte_ethdev/Makefile                   |   2 +
 lib/librte_ethdev/ethdev_lock.c              | 140 +++++++++
 lib/librte_ethdev/ethdev_lock.h              |  31 ++
 lib/librte_ethdev/ethdev_mp.c                | 415 +++++++++++++++++++++++++++
 lib/librte_ethdev/ethdev_mp.h                |  42 +++
 lib/librte_ethdev/ethdev_private.h           |  42 +++
 lib/librte_ethdev/meson.build                |   2 +
 lib/librte_ethdev/rte_ethdev.c               | 312 ++++++++++++++++++--
 lib/librte_ethdev/rte_ethdev.h               | 169 +++++++++++
 lib/librte_ethdev/rte_ethdev_core.h          |   5 +
 lib/librte_ethdev/rte_ethdev_driver.h        |  13 +
 lib/librte_ethdev/rte_ethdev_pci.h           |   3 +
 33 files changed, 1815 insertions(+), 37 deletions(-)
 create mode 100644 examples/multi_process/hotplug_mp/Makefile
 create mode 100644 examples/multi_process/hotplug_mp/commands.c
 create mode 100644 examples/multi_process/hotplug_mp/commands.h
 create mode 100644 examples/multi_process/hotplug_mp/main.c
 create mode 100644 lib/librte_ethdev/ethdev_lock.c
 create mode 100644 lib/librte_ethdev/ethdev_lock.h
 create mode 100644 lib/librte_ethdev/ethdev_mp.c
 create mode 100644 lib/librte_ethdev/ethdev_mp.h
 create mode 100644 lib/librte_ethdev/ethdev_private.h

-- 
2.13.6

^ permalink raw reply	[relevance 1%]

* [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug
  2018-06-28  1:52  1% ` [dpdk-dev] [PATCH v6 00/19] enable hotplug on multi-process Qi Zhang
@ 2018-06-28  1:52  4%   ` Qi Zhang
  0 siblings, 0 replies; 200+ results
From: Qi Zhang @ 2018-06-28  1:52 UTC (permalink / raw)
  To: thomas, anatoly.burakov
  Cc: konstantin.ananyev, dev, bruce.richardson, ferruh.yigit,
	benjamin.h.shelton, narender.vangati, Qi Zhang

Update release notes for the new multi process hotplug feature.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 doc/guides/rel_notes/release_18_08.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..fc4736814 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -46,6 +46,20 @@ New Features
   Flow API support has been added to CXGBE Poll Mode Driver to offload
   flows to Chelsio T5/T6 NICs.
 
+* **Support ethernet device hotplug for primary-secondary model.**
+
+  In primary-secondary process model, ethernet devices are regarded as shared
+  by default, attach or detach a device on any process will broadcast to
+  other processes through mp channel then device information will be
+  synchronzied on all processes. While secondary process can still attach
+  or detach a private device (vdev only) with specific API.
+
+* **Support ethernet device lock.**
+
+  An ethernet device can be directly or conditionally locked. A directly
+  locked device can't be detached, while when try to detach a conditionally
+  locked device a pre-registered callback will be invoked to perform condition
+  check and decide if it can be detached or not.
 
 API Changes
 -----------
@@ -60,6 +74,13 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: scope of rte_eth_dev_attach and rte_eth_dev_detach is extended.
+
+  In primary-secondary process model, ``rte_eth_dev_attach`` will guarantee that
+  device be attached on all processes, if any process failed to attach, it will
+  rollback to orignal status. ``rte_eth_dev_detach`` also guarantee device be
+  detached on all processes, if device is locked by any process, it will roll
+  back to original status.
 
 ABI Changes
 -----------
-- 
2.13.6

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] DPDK 18.05 only works with up to 4 NUMAs systems
  @ 2018-06-28  8:42  3%     ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-06-28  8:42 UTC (permalink / raw)
  To: Kumar, Ravi1, dev

On 28-Jun-18 8:03 AM, Kumar, Ravi1 wrote:
>> On 22-Jun-18 5:37 PM, Kumar, Ravi1 wrote:
>>> Hi,
>>>
>>> As the memory subsystem in DPDK 18.05 is reworked, it has introduced a problem for AMD EPYC 2P platforms.
>>> The issue is that DPDK 18.05 only works with up to 4 NUMAs. For AMD EPYC 2P platforms, DPDK now only works with P0 (NUMA 0-3) and does not work with P1 (NUMA 4-7).
>>>
>>> The problem can be fixed by reducing some of the default settings of the memory subsystem.
>>>
>>> To solve this issue:
>>> -              We can create our own config file for our integrated 10G NIC, that is for amd_xgbe PMD. This will make amd_xgbe immune to this problem.
>>> -              However, when any other NIC (Intel, Mellanox, Cavium or Broadcom etc.) is plugged into NUMA 4-7, the problem will still be exposed.
>>> -              If we only fix it in "config/common_base", it will cover all cases.
>>>
>>> Our current workaround is:
>>> Edit config file "./config/common_base" and change the following line
>>>                   CONFIG_RTE_MAX_MEM_MB_PER_TYPE=131072
>>> TO
>>>                   CONFIG_RTE_MAX_MEM_MB_PER_TYPE=65536
>>>
>>> Any better solution for this issue is welcome.
>>>
>>> We would appreciate if this issue can be fixed in the next release (18.08) so the STOCK version of DPDK works on AMD EPYC 2P platforms.
>>>
>>> Regards,
>>> Ravi
>>>
>>
>> Hi Ravi,
>>
>> What is the reason behind this limitation? Is it too much virtual memory being preallocated?
>>
>> --
>> Thanks,
>> Anatoly
>>
> Hi Anatoly,
> 
> We believe this is true.  By default, too much virtual memory is being preallocated. The result is it can only support up to 4 NUMAs.
> 
> Our workaround is to reduce the amount of preallocated virtual memory by half, so to support up to 8 NUMAs.
> 
> Regards,
> Ravi
> 

I assume you see a bunch of failed mmap() calls with ENOMEM?

In general, changing base config that way is an OK change, and it won't 
even be an ABI break since this memory is allocated at runtime. I just 
want to make sure that we fix the underlying problem, rather than the 
symptom.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3 01/16] cryptodev: replace bus specific struct with generic dev
  @ 2018-06-28  0:52  4%   ` Pablo de Lara
  2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 08/16] cryptodev: define value for unlimited sessions Pablo de Lara
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-28  0:52 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Structure rte_cryptodev_info has currently PCI device
information ("struct rte_pci_device") in it.

This information is not generic to all devices,
so this gets replaced with the generic "rte_device" structure,
compatible with all crypto devices.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/prog_guide/cryptodev_lib.rst  | 2 +-
 doc/guides/rel_notes/deprecation.rst     | 2 --
 doc/guides/rel_notes/release_18_08.rst   | 5 ++++-
 drivers/crypto/qat/qat_sym_pmd.c         | 1 -
 drivers/crypto/virtio/virtio_cryptodev.c | 1 -
 lib/librte_cryptodev/rte_cryptodev.c     | 1 +
 lib/librte_cryptodev/rte_cryptodev.h     | 6 +++---
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 30f0bcf7a..d02bb7514 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -269,7 +269,7 @@ relevant information for the device.
     struct rte_cryptodev_info {
         const char *driver_name;
         uint8_t driver_id;
-        struct rte_pci_device *pci_dev;
+        struct rte_device *device;
 
         uint64_t feature_flags;
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1ce692eac..b71080bb8 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -104,8 +104,6 @@ Deprecation Notices
   - Removal of ``sym`` structure in ``rte_cryptodev_info`` structure,
     containing fields not relevant anymore since the session mempool
     is not internal in the crypto device anymore.
-  - Replacement of ``pci_dev`` field with the more generic ``rte_device``
-    structure.
   - Functions ``rte_cryptodev_queue_pair_attach_sym_session()`` and
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..6bf53dc31 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -60,6 +60,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
+  has been replaced with field ``struct rte_device *device``.
+
 
 ABI Changes
 -----------
@@ -118,7 +121,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cmdline.so.2
      librte_common_octeontx.so.1
      librte_compressdev.so.1
-     librte_cryptodev.so.4
+   + librte_cryptodev.so.5
      librte_distributor.so.1
      librte_eal.so.7
      librte_ethdev.so.9
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index 115639089..0bc042a75 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -74,7 +74,6 @@ static void qat_sym_dev_info_get(struct rte_cryptodev *dev,
 		info->capabilities = internals->qat_dev_capabilities;
 		info->sym.max_nb_sessions = QAT_SYM_PMD_MAX_NB_SESSIONS;
 		info->driver_id = cryptodev_qat_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 	}
 }
 
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index df88953f6..482edea1a 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1409,7 +1409,6 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
 
 	if (info != NULL) {
 		info->driver_id = cryptodev_virtio_driver_id;
-		info->pci_dev = RTE_DEV_TO_PCI(dev->device);
 		info->feature_flags = dev->feature_flags;
 		info->max_nb_queue_pairs = hw->max_dataqueues;
 		info->sym.max_nb_sessions =
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 7e5821246..457ac5670 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -966,6 +966,7 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->driver_name = dev->device->driver->name;
+	dev_info->device = dev->device;
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index b7a4cf0a2..62a5566ba 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -342,9 +342,9 @@ rte_cryptodev_get_feature_name(uint64_t flag);
 
 /**  Crypto device information */
 struct rte_cryptodev_info {
-	const char *driver_name;		/**< Driver name. */
-	uint8_t driver_id;			/**< Driver identifier */
-	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	const char *driver_name;	/**< Driver name. */
+	uint8_t driver_id;		/**< Driver identifier */
+	struct rte_device *device;	/**< Generic device information. */
 
 	uint64_t feature_flags;
 	/**< Feature flags exposes HW/SW features for the given device */
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 12/16] cryptodev: remove old get session size functions
                       ` (2 preceding siblings ...)
  2018-06-28  0:52  2%   ` [dpdk-dev] [PATCH v3 11/16] cryptodev: remove queue start/stop functions Pablo de Lara
@ 2018-06-28  0:53  4%   ` Pablo de Lara
  2018-06-28  0:53  3%   ` [dpdk-dev] [PATCH v3 13/16] cryptodev: replace mbuf scatter gather flag Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-28  0:53 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed rte_cryptodev_get_header_session_size
and rte_cryptodev_get_private_session_size functions,
as they have been substituted with functions
specific for symmetric operations, with _sym_ word
after "rte_cryptodev_".

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst           |  6 ------
 doc/guides/rel_notes/release_18_08.rst         |  8 ++++++++
 lib/librte_cryptodev/rte_cryptodev.c           | 12 ------------
 lib/librte_cryptodev/rte_cryptodev.h           | 25 -------------------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
 5 files changed, 8 insertions(+), 45 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 91592534e..9a73b1d8e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -107,9 +107,3 @@ Deprecation Notices
     with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
-  - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_header_session_size()``.
-    It will be removed in 18.08.
-  - Function ``rte_cryptodev_get_private_session_size()`` will be deprecated
-    in 18.05, and it gets replaced with ``rte_cryptodev_sym_get_private_session_size()``.
-    It will be removed in 18.08.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index cfb2885a1..e482d3d5f 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -70,6 +70,14 @@ API Changes
   - ``rte_cryptodev_queue_pair_start``
   - ``rte_cryptodev_queue_pair_stop``
 
+* cryptodev: Following functions were deprecated and are replaced by
+  other functions in 18.08:
+
+  - ``rte_cryptodev_get_header_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_header_session_size``
+  - ``rte_cryptodev_get_private_session_size`` is replaced with
+    ``rte_cryptodev_sym_get_private_session_size``
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a07904fb9..381330f3d 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1181,12 +1181,6 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
 	return 0;
 }
 
-unsigned int
-rte_cryptodev_get_header_session_size(void)
-{
-	return rte_cryptodev_sym_get_header_session_size();
-}
-
 unsigned int
 rte_cryptodev_sym_get_header_session_size(void)
 {
@@ -1198,12 +1192,6 @@ rte_cryptodev_sym_get_header_session_size(void)
 	return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
 }
 
-unsigned int
-rte_cryptodev_get_private_session_size(uint8_t dev_id)
-{
-	return rte_cryptodev_sym_get_private_session_size(dev_id);
-}
-
 unsigned int
 rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index c94571ac1..fc491a83b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -906,31 +906,6 @@ int
 rte_cryptodev_sym_session_clear(uint8_t dev_id,
 			struct rte_cryptodev_sym_session *sess);
 
-/**
- * @deprecated
- * Get the size of the header session, for all registered drivers.
- *
- * @return
- *   Size of the header session.
- */
-__rte_deprecated
-unsigned int
-rte_cryptodev_get_header_session_size(void);
-
-/**
- * @deprecated
- * Get the size of the private session data for a device.
- *
- * @param	dev_id		The device identifier.
- *
- * @return
- *   - Size of the private data, if successful
- *   - 0 if device is invalid or does not have private session
- */
-__rte_deprecated
-unsigned int
-rte_cryptodev_get_private_session_size(uint8_t dev_id);
-
 /**
  * Get the size of the header session, for all registered drivers.
  *
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 020b45754..0ab6d5195 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -63,8 +63,6 @@ DPDK_17.08 {
 	rte_cryptodev_driver_id_get;
 	rte_cryptodev_driver_name_get;
 	rte_cryptodev_get_aead_algo_enum;
-	rte_cryptodev_get_header_session_size;
-	rte_cryptodev_get_private_session_size;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 08/16] cryptodev: define value for unlimited sessions
    2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 01/16] cryptodev: replace bus specific struct with generic dev Pablo de Lara
@ 2018-06-28  0:52  4%   ` Pablo de Lara
  2018-06-28  0:52  2%   ` [dpdk-dev] [PATCH v3 11/16] cryptodev: remove queue start/stop functions Pablo de Lara
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-28  0:52 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Currently, the info structure contains the maximum number
of sessions that a device can manage.
This field was useful when the session mempool was created inside
each device, but now it is created at the application level.

Most PMDs do not have a limitation on the sessions managed,
but a few do, therefore this field must remain in the structure.
However, a new value, 0, can be used to indicate that
a device does not have an actual maximum of sessions.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 app/test-crypto-perf/main.c            | 2 +-
 doc/guides/rel_notes/release_18_08.rst | 2 ++
 examples/ipsec-secgw/ipsec-secgw.c     | 2 +-
 lib/librte_cryptodev/rte_cryptodev.h   | 5 ++++-
 test/test/test_cryptodev.c             | 6 ++++--
 5 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index b02d3f597..87aaba0ce 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -169,7 +169,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
 		 * A single session is required per queue pair
 		 * in each device
 		 */
-		if (dev_max_nb_sess < opts->nb_qps) {
+		if (dev_max_nb_sess != 0 && dev_max_nb_sess < opts->nb_qps) {
 			RTE_LOG(ERR, USER1,
 				"Device does not support at least "
 				"%u sessions\n", opts->nb_qps);
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 6bf53dc31..2b994ee78 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -62,6 +62,8 @@ API Changes
 
 * cryptodev: In struct ``struct rte_cryptodev_info``, field ``rte_pci_device *pci_dev``
   has been replaced with field ``struct rte_device *device``.
+  Value 0 is accepted in ``sym.max_nb_sessions``, meaning that a device
+  supports an unlimited number of sessions.
 
 
 ABI Changes
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 2582dcb6e..dacf323c9 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1441,7 +1441,7 @@ cryptodevs_init(void)
 		dev_conf.nb_queue_pairs = qp;
 
 		uint32_t dev_max_sess = cdev_info.sym.max_nb_sessions;
-		if (dev_max_sess < (CDEV_MP_NB_OBJS / 2))
+		if (dev_max_sess != 0 && dev_max_sess < (CDEV_MP_NB_OBJS / 2))
 			rte_exit(EXIT_FAILURE,
 				"Device does not support at least %u "
 				"sessions", CDEV_MP_NB_OBJS / 2);
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index a30790b84..8c1a4ad6f 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -357,7 +357,10 @@ struct rte_cryptodev_info {
 
 	struct {
 		unsigned max_nb_sessions;
-		/**< Maximum number of sessions supported by device. */
+		/**< Maximum number of sessions supported by device.
+		 * If 0, the device does not have any limitation in
+		 * number of sessions that can be used.
+		 */
 	} sym;
 };
 
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 5c906cfae..73aadaced 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -436,7 +436,8 @@ testsuite_setup(void)
 	 * Create mempool with maximum number of sessions * 2,
 	 * to include the session headers
 	 */
-	if (info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
+	if (info.sym.max_nb_sessions != 0 &&
+			info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
 		RTE_LOG(ERR, USER1, "Device does not support "
 				"at least %u sessions\n",
 				MAX_NB_SESSIONS);
@@ -8546,7 +8547,8 @@ test_scheduler_attach_slave_op(void)
 		unsigned int session_size =
 			rte_cryptodev_sym_get_private_session_size(i);
 
-		if (info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
+		if (info.sym.max_nb_sessions != 0 &&
+				info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
 			RTE_LOG(ERR, USER1,
 					"Device does not support "
 					"at least %u sessions\n",
-- 
2.14.4

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 11/16] cryptodev: remove queue start/stop functions
    2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 01/16] cryptodev: replace bus specific struct with generic dev Pablo de Lara
  2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 08/16] cryptodev: define value for unlimited sessions Pablo de Lara
@ 2018-06-28  0:52  2%   ` Pablo de Lara
  2018-06-28  0:53  4%   ` [dpdk-dev] [PATCH v3 12/16] cryptodev: remove old get session size functions Pablo de Lara
  2018-06-28  0:53  3%   ` [dpdk-dev] [PATCH v3 13/16] cryptodev: replace mbuf scatter gather flag Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-28  0:52 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

Removed cryptodev queue start/stop functions,
as they were marked deprecated in 18.05, since they
were not implemented by any driver.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/rel_notes/deprecation.rst           |  4 ---
 doc/guides/rel_notes/release_18_08.rst         |  5 +++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c   | 18 -----------
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 18 -----------
 drivers/crypto/armv8/rte_armv8_pmd_ops.c       | 18 -----------
 drivers/crypto/ccp/ccp_pmd_ops.c               | 16 ----------
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c    | 22 -------------
 drivers/crypto/dpaa_sec/dpaa_sec.c             | 22 -------------
 drivers/crypto/kasumi/rte_kasumi_pmd_ops.c     | 18 -----------
 drivers/crypto/mvsam/rte_mrvl_pmd_ops.c        | 28 ----------------
 drivers/crypto/null/null_crypto_pmd_ops.c      | 18 -----------
 drivers/crypto/openssl/rte_openssl_pmd_ops.c   | 18 -----------
 drivers/crypto/qat/qat_sym_pmd.c               |  2 --
 drivers/crypto/scheduler/scheduler_pmd_ops.c   | 18 -----------
 drivers/crypto/snow3g/rte_snow3g_pmd_ops.c     | 18 -----------
 drivers/crypto/virtio/virtio_cryptodev.c       |  2 --
 drivers/crypto/zuc/rte_zuc_pmd_ops.c           | 18 -----------
 lib/librte_cryptodev/rte_cryptodev.c           | 44 --------------------------
 lib/librte_cryptodev/rte_cryptodev.h           | 37 ----------------------
 lib/librte_cryptodev/rte_cryptodev_pmd.h       | 26 ---------------
 lib/librte_cryptodev/rte_cryptodev_version.map |  2 --
 21 files changed, 5 insertions(+), 367 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index dc014da21..91592534e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,10 +105,6 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Functions ``rte_cryptodev_queue_pair_start()`` and
-    ``rte_cryptodev_queue_pair_stop()`` will be deprecated from 18.05
-    and removed in 18.08, as there are no drivers doing anything useful
-    with them.
   - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
     so some will be replaced by more explicit flags.
   - Function ``rte_cryptodev_get_header_session_size()`` will be deprecated
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index 2b994ee78..cfb2885a1 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -65,6 +65,11 @@ API Changes
   Value 0 is accepted in ``sym.max_nb_sessions``, meaning that a device
   supports an unlimited number of sessions.
 
+* cryptodev: Following functions were deprecated and are removed in 18.08:
+
+  - ``rte_cryptodev_queue_pair_start``
+  - ``rte_cryptodev_queue_pair_stop``
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index 796ccdbd8..e24453a7e 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -243,22 +243,6 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_gcm_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_gcm_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_gcm_pmd_qp_count(struct rte_cryptodev *dev)
@@ -340,8 +324,6 @@ struct rte_cryptodev_ops aesni_gcm_pmd_ops = {
 
 		.queue_pair_setup	= aesni_gcm_pmd_qp_setup,
 		.queue_pair_release	= aesni_gcm_pmd_qp_release,
-		.queue_pair_start	= aesni_gcm_pmd_qp_start,
-		.queue_pair_stop	= aesni_gcm_pmd_qp_stop,
 		.queue_pair_count	= aesni_gcm_pmd_qp_count,
 
 		.session_get_size	= aesni_gcm_pmd_session_get_size,
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index 101fdc5c6..6eb37a5bf 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -509,22 +509,6 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-aesni_mb_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-aesni_mb_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 aesni_mb_pmd_qp_count(struct rte_cryptodev *dev)
@@ -607,8 +591,6 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
 
 		.queue_pair_setup	= aesni_mb_pmd_qp_setup,
 		.queue_pair_release	= aesni_mb_pmd_qp_release,
-		.queue_pair_start	= aesni_mb_pmd_qp_start,
-		.queue_pair_stop	= aesni_mb_pmd_qp_stop,
 		.queue_pair_count	= aesni_mb_pmd_qp_count,
 
 		.session_get_size	= aesni_mb_pmd_session_get_size,
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index b654f7528..5e8a5a292 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -258,22 +258,6 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-armv8_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-armv8_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -354,8 +338,6 @@ struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
 
 		.queue_pair_setup	= armv8_crypto_pmd_qp_setup,
 		.queue_pair_release	= armv8_crypto_pmd_qp_release,
-		.queue_pair_start	= armv8_crypto_pmd_qp_start,
-		.queue_pair_stop	= armv8_crypto_pmd_qp_stop,
 		.queue_pair_count	= armv8_crypto_pmd_qp_count,
 
 		.session_get_size	= armv8_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index dbe545c10..1cb944406 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -748,20 +748,6 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-static int
-ccp_pmd_qp_start(struct rte_cryptodev *dev __rte_unused,
-		 uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
-static int
-ccp_pmd_qp_stop(struct rte_cryptodev *dev __rte_unused,
-		uint16_t queue_pair_id __rte_unused)
-{
-	return -ENOTSUP;
-}
-
 static uint32_t
 ccp_pmd_qp_count(struct rte_cryptodev *dev)
 {
@@ -837,8 +823,6 @@ struct rte_cryptodev_ops ccp_ops = {
 
 		.queue_pair_setup	= ccp_pmd_qp_setup,
 		.queue_pair_release	= ccp_pmd_qp_release,
-		.queue_pair_start	= ccp_pmd_qp_start,
-		.queue_pair_stop	= ccp_pmd_qp_stop,
 		.queue_pair_count	= ccp_pmd_qp_count,
 
 		.session_get_size	= ccp_pmd_session_get_size,
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index bc091c560..1b1c30d85 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1470,26 +1470,6 @@ dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return retcode;
 }
 
-/** Start queue pair */
-static int
-dpaa2_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			   __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa2_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa2_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2716,8 +2696,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.stats_reset	      = dpaa2_sec_stats_reset,
 	.queue_pair_setup     = dpaa2_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa2_sec_queue_pair_release,
-	.queue_pair_start     = dpaa2_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa2_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa2_sec_queue_pair_count,
 	.session_get_size     = dpaa2_sec_session_get_size,
 	.session_configure    = dpaa2_sec_session_configure,
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index 73cae483b..b96552c57 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1585,26 +1585,6 @@ dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-dpaa_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev,
-			  __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
-/** Stop queue pair */
-static int
-dpaa_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev,
-			 __rte_unused uint16_t queue_pair_id)
-{
-	PMD_INIT_FUNC_TRACE();
-
-	return 0;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 dpaa_sec_queue_pair_count(struct rte_cryptodev *dev)
@@ -2227,8 +2207,6 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.dev_infos_get        = dpaa_sec_dev_infos_get,
 	.queue_pair_setup     = dpaa_sec_queue_pair_setup,
 	.queue_pair_release   = dpaa_sec_queue_pair_release,
-	.queue_pair_start     = dpaa_sec_queue_pair_start,
-	.queue_pair_stop      = dpaa_sec_queue_pair_stop,
 	.queue_pair_count     = dpaa_sec_queue_pair_count,
 	.session_get_size     = dpaa_sec_session_get_size,
 	.session_configure    = dpaa_sec_session_configure,
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index e72f2ae0b..4174f1f80 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -229,22 +229,6 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-kasumi_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-kasumi_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 kasumi_pmd_qp_count(struct rte_cryptodev *dev)
@@ -325,8 +309,6 @@ struct rte_cryptodev_ops kasumi_pmd_ops = {
 
 		.queue_pair_setup   = kasumi_pmd_qp_setup,
 		.queue_pair_release = kasumi_pmd_qp_release,
-		.queue_pair_start   = kasumi_pmd_qp_start,
-		.queue_pair_stop    = kasumi_pmd_qp_stop,
 		.queue_pair_count   = kasumi_pmd_qp_count,
 
 		.session_get_size   = kasumi_pmd_session_get_size,
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 07850098b..8710ba3b7 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -596,32 +596,6 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair (PMD ops callback) - not supported.
- *
- * @param dev Pointer to the device structure.
- * @param qp_id ID of the Queue Pair.
- * @returns -ENOTSUP. Always.
- */
-static int
-mrvl_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs (PMD ops callback).
  *
  * @param dev Pointer to the device structure.
@@ -739,8 +713,6 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
 
 		.queue_pair_setup	= mrvl_crypto_pmd_qp_setup,
 		.queue_pair_release	= mrvl_crypto_pmd_qp_release,
-		.queue_pair_start	= mrvl_crypto_pmd_qp_start,
-		.queue_pair_stop	= mrvl_crypto_pmd_qp_stop,
 		.queue_pair_count	= mrvl_crypto_pmd_qp_count,
 
 		.session_get_size	= mrvl_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 2842498af..e43fba7db 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -240,22 +240,6 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-null_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-null_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 null_crypto_pmd_qp_count(struct rte_cryptodev *dev)
@@ -336,8 +320,6 @@ struct rte_cryptodev_ops pmd_ops = {
 
 		.queue_pair_setup	= null_crypto_pmd_qp_setup,
 		.queue_pair_release	= null_crypto_pmd_qp_release,
-		.queue_pair_start	= null_crypto_pmd_qp_start,
-		.queue_pair_stop	= null_crypto_pmd_qp_stop,
 		.queue_pair_count	= null_crypto_pmd_qp_count,
 
 		.session_get_size	= null_crypto_pmd_session_get_size,
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index d194e3657..554177d20 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -648,22 +648,6 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-openssl_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-openssl_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 openssl_pmd_qp_count(struct rte_cryptodev *dev)
@@ -746,8 +730,6 @@ struct rte_cryptodev_ops openssl_pmd_ops = {
 
 		.queue_pair_setup	= openssl_pmd_qp_setup,
 		.queue_pair_release	= openssl_pmd_qp_release,
-		.queue_pair_start	= openssl_pmd_qp_start,
-		.queue_pair_stop	= openssl_pmd_qp_stop,
 		.queue_pair_count	= openssl_pmd_qp_count,
 
 		.session_get_size	= openssl_pmd_session_get_size,
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index 84dd5bec8..ee8633b85 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -202,8 +202,6 @@ static struct rte_cryptodev_ops crypto_qat_ops = {
 		.stats_reset		= qat_sym_stats_reset,
 		.queue_pair_setup	= qat_sym_qp_setup,
 		.queue_pair_release	= qat_sym_qp_release,
-		.queue_pair_start	= NULL,
-		.queue_pair_stop	= NULL,
 		.queue_pair_count	= NULL,
 
 		/* Crypto related operations */
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 16a8021c8..f363e3257 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -439,22 +439,6 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return 0;
 }
 
-/** Start queue pair */
-static int
-scheduler_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-scheduler_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 scheduler_pmd_qp_count(struct rte_cryptodev *dev)
@@ -535,8 +519,6 @@ struct rte_cryptodev_ops scheduler_pmd_ops = {
 
 		.queue_pair_setup	= scheduler_pmd_qp_setup,
 		.queue_pair_release	= scheduler_pmd_qp_release,
-		.queue_pair_start	= scheduler_pmd_qp_start,
-		.queue_pair_stop	= scheduler_pmd_qp_stop,
 		.queue_pair_count	= scheduler_pmd_qp_count,
 
 		.session_get_size	= scheduler_pmd_session_get_size,
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index 6f8b9e2c6..fe882c366 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -231,22 +231,6 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-snow3g_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-snow3g_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 snow3g_pmd_qp_count(struct rte_cryptodev *dev)
@@ -327,8 +311,6 @@ struct rte_cryptodev_ops snow3g_pmd_ops = {
 
 		.queue_pair_setup   = snow3g_pmd_qp_setup,
 		.queue_pair_release = snow3g_pmd_qp_release,
-		.queue_pair_start   = snow3g_pmd_qp_start,
-		.queue_pair_stop    = snow3g_pmd_qp_stop,
 		.queue_pair_count   = snow3g_pmd_qp_count,
 
 		.session_get_size   = snow3g_pmd_session_get_size,
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 1da4ae871..0be435c8c 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -515,8 +515,6 @@ static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
 
 	.queue_pair_setup                = virtio_crypto_qp_setup,
 	.queue_pair_release              = virtio_crypto_qp_release,
-	.queue_pair_start                = NULL,
-	.queue_pair_stop                 = NULL,
 	.queue_pair_count                = NULL,
 
 	/* Crypto related operations */
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index b39e35b9f..79326d8f5 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -231,22 +231,6 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
 	return -1;
 }
 
-/** Start queue pair */
-static int
-zuc_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
-/** Stop queue pair */
-static int
-zuc_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
-		__rte_unused uint16_t queue_pair_id)
-{
-	return -ENOTSUP;
-}
-
 /** Return the number of allocated queue pairs */
 static uint32_t
 zuc_pmd_qp_count(struct rte_cryptodev *dev)
@@ -327,8 +311,6 @@ struct rte_cryptodev_ops zuc_pmd_ops = {
 
 		.queue_pair_setup   = zuc_pmd_qp_setup,
 		.queue_pair_release = zuc_pmd_qp_release,
-		.queue_pair_start   = zuc_pmd_qp_start,
-		.queue_pair_stop    = zuc_pmd_qp_stop,
 		.queue_pair_count   = zuc_pmd_qp_count,
 
 		.session_get_size   = zuc_pmd_session_get_size,
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 457ac5670..a07904fb9 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -702,50 +702,6 @@ rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
 	return 0;
 }
 
-int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_start, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_start(dev, queue_pair_id);
-
-}
-
-int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
-		return -EINVAL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-	if (queue_pair_id >= dev->data->nb_queue_pairs) {
-		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
-		return -EINVAL;
-	}
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_stop, -ENOTSUP);
-
-	return dev->dev_ops->queue_pair_stop(dev, queue_pair_id);
-
-}
-
 int
 rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8c1a4ad6f..c94571ac1 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -574,43 +574,6 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
 		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
 		struct rte_mempool *session_pool);
 
-/**
- * @deprecated
- * Start a specified queue pair of a device. It is used
- * when deferred_start flag of the specified queue is true.
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to start. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_crypto_dev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id);
-
-/**
- * @deprecated
- * Stop specified queue pair of a device
- *
- * @param	dev_id		The identifier of the device
- * @param	queue_pair_id	The index of the queue pair to stop. The value
- *				must be in the range [0, nb_queue_pair - 1]
- *				previously supplied to
- *				rte_cryptodev_configure().
- * @return
- *   - 0: Success, the transmit queue is correctly set up.
- *   - -EINVAL: The dev_id or the queue_id out of range.
- *   - -ENOTSUP: The function not supported in PMD driver.
- */
-__rte_deprecated
-extern int
-rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id);
-
 /**
  * Get the number of queue pairs on a specific crypto device
  *
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 1fb7e7d5e..641dd1369 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -184,28 +184,6 @@ typedef void (*cryptodev_stats_reset_t)(struct rte_cryptodev *dev);
 typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
 				struct rte_cryptodev_info *dev_info);
 
-/**
- * Start queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_start_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
-/**
- * Stop queue pair of a device.
- *
- * @param	dev	Crypto device pointer
- * @param	qp_id	Queue Pair Index
- *
- * @return	Returns 0 on success.
- */
-typedef int (*cryptodev_queue_pair_stop_t)(struct rte_cryptodev *dev,
-				uint16_t qp_id);
-
 /**
  * Setup a queue pair for a device.
  *
@@ -344,10 +322,6 @@ struct rte_cryptodev_ops {
 	/**< Set up a device queue pair. */
 	cryptodev_queue_pair_release_t queue_pair_release;
 	/**< Release a queue pair. */
-	cryptodev_queue_pair_start_t queue_pair_start;
-	/**< Start a queue pair. */
-	cryptodev_queue_pair_stop_t queue_pair_stop;
-	/**< Stop a queue pair. */
 	cryptodev_queue_pair_count_t queue_pair_count;
 	/**< Get count of the queue pairs. */
 
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index be8f4c1a7..020b45754 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -22,8 +22,6 @@ DPDK_16.04 {
 	rte_cryptodev_stop;
 	rte_cryptodev_queue_pair_count;
 	rte_cryptodev_queue_pair_setup;
-	rte_cryptodev_queue_pair_start;
-	rte_cryptodev_queue_pair_stop;
 	rte_crypto_op_pool_create;
 
 	local: *;
-- 
2.14.4

^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v3 13/16] cryptodev: replace mbuf scatter gather flag
                       ` (3 preceding siblings ...)
  2018-06-28  0:53  4%   ` [dpdk-dev] [PATCH v3 12/16] cryptodev: remove old get session size functions Pablo de Lara
@ 2018-06-28  0:53  3%   ` Pablo de Lara
  4 siblings, 0 replies; 200+ results
From: Pablo de Lara @ 2018-06-28  0:53 UTC (permalink / raw)
  To: declan.doherty, akhil.goyal, shally.verma, ravi1.kumar,
	jerin.jacob, roy.fan.zhang, fiona.trahe, tdu, jianjay.zhou
  Cc: dev, Pablo de Lara

The current mbuf scatter gatter feature flag is
too ambiguous, as it is not clear if input and/or output
buffers can be scatter gather mbufs or not, plus
if in-place and/or out-of-place is supported.

Therefore, five new flags will replace this flag:
- RTE_CRYPTODEV_FF_IN_PLACE_SGL
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT
- RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/rel_notes/deprecation.rst        |  2 --
 doc/guides/rel_notes/release_18_08.rst      |  8 +++++
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c    |  2 +-
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c |  6 +++-
 drivers/crypto/dpaa_sec/dpaa_sec.c          |  6 +++-
 drivers/crypto/null/null_crypto_pmd.c       |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c    |  2 +-
 drivers/crypto/qat/qat_sym_pmd.c            |  6 +++-
 lib/librte_cryptodev/rte_cryptodev.c        | 12 ++++++--
 lib/librte_cryptodev/rte_cryptodev.h        | 46 +++++++++++++++++++----------
 test/test/test_cryptodev.c                  | 31 +++++++++++++------
 test/test/test_cryptodev_blockcipher.c      | 21 ++++++++++---
 12 files changed, 106 insertions(+), 38 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9a73b1d8e..62d635b74 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -105,5 +105,3 @@ Deprecation Notices
     ``rte_cryptodev_queue_pair_dettach_sym_session()`` will be deprecated from
     18.05 and removed in 18.08, as there are no drivers doing anything useful
     with them.
-  - Some feature flags such as ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` are ambiguous,
-    so some will be replaced by more explicit flags.
diff --git a/doc/guides/rel_notes/release_18_08.rst b/doc/guides/rel_notes/release_18_08.rst
index e482d3d5f..2a136d88c 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -78,6 +78,14 @@ API Changes
   - ``rte_cryptodev_get_private_session_size`` is replaced with
     ``rte_cryptodev_sym_get_private_session_size``
 
+* cryptodev: Feature flag ``RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER`` is
+  replaced with the following more explicit flags:
+  - ``RTE_CRYPTODEV_FF_IN_PLACE_SGL``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT``
+  - ``RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT``
+
 
 ABI Changes
 -----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index cd5b1952b..03917f220 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -492,7 +492,7 @@ aesni_gcm_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
 
 	switch (vector_mode) {
 	case RTE_AESNI_GCM_SSE:
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 1b1c30d85..4daee5f59 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -2762,7 +2762,11 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index b96552c57..8ad25f2be 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -2271,7 +2271,11 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev)
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_SECURITY |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 	internals->max_nb_queue_pairs = RTE_DPAA_MAX_NB_SEC_QPS;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 478ac0b62..224ba7233 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -177,7 +177,7 @@ cryptodev_null_create(const char *name,
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL;
 
 	internals = dev->data->dev_private;
 
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 972e2adfe..94b6e2de9 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1660,7 +1660,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
 
 	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index ee8633b85..629904e2f 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -274,7 +274,11 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev)
 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT |
+			RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT;
 
 	internals = cryptodev->data->dev_private;
 	internals->qat_dev = qat_pci_dev;
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 381330f3d..15110661b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -361,8 +361,16 @@ rte_cryptodev_get_feature_name(uint64_t flag)
 		return "CPU_AESNI";
 	case RTE_CRYPTODEV_FF_HW_ACCELERATED:
 		return "HW_ACCELERATED";
-	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER:
-		return "MBUF_SCATTER_GATHER";
+	case RTE_CRYPTODEV_FF_IN_PLACE_SGL:
+		return "IN_PLACE_SGL";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT:
+		return "OUT_OF_PLACE_SGL_IN_SGL_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT:
+		return "OUT_OF_PLACE_SGL_IN_FB_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT:
+		return "OUT_OF_PLACE_FB_IN_SGL_OUT";
+	case RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT:
+		return "OUT_OF_PLACE_FB_IN_FB_OUT";
 	case RTE_CRYPTODEV_FF_CPU_NEON:
 		return "CPU_NEON";
 	case RTE_CRYPTODEV_FF_CPU_ARM_CE:
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index fc491a83b..6dc7107bb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -300,31 +300,47 @@ rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
  *
  * Keep these flags synchronised with rte_cryptodev_get_feature_name()
  */
-#define	RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO	(1ULL << 0)
+#define	RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO		(1ULL << 0)
 /**< Symmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO	(1ULL << 1)
+#define	RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO		(1ULL << 1)
 /**< Asymmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING	(1ULL << 2)
+#define	RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING		(1ULL << 2)
 /**< Chaining symmetric crypto operations are supported */
-#define	RTE_CRYPTODEV_FF_CPU_SSE		(1ULL << 3)
+#define	RTE_CRYPTODEV_FF_CPU_SSE			(1ULL << 3)
 /**< Utilises CPU SIMD SSE instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AVX		(1ULL << 4)
+#define	RTE_CRYPTODEV_FF_CPU_AVX			(1ULL << 4)
 /**< Utilises CPU SIMD AVX instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AVX2		(1ULL << 5)
+#define	RTE_CRYPTODEV_FF_CPU_AVX2			(1ULL << 5)
 /**< Utilises CPU SIMD AVX2 instructions */
-#define	RTE_CRYPTODEV_FF_CPU_AESNI		(1ULL << 6)
+#define	RTE_CRYPTODEV_FF_CPU_AESNI			(1ULL << 6)
 /**< Utilises CPU AES-NI instructions */
-#define	RTE_CRYPTODEV_FF_HW_ACCELERATED		(1ULL << 7)
-/**< Operations are off-loaded to an external hardware accelerator */
-#define	RTE_CRYPTODEV_FF_CPU_AVX512		(1ULL << 8)
+#define	RTE_CRYPTODEV_FF_HW_ACCELERATED			(1ULL << 7)
+/**< Operations are off-loaded to an
+ * external hardware accelerator
+ */
+#define	RTE_CRYPTODEV_FF_CPU_AVX512			(1ULL << 8)
 /**< Utilises CPU SIMD AVX512 instructions */
-#define	RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER	(1ULL << 9)
-/**< Scatter-gather mbufs are supported */
-#define	RTE_CRYPTODEV_FF_CPU_NEON		(1ULL << 10)
+#define	RTE_CRYPTODEV_FF_IN_PLACE_SGL			(1ULL << 9)
+/**< In-place Scatter-gather (SGL) mbufs are supported */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT	(1ULL << 10)
+/**< Out-of-place Scatter-gather (SGL) mbufs are
+ * supported in input and output
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT	(1ULL << 11)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in input, combined with flat buffers (FB) in output
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_SGL_OUT	(1ULL << 12)
+/**< Out-of-place Scatter-gather (SGL) mbufs are supported
+ * in output, combined with flat buffers (FB) in input
+ */
+#define RTE_CRYPTODEV_FF_OUT_OF_PLACE_FB_IN_FB_OUT	(1ULL << 13)
+/**< Out-of-place flat buffers (FB) are supported in input and output */
+#define	RTE_CRYPTODEV_FF_CPU_NEON			(1ULL << 14)
 /**< Utilises CPU NEON instructions */
-#define	RTE_CRYPTODEV_FF_CPU_ARM_CE		(1ULL << 11)
+#define	RTE_CRYPTODEV_FF_CPU_ARM_CE			(1ULL << 15)
 /**< Utilises ARM CPU Cryptographic Extensions */
-#define	RTE_CRYPTODEV_FF_SECURITY		(1ULL << 12)
+#define	RTE_CRYPTODEV_FF_SECURITY			(1ULL << 16)
 /**< Support Security Protocol Processing */
 
 
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 73aadaced..84fcf0651 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -3160,8 +3160,11 @@ test_kasumi_encryption_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+		printf("Device doesn't support in-place scatter-gather. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -3308,8 +3311,11 @@ test_kasumi_encryption_oop_sgl(const struct kasumi_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+	if (!(feat_flags & RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT)) {
+		printf("Device doesn't support out-of-place scatter-gather "
+				"in both input and output mbufs. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -3659,8 +3665,12 @@ test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata)
 	struct rte_cryptodev_info dev_info;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_SGL_OUT)) {
+		printf("Device doesn't support out-of-place scatter-gather "
+				"in both input and output mbufs. "
 				"Test Skipped.\n");
 		return 0;
 	}
@@ -4493,10 +4503,13 @@ test_zuc_encryption_sgl(const struct wireless_test_data *tdata)
 		return -ENOTSUP;
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
-	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-		printf("Device doesn't support scatter-gather. "
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+		printf("Device doesn't support in-place scatter-gather. "
 				"Test Skipped.\n");
-		return -ENOTSUP;
+		return 0;
 	}
 
 	plaintext_len = ceil_byte_length(tdata->plaintext.len);
diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c
index 256a7daa2..7a11b3af8 100644
--- a/test/test/test_cryptodev_blockcipher.c
+++ b/test/test/test_cryptodev_blockcipher.c
@@ -77,12 +77,25 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 
 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
 		rte_cryptodev_info_get(dev_id, &dev_info);
-		if (!(dev_info.feature_flags &
-				RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
-			printf("Device doesn't support scatter-gather. "
+		uint64_t feat_flags = dev_info.feature_flags;
+		uint64_t oop_flag = RTE_CRYPTODEV_FF_OUT_OF_PLACE_SGL_IN_FB_OUT;
+
+		if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) {
+			if (!(feat_flags & oop_flag)) {
+				printf("Device doesn't support out-of-place "
+					"scatter-gather in input mbuf. "
+					"Test Skipped.\n");
+				return 0;
+			}
+		} else {
+			if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+				printf("Device doesn't support in-place "
+					"scatter-gather mbufs. "
 					"Test Skipped.\n");
-			return 0;
+				return 0;
+			}
 		}
+
 		nb_segs = 3;
 	}
 
-- 
2.14.4

^ permalink raw reply	[relevance 3%]

Results 4401-4600 of ~18000   |  | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2017-11-24 16:06     [dpdk-dev] [RFC PATCH 0/6] mempool: add bucket mempool driver Andrew Rybchenko
2018-04-25 16:32  4% ` [dpdk-dev] [PATCH v3 0/6] mempool: add bucket driver Andrew Rybchenko
2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 2/6] mempool: implement abstract mempool info API Andrew Rybchenko
2018-04-25 16:32  4%   ` [dpdk-dev] [PATCH v3 3/6] mempool: support block dequeue operation Andrew Rybchenko
2018-04-26 10:59  4% ` [dpdk-dev] [PATCH v4 0/5] mempool: add bucket driver Andrew Rybchenko
2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 2/5] mempool: implement abstract mempool info API Andrew Rybchenko
2018-04-26 10:59  4%   ` [dpdk-dev] [PATCH v4 3/5] mempool: support block dequeue operation Andrew Rybchenko
2018-01-15 19:05     [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition Neil Horman
2018-02-14 19:19     ` [dpdk-dev] [PATCH v6] " Neil Horman
2018-05-27 19:34  4%   ` Thomas Monjalon
2018-05-27 21:00  4%     ` Neil Horman
2018-05-27 22:01  4%       ` Thomas Monjalon
2018-05-28 17:08  4%         ` Neil Horman
2018-06-05 12:21  6% ` [dpdk-dev] [PATCH v7] " Neil Horman
2018-06-14 13:30  6% ` [dpdk-dev] [PATCH v8] " Neil Horman
2018-06-25 23:04  4%   ` Thomas Monjalon
2018-06-27 17:58  4%     ` Neil Horman
2018-06-27 18:01  6% ` [dpdk-dev] [PATCH v9] " Neil Horman
2018-01-26  9:03     [dpdk-dev] [PATCH] doc: announce ABI change for crypto info struct Pablo de Lara
2018-05-17  9:00  8% ` [dpdk-dev] [PATCH v3 0/4] Cryptodev API/ABI deprecation notices Pablo de Lara
2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 1/4] doc: announce ABI change for crypto sym info struct Pablo de Lara
2018-05-18 11:42  4%     ` Akhil Goyal
2018-05-17  9:00  4%   ` [dpdk-dev] [PATCH v3 2/4] doc: announce ABI change for crypto " Pablo de Lara
2018-05-17 11:18  4%     ` Trahe, Fiona
2018-05-18 11:41  4%     ` Akhil Goyal
2018-05-21 11:06  8% ` [dpdk-dev] [PATCH v4 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
2018-05-21 11:06  4%   ` [dpdk-dev] [PATCH v4 2/6] doc: announce ABI change for crypto " Pablo de Lara
2018-05-21 13:08  8% ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Pablo de Lara
2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 1/6] doc: announce ABI change for crypto sym info struct Pablo de Lara
2018-05-21 13:08  4%   ` [dpdk-dev] [PATCH v5 2/6] doc: announce ABI change for crypto " Pablo de Lara
2018-05-22 14:30  4%   ` [dpdk-dev] [PATCH v5 0/6] Cryptodev API/ABI deprecation notices Jain, Deepak K
2018-05-22 14:35  4%     ` De Lara Guarch, Pablo
2018-03-10  1:25     [dpdk-dev] [PATCH v1 0/6] net/mlx5: add Multi-Packet Rx support Yongseok Koh
2018-04-24 18:21     ` [dpdk-dev] ***Spam*** Re: [PATCH v4 1/2] mbuf: support attaching external buffer to mbuf Andrew Rybchenko
2018-04-24 19:15       ` [dpdk-dev] " Olivier Matz
2018-04-24 20:22         ` Thomas Monjalon
2018-04-25 15:06  0%       ` Stephen Hemminger
2018-03-20 13:45     [dpdk-dev] [PATCH V1 0/5] Introduce Intel FPGA BUS Rosen Xu
2018-04-26  9:43     ` [dpdk-dev] [PATCH v6 " Xu, Rosen
2018-04-26  9:43       ` [dpdk-dev] [PATCH v6 1/5] iFPGA: Add Intel FPGA BUS Library Xu, Rosen
2018-05-02 13:14  4%     ` Shreyansh Jain
2018-05-02 13:33  0%       ` Zhang, Tianfei
2018-03-28  4:51     [dpdk-dev] [PATCH] eal: add request to map reserved physical memory Ajit Khaparde
2018-04-12 14:35     ` Burakov, Anatoly
2018-04-23  9:23       ` Srinath Mannam
2018-04-27 16:30         ` Scott Branden
2018-04-27 16:49           ` Burakov, Anatoly
2018-06-06  0:18             ` Scott Branden
2018-06-07 12:15  3%           ` Burakov, Anatoly
2018-04-05 13:15     [dpdk-dev] [PATCH] eal/service: remove experimental tags Harry van Haaren
2018-04-06  6:18     ` Jerin Jacob
2018-04-25 12:58  0%   ` Thomas Monjalon
2018-04-30 13:53  0%     ` Alejandro Lucero
2018-04-13 14:43     [dpdk-dev] [PATCH v4 01/10] net: move BPF related definitions into librte_net Konstantin Ananyev
2018-05-04 12:45  1% ` [dpdk-dev] [PATCH v5 1/8] bpf: add BPF loading and execution framework Konstantin Ananyev
2018-05-10 10:23  3%   ` [dpdk-dev] [PATCH v6 2/9] bpf: add ability to load eBPF program from ELF object file Konstantin Ananyev
2018-04-17 15:21     [dpdk-dev] [PATCH v1] cmdline: rework as a wrapper to libedit Adrien Mazarguil
2018-04-19 15:13     ` [dpdk-dev] [PATCH v2] " Adrien Mazarguil
2018-06-26 13:21  0%   ` Olivier Matz
2018-06-27 10:36  0%     ` Bruce Richardson
2018-06-27 11:35  0%       ` Olivier Matz
2018-04-19 10:16     [dpdk-dev] [PATCH v5 00/16] Flow API overhaul for switch offloads Adrien Mazarguil
2018-04-25 15:27  5% ` [dpdk-dev] [PATCH v6 " Adrien Mazarguil
2018-04-25 15:27 15%   ` [dpdk-dev] [PATCH v6 01/16] ethdev: add error types to flow API Adrien Mazarguil
2018-04-25 15:27 21%   ` [dpdk-dev] [PATCH v6 04/16] ethdev: remove DUP action from " Adrien Mazarguil
2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 05/16] ethdev: alter behavior of flow API actions Adrien Mazarguil
2018-04-25 15:27  8%   ` [dpdk-dev] [PATCH v6 06/16] ethdev: fix C99 flexible arrays from flow API Adrien Mazarguil
2018-04-25 15:27  3%   ` [dpdk-dev] [PATCH v6 07/16] ethdev: flatten RSS configuration in " Adrien Mazarguil
2018-04-28  3:46  0%     ` Zhao1, Wei
2018-04-28  5:28  0%       ` Peng, Yuan
2018-04-28  7:45  0%         ` Peng, Yuan
2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 08/16] ethdev: add hash function to RSS flow API action Adrien Mazarguil
2018-04-25 15:27  5%   ` [dpdk-dev] [PATCH v6 09/16] ethdev: add encap level " Adrien Mazarguil
2018-04-25 15:27  7%   ` [dpdk-dev] [PATCH v6 10/16] ethdev: fix TPID handling in flow API Adrien Mazarguil
2018-04-25 16:10  0%     ` Adrien Mazarguil
2018-04-25 16:15  0%       ` Ferruh Yigit
2018-04-25 15:27  4%   ` [dpdk-dev] [PATCH v6 11/16] ethdev: fix default VLAN TCI mask " Adrien Mazarguil
2018-04-25 15:28  8%   ` [dpdk-dev] [PATCH v6 12/16] ethdev: add transfer attribute to " Adrien Mazarguil
2018-04-25 15:28  4%   ` [dpdk-dev] [PATCH v6 13/16] ethdev: fix behavior of VF/PF in " Adrien Mazarguil
2018-04-25 15:28  6%   ` [dpdk-dev] [PATCH v6 14/16] ethdev: rename physical port item " Adrien Mazarguil
2018-04-25 15:28  7%   ` [dpdk-dev] [PATCH v6 15/16] ethdev: add physical port action to " Adrien Mazarguil
2018-04-25 15:28  5%   ` [dpdk-dev] [PATCH v6 16/16] ethdev: add port ID item and " Adrien Mazarguil
2018-04-25 17:34  0%   ` [dpdk-dev] [PATCH v6 00/16] Flow API overhaul for switch offloads Ferruh Yigit
2018-04-20 11:56     [dpdk-dev] [PATCH v6 0/5] introduce new tunnel types Xueming Li
2018-04-23 12:16     ` [dpdk-dev] [PATCH v7 " Xueming Li
2018-04-25 21:31  0%   ` Ferruh Yigit
2018-04-24  2:15     [dpdk-dev] [PATCH] ethdev: remove experimental flag of ports enumeration Thomas Monjalon
2018-04-25 10:21     ` Ferruh Yigit
2018-04-25 10:29       ` Thomas Monjalon
2018-04-25 10:52  0%     ` Ferruh Yigit
2018-04-24 22:16     [dpdk-dev] [PATCH v7 00/11] eal: replace calls to rte_panic and refrain from new instances Arnon Warshavsky
2018-04-25 13:45     ` [dpdk-dev] [PATCH v8 00/10] " Arnon Warshavsky
2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
2018-04-25 13:45  3%   ` [dpdk-dev] [PATCH v8 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
2018-04-25 13:45  2%   ` [dpdk-dev] [PATCH v8 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
2018-04-25 13:53  0%     ` Burakov, Anatoly
2018-04-25 12:24     [dpdk-dev] [PATCH 18.05-RC2 0/4] Clean up EAL runtime data paths Anatoly Burakov
2018-04-30 12:08     ` [dpdk-dev] [PATCH v2 " Anatoly Burakov
2018-05-09 15:59  3%   ` Van Haaren, Harry
2018-05-09 16:11  0%     ` Bruce Richardson
2018-05-09 19:03  0%       ` Thomas Monjalon
2018-05-14  8:26  0%         ` Burakov, Anatoly
2018-04-25 13:45     [dpdk-dev] [PATCH v8 10/10] devtools: prevent new instances of rte_panic and rte_exit Arnon Warshavsky
2018-04-26  6:20     ` [dpdk-dev] [PATCH v9 00/10] eal: replace calls to rte_panic and refrain from new instances Arnon Warshavsky
2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 02/10] bond: replace rte_panic instances in bonding driver Arnon Warshavsky
2018-04-26 16:06  0%     ` Kevin Traynor
2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 03/10] e1000: replace rte_panic instances in e1000 driver Arnon Warshavsky
2018-04-26  6:20  3%   ` [dpdk-dev] [PATCH v9 04/10] ixgbe: replace rte_panic instances in ixgbe driver Arnon Warshavsky
2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 06/10] kni: replace rte_panic instances in kni Arnon Warshavsky
2018-04-26  6:21  3%   ` [dpdk-dev] [PATCH v9 08/10] eal: replace rte_panic instances in ethdev Arnon Warshavsky
2018-04-26 16:07  0%     ` Kevin Traynor
2018-04-26  6:21  2%   ` [dpdk-dev] [PATCH v9 09/10] eal: replace rte_panic instances in init sequence Arnon Warshavsky
2018-04-26 16:07  0%     ` Kevin Traynor
2018-04-25 14:10     [dpdk-dev] [PATCH 1/2] malloc: add biggest free IOVA-contiguous element to stats Anatoly Burakov
2018-04-25 14:40  4% ` Burakov, Anatoly
2018-04-26 12:08     [dpdk-dev] [PATCH v6 0/4] additions to support tunnel encap/decap Declan Doherty
2018-04-26 12:08  2% ` [dpdk-dev] [PATCH v6 2/4] ethdev: Add group JUMP action Declan Doherty
2018-04-26 17:29     ` [dpdk-dev] [PATCH v7 0/4] ethdev: add shared counter support to rte_flow Declan Doherty
2018-04-26 17:29  2%   ` [dpdk-dev] [PATCH v7 2/4] ethdev: Add group JUMP action Declan Doherty
2018-04-26 13:29     [dpdk-dev] [PATCH 01/13] baseband/turbo_sw: update DPDK to work with FlexRAN 1.4.0 Kamil Chalupnik
2018-04-26 13:29     ` [dpdk-dev] [PATCH 05/13] baseband/turbo_sw: scalling input LLR to range [-16 16] Kamil Chalupnik
2018-05-07 12:50  4%   ` De Lara Guarch, Pablo
2018-05-09 14:23  3%   ` [dpdk-dev] [PATCH v2 04/14] baseband/turbo_sw: scalling likelihood ratio (LLR) input Kamil Chalupnik
2018-04-26 13:30  5% ` [dpdk-dev] [PATCH 12/13] bbdev: split queue groups Kamil Chalupnik
2018-05-09 14:35  5%   ` [dpdk-dev] [PATCH v2 08/14] " Kamil Chalupnik
2018-04-26 13:42     [dpdk-dev] [PATCH] lcore: make semantics of lcore role function more intuitive Anatoly Burakov
2018-04-26 14:30     ` Thomas Monjalon
2018-04-26 14:44  4%   ` Carrillo, Erik G
2018-04-26 14:54  5%     ` Thomas Monjalon
2018-04-26 14:56  0%       ` Carrillo, Erik G
2018-04-26 15:37  0%         ` Stephen Hemminger
2018-04-26 15:09     [dpdk-dev] [PATCH 1/2] crypto/scheduler: set null pointer after freeing Pablo de Lara
2018-04-27  8:47     ` Akhil Goyal
2018-04-27 11:36       ` De Lara Guarch, Pablo
2018-04-27 11:58         ` Akhil Goyal
2018-04-27 12:37  3%       ` Van Haaren, Harry
2018-04-27 13:09  0%         ` Bruce Richardson
2018-05-02 17:09     [dpdk-dev] [PATCH v6 0/8] Introduce DPAA2 QDMA raw driver Nipun Gupta
2018-05-03 15:51     ` [dpdk-dev] [PATCH v7 " Nipun Gupta
2018-05-03 15:51  2%   ` [dpdk-dev] [PATCH v7 5/8] raw/dpaa2_qdma: introduce the DPAA2 QDMA driver Nipun Gupta
2018-05-03 14:20  3% [dpdk-dev] Compiling DPDK with CentOS6 Shahar Salzman
2018-05-03 19:37     [dpdk-dev] [PATCH 1/6] net/enic: enable RQ first and then post Rx buffers John Daley
2018-05-03 19:37  3% ` [dpdk-dev] [PATCH 3/6] net/enic: set rte errno to positive value John Daley
2018-05-04 14:02     [dpdk-dev] [PATCH v7] ethdev: check Rx/Tx offloads Wei Dai
2018-05-08 10:05  1% ` [dpdk-dev] [PATCH v8] " Wei Dai
2018-05-10  0:49  1%   ` [dpdk-dev] [PATCH v9] ethdev: new Rx/Tx offloads API Wei Dai
2018-05-10  0:56  1%     ` [dpdk-dev] [PATCH v10] " Wei Dai
2018-05-10 11:30  1%       ` [dpdk-dev] [PATCH v11] " Wei Dai
2018-05-10 11:56  1%         ` [dpdk-dev] [PATCH v12] " Wei Dai
2018-05-08 10:10  1% ` [dpdk-dev] [PATCH v8] ethdev: check Rx/Tx offloads Wei Dai
2018-05-09  9:43     [dpdk-dev] [PATCH 00/11] ethdev: fix race conditions in iterator and notifications Thomas Monjalon
2018-05-10 22:27  3% ` Stephen Hemminger
2018-05-09 17:08  3% [dpdk-dev] rte_eth_dev_socket_id() vs KVM/AWS/ Mike Stolarchuk
2018-05-14  8:09  0% ` Burakov, Anatoly
2018-05-09 19:17     [dpdk-dev] [PATCH] eventdev: make ethernet port identifiers 16 bit Nikhil Rao
2018-05-09 20:52     ` [dpdk-dev] [PATCH v2] " Nikhil Rao
2018-05-10  4:31  3%   ` Jerin Jacob
2018-05-10 13:48  4%     ` [dpdk-dev] [dpdk-stable] " Thomas Monjalon
2018-05-10 14:30  0%       ` Jerin Jacob
2018-05-10 14:54  0%         ` Thomas Monjalon
2018-05-10 15:16  0%           ` Jerin Jacob
2018-05-10 15:45  0%             ` Thomas Monjalon
2018-05-10 16:11  3%               ` Thomas Monjalon
2018-05-09 21:54  4% [dpdk-dev] [PATCH] eventdev: bump library version Nikhil Rao
2018-05-10  4:19  4% [dpdk-dev] [PATCH] doc: update release notes Qi Zhang
2018-05-10  4:22  4% [dpdk-dev] [PATCH v2] " Qi Zhang
2018-05-10  6:24  0% ` Tonghao Zhang
2018-05-10  6:45  0%   ` Zhang, Qi Z
2018-05-10  6:55  4% [dpdk-dev] [PATCH v3] " Qi Zhang
2018-05-14 21:09  4% [dpdk-dev] [PATCH] librte_hash: new hash del abi to returns stored value Vijaya Mohan Guvva
2018-05-17  1:26  3% [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return " Vijaya Mohan Guvva
2018-05-17  8:06  7% ` De Lara Guarch, Pablo
2018-05-24 17:47  4%   ` Wang, Yipeng1
2018-05-22 14:38  4% [dpdk-dev] [pull-request] next-crypto 18.05-rc5 Pablo de Lara
2018-05-24 18:35  7% [dpdk-dev] [PATCH V2] librte_hash: new hash del abi to return stored value Guvva, Vijaya
2018-05-25  1:58  8% ` Honnappa Nagarahalli
2018-05-25  9:17  5% [dpdk-dev] [PATCH] doc: remove old deprecation notice Kirill Rybalchenko
2018-05-25  9:35  4% [dpdk-dev] Process for removing __rte_experimental Shreyansh Jain
2018-05-25  9:49  0% ` Thomas Monjalon
2018-05-25 10:17  0%   ` Luca Boccassi
2018-05-25 11:16  0%     ` Shreyansh Jain
2018-05-25 11:23  3% ` Neil Horman
2018-05-25 12:07 28% [dpdk-dev] [PATCH] doc: move and update experimental API description Shreyansh Jain
2018-05-25 12:22  0% ` Luca Boccassi
2018-05-25 15:37  0%   ` Ferruh Yigit
2018-05-25 13:38  5% [dpdk-dev] [PATCH] doc: deprecation notice for EAL runtime path changes Anatoly Burakov
2018-05-28  3:31  8% [dpdk-dev] Stable ABI status of rte_meter_[t|s]rtcm_profile_config Andy Green
2018-05-30  0:32  4% ` Andy Green
2018-05-30  9:55  4%   ` Singh, Jasvinder
2018-05-30 10:13  4%     ` Andy Green
2018-05-30 11:54     [dpdk-dev] Compilation of MLX5 driver Nitin Katiyar
2018-05-30 13:11     ` Nélio Laranjeiro
2018-05-30 16:45       ` Nitin Katiyar
2018-05-31  5:21         ` Shahaf Shuler
2018-05-31  7:01  4%       ` Nitin Katiyar
2018-05-31  8:05  0%         ` Nélio Laranjeiro
2018-05-31  9:14  0%           ` Nitin Katiyar
2018-05-31  9:53  0%             ` Nélio Laranjeiro
2018-05-31 11:44  0%               ` Nitin Katiyar
2018-05-30 20:25  7% [dpdk-dev] [PATCH v1] doc: update release notes for 18.05 John McNamara
2018-05-30 20:54 12% ` Thomas Monjalon
2018-05-31 10:57  3% [dpdk-dev] [RFC 0/3] Make device mapping more reliable Anatoly Burakov
2018-05-31 15:35  5% [dpdk-dev] [PATCH] eal: move runtime config file to new location Anatoly Burakov
2018-05-31 21:11  6% [dpdk-dev] [PATCH] doc: add template release notes for 18.08 Thomas Monjalon
2018-06-01 17:15     [dpdk-dev] [PATCH 0/9] Support running DPDK without hugetlbfs mountpoint Anatoly Burakov
2018-06-01 17:15  5% ` [dpdk-dev] [PATCH 8/9] doc: add deprecation notice for EAL command line options Anatoly Burakov
2018-06-05  7:50     [dpdk-dev] [PATCH] doc: change tools guide to SPDX license Hemant Agrawal
2018-06-05  7:50  4% ` [dpdk-dev] [PATCH] doc: add SPDX and copyright to rel notes Hemant Agrawal
2018-06-05  7:50  4% ` [dpdk-dev] [PATCH] doc: add SPDX and copyright to contributing guide Hemant Agrawal
2018-06-07 12:38     [dpdk-dev] [PATCH 00/22] enable hotplug on multi-process Qi Zhang
2018-06-21  2:00     ` [dpdk-dev] [PATCH v2 " Qi Zhang
2018-06-21  2:00       ` [dpdk-dev] [PATCH v2 01/22] eal: introduce one device scan Qi Zhang
2018-06-21  7:56  3%     ` Burakov, Anatoly
2018-06-21  2:00       ` [dpdk-dev] [PATCH v2 03/22] ethdev: add function to release port in local process Qi Zhang
2018-06-21  8:06  3%     ` Burakov, Anatoly
2018-06-21  8:21  4%       ` Thomas Monjalon
2018-06-21  8:21  0%       ` Zhang, Qi Z
2018-06-26  7:08     ` [dpdk-dev] [PATCH v4 00/24] enable hotplug on multi-process Qi Zhang
2018-06-26  7:08       ` [dpdk-dev] [PATCH v4 01/24] eal: introduce one device scan Qi Zhang
2018-06-26 11:47  3%     ` Burakov, Anatoly
2018-06-26 12:26  0%       ` Zhang, Qi Z
2018-06-26 16:33  4%         ` Gaëtan Rivet
2018-06-27 12:32  3%           ` Zhang, Qi Z
2018-06-28  1:49  1% ` [dpdk-dev] [PATCH v5 00/24] enable hotplug on multi-process Qi Zhang
2018-06-28  1:50  4%   ` [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug Qi Zhang
2018-06-28  1:52  1% ` [dpdk-dev] [PATCH v6 00/19] enable hotplug on multi-process Qi Zhang
2018-06-28  1:52  4%   ` [dpdk-dev] [PATCH v6 19/19] doc: update release notes for multi process hotplug Qi Zhang
2018-06-08  8:42     [dpdk-dev] [PATCH 0/3] bpf: extend validation of input BPF programs Konstantin Ananyev
2018-06-08  8:42  2% ` [dpdk-dev] [PATCH 1/3] bpf: add extra information for external symbol definitions Konstantin Ananyev
2018-06-08 22:02     [dpdk-dev] [PATCH 0/6] Cryptodev API changes Pablo de Lara
2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 1/6] cryptodev: replace bus specific struct with generic dev Pablo de Lara
2018-06-08 22:02  1% ` [dpdk-dev] [PATCH 3/6] cryptodev: remove max number of sessions Pablo de Lara
2018-06-12 11:37  0%   ` Tomasz Duszynski
2018-06-08 22:02  2% ` [dpdk-dev] [PATCH 4/6] cryptodev: remove queue start/stop functions Pablo de Lara
2018-06-08 22:02  4% ` [dpdk-dev] [PATCH 5/6] cryptodev: remove old get session size functions Pablo de Lara
2018-06-21 12:59  0%   ` Akhil Goyal
2018-06-22 17:02  0%     ` Verma, Shally
2018-06-25 16:40  0%       ` De Lara Guarch, Pablo
2018-06-26  5:28  0%         ` Verma, Shally
2018-06-26  8:17  0%           ` De Lara Guarch, Pablo
2018-06-08 22:02  3% ` [dpdk-dev] [PATCH 6/6] cryptodev: replace mbuf scatter gather flag Pablo de Lara
2018-06-25  8:48     ` [dpdk-dev] [PATCH v2 00/15] Cryptodev API changes for 18.08 Pablo de Lara
2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 01/15] cryptodev: replace bus specific struct with generic dev Pablo de Lara
2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 08/15] cryptodev: define value for unlimited sessions Pablo de Lara
2018-06-25  8:48  2%   ` [dpdk-dev] [PATCH v2 11/15] cryptodev: remove queue start/stop functions Pablo de Lara
2018-06-25  8:48  4%   ` [dpdk-dev] [PATCH v2 12/15] cryptodev: remove old get session size functions Pablo de Lara
2018-06-25  8:48  3%   ` [dpdk-dev] [PATCH v2 13/15] cryptodev: replace mbuf scatter gather flag Pablo de Lara
2018-06-28  0:52     ` [dpdk-dev] [PATCH v3 00/16] Cryptodev API changes for 18.08 Pablo de Lara
2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 01/16] cryptodev: replace bus specific struct with generic dev Pablo de Lara
2018-06-28  0:52  4%   ` [dpdk-dev] [PATCH v3 08/16] cryptodev: define value for unlimited sessions Pablo de Lara
2018-06-28  0:52  2%   ` [dpdk-dev] [PATCH v3 11/16] cryptodev: remove queue start/stop functions Pablo de Lara
2018-06-28  0:53  4%   ` [dpdk-dev] [PATCH v3 12/16] cryptodev: remove old get session size functions Pablo de Lara
2018-06-28  0:53  3%   ` [dpdk-dev] [PATCH v3 13/16] cryptodev: replace mbuf scatter gather flag Pablo de Lara
2018-06-13  9:36  8% [dpdk-dev] [PATCH] cryptodev: fix ABI breakage Pablo de Lara
2018-06-13  9:50  4% ` Ananyev, Konstantin
2018-06-13 10:00  4% ` Gujjar, Abhinandan S
2018-06-27 21:14  4%   ` De Lara Guarch, Pablo
2018-06-17  3:13     [dpdk-dev] [PATCH v2 0/3] Support UDP/IPv4 GSO Jiayu Hu
2018-06-22  5:54     ` [dpdk-dev] [PATCH v3 " Jiayu Hu
2018-06-22  5:54       ` [dpdk-dev] [PATCH v3 1/3] gso: support UDP/IPv4 fragmentation Jiayu Hu
2018-06-26 23:58         ` Ophir Munk
2018-06-27  2:28  3%       ` Hu, Jiayu
2018-06-27  5:05  3%         ` Hu, Jiayu
2018-06-19  6:26     [dpdk-dev] [PATCH 0/2] add head/tailroom requirement for crypto PMDs Anoob Joseph
2018-06-19  6:26     ` [dpdk-dev] [PATCH 1/2] cryptodev: add min headroom and tailroom requirement Anoob Joseph
2018-06-21 14:24       ` Akhil Goyal
2018-06-22  6:52  3%     ` Joseph, Anoob
2018-06-22 10:03  0%       ` Akhil Goyal
2018-06-22 16:37     [dpdk-dev] DPDK 18.05 only works with up to 4 NUMAs systems Kumar, Ravi1
2018-06-25 16:16     ` Burakov, Anatoly
2018-06-28  7:03       ` Kumar, Ravi1
2018-06-28  8:42  3%     ` Burakov, Anatoly
2018-06-27  5:50  4% [dpdk-dev] [PATCH 1/2] compressdev: replace mbuf scatter gather flag Pablo de Lara
2018-06-27 12:16  4% ` [dpdk-dev] [PATCH v2 " Pablo de Lara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).