[dpdk-dev,v6] ethdev: check Rx/Tx offloads

Message ID 1525311040-26694-1-git-send-email-wei.dai@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Wei Dai May 3, 2018, 1:30 a.m. UTC
  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().
From application, a pure per-port offloading can only be enabled in
rte_eth_dev_configure().
Only supported per queue offloading can be sent to
rte_eth_[rt]x_queue_setup( ). A per queue offloading is
enabled only if it is enabled in rte_eth_dev_configure( ) OR
if it is enabled in rte_eth_[rt]x_queue_setup( ).
If a per queue offloading is enabled in rte_eth_dev_configure(),
it can't be disabled in rte_eth_[rt]x_queue_setup( ).
If a per queue offloading is disabled in rte_eth_dev_configure( ),
it can be enabled or disabled( ) in rte_eth_[rt]x_queue_setup( ).

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

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
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.
---
 lib/librte_ether/rte_ethdev.c | 70 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
  

Comments

Ferruh Yigit May 4, 2018, 11:12 a.m. UTC | #1
On 5/3/2018 2:30 AM, Wei Dai wrote:
> 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().
> From application, a pure per-port offloading can only be enabled in
> rte_eth_dev_configure().
> Only supported per queue offloading can be sent to
> rte_eth_[rt]x_queue_setup( ). A per queue offloading is
> enabled only if it is enabled in rte_eth_dev_configure( ) OR
> if it is enabled in rte_eth_[rt]x_queue_setup( ).
> If a per queue offloading is enabled in rte_eth_dev_configure(),
> it can't be disabled in rte_eth_[rt]x_queue_setup( ).
> If a per queue offloading is disabled in rte_eth_dev_configure( ),
> it can be enabled or disabled( ) in rte_eth_[rt]x_queue_setup( ).
> 
> This patch can make above such checking in a common way in rte_ethdev
> layer to avoid same checking in underlying PMD.

Hi Wei, Thomas,

There are a few comments below but there is another concern, this change will
break existing checks in PMDs.
Perhaps this check, PMD updates and update to document API change should go in
one patch, what do you think?

> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> 
> ---
> 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.

<...>

> @@ -1547,6 +1569,30 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
>  						    &local_conf.offloads);
>  	}
>  
> +	/*
> +	 * Only per-queue offload can be enabled from application.
> +	 * If any other offload is sent to this function, return -EINVAL
> +	 */
> +	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 "
> +				    "Requested offload 0x%" PRIx64 "doesn't "
> +				    "match per-queue capability 0x%" PRIx64
> +				    " in %s\n",
> +				    port_id,
> +				    rx_queue_id,
> +				    local_conf.offloads,
> +				    dev_info.rx_queue_offload_capa,
> +				    __func__);
> +		return -EINVAL;
> +	}

Application will be allowed to provide queue or port offload in setup, only
error case should be if application request a port level offload that is not
already enabled in configure()

Also similar check in configure() required, to be sure app is not requesting
offload beyond device capability (port + queue)

> +
> +	/*
> +	 * If an offload has already been enabled in rte_eth_dev_configure(),
> +	 * there is no need to enable it again in queue level.
> +	 */
> +	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;

This is OK, with above check PMD will only observe new queue offload request.

>  	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
>  					      socket_id, &local_conf, mp);
>  	if (!ret) {
> @@ -1681,6 +1727,30 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
>  					  &local_conf.offloads);
>  	}
>  
> +	/*
> +	 * Only per-queue offload can be enabled from applcation.
> +	 * If any other offload is sent to this function, return -EINVAL
> +	 */
> +	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 "
> +				    "Requested offload 0x%" PRIx64 "doesn't "
> +				    "match per-queue capability 0x%" PRIx64
> +				    " in %s\n",
> +				    port_id,
> +				    tx_queue_id,
> +				    local_conf.offloads,
> +				    dev_info.tx_queue_offload_capa,
> +				    __func__);
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * If an offload has already be enabled in rte_eth_dev_configure,
> +	 * there is no need to enable it in queue level again
> +	 */
> +	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
> +
>  	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
>  		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
>  }
>
  

Patch

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f0f53d4..39a0f0e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1196,6 +1196,28 @@  rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 							ETHER_MAX_LEN;
 	}
 
+	/* Any requested offload must be within its device capability */
+	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 "
+				    "capability 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 "
+				    "capability 0x%" PRIx64 "\n",
+				    port_id,
+				    local_conf.txmode.offloads,
+				    dev_info.tx_offload_capa);
+		return -EINVAL;
+	}
+
 	/*
 	 * Setup new number of RX/TX queues and reconfigure device.
 	 */
@@ -1547,6 +1569,30 @@  rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 						    &local_conf.offloads);
 	}
 
+	/*
+	 * Only per-queue offload can be enabled from application.
+	 * If any other offload is sent to this function, return -EINVAL
+	 */
+	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 "
+				    "Requested offload 0x%" PRIx64 "doesn't "
+				    "match per-queue capability 0x%" PRIx64
+				    " in %s\n",
+				    port_id,
+				    rx_queue_id,
+				    local_conf.offloads,
+				    dev_info.rx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * If an offload has already been enabled in rte_eth_dev_configure(),
+	 * there is no need to enable it again in queue level.
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.rxmode.offloads;
+
 	ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
 					      socket_id, &local_conf, mp);
 	if (!ret) {
@@ -1681,6 +1727,30 @@  rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 					  &local_conf.offloads);
 	}
 
+	/*
+	 * Only per-queue offload can be enabled from applcation.
+	 * If any other offload is sent to this function, return -EINVAL
+	 */
+	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 "
+				    "Requested offload 0x%" PRIx64 "doesn't "
+				    "match per-queue capability 0x%" PRIx64
+				    " in %s\n",
+				    port_id,
+				    tx_queue_id,
+				    local_conf.offloads,
+				    dev_info.tx_queue_offload_capa,
+				    __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * If an offload has already be enabled in rte_eth_dev_configure,
+	 * there is no need to enable it in queue level again
+	 */
+	local_conf.offloads &= ~dev->data->dev_conf.txmode.offloads;
+
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }