* [PATCH 01/13] net/intel: introduce infrastructure for Tx path selection
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 10:25 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 02/13] net/ice: use same Tx path across processes Ciara Loftus
` (12 subsequent siblings)
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
The code for determining which Tx path to select during initialisation
has become complicated in many intel drivers due to the amount of
different paths and features available within each path. This commit
aims to simplify and genericize the path selection logic.
The following information about each Tx burst function is stored and
used by the new common function to select the appropriate Tx path:
- Tx Offloads
- SIMD bitwidth
The implementation is based off the Rx path selection infrastructure
introduced in a previous commit.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/common/tx.h | 71 +++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 5af64a4cfe..c6c1904ba3 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
+#include <rte_vect.h>
/* forward declaration of the common intel (ci) queue structure */
struct ci_tx_queue;
@@ -117,6 +118,17 @@ struct ci_tx_queue {
};
};
+struct ci_tx_path_features {
+ uint32_t tx_offloads;
+ enum rte_vect_max_simd simd_width;
+};
+
+struct ci_tx_path_info {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+ struct ci_tx_path_features features;
+};
+
static __rte_always_inline void
ci_tx_backlog_entry(struct ci_tx_entry *txep, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -262,4 +274,63 @@ ci_txq_release_all_mbufs(struct ci_tx_queue *txq, bool use_ctx)
memset(txq->sw_ring_vec, 0, sizeof(txq->sw_ring_vec[0]) * nb_desc);
}
+/**
+ * Select the best matching Tx path based on features
+ *
+ * @param req_features
+ * The requested features for the Tx path
+ * @param infos
+ * Array of information about the available Tx paths
+ * @param num_paths
+ * Number of available paths in the infos array
+ * @param default_path
+ * Index of the default path to use if no suitable path is found
+ *
+ * @return
+ * The packet burst function index that best matches the requested features,
+ * or default_path if no suitable path is found
+ */
+static inline int
+ci_tx_path_select(struct ci_tx_path_features req_features,
+ const struct ci_tx_path_info *infos,
+ int num_paths,
+ int default_path)
+{
+ int i, idx = default_path;
+ const struct ci_tx_path_features *chosen_path_features = NULL;
+
+ for (i = 0; i < num_paths; i++) {
+ const struct ci_tx_path_features *path_features = &infos[i].features;
+
+ /* Ensure the path supports the requested TX offloads. */
+ if ((path_features->tx_offloads & req_features.tx_offloads) !=
+ req_features.tx_offloads)
+ continue;
+
+ /* Ensure the path's SIMD width is compatible with the requested width. */
+ if (path_features->simd_width > req_features.simd_width)
+ continue;
+
+ /* Do not select the path if it is less suitable than the chosen path. */
+ if (chosen_path_features != NULL) {
+ /* Do not select paths with lower SIMD width than the chosen path. */
+ if (path_features->simd_width < chosen_path_features->simd_width)
+ continue;
+ /* Do not select paths with more offloads enabled than the chosen path if
+ * the SIMD widths are the same.
+ */
+ if (path_features->simd_width == chosen_path_features->simd_width &&
+ rte_popcount32(path_features->tx_offloads) >
+ rte_popcount32(chosen_path_features->tx_offloads))
+ continue;
+ }
+
+ /* Finally, select the path since it has met all the requirements. */
+ idx = i;
+ chosen_path_features = &infos[idx].features;
+ }
+
+ return idx;
+}
+
#endif /* _COMMON_INTEL_TX_H_ */
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 01/13] net/intel: introduce infrastructure for Tx path selection
2025-12-09 11:26 ` [PATCH 01/13] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
@ 2025-12-11 10:25 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 10:25 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Tue, Dec 09, 2025 at 11:26:40AM +0000, Ciara Loftus wrote:
> The code for determining which Tx path to select during initialisation
> has become complicated in many intel drivers due to the amount of
> different paths and features available within each path. This commit
> aims to simplify and genericize the path selection logic.
>
> The following information about each Tx burst function is stored and
> used by the new common function to select the appropriate Tx path:
> - Tx Offloads
> - SIMD bitwidth
>
> The implementation is based off the Rx path selection infrastructure
> introduced in a previous commit.
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Generally looks good, a few minor suggestions inline below.
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> drivers/net/intel/common/tx.h | 71 +++++++++++++++++++++++++++++++++++
> 1 file changed, 71 insertions(+)
>
> diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
> index 5af64a4cfe..c6c1904ba3 100644
> --- a/drivers/net/intel/common/tx.h
> +++ b/drivers/net/intel/common/tx.h
> @@ -8,6 +8,7 @@
> #include <stdint.h>
> #include <rte_mbuf.h>
> #include <rte_ethdev.h>
> +#include <rte_vect.h>
>
> /* forward declaration of the common intel (ci) queue structure */
> struct ci_tx_queue;
> @@ -117,6 +118,17 @@ struct ci_tx_queue {
> };
> };
>
> +struct ci_tx_path_features {
> + uint32_t tx_offloads;
> + enum rte_vect_max_simd simd_width;
> +};
> +
> +struct ci_tx_path_info {
> + eth_tx_burst_t pkt_burst;
> + const char *info;
> + struct ci_tx_path_features features;
> +};
> +
> static __rte_always_inline void
> ci_tx_backlog_entry(struct ci_tx_entry *txep, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
> {
> @@ -262,4 +274,63 @@ ci_txq_release_all_mbufs(struct ci_tx_queue *txq, bool use_ctx)
> memset(txq->sw_ring_vec, 0, sizeof(txq->sw_ring_vec[0]) * nb_desc);
> }
>
> +/**
> + * Select the best matching Tx path based on features
> + *
> + * @param req_features
> + * The requested features for the Tx path
> + * @param infos
> + * Array of information about the available Tx paths
> + * @param num_paths
> + * Number of available paths in the infos array
> + * @param default_path
> + * Index of the default path to use if no suitable path is found
> + *
> + * @return
> + * The packet burst function index that best matches the requested features,
> + * or default_path if no suitable path is found
> + */
> +static inline int
> +ci_tx_path_select(struct ci_tx_path_features req_features,
Is there a reason we are passing this by value, rather than as a const
pointer?
> + const struct ci_tx_path_info *infos,
> + int num_paths,
Minor nit: general the size of arrays should be of type "size_t", which
matches the value got from sizeof, and hence RTE_DIM. Since we don't need
to support negative sized arrays, an unsigned type is better generally.
> + int default_path)
> +{
> + int i, idx = default_path;
> + const struct ci_tx_path_features *chosen_path_features = NULL;
> +
> + for (i = 0; i < num_paths; i++) {
If num_paths is size_t, "i" should be an unsigned value to match. I'd also
to prefer that "i" also be defined inside the "for" statement, since its
unneeded outside of it.
> + const struct ci_tx_path_features *path_features = &infos[i].features;
> +
> + /* Ensure the path supports the requested TX offloads. */
> + if ((path_features->tx_offloads & req_features.tx_offloads) !=
> + req_features.tx_offloads)
> + continue;
> +
> + /* Ensure the path's SIMD width is compatible with the requested width. */
> + if (path_features->simd_width > req_features.simd_width)
> + continue;
> +
> + /* Do not select the path if it is less suitable than the chosen path. */
> + if (chosen_path_features != NULL) {
> + /* Do not select paths with lower SIMD width than the chosen path. */
> + if (path_features->simd_width < chosen_path_features->simd_width)
> + continue;
> + /* Do not select paths with more offloads enabled than the chosen path if
> + * the SIMD widths are the same.
> + */
> + if (path_features->simd_width == chosen_path_features->simd_width &&
> + rte_popcount32(path_features->tx_offloads) >
> + rte_popcount32(chosen_path_features->tx_offloads))
> + continue;
> + }
> +
> + /* Finally, select the path since it has met all the requirements. */
> + idx = i;
> + chosen_path_features = &infos[idx].features;
> + }
> +
> + return idx;
> +}
> +
> #endif /* _COMMON_INTEL_TX_H_ */
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 02/13] net/ice: use same Tx path across processes
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
2025-12-09 11:26 ` [PATCH 01/13] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:39 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 03/13] net/ice: use common Tx path selection infrastructure Ciara Loftus
` (11 subsequent siblings)
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
In the interest of simplicity, let the primary process select the Tx
path to be used by all processes using the given device.
The many logs which report individual Tx path selections have been
consolidated into one single log.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/ice/ice_ethdev.c | 1 +
drivers/net/intel/ice/ice_ethdev.h | 12 ++-
drivers/net/intel/ice/ice_rxtx.c | 139 ++++++++++++++++-------------
3 files changed, 87 insertions(+), 65 deletions(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index c721d135f5..a805e78d03 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -3900,6 +3900,7 @@ ice_dev_configure(struct rte_eth_dev *dev)
ad->tx_simple_allowed = true;
ad->rx_func_type = ICE_RX_DEFAULT;
+ ad->tx_func_type = ICE_TX_DEFAULT;
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 72ed65f13b..0b8af339d1 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -208,6 +208,16 @@ enum ice_rx_func_type {
ICE_RX_AVX512_SCATTERED_OFFLOAD,
};
+enum ice_tx_func_type {
+ ICE_TX_DEFAULT,
+ ICE_TX_SIMPLE,
+ ICE_TX_SSE,
+ ICE_TX_AVX2,
+ ICE_TX_AVX2_OFFLOAD,
+ ICE_TX_AVX512,
+ ICE_TX_AVX512_OFFLOAD,
+};
+
struct ice_adapter;
/**
@@ -658,6 +668,7 @@ struct ice_adapter {
bool tx_vec_allowed;
bool tx_simple_allowed;
enum ice_rx_func_type rx_func_type;
+ enum ice_tx_func_type tx_func_type;
/* ptype mapping table */
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[ICE_MAX_PKT_TYPE];
bool is_safe_mode;
@@ -679,7 +690,6 @@ struct ice_adapter {
/* Set bit if the engine is disabled */
unsigned long disabled_engine_mask;
struct ice_parser *psr;
- enum rte_vect_max_simd tx_simd_width;
bool rx_vec_offload_support;
};
diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
index 74db0fbec9..f05ca83e5b 100644
--- a/drivers/net/intel/ice/ice_rxtx.c
+++ b/drivers/net/intel/ice/ice_rxtx.c
@@ -4091,6 +4091,44 @@ ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
return i;
}
+static const struct {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+} ice_tx_burst_infos[] = {
+ [ICE_TX_DEFAULT] = {
+ .pkt_burst = ice_xmit_pkts,
+ .info = "Scalar"
+ },
+ [ICE_TX_SIMPLE] = {
+ .pkt_burst = ice_xmit_pkts_simple,
+ .info = "Scalar Simple"
+ },
+#ifdef RTE_ARCH_X86
+ [ICE_TX_SSE] = {
+ .pkt_burst = ice_xmit_pkts_vec,
+ .info = "Vector SSE"
+ },
+ [ICE_TX_AVX2] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2"
+ },
+ [ICE_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
+ .info = "Offload Vector AVX2"
+ },
+#ifdef CC_AVX512_SUPPORT
+ [ICE_TX_AVX512] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512"
+ },
+ [ICE_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
+ .info = "Offload Vector AVX512"
+ },
+#endif
+#endif
+};
+
void __rte_cold
ice_set_tx_function(struct rte_eth_dev *dev)
{
@@ -4101,74 +4139,58 @@ ice_set_tx_function(struct rte_eth_dev *dev)
struct ci_tx_queue *txq;
int i;
int tx_check_ret = -1;
+ enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ad->tx_simd_width = RTE_VECT_SIMD_DISABLED;
- tx_check_ret = ice_tx_vec_dev_check(dev);
- ad->tx_simd_width = ice_get_max_simd_bitwidth();
- if (tx_check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- ad->tx_vec_allowed = true;
-
- if (ad->tx_simd_width < RTE_VECT_SIMD_256 &&
- tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
- ad->tx_vec_allowed = false;
-
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq && ice_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
+ tx_check_ret = ice_tx_vec_dev_check(dev);
+ tx_simd_width = ice_get_max_simd_bitwidth();
+ if (tx_check_ret >= 0 &&
+ rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
+ ad->tx_vec_allowed = true;
+
+ if (tx_simd_width < RTE_VECT_SIMD_256 &&
+ tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
+ ad->tx_vec_allowed = false;
+
+ if (ad->tx_vec_allowed) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq && ice_txq_vec_setup(txq)) {
+ ad->tx_vec_allowed = false;
+ break;
}
}
- } else {
- ad->tx_vec_allowed = false;
}
+ } else {
+ ad->tx_vec_allowed = false;
}
if (ad->tx_vec_allowed) {
dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
+ if (tx_simd_width == RTE_VECT_SIMD_512) {
#ifdef CC_AVX512_SUPPORT
if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx512_offload;
+ ad->tx_func_type = ICE_TX_AVX512_OFFLOAD;
dev->tx_pkt_prepare = ice_prep_pkts;
} else {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = ice_xmit_pkts_vec_avx512;
+ ad->tx_func_type = ICE_TX_AVX512;
}
#endif
} else {
if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx2_offload;
+ ad->tx_func_type = ICE_TX_AVX2_OFFLOAD;
dev->tx_pkt_prepare = ice_prep_pkts;
} else {
- PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- ice_xmit_pkts_vec_avx2 :
- ice_xmit_pkts_vec;
+ ad->tx_func_type = tx_simd_width == RTE_VECT_SIMD_256 ?
+ ICE_TX_AVX2 :
+ ICE_TX_SSE;
}
}
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
- return;
+ goto out;
}
#endif
@@ -4186,24 +4208,13 @@ ice_set_tx_function(struct rte_eth_dev *dev)
ad->tx_pkt_burst = dev->tx_pkt_burst;
dev->tx_pkt_burst = ice_xmit_pkts_check;
}
-}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} ice_tx_burst_infos[] = {
- { ice_xmit_pkts_simple, "Scalar Simple" },
- { ice_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { ice_xmit_pkts_vec_avx512, "Vector AVX512" },
- { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" },
-#endif
- { ice_xmit_pkts_vec_avx2, "Vector AVX2" },
- { ice_xmit_pkts_vec_avx2_offload, "Offload Vector AVX2" },
- { ice_xmit_pkts_vec, "Vector SSE" },
-#endif
-};
+out:
+ dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
+ ice_tx_burst_infos[ad->tx_func_type].pkt_burst;
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ ice_tx_burst_infos[ad->tx_func_type].info, dev->data->port_id);
+}
int
ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 02/13] net/ice: use same Tx path across processes
2025-12-09 11:26 ` [PATCH 02/13] net/ice: use same Tx path across processes Ciara Loftus
@ 2025-12-11 11:39 ` Bruce Richardson
2025-12-12 10:39 ` Loftus, Ciara
0 siblings, 1 reply; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:39 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Tue, Dec 09, 2025 at 11:26:41AM +0000, Ciara Loftus wrote:
> In the interest of simplicity, let the primary process select the Tx
> path to be used by all processes using the given device.
>
> The many logs which report individual Tx path selections have been
> consolidated into one single log.
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
> drivers/net/intel/ice/ice_ethdev.c | 1 +
> drivers/net/intel/ice/ice_ethdev.h | 12 ++-
> drivers/net/intel/ice/ice_rxtx.c | 139 ++++++++++++++++-------------
> 3 files changed, 87 insertions(+), 65 deletions(-)
>
> diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
> index c721d135f5..a805e78d03 100644
> --- a/drivers/net/intel/ice/ice_ethdev.c
> +++ b/drivers/net/intel/ice/ice_ethdev.c
> @@ -3900,6 +3900,7 @@ ice_dev_configure(struct rte_eth_dev *dev)
> ad->tx_simple_allowed = true;
>
> ad->rx_func_type = ICE_RX_DEFAULT;
> + ad->tx_func_type = ICE_TX_DEFAULT;
>
> if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
> dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
> diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
> index 72ed65f13b..0b8af339d1 100644
> --- a/drivers/net/intel/ice/ice_ethdev.h
> +++ b/drivers/net/intel/ice/ice_ethdev.h
> @@ -208,6 +208,16 @@ enum ice_rx_func_type {
> ICE_RX_AVX512_SCATTERED_OFFLOAD,
> };
>
> +enum ice_tx_func_type {
> + ICE_TX_DEFAULT,
> + ICE_TX_SIMPLE,
> + ICE_TX_SSE,
> + ICE_TX_AVX2,
> + ICE_TX_AVX2_OFFLOAD,
> + ICE_TX_AVX512,
> + ICE_TX_AVX512_OFFLOAD,
> +};
> +
> struct ice_adapter;
>
> /**
> @@ -658,6 +668,7 @@ struct ice_adapter {
> bool tx_vec_allowed;
Can tx_vec_allowed by dropped at this point?
> bool tx_simple_allowed;
> enum ice_rx_func_type rx_func_type;
> + enum ice_tx_func_type tx_func_type;
> /* ptype mapping table */
> alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[ICE_MAX_PKT_TYPE];
> bool is_safe_mode;
> @@ -679,7 +690,6 @@ struct ice_adapter {
> /* Set bit if the engine is disabled */
> unsigned long disabled_engine_mask;
> struct ice_parser *psr;
> - enum rte_vect_max_simd tx_simd_width;
> bool rx_vec_offload_support;
> };
>
> diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
> index 74db0fbec9..f05ca83e5b 100644
> --- a/drivers/net/intel/ice/ice_rxtx.c
> +++ b/drivers/net/intel/ice/ice_rxtx.c
> @@ -4091,6 +4091,44 @@ ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> return i;
> }
>
> +static const struct {
> + eth_tx_burst_t pkt_burst;
> + const char *info;
> +} ice_tx_burst_infos[] = {
> + [ICE_TX_DEFAULT] = {
> + .pkt_burst = ice_xmit_pkts,
> + .info = "Scalar"
> + },
> + [ICE_TX_SIMPLE] = {
> + .pkt_burst = ice_xmit_pkts_simple,
> + .info = "Scalar Simple"
> + },
> +#ifdef RTE_ARCH_X86
> + [ICE_TX_SSE] = {
> + .pkt_burst = ice_xmit_pkts_vec,
> + .info = "Vector SSE"
> + },
> + [ICE_TX_AVX2] = {
> + .pkt_burst = ice_xmit_pkts_vec_avx2,
> + .info = "Vector AVX2"
> + },
> + [ICE_TX_AVX2_OFFLOAD] = {
> + .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
> + .info = "Offload Vector AVX2"
> + },
> +#ifdef CC_AVX512_SUPPORT
> + [ICE_TX_AVX512] = {
> + .pkt_burst = ice_xmit_pkts_vec_avx512,
> + .info = "Vector AVX512"
> + },
> + [ICE_TX_AVX512_OFFLOAD] = {
> + .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
> + .info = "Offload Vector AVX512"
> + },
> +#endif
> +#endif
> +};
> +
> void __rte_cold
> ice_set_tx_function(struct rte_eth_dev *dev)
> {
> @@ -4101,74 +4139,58 @@ ice_set_tx_function(struct rte_eth_dev *dev)
> struct ci_tx_queue *txq;
> int i;
> int tx_check_ret = -1;
> + enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
>
> - if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> - ad->tx_simd_width = RTE_VECT_SIMD_DISABLED;
> - tx_check_ret = ice_tx_vec_dev_check(dev);
> - ad->tx_simd_width = ice_get_max_simd_bitwidth();
> - if (tx_check_ret >= 0 &&
> - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
> - ad->tx_vec_allowed = true;
> -
> - if (ad->tx_simd_width < RTE_VECT_SIMD_256 &&
> - tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
> - ad->tx_vec_allowed = false;
> -
> - if (ad->tx_vec_allowed) {
> - for (i = 0; i < dev->data->nb_tx_queues; i++) {
> - txq = dev->data->tx_queues[i];
> - if (txq && ice_txq_vec_setup(txq)) {
> - ad->tx_vec_allowed = false;
> - break;
> - }
> + /* The primary process selects the tx path for all processes. */
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> + goto out;
> +
> + tx_check_ret = ice_tx_vec_dev_check(dev);
> + tx_simd_width = ice_get_max_simd_bitwidth();
> + if (tx_check_ret >= 0 &&
> + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
> + ad->tx_vec_allowed = true;
> +
> + if (tx_simd_width < RTE_VECT_SIMD_256 &&
> + tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
> + ad->tx_vec_allowed = false;
> +
> + if (ad->tx_vec_allowed) {
> + for (i = 0; i < dev->data->nb_tx_queues; i++) {
> + txq = dev->data->tx_queues[i];
> + if (txq && ice_txq_vec_setup(txq)) {
> + ad->tx_vec_allowed = false;
> + break;
> }
> }
> - } else {
> - ad->tx_vec_allowed = false;
> }
> + } else {
> + ad->tx_vec_allowed = false;
> }
>
> if (ad->tx_vec_allowed) {
> dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
> - if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
> + if (tx_simd_width == RTE_VECT_SIMD_512) {
> #ifdef CC_AVX512_SUPPORT
> if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
> - PMD_DRV_LOG(NOTICE,
> - "Using AVX512 OFFLOAD Vector Tx (port %d).",
> - dev->data->port_id);
> - dev->tx_pkt_burst =
> - ice_xmit_pkts_vec_avx512_offload;
> + ad->tx_func_type = ICE_TX_AVX512_OFFLOAD;
> dev->tx_pkt_prepare = ice_prep_pkts;
> } else {
> - PMD_DRV_LOG(NOTICE,
> - "Using AVX512 Vector Tx (port %d).",
> - dev->data->port_id);
> - dev->tx_pkt_burst = ice_xmit_pkts_vec_avx512;
> + ad->tx_func_type = ICE_TX_AVX512;
> }
> #endif
> } else {
> if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
> - PMD_DRV_LOG(NOTICE,
> - "Using AVX2 OFFLOAD Vector Tx (port %d).",
> - dev->data->port_id);
> - dev->tx_pkt_burst =
> - ice_xmit_pkts_vec_avx2_offload;
> + ad->tx_func_type = ICE_TX_AVX2_OFFLOAD;
> dev->tx_pkt_prepare = ice_prep_pkts;
> } else {
> - PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).",
> - ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
> - dev->data->port_id);
> - dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
> - ice_xmit_pkts_vec_avx2 :
> - ice_xmit_pkts_vec;
> + ad->tx_func_type = tx_simd_width == RTE_VECT_SIMD_256 ?
> + ICE_TX_AVX2 :
> + ICE_TX_SSE;
> }
> }
>
> - if (mbuf_check) {
> - ad->tx_pkt_burst = dev->tx_pkt_burst;
> - dev->tx_pkt_burst = ice_xmit_pkts_check;
> - }
> - return;
> + goto out;
> }
> #endif
>
> @@ -4186,24 +4208,13 @@ ice_set_tx_function(struct rte_eth_dev *dev)
> ad->tx_pkt_burst = dev->tx_pkt_burst;
> dev->tx_pkt_burst = ice_xmit_pkts_check;
> }
> -}
>
> -static const struct {
> - eth_tx_burst_t pkt_burst;
> - const char *info;
> -} ice_tx_burst_infos[] = {
> - { ice_xmit_pkts_simple, "Scalar Simple" },
> - { ice_xmit_pkts, "Scalar" },
> -#ifdef RTE_ARCH_X86
> -#ifdef CC_AVX512_SUPPORT
> - { ice_xmit_pkts_vec_avx512, "Vector AVX512" },
> - { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" },
> -#endif
> - { ice_xmit_pkts_vec_avx2, "Vector AVX2" },
> - { ice_xmit_pkts_vec_avx2_offload, "Offload Vector AVX2" },
> - { ice_xmit_pkts_vec, "Vector SSE" },
> -#endif
> -};
Looking at the code with this patch applied, I think there may be an issue
with the scalar case in this version. At line 4197 we have a block which
assigns a value to tx_pkt_burst and tx_burst_prepare, but does not assign a
value to the tx_func_type values. That means when it falls through into the
"out" section, the function point for pkt_burst get overwritten.
> +out:
> + dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
> + ice_tx_burst_infos[ad->tx_func_type].pkt_burst;
> + PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
> + ice_tx_burst_infos[ad->tx_func_type].info, dev->data->port_id);
> +}
>
> int
> ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread* RE: [PATCH 02/13] net/ice: use same Tx path across processes
2025-12-11 11:39 ` Bruce Richardson
@ 2025-12-12 10:39 ` Loftus, Ciara
0 siblings, 0 replies; 48+ messages in thread
From: Loftus, Ciara @ 2025-12-12 10:39 UTC (permalink / raw)
To: Richardson, Bruce; +Cc: dev
>
> On Tue, Dec 09, 2025 at 11:26:41AM +0000, Ciara Loftus wrote:
> > In the interest of simplicity, let the primary process select the Tx
> > path to be used by all processes using the given device.
> >
> > The many logs which report individual Tx path selections have been
> > consolidated into one single log.
> >
> > Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> > ---
> > drivers/net/intel/ice/ice_ethdev.c | 1 +
> > drivers/net/intel/ice/ice_ethdev.h | 12 ++-
> > drivers/net/intel/ice/ice_rxtx.c | 139 ++++++++++++++++-------------
> > 3 files changed, 87 insertions(+), 65 deletions(-)
> >
> > diff --git a/drivers/net/intel/ice/ice_ethdev.c
> b/drivers/net/intel/ice/ice_ethdev.c
> > index c721d135f5..a805e78d03 100644
> > --- a/drivers/net/intel/ice/ice_ethdev.c
> > +++ b/drivers/net/intel/ice/ice_ethdev.c
> > @@ -3900,6 +3900,7 @@ ice_dev_configure(struct rte_eth_dev *dev)
> > ad->tx_simple_allowed = true;
> >
> > ad->rx_func_type = ICE_RX_DEFAULT;
> > + ad->tx_func_type = ICE_TX_DEFAULT;
> >
> > if (dev->data->dev_conf.rxmode.mq_mode &
> RTE_ETH_MQ_RX_RSS_FLAG)
> > dev->data->dev_conf.rxmode.offloads |=
> RTE_ETH_RX_OFFLOAD_RSS_HASH;
> > diff --git a/drivers/net/intel/ice/ice_ethdev.h
> b/drivers/net/intel/ice/ice_ethdev.h
> > index 72ed65f13b..0b8af339d1 100644
> > --- a/drivers/net/intel/ice/ice_ethdev.h
> > +++ b/drivers/net/intel/ice/ice_ethdev.h
> > @@ -208,6 +208,16 @@ enum ice_rx_func_type {
> > ICE_RX_AVX512_SCATTERED_OFFLOAD,
> > };
> >
> > +enum ice_tx_func_type {
> > + ICE_TX_DEFAULT,
> > + ICE_TX_SIMPLE,
> > + ICE_TX_SSE,
> > + ICE_TX_AVX2,
> > + ICE_TX_AVX2_OFFLOAD,
> > + ICE_TX_AVX512,
> > + ICE_TX_AVX512_OFFLOAD,
> > +};
> > +
> > struct ice_adapter;
> >
> > /**
> > @@ -658,6 +668,7 @@ struct ice_adapter {
> > bool tx_vec_allowed;
>
> Can tx_vec_allowed by dropped at this point?
In this driver I don't think so, as it's used during ice_tx_done_cleanup() to select
the appropriate cleanup function. If we were to remove it we would need to
evaluate something like the following every time instead of using the bool:
ice_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_128
>
> > bool tx_simple_allowed;
> > enum ice_rx_func_type rx_func_type;
> > + enum ice_tx_func_type tx_func_type;
> > /* ptype mapping table */
> > alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t
> ptype_tbl[ICE_MAX_PKT_TYPE];
> > bool is_safe_mode;
> > @@ -679,7 +690,6 @@ struct ice_adapter {
> > /* Set bit if the engine is disabled */
> > unsigned long disabled_engine_mask;
> > struct ice_parser *psr;
> > - enum rte_vect_max_simd tx_simd_width;
> > bool rx_vec_offload_support;
> > };
> >
> > diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
> > index 74db0fbec9..f05ca83e5b 100644
> > --- a/drivers/net/intel/ice/ice_rxtx.c
> > +++ b/drivers/net/intel/ice/ice_rxtx.c
> > @@ -4091,6 +4091,44 @@ ice_prep_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts,
> > return i;
> > }
> >
> > +static const struct {
> > + eth_tx_burst_t pkt_burst;
> > + const char *info;
> > +} ice_tx_burst_infos[] = {
> > + [ICE_TX_DEFAULT] = {
> > + .pkt_burst = ice_xmit_pkts,
> > + .info = "Scalar"
> > + },
> > + [ICE_TX_SIMPLE] = {
> > + .pkt_burst = ice_xmit_pkts_simple,
> > + .info = "Scalar Simple"
> > + },
> > +#ifdef RTE_ARCH_X86
> > + [ICE_TX_SSE] = {
> > + .pkt_burst = ice_xmit_pkts_vec,
> > + .info = "Vector SSE"
> > + },
> > + [ICE_TX_AVX2] = {
> > + .pkt_burst = ice_xmit_pkts_vec_avx2,
> > + .info = "Vector AVX2"
> > + },
> > + [ICE_TX_AVX2_OFFLOAD] = {
> > + .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
> > + .info = "Offload Vector AVX2"
> > + },
> > +#ifdef CC_AVX512_SUPPORT
> > + [ICE_TX_AVX512] = {
> > + .pkt_burst = ice_xmit_pkts_vec_avx512,
> > + .info = "Vector AVX512"
> > + },
> > + [ICE_TX_AVX512_OFFLOAD] = {
> > + .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
> > + .info = "Offload Vector AVX512"
> > + },
> > +#endif
> > +#endif
> > +};
> > +
> > void __rte_cold
> > ice_set_tx_function(struct rte_eth_dev *dev)
> > {
> > @@ -4101,74 +4139,58 @@ ice_set_tx_function(struct rte_eth_dev *dev)
> > struct ci_tx_queue *txq;
> > int i;
> > int tx_check_ret = -1;
> > + enum rte_vect_max_simd tx_simd_width =
> RTE_VECT_SIMD_DISABLED;
> >
> > - if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > - ad->tx_simd_width = RTE_VECT_SIMD_DISABLED;
> > - tx_check_ret = ice_tx_vec_dev_check(dev);
> > - ad->tx_simd_width = ice_get_max_simd_bitwidth();
> > - if (tx_check_ret >= 0 &&
> > - rte_vect_get_max_simd_bitwidth() >=
> RTE_VECT_SIMD_128) {
> > - ad->tx_vec_allowed = true;
> > -
> > - if (ad->tx_simd_width < RTE_VECT_SIMD_256 &&
> > - tx_check_ret ==
> ICE_VECTOR_OFFLOAD_PATH)
> > - ad->tx_vec_allowed = false;
> > -
> > - if (ad->tx_vec_allowed) {
> > - for (i = 0; i < dev->data->nb_tx_queues; i++) {
> > - txq = dev->data->tx_queues[i];
> > - if (txq && ice_txq_vec_setup(txq)) {
> > - ad->tx_vec_allowed = false;
> > - break;
> > - }
> > + /* The primary process selects the tx path for all processes. */
> > + if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> > + goto out;
> > +
> > + tx_check_ret = ice_tx_vec_dev_check(dev);
> > + tx_simd_width = ice_get_max_simd_bitwidth();
> > + if (tx_check_ret >= 0 &&
> > + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
> {
> > + ad->tx_vec_allowed = true;
> > +
> > + if (tx_simd_width < RTE_VECT_SIMD_256 &&
> > + tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
> > + ad->tx_vec_allowed = false;
> > +
> > + if (ad->tx_vec_allowed) {
> > + for (i = 0; i < dev->data->nb_tx_queues; i++) {
> > + txq = dev->data->tx_queues[i];
> > + if (txq && ice_txq_vec_setup(txq)) {
> > + ad->tx_vec_allowed = false;
> > + break;
> > }
> > }
> > - } else {
> > - ad->tx_vec_allowed = false;
> > }
> > + } else {
> > + ad->tx_vec_allowed = false;
> > }
> >
> > if (ad->tx_vec_allowed) {
> > dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
> > - if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
> > + if (tx_simd_width == RTE_VECT_SIMD_512) {
> > #ifdef CC_AVX512_SUPPORT
> > if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
> > - PMD_DRV_LOG(NOTICE,
> > - "Using AVX512 OFFLOAD Vector Tx
> (port %d).",
> > - dev->data->port_id);
> > - dev->tx_pkt_burst =
> > - ice_xmit_pkts_vec_avx512_offload;
> > + ad->tx_func_type =
> ICE_TX_AVX512_OFFLOAD;
> > dev->tx_pkt_prepare = ice_prep_pkts;
> > } else {
> > - PMD_DRV_LOG(NOTICE,
> > - "Using AVX512 Vector Tx (port
> %d).",
> > - dev->data->port_id);
> > - dev->tx_pkt_burst =
> ice_xmit_pkts_vec_avx512;
> > + ad->tx_func_type = ICE_TX_AVX512;
> > }
> > #endif
> > } else {
> > if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
> > - PMD_DRV_LOG(NOTICE,
> > - "Using AVX2 OFFLOAD Vector Tx
> (port %d).",
> > - dev->data->port_id);
> > - dev->tx_pkt_burst =
> > - ice_xmit_pkts_vec_avx2_offload;
> > + ad->tx_func_type = ICE_TX_AVX2_OFFLOAD;
> > dev->tx_pkt_prepare = ice_prep_pkts;
> > } else {
> > - PMD_DRV_LOG(DEBUG, "Using %sVector Tx
> (port %d).",
> > - ad->tx_simd_width ==
> RTE_VECT_SIMD_256 ? "avx2 " : "",
> > - dev->data->port_id);
> > - dev->tx_pkt_burst = ad->tx_simd_width ==
> RTE_VECT_SIMD_256 ?
> > - ice_xmit_pkts_vec_avx2 :
> > - ice_xmit_pkts_vec;
> > + ad->tx_func_type = tx_simd_width ==
> RTE_VECT_SIMD_256 ?
> > + ICE_TX_AVX2 :
> > + ICE_TX_SSE;
> > }
> > }
> >
> > - if (mbuf_check) {
> > - ad->tx_pkt_burst = dev->tx_pkt_burst;
> > - dev->tx_pkt_burst = ice_xmit_pkts_check;
> > - }
> > - return;
> > + goto out;
> > }
> > #endif
> >
> > @@ -4186,24 +4208,13 @@ ice_set_tx_function(struct rte_eth_dev *dev)
> > ad->tx_pkt_burst = dev->tx_pkt_burst;
> > dev->tx_pkt_burst = ice_xmit_pkts_check;
> > }
> > -}
> >
> > -static const struct {
> > - eth_tx_burst_t pkt_burst;
> > - const char *info;
> > -} ice_tx_burst_infos[] = {
> > - { ice_xmit_pkts_simple, "Scalar Simple" },
> > - { ice_xmit_pkts, "Scalar" },
> > -#ifdef RTE_ARCH_X86
> > -#ifdef CC_AVX512_SUPPORT
> > - { ice_xmit_pkts_vec_avx512, "Vector AVX512" },
> > - { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" },
> > -#endif
> > - { ice_xmit_pkts_vec_avx2, "Vector AVX2" },
> > - { ice_xmit_pkts_vec_avx2_offload, "Offload Vector AVX2" },
> > - { ice_xmit_pkts_vec, "Vector SSE" },
> > -#endif
> > -};
>
> Looking at the code with this patch applied, I think there may be an issue
> with the scalar case in this version. At line 4197 we have a block which
> assigns a value to tx_pkt_burst and tx_burst_prepare, but does not assign a
> value to the tx_func_type values. That means when it falls through into the
> "out" section, the function point for pkt_burst get overwritten.
This should be fixed in the v2.
>
> > +out:
> > + dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
> > + ice_tx_burst_infos[ad-
> >tx_func_type].pkt_burst;
> > + PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
> > + ice_tx_burst_infos[ad->tx_func_type].info, dev->data-
> >port_id);
> > +}
> >
> > int
> > ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t
> queue_id,
> > --
> > 2.43.0
> >
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 03/13] net/ice: use common Tx path selection infrastructure
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
2025-12-09 11:26 ` [PATCH 01/13] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
2025-12-09 11:26 ` [PATCH 02/13] net/ice: use same Tx path across processes Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:56 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 04/13] net/iavf: use same Tx path across processes Ciara Loftus
` (10 subsequent siblings)
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Introduce a new feature "simple tx" to the common
infrastructure which represents whether or not a simplified transmit
path may be selected for the device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/common/tx.h | 10 ++
drivers/net/intel/ice/ice_rxtx.c | 142 +++++++++-----------
drivers/net/intel/ice/ice_rxtx.h | 30 ++++-
drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +----
drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
5 files changed, 103 insertions(+), 120 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index c6c1904ba3..3480c5e07c 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -118,15 +118,21 @@ struct ci_tx_queue {
};
};
+struct ci_tx_path_features_extra {
+ bool simple_tx;
+};
+
struct ci_tx_path_features {
uint32_t tx_offloads;
enum rte_vect_max_simd simd_width;
+ struct ci_tx_path_features_extra extra;
};
struct ci_tx_path_info {
eth_tx_burst_t pkt_burst;
const char *info;
struct ci_tx_path_features features;
+ eth_tx_prep_t pkt_prep;
};
static __rte_always_inline void
@@ -302,6 +308,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
for (i = 0; i < num_paths; i++) {
const struct ci_tx_path_features *path_features = &infos[i].features;
+ /* Do not use a simple tx path if not requested. */
+ if (path_features->extra.simple_tx && !req_features.extra.simple_tx)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features.tx_offloads) !=
req_features.tx_offloads)
diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
index f05ca83e5b..ca9cdc9618 100644
--- a/drivers/net/intel/ice/ice_rxtx.c
+++ b/drivers/net/intel/ice/ice_rxtx.c
@@ -4091,39 +4091,70 @@ ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
return i;
}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} ice_tx_burst_infos[] = {
+static const struct ci_tx_path_info ice_tx_path_infos[] = {
[ICE_TX_DEFAULT] = {
.pkt_burst = ice_xmit_pkts,
- .info = "Scalar"
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS
+ },
+ .pkt_prep = ice_prep_pkts
},
[ICE_TX_SIMPLE] = {
.pkt_burst = ice_xmit_pkts_simple,
- .info = "Scalar Simple"
+ .info = "Scalar Simple",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS,
+ .extra.simple_tx = true
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
},
#ifdef RTE_ARCH_X86
[ICE_TX_SSE] = {
.pkt_burst = ice_xmit_pkts_vec,
- .info = "Vector SSE"
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
},
[ICE_TX_AVX2] = {
.pkt_burst = ice_xmit_pkts_vec_avx2,
- .info = "Vector AVX2"
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
},
[ICE_TX_AVX2_OFFLOAD] = {
.pkt_burst = ice_xmit_pkts_vec_avx2_offload,
- .info = "Offload Vector AVX2"
+ .info = "Offload Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = ice_prep_pkts
},
#ifdef CC_AVX512_SUPPORT
[ICE_TX_AVX512] = {
.pkt_burst = ice_xmit_pkts_vec_avx512,
- .info = "Vector AVX512"
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
},
[ICE_TX_AVX512_OFFLOAD] = {
.pkt_burst = ice_xmit_pkts_vec_avx512_offload,
- .info = "Offload Vector AVX512"
+ .info = "Offload Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = ice_prep_pkts
},
#endif
#endif
@@ -4135,85 +4166,36 @@ ice_set_tx_function(struct rte_eth_dev *dev)
struct ice_adapter *ad =
ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
int mbuf_check = ad->devargs.mbuf_check;
-#ifdef RTE_ARCH_X86
- struct ci_tx_queue *txq;
- int i;
- int tx_check_ret = -1;
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
/* The primary process selects the tx path for all processes. */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
goto out;
- tx_check_ret = ice_tx_vec_dev_check(dev);
- tx_simd_width = ice_get_max_simd_bitwidth();
- if (tx_check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- ad->tx_vec_allowed = true;
-
- if (tx_simd_width < RTE_VECT_SIMD_256 &&
- tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
- ad->tx_vec_allowed = false;
+ req_features.extra.simple_tx = ad->tx_simple_allowed;
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq && ice_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- } else {
- ad->tx_vec_allowed = false;
- }
-
- if (ad->tx_vec_allowed) {
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- if (tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- ad->tx_func_type = ICE_TX_AVX512_OFFLOAD;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- ad->tx_func_type = ICE_TX_AVX512;
- }
-#endif
- } else {
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- ad->tx_func_type = ICE_TX_AVX2_OFFLOAD;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- ad->tx_func_type = tx_simd_width == RTE_VECT_SIMD_256 ?
- ICE_TX_AVX2 :
- ICE_TX_SSE;
- }
- }
-
- goto out;
- }
+#ifdef RTE_ARCH_X86
+ if (ice_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = ice_get_max_simd_bitwidth();
#endif
- if (ad->tx_simple_allowed) {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts_simple;
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- } else {
- PMD_INIT_LOG(DEBUG, "Normal tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts;
- dev->tx_pkt_prepare = ice_prep_pkts;
- }
+ ad->tx_func_type = ci_tx_path_select(req_features,
+ &ice_tx_path_infos[0],
+ RTE_DIM(ice_tx_path_infos),
+ ICE_TX_DEFAULT);
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
+ if (ice_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_128)
+ ad->tx_vec_allowed = true;
out:
dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
- ice_tx_burst_infos[ad->tx_func_type].pkt_burst;
+ ice_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = ice_tx_path_infos[ad->tx_func_type].pkt_prep;
PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
- ice_tx_burst_infos[ad->tx_func_type].info, dev->data->port_id);
+ ice_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
}
int
@@ -4224,10 +4206,10 @@ ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(ice_tx_burst_infos); ++i) {
- if (pkt_burst == ice_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(ice_tx_path_infos); ++i) {
+ if (pkt_burst == ice_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- ice_tx_burst_infos[i].info);
+ ice_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/ice/ice_rxtx.h b/drivers/net/intel/ice/ice_rxtx.h
index 141a62a7da..d7e8c1b0c4 100644
--- a/drivers/net/intel/ice/ice_rxtx.h
+++ b/drivers/net/intel/ice/ice_rxtx.h
@@ -108,6 +108,35 @@
RTE_ETH_RX_OFFLOAD_VLAN_FILTER |\
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+/* basic scalar path */
+#define ICE_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
+/* basic vector path */
+#define ICE_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* vector offload paths */
+#define ICE_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ ICE_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)
+
/* Max header size can be 2K - 64 bytes */
#define ICE_RX_HDR_BUF_SIZE (2048 - 64)
@@ -249,7 +278,6 @@ void ice_select_rxd_to_pkt_fields_handler(struct ci_rx_queue *rxq,
int ice_rx_vec_dev_check(struct rte_eth_dev *dev);
int ice_tx_vec_dev_check(struct rte_eth_dev *dev);
int ice_rxq_vec_setup(struct ci_rx_queue *rxq);
-int ice_txq_vec_setup(struct ci_tx_queue *txq);
uint16_t ice_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
uint16_t ice_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_common.h b/drivers/net/intel/ice/ice_rxtx_vec_common.h
index 39581cb7ae..ff46a8fb49 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_common.h
+++ b/drivers/net/intel/ice/ice_rxtx_vec_common.h
@@ -51,28 +51,6 @@ _ice_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq)
memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
}
-#define ICE_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
- RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
-
-#define ICE_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define ICE_VECTOR_PATH 0
-#define ICE_VECTOR_OFFLOAD_PATH 1
-
static inline int
ice_rx_vec_queue_default(struct ci_rx_queue *rxq)
{
@@ -98,13 +76,7 @@ ice_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > ICE_TX_MAX_FREE_BUF_SZ)
return -1;
- if (txq->offloads & ICE_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (txq->offloads & ICE_TX_VECTOR_OFFLOAD)
- return ICE_VECTOR_OFFLOAD_PATH;
-
- return ICE_VECTOR_PATH;
+ return 0;
}
static inline int
@@ -130,18 +102,15 @@ ice_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret = 0;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = ice_tx_vec_queue_default(txq);
if (ret < 0)
return -1;
- if (ret == ICE_VECTOR_OFFLOAD_PATH)
- result = ret;
}
- return result;
+ return ret;
}
static inline void
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_sse.c b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
index 1545bc3b6e..4fc1b7e881 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_sse.c
+++ b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
@@ -718,12 +718,6 @@ ice_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-ice_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
ice_rx_vec_dev_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 03/13] net/ice: use common Tx path selection infrastructure
2025-12-09 11:26 ` [PATCH 03/13] net/ice: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-11 11:56 ` Bruce Richardson
2025-12-11 12:02 ` Bruce Richardson
0 siblings, 1 reply; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:56 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Tue, Dec 09, 2025 at 11:26:42AM +0000, Ciara Loftus wrote:
> Replace the existing complicated logic with the use of the common
> function. Introduce a new feature "simple tx" to the common
> infrastructure which represents whether or not a simplified transmit
> path may be selected for the device.
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
> drivers/net/intel/common/tx.h | 10 ++
> drivers/net/intel/ice/ice_rxtx.c | 142 +++++++++-----------
> drivers/net/intel/ice/ice_rxtx.h | 30 ++++-
> drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +----
> drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
> 5 files changed, 103 insertions(+), 120 deletions(-)
>
> diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
> index c6c1904ba3..3480c5e07c 100644
> --- a/drivers/net/intel/common/tx.h
> +++ b/drivers/net/intel/common/tx.h
> @@ -118,15 +118,21 @@ struct ci_tx_queue {
> };
> };
>
> +struct ci_tx_path_features_extra {
> + bool simple_tx;
> +};
> +
> struct ci_tx_path_features {
> uint32_t tx_offloads;
> enum rte_vect_max_simd simd_width;
> + struct ci_tx_path_features_extra extra;
Two thoughts on this - do we really need a substructure here rather than
just adding the flags directly to the path_features structure? Secondly,
should this addition not be included in patch 1, which adds the rest of the
support for the tx path selection logic? I don't see a reason to put half
the infrastructure there and the rest here.
> };
>
> struct ci_tx_path_info {
> eth_tx_burst_t pkt_burst;
> const char *info;
> struct ci_tx_path_features features;
> + eth_tx_prep_t pkt_prep;
> };
Similar comment here - should the pkt_prep function not be in place from
the first patch?
>
> static __rte_always_inline void
> @@ -302,6 +308,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
> for (i = 0; i < num_paths; i++) {
> const struct ci_tx_path_features *path_features = &infos[i].features;
>
> + /* Do not use a simple tx path if not requested. */
> + if (path_features->extra.simple_tx && !req_features.extra.simple_tx)
> + continue;
> +
> /* Ensure the path supports the requested TX offloads. */
> if ((path_features->tx_offloads & req_features.tx_offloads) !=
> req_features.tx_offloads)
> diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
> index f05ca83e5b..ca9cdc9618 100644
> --- a/drivers/net/intel/ice/ice_rxtx.c
> +++ b/drivers/net/intel/ice/ice_rxtx.c
> @@ -4091,39 +4091,70 @@ ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> return i;
> }
>
> -static const struct {
> - eth_tx_burst_t pkt_burst;
> - const char *info;
> -} ice_tx_burst_infos[] = {
> +static const struct ci_tx_path_info ice_tx_path_infos[] = {
> [ICE_TX_DEFAULT] = {
> .pkt_burst = ice_xmit_pkts,
> - .info = "Scalar"
> + .info = "Scalar",
> + .features = {
> + .tx_offloads = ICE_TX_SCALAR_OFFLOADS
> + },
> + .pkt_prep = ice_prep_pkts
> },
> [ICE_TX_SIMPLE] = {
> .pkt_burst = ice_xmit_pkts_simple,
> - .info = "Scalar Simple"
> + .info = "Scalar Simple",
> + .features = {
> + .tx_offloads = ICE_TX_SCALAR_OFFLOADS,
> + .extra.simple_tx = true
> + },
> + .pkt_prep = rte_eth_tx_pkt_prepare_dummy
> },
> #ifdef RTE_ARCH_X86
> [ICE_TX_SSE] = {
> .pkt_burst = ice_xmit_pkts_vec,
> - .info = "Vector SSE"
> + .info = "Vector SSE",
> + .features = {
> + .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
> + .simd_width = RTE_VECT_SIMD_128
> + },
> + .pkt_prep = rte_eth_tx_pkt_prepare_dummy
> },
> [ICE_TX_AVX2] = {
> .pkt_burst = ice_xmit_pkts_vec_avx2,
> - .info = "Vector AVX2"
> + .info = "Vector AVX2",
> + .features = {
> + .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
> + .simd_width = RTE_VECT_SIMD_256
> + },
> + .pkt_prep = rte_eth_tx_pkt_prepare_dummy
> },
> [ICE_TX_AVX2_OFFLOAD] = {
> .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
> - .info = "Offload Vector AVX2"
> + .info = "Offload Vector AVX2",
> + .features = {
> + .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
> + .simd_width = RTE_VECT_SIMD_256
> + },
> + .pkt_prep = ice_prep_pkts
> },
> #ifdef CC_AVX512_SUPPORT
> [ICE_TX_AVX512] = {
> .pkt_burst = ice_xmit_pkts_vec_avx512,
> - .info = "Vector AVX512"
> + .info = "Vector AVX512",
> + .features = {
> + .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
> + .simd_width = RTE_VECT_SIMD_512
> + },
> + .pkt_prep = rte_eth_tx_pkt_prepare_dummy
> },
> [ICE_TX_AVX512_OFFLOAD] = {
> .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
> - .info = "Offload Vector AVX512"
> + .info = "Offload Vector AVX512",
> + .features = {
> + .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
> + .simd_width = RTE_VECT_SIMD_512
> + },
> + .pkt_prep = ice_prep_pkts
> },
> #endif
> #endif
> @@ -4135,85 +4166,36 @@ ice_set_tx_function(struct rte_eth_dev *dev)
> struct ice_adapter *ad =
> ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> int mbuf_check = ad->devargs.mbuf_check;
> -#ifdef RTE_ARCH_X86
> - struct ci_tx_queue *txq;
> - int i;
> - int tx_check_ret = -1;
> - enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
> + struct ci_tx_path_features req_features = {
> + .tx_offloads = dev->data->dev_conf.txmode.offloads,
> + .simd_width = RTE_VECT_SIMD_DISABLED,
> + };
>
> /* The primary process selects the tx path for all processes. */
> if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> goto out;
>
> - tx_check_ret = ice_tx_vec_dev_check(dev);
> - tx_simd_width = ice_get_max_simd_bitwidth();
> - if (tx_check_ret >= 0 &&
> - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
> - ad->tx_vec_allowed = true;
> -
> - if (tx_simd_width < RTE_VECT_SIMD_256 &&
> - tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
> - ad->tx_vec_allowed = false;
> + req_features.extra.simple_tx = ad->tx_simple_allowed;
>
> - if (ad->tx_vec_allowed) {
> - for (i = 0; i < dev->data->nb_tx_queues; i++) {
> - txq = dev->data->tx_queues[i];
> - if (txq && ice_txq_vec_setup(txq)) {
> - ad->tx_vec_allowed = false;
> - break;
> - }
> - }
> - }
> - } else {
> - ad->tx_vec_allowed = false;
> - }
> -
This code being removed was reworked in the previous patch. Do you think it
would be as simple to merge this patch with the previous one, rather than
adjusting the code twice?
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 03/13] net/ice: use common Tx path selection infrastructure
2025-12-11 11:56 ` Bruce Richardson
@ 2025-12-11 12:02 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 12:02 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Thu, Dec 11, 2025 at 11:56:12AM +0000, Bruce Richardson wrote:
> On Tue, Dec 09, 2025 at 11:26:42AM +0000, Ciara Loftus wrote:
> > Replace the existing complicated logic with the use of the common
> > function. Introduce a new feature "simple tx" to the common
> > infrastructure which represents whether or not a simplified transmit
> > path may be selected for the device.
> >
> > Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> > ---
> > drivers/net/intel/common/tx.h | 10 ++
> > drivers/net/intel/ice/ice_rxtx.c | 142 +++++++++-----------
> > drivers/net/intel/ice/ice_rxtx.h | 30 ++++-
> > drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +----
> > drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
> > 5 files changed, 103 insertions(+), 120 deletions(-)
> >
> > diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
> > index c6c1904ba3..3480c5e07c 100644
> > --- a/drivers/net/intel/common/tx.h
> > +++ b/drivers/net/intel/common/tx.h
> > @@ -118,15 +118,21 @@ struct ci_tx_queue {
> > };
> > };
> >
> > +struct ci_tx_path_features_extra {
> > + bool simple_tx;
> > +};
> > +
> > struct ci_tx_path_features {
> > uint32_t tx_offloads;
> > enum rte_vect_max_simd simd_width;
> > + struct ci_tx_path_features_extra extra;
>
> Two thoughts on this - do we really need a substructure here rather than
> just adding the flags directly to the path_features structure? Secondly,
> should this addition not be included in patch 1, which adds the rest of the
> support for the tx path selection logic? I don't see a reason to put half
> the infrastructure there and the rest here.
>
Just as follow-up here. I see there are more extra features added in later
drivers, but those (AFAIK) are pretty much limited to the drivers adding
them. Multiple drivers have simple scalar paths so I think this could be
part of the base infrastructure in patch one, while the others can stay
with their individual drivers.
/Bruce
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 04/13] net/iavf: use same Tx path across processes
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (2 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 03/13] net/ice: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 05/13] net/iavf: use common Tx path selection infrastructure Ciara Loftus
` (9 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
In the interest of simplicity, let the primary process select the Tx
path to be used by all processes using the given device.
The many logs which report individual Tx path selections have been
consolidated into one single log.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/iavf/iavf_ethdev.c | 5 +-
drivers/net/intel/iavf/iavf_rxtx.c | 90 ++++++++++------------------
2 files changed, 34 insertions(+), 61 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 15e49fe248..ab65e99f68 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -671,6 +671,8 @@ iavf_dev_configure(struct rte_eth_dev *dev)
*/
ad->tx_vec_allowed = true;
+ ad->tx_func_type = IAVF_TX_DEFAULT;
+
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
@@ -2795,8 +2797,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->tx_pkt_prepare = &iavf_prep_pkts;
/* For secondary processes, we don't initialise any further as primary
- * has already done this work. Only check if we need a different RX
- * and TX function.
+ * has already done this work.
*/
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
iavf_set_rx_function(eth_dev);
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c b/drivers/net/intel/iavf/iavf_rxtx.c
index d8662fd815..055b2b0ae0 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -4229,7 +4229,6 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
{
struct iavf_adapter *adapter =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- enum iavf_tx_func_type tx_func_type;
int mbuf_check = adapter->devargs.mbuf_check;
int no_poll_on_link_down = adapter->devargs.no_poll_on_link_down;
#ifdef RTE_ARCH_X86
@@ -4241,6 +4240,10 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
bool use_avx512 = false;
enum rte_vect_max_simd tx_simd_path = iavf_get_max_simd_bitwidth();
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
check_ret = iavf_tx_vec_dev_check(dev);
if (check_ret >= 0 &&
@@ -4254,47 +4257,29 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
use_avx512 = tx_simd_path == RTE_VECT_SIMD_512;
if (!use_sse && !use_avx2 && !use_avx512)
- goto normal;
+ goto out;
+
+ if (use_sse)
+ adapter->tx_func_type = IAVF_TX_SSE;
- if (use_sse) {
- PMD_DRV_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_SSE;
- }
if (!use_avx512 && use_avx2) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX2;
- PMD_DRV_LOG(DEBUG, "Using AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_OFFLOAD_PATH) {
- PMD_DRV_LOG(DEBUG,
- "AVX2 does not support requested Tx offloads.");
- goto normal;
- } else {
- tx_func_type = IAVF_TX_AVX2_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
+ if (check_ret == IAVF_VECTOR_PATH)
+ adapter->tx_func_type = IAVF_TX_AVX2;
+ else if (check_ret == IAVF_VECTOR_CTX_OFFLOAD_PATH)
+ goto out;
+ else
+ adapter->tx_func_type = IAVF_TX_AVX2_OFFLOAD;
}
#ifdef CC_AVX512_SUPPORT
if (use_avx512) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX512;
- PMD_DRV_LOG(DEBUG, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_OFFLOAD_PATH) {
- tx_func_type = IAVF_TX_AVX512_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_PATH) {
- tx_func_type = IAVF_TX_AVX512_CTX;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT Vector Tx (port %d).",
- dev->data->port_id);
- } else {
- tx_func_type = IAVF_TX_AVX512_CTX_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
+ if (check_ret == IAVF_VECTOR_PATH)
+ adapter->tx_func_type = IAVF_TX_AVX512;
+ else if (check_ret == IAVF_VECTOR_OFFLOAD_PATH)
+ adapter->tx_func_type = IAVF_TX_AVX512_OFFLOAD;
+ else if (check_ret == IAVF_VECTOR_CTX_PATH)
+ adapter->tx_func_type = IAVF_TX_AVX512_CTX;
+ else
+ adapter->tx_func_type = IAVF_TX_AVX512_CTX_OFFLOAD;
}
#endif
@@ -4305,33 +4290,20 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
iavf_txq_vec_setup(txq);
}
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
- return;
+ goto out;
}
-
-normal:
#endif
- PMD_DRV_LOG(DEBUG, "Using Basic Tx callback (port=%d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_DEFAULT;
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
+out:
+ if (no_poll_on_link_down)
dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
+ else if (mbuf_check)
dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
+ else
+ dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[adapter->tx_func_type].pkt_burst;
+
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ iavf_tx_pkt_burst_ops[adapter->tx_func_type].info, dev->data->port_id);
}
static int
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 05/13] net/iavf: use common Tx path selection infrastructure
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (3 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 04/13] net/iavf: use same Tx path across processes Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 06/13] net/i40e: use same Tx path across processes Ciara Loftus
` (8 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Introduce two new features "disabled" and "context desc" to
the common infrastructure which represents whether or not the path is
disabled, or if it uses a context descriptor.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/common/tx.h | 14 ++
drivers/net/intel/iavf/iavf.h | 2 -
drivers/net/intel/iavf/iavf_ethdev.c | 4 -
drivers/net/intel/iavf/iavf_rxtx.c | 193 ++++++++++--------
drivers/net/intel/iavf/iavf_rxtx.h | 46 +++--
drivers/net/intel/iavf/iavf_rxtx_vec_common.h | 39 +---
6 files changed, 153 insertions(+), 145 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 3480c5e07c..5d965a86c9 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -120,6 +120,8 @@ struct ci_tx_queue {
struct ci_tx_path_features_extra {
bool simple_tx;
+ bool ctx_desc;
+ bool disabled;
};
struct ci_tx_path_features {
@@ -308,6 +310,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
for (i = 0; i < num_paths; i++) {
const struct ci_tx_path_features *path_features = &infos[i].features;
+ /* Do not select a disabled tx path. */
+ if (path_features->extra.disabled)
+ continue;
+
/* Do not use a simple tx path if not requested. */
if (path_features->extra.simple_tx && !req_features.extra.simple_tx)
continue;
@@ -321,6 +327,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
if (path_features->simd_width > req_features.simd_width)
continue;
+ /* If a context descriptor is requested, ensure the path supports it. */
+ if (!path_features->extra.ctx_desc && req_features.extra.ctx_desc)
+ continue;
+
/* Do not select the path if it is less suitable than the chosen path. */
if (chosen_path_features != NULL) {
/* Do not select paths with lower SIMD width than the chosen path. */
@@ -333,6 +343,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
rte_popcount32(path_features->tx_offloads) >
rte_popcount32(chosen_path_features->tx_offloads))
continue;
+
+ /* Don't use a context descriptor unless necessary */
+ if (path_features->extra.ctx_desc && !chosen_path_features->extra.ctx_desc)
+ continue;
}
/* Finally, select the path since it has met all the requirements. */
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index d78582e05c..921bf0a607 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -375,8 +375,6 @@ struct iavf_adapter {
struct iavf_security_ctx *security_ctx;
bool rx_bulk_alloc_allowed;
- /* For vector PMD */
- bool tx_vec_allowed;
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[IAVF_MAX_PKT_TYPE];
bool stopped;
bool closed;
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index ab65e99f68..bf1186c20f 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -666,10 +666,6 @@ iavf_dev_configure(struct rte_eth_dev *dev)
return -EIO;
ad->rx_bulk_alloc_allowed = true;
- /* Initialize to TRUE. If any of Rx queues doesn't meet the
- * vector Rx/Tx preconditions, it will be reset.
- */
- ad->tx_vec_allowed = true;
ad->tx_func_type = IAVF_TX_DEFAULT;
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c b/drivers/net/intel/iavf/iavf_rxtx.c
index 055b2b0ae0..a8c19fd031 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -208,19 +208,6 @@ check_tx_thresh(uint16_t nb_desc, uint16_t tx_rs_thresh,
return 0;
}
-static inline bool
-check_tx_vec_allow(struct ci_tx_queue *txq)
-{
- if (!(txq->offloads & IAVF_TX_NO_VECTOR_FLAGS) &&
- txq->tx_rs_thresh >= IAVF_VPMD_TX_BURST &&
- txq->tx_rs_thresh <= IAVF_VPMD_TX_MAX_FREE_BUF) {
- PMD_INIT_LOG(DEBUG, "Vector tx can be enabled on this txq.");
- return true;
- }
- PMD_INIT_LOG(DEBUG, "Vector Tx cannot be enabled on this txq.");
- return false;
-}
-
static inline bool
check_rx_bulk_allow(struct ci_rx_queue *rxq)
{
@@ -861,12 +848,6 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
dev->data->tx_queues[queue_idx] = txq;
txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx);
- if (check_tx_vec_allow(txq) == false) {
- struct iavf_adapter *ad =
- IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- ad->tx_vec_allowed = false;
- }
-
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS &&
vf->tm_conf.committed) {
int tc;
@@ -4002,26 +3983,82 @@ iavf_rx_burst_mode_get(struct rte_eth_dev *dev,
return -EINVAL;
}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} iavf_tx_pkt_burst_ops[] = {
- [IAVF_TX_DISABLED] = {iavf_xmit_pkts_no_poll, "Disabled"},
- [IAVF_TX_DEFAULT] = {iavf_xmit_pkts, "Scalar"},
+static const struct ci_tx_path_info iavf_tx_path_infos[] = {
+ [IAVF_TX_DISABLED] = {
+ .pkt_burst = iavf_xmit_pkts_no_poll,
+ .info = "Disabled",
+ .features = {
+ .extra.disabled = true
+ }
+ },
+ [IAVF_TX_DEFAULT] = {
+ .pkt_burst = iavf_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = IAVF_TX_SCALAR_OFFLOADS,
+ .extra.ctx_desc = true
+ }
+ },
#ifdef RTE_ARCH_X86
- [IAVF_TX_SSE] = {iavf_xmit_pkts_vec, "Vector SSE"},
- [IAVF_TX_AVX2] = {iavf_xmit_pkts_vec_avx2, "Vector AVX2"},
- [IAVF_TX_AVX2_OFFLOAD] = {iavf_xmit_pkts_vec_avx2_offload,
- "Vector AVX2 Offload"},
+ [IAVF_TX_SSE] = {
+ .pkt_burst = iavf_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ }
+ },
+ [IAVF_TX_AVX2] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
+ [IAVF_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2_offload,
+ .info = "Vector AVX2 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
#ifdef CC_AVX512_SUPPORT
- [IAVF_TX_AVX512] = {iavf_xmit_pkts_vec_avx512, "Vector AVX512"},
- [IAVF_TX_AVX512_OFFLOAD] = {iavf_xmit_pkts_vec_avx512_offload,
- "Vector AVX512 Offload"},
- [IAVF_TX_AVX512_CTX] = {iavf_xmit_pkts_vec_avx512_ctx,
- "Vector AVX512 Ctx"},
+ [IAVF_TX_AVX512] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_offload,
+ .info = "Vector AVX512 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_CTX] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx,
+ .info = "Vector AVX512 Ctx",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .extra.ctx_desc = true
+ }
+ },
[IAVF_TX_AVX512_CTX_OFFLOAD] = {
- iavf_xmit_pkts_vec_avx512_ctx_offload,
- "Vector AVX512 Ctx Offload"},
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx_offload,
+ .info = "Vector AVX512 Ctx Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .extra.ctx_desc = true
+ }
+ },
#endif
#endif
};
@@ -4034,10 +4071,10 @@ iavf_tx_burst_mode_get(struct rte_eth_dev *dev,
eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
size_t i;
- for (i = 0; i < RTE_DIM(iavf_tx_pkt_burst_ops); i++) {
- if (pkt_burst == iavf_tx_pkt_burst_ops[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(iavf_tx_path_infos); i++) {
+ if (pkt_burst == iavf_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- iavf_tx_pkt_burst_ops[i].info);
+ iavf_tx_path_infos[i].info);
return 0;
}
}
@@ -4073,7 +4110,7 @@ iavf_xmit_pkts_no_poll(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_func_type = txq->iavf_vsi->adapter->tx_func_type;
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue,
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue,
tx_pkts, nb_pkts);
}
@@ -4158,7 +4195,7 @@ iavf_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts,
return 0;
}
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
/* choose rx function*/
@@ -4231,79 +4268,59 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
int mbuf_check = adapter->devargs.mbuf_check;
int no_poll_on_link_down = adapter->devargs.no_poll_on_link_down;
-#ifdef RTE_ARCH_X86
struct ci_tx_queue *txq;
int i;
- int check_ret;
- bool use_sse = false;
- bool use_avx2 = false;
- bool use_avx512 = false;
- enum rte_vect_max_simd tx_simd_path = iavf_get_max_simd_bitwidth();
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
/* The primary process selects the tx path for all processes. */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
goto out;
- check_ret = iavf_tx_vec_dev_check(dev);
-
- if (check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- /* SSE not support offload path yet. */
- if (check_ret == IAVF_VECTOR_PATH) {
- use_sse = true;
- }
-
- use_avx2 = tx_simd_path == RTE_VECT_SIMD_256;
- use_avx512 = tx_simd_path == RTE_VECT_SIMD_512;
-
- if (!use_sse && !use_avx2 && !use_avx512)
- goto out;
+#ifdef RTE_ARCH_X86
+ if (iavf_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = iavf_get_max_simd_bitwidth();
- if (use_sse)
- adapter->tx_func_type = IAVF_TX_SSE;
+ if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0)
+ req_features.extra.ctx_desc = true;
- if (!use_avx512 && use_avx2) {
- if (check_ret == IAVF_VECTOR_PATH)
- adapter->tx_func_type = IAVF_TX_AVX2;
- else if (check_ret == IAVF_VECTOR_CTX_OFFLOAD_PATH)
- goto out;
- else
- adapter->tx_func_type = IAVF_TX_AVX2_OFFLOAD;
- }
-#ifdef CC_AVX512_SUPPORT
- if (use_avx512) {
- if (check_ret == IAVF_VECTOR_PATH)
- adapter->tx_func_type = IAVF_TX_AVX512;
- else if (check_ret == IAVF_VECTOR_OFFLOAD_PATH)
- adapter->tx_func_type = IAVF_TX_AVX512_OFFLOAD;
- else if (check_ret == IAVF_VECTOR_CTX_PATH)
- adapter->tx_func_type = IAVF_TX_AVX512_CTX;
- else
- adapter->tx_func_type = IAVF_TX_AVX512_CTX_OFFLOAD;
- }
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT &&
+ txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
+ req_features.extra.ctx_desc = true;
+ }
#endif
+ adapter->tx_func_type = ci_tx_path_select(req_features,
+ &iavf_tx_path_infos[0],
+ RTE_DIM(iavf_tx_path_infos),
+ IAVF_TX_DEFAULT);
+
+ if (iavf_tx_path_infos[adapter->tx_func_type].features.simd_width != 0) {
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
if (!txq)
continue;
iavf_txq_vec_setup(txq);
+ txq->use_ctx =
+ iavf_tx_path_infos[adapter->tx_func_type].features.extra.ctx_desc;
}
-
- goto out;
}
-#endif
-
out:
if (no_poll_on_link_down)
dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
else if (mbuf_check)
dev->tx_pkt_burst = iavf_xmit_pkts_check;
else
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[adapter->tx_func_type].pkt_burst;
+ dev->tx_pkt_burst = iavf_tx_path_infos[adapter->tx_func_type].pkt_burst;
PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
- iavf_tx_pkt_burst_ops[adapter->tx_func_type].info, dev->data->port_id);
+ iavf_tx_path_infos[adapter->tx_func_type].info, dev->data->port_id);
}
static int
diff --git a/drivers/net/intel/iavf/iavf_rxtx.h b/drivers/net/intel/iavf/iavf_rxtx.h
index 8efb3bd04e..bff456e509 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.h
+++ b/drivers/net/intel/iavf/iavf_rxtx.h
@@ -35,22 +35,38 @@
#define IAVF_VPMD_DESCS_PER_LOOP_WIDE CI_VPMD_DESCS_PER_LOOP_WIDE
#define IAVF_VPMD_TX_MAX_FREE_BUF 64
-#define IAVF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_SECURITY)
-
-#define IAVF_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+/* basic scalar path */
+#define IAVF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_SECURITY | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
+/* basic vector path */
+#define IAVF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* offload vector path */
+#define IAVF_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define IAVF_TX_VECTOR_OFFLOAD_CTX ( \
+/* offload vector path with context descriptor */
+#define IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ IAVF_TX_VECTOR_OFFLOAD_OFFLOADS | \
RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_QINQ_INSERT)
diff --git a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
index 66f65b46e9..f1ea57034f 100644
--- a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
@@ -73,8 +73,6 @@ iavf_rx_vec_queue_default(struct ci_rx_queue *rxq)
static inline int
iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
{
- bool vlan_offload = false, vlan_needs_ctx = false;
-
if (!txq)
return -1;
@@ -82,35 +80,7 @@ iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > IAVF_VPMD_TX_MAX_FREE_BUF)
return -1;
- if (txq->offloads & IAVF_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_PATH;
- }
-
- /* Vlan tci needs to be inserted via ctx desc, if the vlan_flag is L2TAG2. */
- if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) {
- vlan_offload = true;
- if (txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
- vlan_needs_ctx = true;
- }
-
- /**
- * Tunneling parameters and other fields need be configured in ctx desc
- * if the outer checksum offload is enabled.
- */
- if (txq->offloads & (IAVF_TX_VECTOR_OFFLOAD | IAVF_TX_VECTOR_OFFLOAD_CTX) || vlan_offload) {
- if (txq->offloads & IAVF_TX_VECTOR_OFFLOAD_CTX || vlan_needs_ctx) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_OFFLOAD_PATH;
- } else {
- return IAVF_VECTOR_OFFLOAD_PATH;
- }
- } else {
- return IAVF_VECTOR_PATH;
- }
+ return 0;
}
static inline int
@@ -137,19 +107,16 @@ iavf_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = iavf_tx_vec_queue_default(txq);
if (ret < 0)
- return -1;
- if (ret > result)
- result = ret;
+ break;
}
- return result;
+ return ret;
}
/******************************************************************************
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 06/13] net/i40e: use same Tx path across processes
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (4 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 05/13] net/iavf: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 07/13] net/i40e: use common Tx path selection infrastructure Ciara Loftus
` (7 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
In the interest of simplicity, let the primary process select the Tx
path to be used by all processes using the given device.
The many logs which report individual Tx path selections have been
consolidated into one single log.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/i40e/i40e_ethdev.h | 11 +++
drivers/net/intel/i40e/i40e_rxtx.c | 118 +++++++++++++++------------
2 files changed, 76 insertions(+), 53 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index 3fca089d6c..9a89f94f0e 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1243,6 +1243,16 @@ enum i40e_rx_func_type {
I40E_RX_ALTIVEC_SCATTERED,
};
+enum i40e_tx_func_type {
+ I40E_TX_DEFAULT,
+ I40E_TX_SCALAR_SIMPLE,
+ I40E_TX_SSE,
+ I40E_TX_AVX2,
+ I40E_TX_AVX512,
+ I40E_TX_NEON,
+ I40E_TX_ALTIVEC,
+};
+
/*
* Structure to store private data for each PF/VF instance.
*/
@@ -1260,6 +1270,7 @@ struct i40e_adapter {
bool tx_vec_allowed;
enum i40e_rx_func_type rx_func_type;
+ enum i40e_tx_func_type tx_func_type;
uint64_t mbuf_check; /* mbuf check flags. */
uint16_t max_pkt_len; /* Maximum packet length */
diff --git a/drivers/net/intel/i40e/i40e_rxtx.c b/drivers/net/intel/i40e/i40e_rxtx.c
index 255414dd03..04c3a6c311 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.c
+++ b/drivers/net/intel/i40e/i40e_rxtx.c
@@ -3519,6 +3519,46 @@ i40e_set_tx_function_flag(struct rte_eth_dev *dev, struct ci_tx_queue *txq)
txq->queue_id);
}
+static const struct {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+} i40e_tx_burst_infos[] = {
+ [I40E_TX_DEFAULT] = {
+ .pkt_burst = i40e_xmit_pkts,
+ .info = "Scalar",
+ },
+ [I40E_TX_SCALAR_SIMPLE] = {
+ .pkt_burst = i40e_xmit_pkts_simple,
+ .info = "Scalar Simple",
+ },
+#ifdef RTE_ARCH_X86
+ [I40E_TX_SSE] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector SSE",
+ },
+ [I40E_TX_AVX2] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ },
+#ifdef CC_AVX512_SUPPORT
+ [I40E_TX_AVX512] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ },
+#endif
+#elif defined(RTE_ARCH_ARM64)
+ [I40E_TX_NEON] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector Neon",
+ },
+#elif defined(RTE_ARCH_PPC_64)
+ [I40E_TX_ALTIVEC] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector AltiVec",
+ },
+#endif
+};
+
void __rte_cold
i40e_set_tx_function(struct rte_eth_dev *dev)
{
@@ -3527,19 +3567,20 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
uint64_t mbuf_check = ad->mbuf_check;
int i;
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
#ifdef RTE_ARCH_X86
- ad->tx_simd_width = i40e_get_max_simd_bitwidth();
+ ad->tx_simd_width = i40e_get_max_simd_bitwidth();
#endif
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- struct ci_tx_queue *txq =
- dev->data->tx_queues[i];
+ if (ad->tx_vec_allowed) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ struct ci_tx_queue *txq =
+ dev->data->tx_queues[i];
- if (txq && i40e_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
+ if (txq && i40e_txq_vec_setup(txq)) {
+ ad->tx_vec_allowed = false;
+ break;
}
}
}
@@ -3552,66 +3593,37 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
#ifdef RTE_ARCH_X86
if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
#ifdef CC_AVX512_SUPPORT
- PMD_DRV_LOG(NOTICE, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec_avx512;
+ ad->tx_func_type = I40E_TX_AVX512;
#else
- PMD_DRV_LOG(ERR, "Invalid Tx SIMD width reported, defaulting to "
- "using scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts;
+ ad->tx_func_type = I40E_TX_DEFAULT;
#endif
} else {
- PMD_INIT_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- i40e_xmit_pkts_vec_avx2 :
- i40e_xmit_pkts_vec;
+ ad->tx_func_type = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
+ I40E_TX_AVX2 :
+ I40E_TX_SSE;
dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
}
#else /* RTE_ARCH_X86 */
- PMD_INIT_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec;
+ ad->tx_func_type = I40E_TX_SSE;
dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
#endif /* RTE_ARCH_X86 */
} else {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts_simple;
+ ad->tx_func_type = I40E_TX_SCALAR_SIMPLE;
dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
}
dev->tx_pkt_prepare = i40e_simple_prep_pkts;
} else {
- PMD_INIT_LOG(DEBUG, "Xmit tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts;
+ ad->tx_func_type = I40E_TX_DEFAULT;
dev->tx_pkt_prepare = i40e_prep_pkts;
}
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = i40e_xmit_pkts_check;
- }
-}
+out:
+ dev->tx_pkt_burst = mbuf_check ? i40e_xmit_pkts_check :
+ i40e_tx_burst_infos[ad->tx_func_type].pkt_burst;
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} i40e_tx_burst_infos[] = {
- { i40e_xmit_pkts_simple, "Scalar Simple" },
- { i40e_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { i40e_xmit_pkts_vec_avx512, "Vector AVX512" },
-#endif
- { i40e_xmit_pkts_vec_avx2, "Vector AVX2" },
- { i40e_xmit_pkts_vec, "Vector SSE" },
-#elif defined(RTE_ARCH_ARM64)
- { i40e_xmit_pkts_vec, "Vector Neon" },
-#elif defined(RTE_ARCH_PPC_64)
- { i40e_xmit_pkts_vec, "Vector AltiVec" },
-#endif
-};
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ i40e_tx_burst_infos[ad->tx_func_type].info, dev->data->port_id);
+}
int
i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 07/13] net/i40e: use common Tx path selection infrastructure
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (5 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 06/13] net/i40e: use same Tx path across processes Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 08/13] net/idpf: " Ciara Loftus
` (6 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/i40e/i40e_ethdev.h | 2 -
drivers/net/intel/i40e/i40e_rxtx.c | 112 +++++++++---------
drivers/net/intel/i40e/i40e_rxtx.h | 20 +++-
.../net/intel/i40e/i40e_rxtx_vec_altivec.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_neon.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_sse.c | 6 -
6 files changed, 78 insertions(+), 74 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index 9a89f94f0e..8a86e26858 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1290,8 +1290,6 @@ struct i40e_adapter {
/* For RSS reta table update */
uint8_t rss_reta_updated;
-
- enum rte_vect_max_simd tx_simd_width;
};
/**
diff --git a/drivers/net/intel/i40e/i40e_rxtx.c b/drivers/net/intel/i40e/i40e_rxtx.c
index 04c3a6c311..1f9ccd2aa7 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.c
+++ b/drivers/net/intel/i40e/i40e_rxtx.c
@@ -2375,8 +2375,7 @@ i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
/* check vector conflict */
if (ad->tx_vec_allowed) {
- if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ ||
- i40e_txq_vec_setup(txq)) {
+ if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ) {
PMD_DRV_LOG(ERR, "Failed vector tx setup.");
return -EINVAL;
}
@@ -3519,42 +3518,73 @@ i40e_set_tx_function_flag(struct rte_eth_dev *dev, struct ci_tx_queue *txq)
txq->queue_id);
}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} i40e_tx_burst_infos[] = {
+static const struct ci_tx_path_info i40e_tx_path_infos[] = {
[I40E_TX_DEFAULT] = {
.pkt_burst = i40e_xmit_pkts,
.info = "Scalar",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ },
+ .pkt_prep = i40e_prep_pkts,
},
[I40E_TX_SCALAR_SIMPLE] = {
.pkt_burst = i40e_xmit_pkts_simple,
.info = "Scalar Simple",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ .extra.simple_tx = true
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
#ifdef RTE_ARCH_X86
[I40E_TX_SSE] = {
.pkt_burst = i40e_xmit_pkts_vec,
.info = "Vector SSE",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
[I40E_TX_AVX2] = {
.pkt_burst = i40e_xmit_pkts_vec_avx2,
.info = "Vector AVX2",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
#ifdef CC_AVX512_SUPPORT
[I40E_TX_AVX512] = {
.pkt_burst = i40e_xmit_pkts_vec_avx512,
.info = "Vector AVX512",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
#endif
#elif defined(RTE_ARCH_ARM64)
[I40E_TX_NEON] = {
.pkt_burst = i40e_xmit_pkts_vec,
.info = "Vector Neon",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
#elif defined(RTE_ARCH_PPC_64)
[I40E_TX_ALTIVEC] = {
.pkt_burst = i40e_xmit_pkts_vec,
.info = "Vector AltiVec",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
},
#endif
};
@@ -3565,64 +3595,40 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
struct i40e_adapter *ad =
I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
uint64_t mbuf_check = ad->mbuf_check;
- int i;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .extra.simple_tx = ad->tx_simple_allowed
+ };
/* The primary process selects the tx path for all processes. */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
goto out;
-#ifdef RTE_ARCH_X86
- ad->tx_simd_width = i40e_get_max_simd_bitwidth();
-#endif
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- struct ci_tx_queue *txq =
- dev->data->tx_queues[i];
-
- if (txq && i40e_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)
- ad->tx_vec_allowed = false;
-
- if (ad->tx_simple_allowed) {
- if (ad->tx_vec_allowed) {
+ if (ad->tx_vec_allowed) {
#ifdef RTE_ARCH_X86
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- ad->tx_func_type = I40E_TX_AVX512;
+ req_features.simd_width = i40e_get_max_simd_bitwidth();
#else
- ad->tx_func_type = I40E_TX_DEFAULT;
+ req_features.simd_width = rte_vect_get_max_simd_bitwidth();
#endif
- } else {
- ad->tx_func_type = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- I40E_TX_AVX2 :
- I40E_TX_SSE;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
-#else /* RTE_ARCH_X86 */
- ad->tx_func_type = I40E_TX_SSE;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
-#endif /* RTE_ARCH_X86 */
- } else {
- ad->tx_func_type = I40E_TX_SCALAR_SIMPLE;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
- dev->tx_pkt_prepare = i40e_simple_prep_pkts;
- } else {
- ad->tx_func_type = I40E_TX_DEFAULT;
- dev->tx_pkt_prepare = i40e_prep_pkts;
}
+ ad->tx_func_type = ci_tx_path_select(req_features, &i40e_tx_path_infos[0],
+ RTE_DIM(i40e_tx_path_infos), I40E_TX_DEFAULT);
+
out:
dev->tx_pkt_burst = mbuf_check ? i40e_xmit_pkts_check :
- i40e_tx_burst_infos[ad->tx_func_type].pkt_burst;
+ i40e_tx_path_infos[ad->tx_func_type].pkt_burst;
PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
- i40e_tx_burst_infos[ad->tx_func_type].info, dev->data->port_id);
+ i40e_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+
+ if (ad->tx_func_type == I40E_TX_SCALAR_SIMPLE ||
+ ad->tx_func_type == I40E_TX_SSE ||
+ ad->tx_func_type == I40E_TX_NEON ||
+ ad->tx_func_type == I40E_TX_ALTIVEC ||
+ ad->tx_func_type == I40E_TX_AVX2)
+ dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
}
int
@@ -3633,10 +3639,10 @@ i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(i40e_tx_burst_infos); ++i) {
- if (pkt_burst == i40e_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(i40e_tx_path_infos); ++i) {
+ if (pkt_burst == i40e_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- i40e_tx_burst_infos[i].info);
+ i40e_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/i40e/i40e_rxtx.h b/drivers/net/intel/i40e/i40e_rxtx.h
index b5a901794f..ed173d8f17 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.h
+++ b/drivers/net/intel/i40e/i40e_rxtx.h
@@ -91,6 +91,25 @@ enum i40e_header_split_mode {
RTE_ETH_RX_OFFLOAD_VLAN_FILTER | \
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+#define I40E_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define I40E_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
/** Offload features */
union i40e_tx_offload {
uint64_t data;
@@ -165,7 +184,6 @@ uint16_t i40e_recv_scattered_pkts_vec(void *rx_queue,
uint16_t nb_pkts);
int i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev);
int i40e_rxq_vec_setup(struct ci_rx_queue *rxq);
-int i40e_txq_vec_setup(struct ci_tx_queue *txq);
void i40e_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq);
uint16_t i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
index 87a57e7520..bbb6d907cf 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
@@ -547,12 +547,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue __rte_unused * txq)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
index c9098e4c1a..b5be0c1b59 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
@@ -697,12 +697,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
index c035408dcc..c209135890 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
@@ -704,12 +704,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 08/13] net/idpf: use common Tx path selection infrastructure
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (6 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 07/13] net/i40e: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 09/13] net/cpfl: " Ciara Loftus
` (5 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Introduce a new feature "single queue" to the common
infrastructure which represents whether single or split queue mode is
used in the given path.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/common/tx.h | 5 +
drivers/net/intel/idpf/idpf_common_device.h | 10 ++
drivers/net/intel/idpf/idpf_common_rxtx.c | 49 ++++++++
drivers/net/intel/idpf/idpf_common_rxtx.h | 12 ++
drivers/net/intel/idpf/idpf_rxtx.c | 112 +++++-------------
drivers/net/intel/idpf/idpf_rxtx_vec_common.h | 10 --
6 files changed, 107 insertions(+), 91 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 5d965a86c9..32cee09e8f 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -122,6 +122,7 @@ struct ci_tx_path_features_extra {
bool simple_tx;
bool ctx_desc;
bool disabled;
+ bool single_queue;
};
struct ci_tx_path_features {
@@ -318,6 +319,10 @@ ci_tx_path_select(struct ci_tx_path_features req_features,
if (path_features->extra.simple_tx && !req_features.extra.simple_tx)
continue;
+ /* If requested, ensure the path supports single queue TX. */
+ if (path_features->extra.single_queue != req_features.extra.single_queue)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features.tx_offloads) !=
req_features.tx_offloads)
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index c32dcfbb12..eff04a83eb 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -75,6 +75,15 @@ enum idpf_rx_func_type {
IDPF_RX_MAX
};
+enum idpf_tx_func_type {
+ IDPF_TX_DEFAULT,
+ IDPF_TX_SINGLEQ,
+ IDPF_TX_SINGLEQ_AVX2,
+ IDPF_TX_AVX512,
+ IDPF_TX_SINGLEQ_AVX512,
+ IDPF_TX_MAX
+};
+
struct idpf_adapter {
struct idpf_hw hw;
struct virtchnl2_version_info virtchnl_version;
@@ -92,6 +101,7 @@ struct idpf_adapter {
uint64_t time_hw;
enum idpf_rx_func_type rx_func_type;
+ enum idpf_tx_func_type tx_func_type;
};
struct idpf_chunks_info {
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.c b/drivers/net/intel/idpf/idpf_common_rxtx.c
index a5d0795057..2d926ee939 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.c
@@ -1701,3 +1701,52 @@ const struct ci_rx_path_info idpf_rx_path_infos[] = {
#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
};
+
+RTE_EXPORT_INTERNAL_SYMBOL(idpf_tx_path_infos)
+const struct ci_tx_path_info idpf_tx_path_infos[] = {
+ [IDPF_TX_DEFAULT] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts,
+ .info = "Split Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS
+ }
+ },
+ [IDPF_TX_SINGLEQ] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts,
+ .info = "Single Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS,
+ .extra.single_queue = true
+ }
+ },
+#ifdef RTE_ARCH_X86
+ [IDPF_TX_SINGLEQ_AVX2] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx2,
+ .info = "Single AVX2",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ .extra.single_queue = true
+ }
+ },
+#ifdef CC_AVX512_SUPPORT
+ [IDPF_TX_AVX512] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts_avx512,
+ .info = "Split AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IDPF_TX_SINGLEQ_AVX512] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx512,
+ .info = "Single AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .extra.single_queue = true
+ }
+ },
+#endif /* CC_AVX512_SUPPORT */
+#endif /* RTE_ARCH_X86 */
+};
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.h b/drivers/net/intel/idpf/idpf_common_rxtx.h
index 3bc3323af4..7c6ff5d047 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.h
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.h
@@ -106,6 +106,17 @@
RTE_ETH_RX_OFFLOAD_SCATTER)
#define IDPF_RX_VECTOR_OFFLOADS 0
+#define IDPF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define IDPF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
struct idpf_rx_stats {
RTE_ATOMIC(uint64_t) mbuf_alloc_failed;
};
@@ -264,5 +275,6 @@ uint16_t idpf_dp_singleq_xmit_pkts_avx2(void *tx_queue,
uint16_t nb_pkts);
extern const struct ci_rx_path_info idpf_rx_path_infos[IDPF_RX_MAX];
+extern const struct ci_tx_path_info idpf_tx_path_infos[IDPF_TX_MAX];
#endif /* _IDPF_COMMON_RXTX_H_ */
diff --git a/drivers/net/intel/idpf/idpf_rxtx.c b/drivers/net/intel/idpf/idpf_rxtx.c
index 4796d8b862..1fd55de9ab 100644
--- a/drivers/net/intel/idpf/idpf_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_rxtx.c
@@ -813,97 +813,47 @@ idpf_set_tx_function(struct rte_eth_dev *dev)
{
struct idpf_vport *vport = dev->data->dev_private;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = idpf_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .extra.single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
+
+#ifdef RTE_ARCH_X86
+ if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH)
+ req_features.simd_width = idpf_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.extra.single_queue) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ vport->tx_vec_allowed = true;
}
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
index ecdf2f0e23..425f0792a1 100644
--- a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
+++ b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define IDPF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
idpf_tx_desc_done(struct ci_tx_queue *txq, uint16_t idx)
@@ -74,9 +67,6 @@ idpf_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return IDPF_SCALAR_PATH;
- if ((txq->offloads & IDPF_TX_NO_VECTOR_FLAGS) != 0)
- return IDPF_SCALAR_PATH;
-
return IDPF_VECTOR_PATH;
}
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 09/13] net/cpfl: use common Tx path selection infrastructure
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (7 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 08/13] net/idpf: " Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-09 11:26 ` [PATCH 10/13] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
` (4 subsequent siblings)
13 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/cpfl/cpfl_rxtx.c | 114 +++++-------------
drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h | 10 --
2 files changed, 32 insertions(+), 92 deletions(-)
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx.c b/drivers/net/intel/cpfl/cpfl_rxtx.c
index 453ec975d5..2bf66159b5 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx.c
+++ b/drivers/net/intel/cpfl/cpfl_rxtx.c
@@ -1462,97 +1462,47 @@ cpfl_set_tx_function(struct rte_eth_dev *dev)
struct cpfl_vport *cpfl_vport = dev->data->dev_private;
struct idpf_vport *vport = &cpfl_vport->base;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
- struct cpfl_tx_queue *cpfl_txq;
+ struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = cpfl_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .extra.single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
+ if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH)
+ req_features.simd_width = cpfl_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+
+#ifdef RTE_ARCH_X86
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.extra.single_queue) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- if (cpfl_txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ vport->tx_vec_allowed = true;
}
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
index 525ca9a6e0..f0daa1eb30 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
+++ b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define CPFL_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
cpfl_rx_vec_queue_default(struct idpf_rx_queue *rxq)
@@ -62,9 +55,6 @@ cpfl_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return CPFL_SCALAR_PATH;
- if ((txq->offloads & CPFL_TX_NO_VECTOR_FLAGS) != 0)
- return CPFL_SCALAR_PATH;
-
return CPFL_VECTOR_PATH;
}
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH 10/13] docs: fix TSO and checksum offload feature status in ice doc
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (8 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 09/13] net/cpfl: " Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:58 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 11/13] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
` (3 subsequent siblings)
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable
TSO is only supported on the scalar path so change its status to
partially supported. L3 and L4 checksum offload are enabled on scalar
and vector paths so change their statuses from partial to supported.
Fixes: f88de4694d94 ("net/ice: support Tx SSE vector")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
doc/guides/nics/features/ice.ini | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index e9796c1eab..893d09e9ec 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -21,7 +21,7 @@ Power mgmt address monitor = Y
MTU update = Y
Buffer split on Rx = P
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
DCB = Y
@@ -34,8 +34,8 @@ Traffic manager = Y
CRC offload = Y
VLAN offload = Y
QinQ offload = P
-L3 checksum offload = P
-L4 checksum offload = P
+L3 checksum offload = Y
+L4 checksum offload = Y
Timestamp offload = P
Inner L3 checksum = P
Inner L4 checksum = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 10/13] docs: fix TSO and checksum offload feature status in ice doc
2025-12-09 11:26 ` [PATCH 10/13] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
@ 2025-12-11 11:58 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:58 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev, stable
On Tue, Dec 09, 2025 at 11:26:49AM +0000, Ciara Loftus wrote:
> TSO is only supported on the scalar path so change its status to
> partially supported. L3 and L4 checksum offload are enabled on scalar
> and vector paths so change their statuses from partial to supported.
>
> Fixes: f88de4694d94 ("net/ice: support Tx SSE vector")
> Cc: stable@dpdk.org
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
I still think we need a better solution for items only supported on scalar
paths, but until then let's keep the current scheme.
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> doc/guides/nics/features/ice.ini | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
> index e9796c1eab..893d09e9ec 100644
> --- a/doc/guides/nics/features/ice.ini
> +++ b/doc/guides/nics/features/ice.ini
> @@ -21,7 +21,7 @@ Power mgmt address monitor = Y
> MTU update = Y
> Buffer split on Rx = P
> Scattered Rx = Y
> -TSO = Y
> +TSO = P
> Promiscuous mode = Y
> Allmulticast mode = Y
> DCB = Y
> @@ -34,8 +34,8 @@ Traffic manager = Y
> CRC offload = Y
> VLAN offload = Y
> QinQ offload = P
> -L3 checksum offload = P
> -L4 checksum offload = P
> +L3 checksum offload = Y
> +L4 checksum offload = Y
> Timestamp offload = P
> Inner L3 checksum = P
> Inner L4 checksum = P
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 11/13] docs: fix TSO feature status in iavf driver documentation
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (9 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 10/13] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:58 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 12/13] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
` (2 subsequent siblings)
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 319c421f3890 ("net/avf: enable SSE Rx Tx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 7695e3ff7c..6c9e97594f 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -17,7 +17,7 @@ Burst mode info = Y
Power mgmt address monitor = Y
MTU update = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 11/13] docs: fix TSO feature status in iavf driver documentation
2025-12-09 11:26 ` [PATCH 11/13] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
@ 2025-12-11 11:58 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:58 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev, stable
On Tue, Dec 09, 2025 at 11:26:50AM +0000, Ciara Loftus wrote:
> TSO is only supported on the scalar path so change the status to
> partially supported.
>
> Fixes: 319c421f3890 ("net/avf: enable SSE Rx Tx")
> Cc: stable@dpdk.org
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> doc/guides/nics/features/iavf.ini | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
> index 7695e3ff7c..6c9e97594f 100644
> --- a/doc/guides/nics/features/iavf.ini
> +++ b/doc/guides/nics/features/iavf.ini
> @@ -17,7 +17,7 @@ Burst mode info = Y
> Power mgmt address monitor = Y
> MTU update = Y
> Scattered Rx = Y
> -TSO = Y
> +TSO = P
> Promiscuous mode = Y
> Allmulticast mode = Y
> Unicast MAC filter = Y
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 12/13] docs: fix inline crypto feature status in iavf driver doc
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (10 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 11/13] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:59 ` Bruce Richardson
2025-12-09 11:26 ` [PATCH 13/13] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable
inline crypto is only supported on the scalar path so change its status
to partially supported.
Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 6c9e97594f..0ba6f7dfd7 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -27,7 +27,7 @@ RSS key update = Y
RSS reta update = Y
VLAN filter = Y
Traffic manager = Y
-Inline crypto = Y
+Inline crypto = P
CRC offload = Y
VLAN offload = P
QinQ offload = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 12/13] docs: fix inline crypto feature status in iavf driver doc
2025-12-09 11:26 ` [PATCH 12/13] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
@ 2025-12-11 11:59 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:59 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev, stable
On Tue, Dec 09, 2025 at 11:26:51AM +0000, Ciara Loftus wrote:
> inline crypto is only supported on the scalar path so change its status
> to partially supported.
>
> Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
> Cc: stable@dpdk.org
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> doc/guides/nics/features/iavf.ini | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
> index 6c9e97594f..0ba6f7dfd7 100644
> --- a/doc/guides/nics/features/iavf.ini
> +++ b/doc/guides/nics/features/iavf.ini
> @@ -27,7 +27,7 @@ RSS key update = Y
> RSS reta update = Y
> VLAN filter = Y
> Traffic manager = Y
> -Inline crypto = Y
> +Inline crypto = P
> CRC offload = Y
> VLAN offload = P
> QinQ offload = P
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 13/13] docs: fix TSO feature status in i40e driver documentation
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (11 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 12/13] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
@ 2025-12-09 11:26 ` Ciara Loftus
2025-12-11 11:59 ` Bruce Richardson
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
13 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-09 11:26 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 9ed94e5bb04e ("i40e: add vector Rx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
doc/guides/nics/features/i40e.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
index 4610444ace..fb00b69830 100644
--- a/doc/guides/nics/features/i40e.ini
+++ b/doc/guides/nics/features/i40e.ini
@@ -16,7 +16,7 @@ Runtime Tx queue setup = Y
Burst mode info = Y
Power mgmt address monitor = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH 13/13] docs: fix TSO feature status in i40e driver documentation
2025-12-09 11:26 ` [PATCH 13/13] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
@ 2025-12-11 11:59 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-11 11:59 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev, stable
On Tue, Dec 09, 2025 at 11:26:52AM +0000, Ciara Loftus wrote:
> TSO is only supported on the scalar path so change the status to
> partially supported.
>
> Fixes: 9ed94e5bb04e ("i40e: add vector Rx")
> Cc: stable@dpdk.org
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> doc/guides/nics/features/i40e.ini | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
> index 4610444ace..fb00b69830 100644
> --- a/doc/guides/nics/features/i40e.ini
> +++ b/doc/guides/nics/features/i40e.ini
> @@ -16,7 +16,7 @@ Runtime Tx queue setup = Y
> Burst mode info = Y
> Power mgmt address monitor = Y
> Scattered Rx = Y
> -TSO = Y
> +TSO = P
> Promiscuous mode = Y
> Allmulticast mode = Y
> Unicast MAC filter = Y
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v2 00/10] net/intel: tx path selection simplification
2025-12-09 11:26 [PATCH 00/13] net/intel: tx path selection simplification Ciara Loftus
` (12 preceding siblings ...)
2025-12-09 11:26 ` [PATCH 13/13] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
` (10 more replies)
13 siblings, 11 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
This series aims to simplify the process of selecting a Tx burst
function for the Intel drivers i40e, iavf, ice, idpf and cpfl by:
1. enforcing the same tx burst function for both primary and secondary
processes.
2. using a common function for selecting the tx burst function based on
maximum SIMD width, function features (context descriptor, single queue, etc.)
and requested tx offloads.
Some fixes are made to errors in the documentation that became evident
while implementing the new selection infratructure in each driver.
v2:
* Consolidated the patches that enforce primary/secondary path selection
alignment and the introduction of the infrastructure per driver.
* Introduce the "simple tx" feature in patch 1 rather than later.
* Changed some types and arrangements of structs in tx.h
* Fixed some issues relating to mbuf_check and tx_pkt_prepare
* Use the same path in primary and secondary for idpf and cpfl as well.
Ciara Loftus (10):
net/intel: introduce infrastructure for Tx path selection
net/ice: use common Tx path selection infrastructure
net/iavf: use common Tx path selection infrastructure
net/i40e: use common Tx path selection infrastructure
net/idpf: use common Tx path selection infrastructure
net/cpfl: use common Tx path selection infrastructure
docs: fix TSO and checksum offload feature status in ice doc
docs: fix TSO feature status in iavf driver documentation
docs: fix inline crypto feature status in iavf driver doc
docs: fix TSO feature status in i40e driver documentation
doc/guides/nics/features/i40e.ini | 2 +-
doc/guides/nics/features/iavf.ini | 4 +-
doc/guides/nics/features/ice.ini | 6 +-
drivers/net/intel/common/tx.h | 96 +++++++
drivers/net/intel/cpfl/cpfl_rxtx.c | 120 +++------
drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h | 10 -
drivers/net/intel/i40e/i40e_ethdev.h | 14 +-
drivers/net/intel/i40e/i40e_rxtx.c | 190 +++++++-------
drivers/net/intel/i40e/i40e_rxtx.h | 20 +-
.../net/intel/i40e/i40e_rxtx_vec_altivec.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_neon.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_sse.c | 6 -
drivers/net/intel/iavf/iavf.h | 2 -
drivers/net/intel/iavf/iavf_ethdev.c | 9 +-
drivers/net/intel/iavf/iavf_rxtx.c | 240 +++++++++---------
drivers/net/intel/iavf/iavf_rxtx.h | 46 ++--
drivers/net/intel/iavf/iavf_rxtx_vec_common.h | 39 +--
drivers/net/intel/ice/ice_ethdev.c | 1 +
drivers/net/intel/ice/ice_ethdev.h | 14 +-
drivers/net/intel/ice/ice_rxtx.c | 204 ++++++++-------
drivers/net/intel/ice/ice_rxtx.h | 30 ++-
drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +--
drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
drivers/net/intel/idpf/idpf_common_device.h | 12 +-
drivers/net/intel/idpf/idpf_common_rxtx.c | 49 ++++
drivers/net/intel/idpf/idpf_common_rxtx.h | 12 +
drivers/net/intel/idpf/idpf_rxtx.c | 118 +++------
drivers/net/intel/idpf/idpf_rxtx_vec_common.h | 10 -
28 files changed, 675 insertions(+), 632 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 01/10] net/intel: introduce infrastructure for Tx path selection
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 02/10] net/ice: use common Tx path selection infrastructure Ciara Loftus
` (9 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, Bruce Richardson
The code for determining which Tx path to select during initialisation
has become complicated in many intel drivers due to the amount of
different paths and features available within each path. This commit
aims to simplify and genericize the path selection logic.
The following information about each Tx burst function is stored and
used by the new common function to select the appropriate Tx path:
- Tx Offloads
- SIMD bitwidth
- "Simple" Tx
The implementation is based off the Rx path selection infrastructure
introduced in a previous commit.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
v2:
* Change req_features to pointer instead of passing by value
* Change num_paths from int to size_t
* Change i from int to unsigned int and define it inside the for
statement.
* Remove ci_tx_path_features_extra substructure
* Add simple tx feature in this patch rather in a later patch when it
is first used by a driver.
---
drivers/net/intel/common/tx.h | 77 +++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 5af64a4cfe..04d9aa8473 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
+#include <rte_vect.h>
/* forward declaration of the common intel (ci) queue structure */
struct ci_tx_queue;
@@ -117,6 +118,19 @@ struct ci_tx_queue {
};
};
+struct ci_tx_path_features {
+ uint32_t tx_offloads;
+ enum rte_vect_max_simd simd_width;
+ bool simple_tx;
+};
+
+struct ci_tx_path_info {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+ struct ci_tx_path_features features;
+ eth_tx_prep_t pkt_prep;
+};
+
static __rte_always_inline void
ci_tx_backlog_entry(struct ci_tx_entry *txep, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -262,4 +276,67 @@ ci_txq_release_all_mbufs(struct ci_tx_queue *txq, bool use_ctx)
memset(txq->sw_ring_vec, 0, sizeof(txq->sw_ring_vec[0]) * nb_desc);
}
+/**
+ * Select the best matching Tx path based on features
+ *
+ * @param req_features
+ * The requested features for the Tx path
+ * @param infos
+ * Array of information about the available Tx paths
+ * @param num_paths
+ * Number of available paths in the infos array
+ * @param default_path
+ * Index of the default path to use if no suitable path is found
+ *
+ * @return
+ * The packet burst function index that best matches the requested features,
+ * or default_path if no suitable path is found
+ */
+static inline int
+ci_tx_path_select(const struct ci_tx_path_features *req_features,
+ const struct ci_tx_path_info *infos,
+ size_t num_paths,
+ int default_path)
+{
+ int idx = default_path;
+ const struct ci_tx_path_features *chosen_path_features = NULL;
+
+ for (unsigned int i = 0; i < num_paths; i++) {
+ const struct ci_tx_path_features *path_features = &infos[i].features;
+
+ /* Do not use a simple tx path if not requested. */
+ if (path_features->simple_tx && !req_features->simple_tx)
+ continue;
+
+ /* Ensure the path supports the requested TX offloads. */
+ if ((path_features->tx_offloads & req_features->tx_offloads) !=
+ req_features->tx_offloads)
+ continue;
+
+ /* Ensure the path's SIMD width is compatible with the requested width. */
+ if (path_features->simd_width > req_features->simd_width)
+ continue;
+
+ /* Do not select the path if it is less suitable than the chosen path. */
+ if (chosen_path_features != NULL) {
+ /* Do not select paths with lower SIMD width than the chosen path. */
+ if (path_features->simd_width < chosen_path_features->simd_width)
+ continue;
+ /* Do not select paths with more offloads enabled than the chosen path if
+ * the SIMD widths are the same.
+ */
+ if (path_features->simd_width == chosen_path_features->simd_width &&
+ rte_popcount32(path_features->tx_offloads) >
+ rte_popcount32(chosen_path_features->tx_offloads))
+ continue;
+ }
+
+ /* Finally, select the path since it has met all the requirements. */
+ idx = i;
+ chosen_path_features = &infos[idx].features;
+ }
+
+ return idx;
+}
+
#endif /* _COMMON_INTEL_TX_H_ */
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 02/10] net/ice: use common Tx path selection infrastructure
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 03/10] net/iavf: " Ciara Loftus
` (8 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Also let the primary process select the Tx path to be used by
all processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* Fixed mbuf_check function
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
---
drivers/net/intel/ice/ice_ethdev.c | 1 +
drivers/net/intel/ice/ice_ethdev.h | 14 +-
drivers/net/intel/ice/ice_rxtx.c | 204 ++++++++++----------
drivers/net/intel/ice/ice_rxtx.h | 30 ++-
drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +---
drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
6 files changed, 142 insertions(+), 148 deletions(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index c721d135f5..a805e78d03 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -3900,6 +3900,7 @@ ice_dev_configure(struct rte_eth_dev *dev)
ad->tx_simple_allowed = true;
ad->rx_func_type = ICE_RX_DEFAULT;
+ ad->tx_func_type = ICE_TX_DEFAULT;
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 72ed65f13b..7fa2db1bd2 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -208,6 +208,16 @@ enum ice_rx_func_type {
ICE_RX_AVX512_SCATTERED_OFFLOAD,
};
+enum ice_tx_func_type {
+ ICE_TX_DEFAULT,
+ ICE_TX_SIMPLE,
+ ICE_TX_SSE,
+ ICE_TX_AVX2,
+ ICE_TX_AVX2_OFFLOAD,
+ ICE_TX_AVX512,
+ ICE_TX_AVX512_OFFLOAD,
+};
+
struct ice_adapter;
/**
@@ -658,14 +668,13 @@ struct ice_adapter {
bool tx_vec_allowed;
bool tx_simple_allowed;
enum ice_rx_func_type rx_func_type;
+ enum ice_tx_func_type tx_func_type;
/* ptype mapping table */
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[ICE_MAX_PKT_TYPE];
bool is_safe_mode;
struct ice_devargs devargs;
enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
uint16_t fdir_ref_cnt;
- /* For vector PMD */
- eth_rx_burst_t tx_pkt_burst;
/* For PTP */
uint8_t ptp_tx_block;
uint8_t ptp_tx_index;
@@ -679,7 +688,6 @@ struct ice_adapter {
/* Set bit if the engine is disabled */
unsigned long disabled_engine_mask;
struct ice_parser *psr;
- enum rte_vect_max_simd tx_simd_width;
bool rx_vec_offload_support;
};
diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
index 74db0fbec9..3fdb9fbf6e 100644
--- a/drivers/net/intel/ice/ice_rxtx.c
+++ b/drivers/net/intel/ice/ice_rxtx.c
@@ -3929,6 +3929,75 @@ ice_check_empty_mbuf(struct rte_mbuf *tx_pkt)
return 0;
}
+static const struct ci_tx_path_info ice_tx_path_infos[] = {
+ [ICE_TX_DEFAULT] = {
+ .pkt_burst = ice_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+ [ICE_TX_SIMPLE] = {
+ .pkt_burst = ice_xmit_pkts_simple,
+ .info = "Scalar Simple",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS,
+ .simple_tx = true
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+#ifdef RTE_ARCH_X86
+ [ICE_TX_SSE] = {
+ .pkt_burst = ice_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX2] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
+ .info = "Offload Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+#ifdef CC_AVX512_SUPPORT
+ [ICE_TX_AVX512] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
+ .info = "Offload Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+#endif
+#endif
+};
+
/* Tx mbuf check */
static uint16_t
ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -3941,6 +4010,7 @@ ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
const char *reason = NULL;
struct ice_adapter *adapter = txq->ice_vsi->adapter;
uint64_t ol_flags;
+ enum ice_tx_func_type tx_func_type = adapter->tx_func_type;
for (idx = 0; idx < nb_pkts; idx++) {
mb = tx_pkts[idx];
@@ -4025,7 +4095,7 @@ ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
return 0;
}
- return adapter->tx_pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return ice_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
uint16_t
@@ -4097,113 +4167,37 @@ ice_set_tx_function(struct rte_eth_dev *dev)
struct ice_adapter *ad =
ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
int mbuf_check = ad->devargs.mbuf_check;
-#ifdef RTE_ARCH_X86
- struct ci_tx_queue *txq;
- int i;
- int tx_check_ret = -1;
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ad->tx_simd_width = RTE_VECT_SIMD_DISABLED;
- tx_check_ret = ice_tx_vec_dev_check(dev);
- ad->tx_simd_width = ice_get_max_simd_bitwidth();
- if (tx_check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- ad->tx_vec_allowed = true;
-
- if (ad->tx_simd_width < RTE_VECT_SIMD_256 &&
- tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
- ad->tx_vec_allowed = false;
-
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq && ice_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- } else {
- ad->tx_vec_allowed = false;
- }
- }
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
- if (ad->tx_vec_allowed) {
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx512_offload;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = ice_xmit_pkts_vec_avx512;
- }
-#endif
- } else {
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx2_offload;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- ice_xmit_pkts_vec_avx2 :
- ice_xmit_pkts_vec;
- }
- }
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
- return;
- }
+ req_features.simple_tx = ad->tx_simple_allowed;
+
+#ifdef RTE_ARCH_X86
+ if (ice_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = ice_get_max_simd_bitwidth();
#endif
- if (ad->tx_simple_allowed) {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts_simple;
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- } else {
- PMD_INIT_LOG(DEBUG, "Normal tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts;
- dev->tx_pkt_prepare = ice_prep_pkts;
- }
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &ice_tx_path_infos[0],
+ RTE_DIM(ice_tx_path_infos),
+ ICE_TX_DEFAULT);
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
-}
+out:
+ if (ice_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_128)
+ ad->tx_vec_allowed = true;
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} ice_tx_burst_infos[] = {
- { ice_xmit_pkts_simple, "Scalar Simple" },
- { ice_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { ice_xmit_pkts_vec_avx512, "Vector AVX512" },
- { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" },
-#endif
- { ice_xmit_pkts_vec_avx2, "Vector AVX2" },
- { ice_xmit_pkts_vec_avx2_offload, "Offload Vector AVX2" },
- { ice_xmit_pkts_vec, "Vector SSE" },
-#endif
-};
+ dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
+ ice_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = ice_tx_path_infos[ad->tx_func_type].pkt_prep;
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ ice_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+}
int
ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
@@ -4213,10 +4207,10 @@ ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(ice_tx_burst_infos); ++i) {
- if (pkt_burst == ice_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(ice_tx_path_infos); ++i) {
+ if (pkt_burst == ice_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- ice_tx_burst_infos[i].info);
+ ice_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/ice/ice_rxtx.h b/drivers/net/intel/ice/ice_rxtx.h
index 141a62a7da..d7e8c1b0c4 100644
--- a/drivers/net/intel/ice/ice_rxtx.h
+++ b/drivers/net/intel/ice/ice_rxtx.h
@@ -108,6 +108,35 @@
RTE_ETH_RX_OFFLOAD_VLAN_FILTER |\
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+/* basic scalar path */
+#define ICE_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
+/* basic vector path */
+#define ICE_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* vector offload paths */
+#define ICE_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ ICE_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)
+
/* Max header size can be 2K - 64 bytes */
#define ICE_RX_HDR_BUF_SIZE (2048 - 64)
@@ -249,7 +278,6 @@ void ice_select_rxd_to_pkt_fields_handler(struct ci_rx_queue *rxq,
int ice_rx_vec_dev_check(struct rte_eth_dev *dev);
int ice_tx_vec_dev_check(struct rte_eth_dev *dev);
int ice_rxq_vec_setup(struct ci_rx_queue *rxq);
-int ice_txq_vec_setup(struct ci_tx_queue *txq);
uint16_t ice_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
uint16_t ice_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_common.h b/drivers/net/intel/ice/ice_rxtx_vec_common.h
index 39581cb7ae..ff46a8fb49 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_common.h
+++ b/drivers/net/intel/ice/ice_rxtx_vec_common.h
@@ -51,28 +51,6 @@ _ice_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq)
memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
}
-#define ICE_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
- RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
-
-#define ICE_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define ICE_VECTOR_PATH 0
-#define ICE_VECTOR_OFFLOAD_PATH 1
-
static inline int
ice_rx_vec_queue_default(struct ci_rx_queue *rxq)
{
@@ -98,13 +76,7 @@ ice_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > ICE_TX_MAX_FREE_BUF_SZ)
return -1;
- if (txq->offloads & ICE_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (txq->offloads & ICE_TX_VECTOR_OFFLOAD)
- return ICE_VECTOR_OFFLOAD_PATH;
-
- return ICE_VECTOR_PATH;
+ return 0;
}
static inline int
@@ -130,18 +102,15 @@ ice_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret = 0;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = ice_tx_vec_queue_default(txq);
if (ret < 0)
return -1;
- if (ret == ICE_VECTOR_OFFLOAD_PATH)
- result = ret;
}
- return result;
+ return ret;
}
static inline void
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_sse.c b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
index 1545bc3b6e..4fc1b7e881 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_sse.c
+++ b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
@@ -718,12 +718,6 @@ ice_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-ice_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
ice_rx_vec_dev_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 03/10] net/iavf: use common Tx path selection infrastructure
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 02/10] net/ice: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 04/10] net/i40e: " Ciara Loftus
` (7 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Introduce two new features "disabled" and "context desc" to the common
infrastructure which represents whether or not the path is disabled, or
if it uses a context descriptor.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
---
drivers/net/intel/common/tx.h | 14 +
drivers/net/intel/iavf/iavf.h | 2 -
drivers/net/intel/iavf/iavf_ethdev.c | 9 +-
drivers/net/intel/iavf/iavf_rxtx.c | 240 +++++++++---------
drivers/net/intel/iavf/iavf_rxtx.h | 46 ++--
drivers/net/intel/iavf/iavf_rxtx_vec_common.h | 39 +--
6 files changed, 166 insertions(+), 184 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 04d9aa8473..60b1bd642a 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -122,6 +122,8 @@ struct ci_tx_path_features {
uint32_t tx_offloads;
enum rte_vect_max_simd simd_width;
bool simple_tx;
+ bool ctx_desc;
+ bool disabled;
};
struct ci_tx_path_info {
@@ -304,10 +306,18 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
for (unsigned int i = 0; i < num_paths; i++) {
const struct ci_tx_path_features *path_features = &infos[i].features;
+ /* Do not select a disabled tx path. */
+ if (path_features->disabled)
+ continue;
+
/* Do not use a simple tx path if not requested. */
if (path_features->simple_tx && !req_features->simple_tx)
continue;
+ /* If a context descriptor is requested, ensure the path supports it. */
+ if (!path_features->ctx_desc && req_features->ctx_desc)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features->tx_offloads) !=
req_features->tx_offloads)
@@ -329,6 +339,10 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
rte_popcount32(path_features->tx_offloads) >
rte_popcount32(chosen_path_features->tx_offloads))
continue;
+
+ /* Don't use a context descriptor unless necessary */
+ if (path_features->ctx_desc && !chosen_path_features->ctx_desc)
+ continue;
}
/* Finally, select the path since it has met all the requirements. */
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index d78582e05c..921bf0a607 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -375,8 +375,6 @@ struct iavf_adapter {
struct iavf_security_ctx *security_ctx;
bool rx_bulk_alloc_allowed;
- /* For vector PMD */
- bool tx_vec_allowed;
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[IAVF_MAX_PKT_TYPE];
bool stopped;
bool closed;
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 15e49fe248..bf1186c20f 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -666,10 +666,8 @@ iavf_dev_configure(struct rte_eth_dev *dev)
return -EIO;
ad->rx_bulk_alloc_allowed = true;
- /* Initialize to TRUE. If any of Rx queues doesn't meet the
- * vector Rx/Tx preconditions, it will be reset.
- */
- ad->tx_vec_allowed = true;
+
+ ad->tx_func_type = IAVF_TX_DEFAULT;
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
@@ -2795,8 +2793,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->tx_pkt_prepare = &iavf_prep_pkts;
/* For secondary processes, we don't initialise any further as primary
- * has already done this work. Only check if we need a different RX
- * and TX function.
+ * has already done this work.
*/
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
iavf_set_rx_function(eth_dev);
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c b/drivers/net/intel/iavf/iavf_rxtx.c
index d8662fd815..794232c5dd 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -208,19 +208,6 @@ check_tx_thresh(uint16_t nb_desc, uint16_t tx_rs_thresh,
return 0;
}
-static inline bool
-check_tx_vec_allow(struct ci_tx_queue *txq)
-{
- if (!(txq->offloads & IAVF_TX_NO_VECTOR_FLAGS) &&
- txq->tx_rs_thresh >= IAVF_VPMD_TX_BURST &&
- txq->tx_rs_thresh <= IAVF_VPMD_TX_MAX_FREE_BUF) {
- PMD_INIT_LOG(DEBUG, "Vector tx can be enabled on this txq.");
- return true;
- }
- PMD_INIT_LOG(DEBUG, "Vector Tx cannot be enabled on this txq.");
- return false;
-}
-
static inline bool
check_rx_bulk_allow(struct ci_rx_queue *rxq)
{
@@ -861,12 +848,6 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
dev->data->tx_queues[queue_idx] = txq;
txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx);
- if (check_tx_vec_allow(txq) == false) {
- struct iavf_adapter *ad =
- IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- ad->tx_vec_allowed = false;
- }
-
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS &&
vf->tm_conf.committed) {
int tc;
@@ -4002,26 +3983,82 @@ iavf_rx_burst_mode_get(struct rte_eth_dev *dev,
return -EINVAL;
}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} iavf_tx_pkt_burst_ops[] = {
- [IAVF_TX_DISABLED] = {iavf_xmit_pkts_no_poll, "Disabled"},
- [IAVF_TX_DEFAULT] = {iavf_xmit_pkts, "Scalar"},
+static const struct ci_tx_path_info iavf_tx_path_infos[] = {
+ [IAVF_TX_DISABLED] = {
+ .pkt_burst = iavf_xmit_pkts_no_poll,
+ .info = "Disabled",
+ .features = {
+ .disabled = true
+ }
+ },
+ [IAVF_TX_DEFAULT] = {
+ .pkt_burst = iavf_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = IAVF_TX_SCALAR_OFFLOADS,
+ .ctx_desc = true
+ }
+ },
#ifdef RTE_ARCH_X86
- [IAVF_TX_SSE] = {iavf_xmit_pkts_vec, "Vector SSE"},
- [IAVF_TX_AVX2] = {iavf_xmit_pkts_vec_avx2, "Vector AVX2"},
- [IAVF_TX_AVX2_OFFLOAD] = {iavf_xmit_pkts_vec_avx2_offload,
- "Vector AVX2 Offload"},
+ [IAVF_TX_SSE] = {
+ .pkt_burst = iavf_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ }
+ },
+ [IAVF_TX_AVX2] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
+ [IAVF_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2_offload,
+ .info = "Vector AVX2 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
#ifdef CC_AVX512_SUPPORT
- [IAVF_TX_AVX512] = {iavf_xmit_pkts_vec_avx512, "Vector AVX512"},
- [IAVF_TX_AVX512_OFFLOAD] = {iavf_xmit_pkts_vec_avx512_offload,
- "Vector AVX512 Offload"},
- [IAVF_TX_AVX512_CTX] = {iavf_xmit_pkts_vec_avx512_ctx,
- "Vector AVX512 Ctx"},
+ [IAVF_TX_AVX512] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_offload,
+ .info = "Vector AVX512 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_CTX] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx,
+ .info = "Vector AVX512 Ctx",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .ctx_desc = true
+ }
+ },
[IAVF_TX_AVX512_CTX_OFFLOAD] = {
- iavf_xmit_pkts_vec_avx512_ctx_offload,
- "Vector AVX512 Ctx Offload"},
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx_offload,
+ .info = "Vector AVX512 Ctx Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .ctx_desc = true
+ }
+ },
#endif
#endif
};
@@ -4034,10 +4071,10 @@ iavf_tx_burst_mode_get(struct rte_eth_dev *dev,
eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
size_t i;
- for (i = 0; i < RTE_DIM(iavf_tx_pkt_burst_ops); i++) {
- if (pkt_burst == iavf_tx_pkt_burst_ops[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(iavf_tx_path_infos); i++) {
+ if (pkt_burst == iavf_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- iavf_tx_pkt_burst_ops[i].info);
+ iavf_tx_path_infos[i].info);
return 0;
}
}
@@ -4073,7 +4110,7 @@ iavf_xmit_pkts_no_poll(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_func_type = txq->iavf_vsi->adapter->tx_func_type;
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue,
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue,
tx_pkts, nb_pkts);
}
@@ -4158,7 +4195,7 @@ iavf_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts,
return 0;
}
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
/* choose rx function*/
@@ -4229,109 +4266,62 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
{
struct iavf_adapter *adapter =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- enum iavf_tx_func_type tx_func_type;
int mbuf_check = adapter->devargs.mbuf_check;
int no_poll_on_link_down = adapter->devargs.no_poll_on_link_down;
-#ifdef RTE_ARCH_X86
struct ci_tx_queue *txq;
int i;
- int check_ret;
- bool use_sse = false;
- bool use_avx2 = false;
- bool use_avx512 = false;
- enum rte_vect_max_simd tx_simd_path = iavf_get_max_simd_bitwidth();
-
- check_ret = iavf_tx_vec_dev_check(dev);
-
- if (check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- /* SSE not support offload path yet. */
- if (check_ret == IAVF_VECTOR_PATH) {
- use_sse = true;
- }
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- use_avx2 = tx_simd_path == RTE_VECT_SIMD_256;
- use_avx512 = tx_simd_path == RTE_VECT_SIMD_512;
+#ifdef RTE_ARCH_X86
+ if (iavf_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = iavf_get_max_simd_bitwidth();
- if (!use_sse && !use_avx2 && !use_avx512)
- goto normal;
+ if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0)
+ req_features.ctx_desc = true;
- if (use_sse) {
- PMD_DRV_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_SSE;
- }
- if (!use_avx512 && use_avx2) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX2;
- PMD_DRV_LOG(DEBUG, "Using AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_OFFLOAD_PATH) {
- PMD_DRV_LOG(DEBUG,
- "AVX2 does not support requested Tx offloads.");
- goto normal;
- } else {
- tx_func_type = IAVF_TX_AVX2_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
- }
-#ifdef CC_AVX512_SUPPORT
- if (use_avx512) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX512;
- PMD_DRV_LOG(DEBUG, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_OFFLOAD_PATH) {
- tx_func_type = IAVF_TX_AVX512_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_PATH) {
- tx_func_type = IAVF_TX_AVX512_CTX;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT Vector Tx (port %d).",
- dev->data->port_id);
- } else {
- tx_func_type = IAVF_TX_AVX512_CTX_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
- }
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT &&
+ txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
+ req_features.ctx_desc = true;
+ }
#endif
+ adapter->tx_func_type = ci_tx_path_select(&req_features,
+ &iavf_tx_path_infos[0],
+ RTE_DIM(iavf_tx_path_infos),
+ IAVF_TX_DEFAULT);
+
+out:
+ if (iavf_tx_path_infos[adapter->tx_func_type].features.simd_width != 0) {
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
if (!txq)
continue;
iavf_txq_vec_setup(txq);
+ txq->use_ctx =
+ iavf_tx_path_infos[adapter->tx_func_type].features.ctx_desc;
}
-
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
- return;
}
-normal:
-#endif
- PMD_DRV_LOG(DEBUG, "Using Basic Tx callback (port=%d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_DEFAULT;
-
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
+ if (no_poll_on_link_down)
dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
+ else if (mbuf_check)
dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
+ else
+ dev->tx_pkt_burst = iavf_tx_path_infos[adapter->tx_func_type].pkt_burst;
+
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ iavf_tx_path_infos[adapter->tx_func_type].info, dev->data->port_id);
}
static int
diff --git a/drivers/net/intel/iavf/iavf_rxtx.h b/drivers/net/intel/iavf/iavf_rxtx.h
index 8efb3bd04e..bff456e509 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.h
+++ b/drivers/net/intel/iavf/iavf_rxtx.h
@@ -35,22 +35,38 @@
#define IAVF_VPMD_DESCS_PER_LOOP_WIDE CI_VPMD_DESCS_PER_LOOP_WIDE
#define IAVF_VPMD_TX_MAX_FREE_BUF 64
-#define IAVF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_SECURITY)
-
-#define IAVF_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+/* basic scalar path */
+#define IAVF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_SECURITY | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
+/* basic vector path */
+#define IAVF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* offload vector path */
+#define IAVF_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define IAVF_TX_VECTOR_OFFLOAD_CTX ( \
+/* offload vector path with context descriptor */
+#define IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ IAVF_TX_VECTOR_OFFLOAD_OFFLOADS | \
RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_QINQ_INSERT)
diff --git a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
index 66f65b46e9..f1ea57034f 100644
--- a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
@@ -73,8 +73,6 @@ iavf_rx_vec_queue_default(struct ci_rx_queue *rxq)
static inline int
iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
{
- bool vlan_offload = false, vlan_needs_ctx = false;
-
if (!txq)
return -1;
@@ -82,35 +80,7 @@ iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > IAVF_VPMD_TX_MAX_FREE_BUF)
return -1;
- if (txq->offloads & IAVF_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_PATH;
- }
-
- /* Vlan tci needs to be inserted via ctx desc, if the vlan_flag is L2TAG2. */
- if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) {
- vlan_offload = true;
- if (txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
- vlan_needs_ctx = true;
- }
-
- /**
- * Tunneling parameters and other fields need be configured in ctx desc
- * if the outer checksum offload is enabled.
- */
- if (txq->offloads & (IAVF_TX_VECTOR_OFFLOAD | IAVF_TX_VECTOR_OFFLOAD_CTX) || vlan_offload) {
- if (txq->offloads & IAVF_TX_VECTOR_OFFLOAD_CTX || vlan_needs_ctx) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_OFFLOAD_PATH;
- } else {
- return IAVF_VECTOR_OFFLOAD_PATH;
- }
- } else {
- return IAVF_VECTOR_PATH;
- }
+ return 0;
}
static inline int
@@ -137,19 +107,16 @@ iavf_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = iavf_tx_vec_queue_default(txq);
if (ret < 0)
- return -1;
- if (ret > result)
- result = ret;
+ break;
}
- return result;
+ return ret;
}
/******************************************************************************
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 04/10] net/i40e: use common Tx path selection infrastructure
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (2 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 03/10] net/iavf: " Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 05/10] net/idpf: " Ciara Loftus
` (6 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
* Fixed mbuf_check logic
* Fixed assignment of pkt_prepare function
---
drivers/net/intel/i40e/i40e_ethdev.h | 14 +-
drivers/net/intel/i40e/i40e_rxtx.c | 190 ++++++++++--------
drivers/net/intel/i40e/i40e_rxtx.h | 20 +-
.../net/intel/i40e/i40e_rxtx_vec_altivec.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_neon.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_sse.c | 6 -
6 files changed, 135 insertions(+), 107 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index 3fca089d6c..1fe504d0cd 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1243,6 +1243,16 @@ enum i40e_rx_func_type {
I40E_RX_ALTIVEC_SCATTERED,
};
+enum i40e_tx_func_type {
+ I40E_TX_DEFAULT,
+ I40E_TX_SCALAR_SIMPLE,
+ I40E_TX_SSE,
+ I40E_TX_AVX2,
+ I40E_TX_AVX512,
+ I40E_TX_NEON,
+ I40E_TX_ALTIVEC,
+};
+
/*
* Structure to store private data for each PF/VF instance.
*/
@@ -1260,10 +1270,10 @@ struct i40e_adapter {
bool tx_vec_allowed;
enum i40e_rx_func_type rx_func_type;
+ enum i40e_tx_func_type tx_func_type;
uint64_t mbuf_check; /* mbuf check flags. */
uint16_t max_pkt_len; /* Maximum packet length */
- eth_tx_burst_t tx_pkt_burst;
/* For PTP */
struct rte_timecounter systime_tc;
@@ -1279,8 +1289,6 @@ struct i40e_adapter {
/* For RSS reta table update */
uint8_t rss_reta_updated;
-
- enum rte_vect_max_simd tx_simd_width;
};
/**
diff --git a/drivers/net/intel/i40e/i40e_rxtx.c b/drivers/net/intel/i40e/i40e_rxtx.c
index 255414dd03..a7d80e2bc0 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.c
+++ b/drivers/net/intel/i40e/i40e_rxtx.c
@@ -1550,6 +1550,77 @@ i40e_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
return nb_tx;
}
+static const struct ci_tx_path_info i40e_tx_path_infos[] = {
+ [I40E_TX_DEFAULT] = {
+ .pkt_burst = i40e_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ },
+ .pkt_prep = i40e_prep_pkts,
+ },
+ [I40E_TX_SCALAR_SIMPLE] = {
+ .pkt_burst = i40e_xmit_pkts_simple,
+ .info = "Scalar Simple",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ .simple_tx = true
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#ifdef RTE_ARCH_X86
+ [I40E_TX_SSE] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+ [I40E_TX_AVX2] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#ifdef CC_AVX512_SUPPORT
+ [I40E_TX_AVX512] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#endif
+#elif defined(RTE_ARCH_ARM64)
+ [I40E_TX_NEON] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector Neon",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#elif defined(RTE_ARCH_PPC_64)
+ [I40E_TX_ALTIVEC] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector AltiVec",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#endif
+};
+
/* Tx mbuf check */
static uint16_t
i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -1562,6 +1633,7 @@ i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
const char *reason = NULL;
uint16_t good_pkts = nb_pkts;
struct i40e_adapter *adapter = txq->i40e_vsi->adapter;
+ enum i40e_tx_func_type tx_func_type = adapter->tx_func_type;
for (idx = 0; idx < nb_pkts; idx++) {
mb = tx_pkts[idx];
@@ -1652,7 +1724,7 @@ i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
return 0;
}
- return adapter->tx_pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return i40e_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
/*********************************************************************
@@ -2375,8 +2447,7 @@ i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
/* check vector conflict */
if (ad->tx_vec_allowed) {
- if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ ||
- i40e_txq_vec_setup(txq)) {
+ if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ) {
PMD_DRV_LOG(ERR, "Failed vector tx setup.");
return -EINVAL;
}
@@ -3525,93 +3596,42 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
struct i40e_adapter *ad =
I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
uint64_t mbuf_check = ad->mbuf_check;
- int i;
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-#ifdef RTE_ARCH_X86
- ad->tx_simd_width = i40e_get_max_simd_bitwidth();
-#endif
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- struct ci_tx_queue *txq =
- dev->data->tx_queues[i];
-
- if (txq && i40e_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- }
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .simple_tx = ad->tx_simple_allowed
+ };
- if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)
- ad->tx_vec_allowed = false;
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- if (ad->tx_simple_allowed) {
- if (ad->tx_vec_allowed) {
+ if (ad->tx_vec_allowed) {
#ifdef RTE_ARCH_X86
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- PMD_DRV_LOG(NOTICE, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec_avx512;
+ req_features.simd_width = i40e_get_max_simd_bitwidth();
#else
- PMD_DRV_LOG(ERR, "Invalid Tx SIMD width reported, defaulting to "
- "using scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts;
+ req_features.simd_width = rte_vect_get_max_simd_bitwidth();
#endif
- } else {
- PMD_INIT_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- i40e_xmit_pkts_vec_avx2 :
- i40e_xmit_pkts_vec;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
-#else /* RTE_ARCH_X86 */
- PMD_INIT_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
-#endif /* RTE_ARCH_X86 */
- } else {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts_simple;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
- dev->tx_pkt_prepare = i40e_simple_prep_pkts;
- } else {
- PMD_INIT_LOG(DEBUG, "Xmit tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts;
- dev->tx_pkt_prepare = i40e_prep_pkts;
}
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = i40e_xmit_pkts_check;
- }
-}
+ ad->tx_func_type = ci_tx_path_select(&req_features, &i40e_tx_path_infos[0],
+ RTE_DIM(i40e_tx_path_infos), I40E_TX_DEFAULT);
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} i40e_tx_burst_infos[] = {
- { i40e_xmit_pkts_simple, "Scalar Simple" },
- { i40e_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { i40e_xmit_pkts_vec_avx512, "Vector AVX512" },
-#endif
- { i40e_xmit_pkts_vec_avx2, "Vector AVX2" },
- { i40e_xmit_pkts_vec, "Vector SSE" },
-#elif defined(RTE_ARCH_ARM64)
- { i40e_xmit_pkts_vec, "Vector Neon" },
-#elif defined(RTE_ARCH_PPC_64)
- { i40e_xmit_pkts_vec, "Vector AltiVec" },
-#endif
-};
+out:
+ dev->tx_pkt_burst = mbuf_check ? i40e_xmit_pkts_check :
+ i40e_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = i40e_tx_path_infos[ad->tx_func_type].pkt_prep;
+
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ i40e_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+
+ if (ad->tx_func_type == I40E_TX_SCALAR_SIMPLE ||
+ ad->tx_func_type == I40E_TX_SSE ||
+ ad->tx_func_type == I40E_TX_NEON ||
+ ad->tx_func_type == I40E_TX_ALTIVEC ||
+ ad->tx_func_type == I40E_TX_AVX2)
+ dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
+}
int
i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
@@ -3621,10 +3641,10 @@ i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(i40e_tx_burst_infos); ++i) {
- if (pkt_burst == i40e_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(i40e_tx_path_infos); ++i) {
+ if (pkt_burst == i40e_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- i40e_tx_burst_infos[i].info);
+ i40e_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/i40e/i40e_rxtx.h b/drivers/net/intel/i40e/i40e_rxtx.h
index b5a901794f..ed173d8f17 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.h
+++ b/drivers/net/intel/i40e/i40e_rxtx.h
@@ -91,6 +91,25 @@ enum i40e_header_split_mode {
RTE_ETH_RX_OFFLOAD_VLAN_FILTER | \
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+#define I40E_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define I40E_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
/** Offload features */
union i40e_tx_offload {
uint64_t data;
@@ -165,7 +184,6 @@ uint16_t i40e_recv_scattered_pkts_vec(void *rx_queue,
uint16_t nb_pkts);
int i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev);
int i40e_rxq_vec_setup(struct ci_rx_queue *rxq);
-int i40e_txq_vec_setup(struct ci_tx_queue *txq);
void i40e_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq);
uint16_t i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
index 87a57e7520..bbb6d907cf 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
@@ -547,12 +547,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue __rte_unused * txq)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
index c9098e4c1a..b5be0c1b59 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
@@ -697,12 +697,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
index c035408dcc..c209135890 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
@@ -704,12 +704,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 05/10] net/idpf: use common Tx path selection infrastructure
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (3 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 04/10] net/i40e: " Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 06/10] net/cpfl: " Ciara Loftus
` (5 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Introduce a new feature "single queue" to the common infrastructure
which represents whether single or split queue mode is used in the given
path.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* removed unnecessary tx_vec_allowed
---
drivers/net/intel/common/tx.h | 5 +
drivers/net/intel/idpf/idpf_common_device.h | 10 ++
drivers/net/intel/idpf/idpf_common_rxtx.c | 49 ++++++++
drivers/net/intel/idpf/idpf_common_rxtx.h | 12 ++
drivers/net/intel/idpf/idpf_rxtx.c | 118 ++++++------------
drivers/net/intel/idpf/idpf_rxtx_vec_common.h | 10 --
6 files changed, 112 insertions(+), 92 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 60b1bd642a..24fcfbe225 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -124,6 +124,7 @@ struct ci_tx_path_features {
bool simple_tx;
bool ctx_desc;
bool disabled;
+ bool single_queue;
};
struct ci_tx_path_info {
@@ -318,6 +319,10 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
if (!path_features->ctx_desc && req_features->ctx_desc)
continue;
+ /* If requested, ensure the path supports single queue TX. */
+ if (path_features->single_queue != req_features->single_queue)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features->tx_offloads) !=
req_features->tx_offloads)
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index c32dcfbb12..eff04a83eb 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -75,6 +75,15 @@ enum idpf_rx_func_type {
IDPF_RX_MAX
};
+enum idpf_tx_func_type {
+ IDPF_TX_DEFAULT,
+ IDPF_TX_SINGLEQ,
+ IDPF_TX_SINGLEQ_AVX2,
+ IDPF_TX_AVX512,
+ IDPF_TX_SINGLEQ_AVX512,
+ IDPF_TX_MAX
+};
+
struct idpf_adapter {
struct idpf_hw hw;
struct virtchnl2_version_info virtchnl_version;
@@ -92,6 +101,7 @@ struct idpf_adapter {
uint64_t time_hw;
enum idpf_rx_func_type rx_func_type;
+ enum idpf_tx_func_type tx_func_type;
};
struct idpf_chunks_info {
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.c b/drivers/net/intel/idpf/idpf_common_rxtx.c
index a5d0795057..cfeab8a1e4 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.c
@@ -1701,3 +1701,52 @@ const struct ci_rx_path_info idpf_rx_path_infos[] = {
#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
};
+
+RTE_EXPORT_INTERNAL_SYMBOL(idpf_tx_path_infos)
+const struct ci_tx_path_info idpf_tx_path_infos[] = {
+ [IDPF_TX_DEFAULT] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts,
+ .info = "Split Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS
+ }
+ },
+ [IDPF_TX_SINGLEQ] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts,
+ .info = "Single Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS,
+ .single_queue = true
+ }
+ },
+#ifdef RTE_ARCH_X86
+ [IDPF_TX_SINGLEQ_AVX2] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx2,
+ .info = "Single AVX2",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ .single_queue = true
+ }
+ },
+#ifdef CC_AVX512_SUPPORT
+ [IDPF_TX_AVX512] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts_avx512,
+ .info = "Split AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IDPF_TX_SINGLEQ_AVX512] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx512,
+ .info = "Single AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .single_queue = true
+ }
+ },
+#endif /* CC_AVX512_SUPPORT */
+#endif /* RTE_ARCH_X86 */
+};
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.h b/drivers/net/intel/idpf/idpf_common_rxtx.h
index 3bc3323af4..7c6ff5d047 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.h
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.h
@@ -106,6 +106,17 @@
RTE_ETH_RX_OFFLOAD_SCATTER)
#define IDPF_RX_VECTOR_OFFLOADS 0
+#define IDPF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define IDPF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
struct idpf_rx_stats {
RTE_ATOMIC(uint64_t) mbuf_alloc_failed;
};
@@ -264,5 +275,6 @@ uint16_t idpf_dp_singleq_xmit_pkts_avx2(void *tx_queue,
uint16_t nb_pkts);
extern const struct ci_rx_path_info idpf_rx_path_infos[IDPF_RX_MAX];
+extern const struct ci_tx_path_info idpf_tx_path_infos[IDPF_TX_MAX];
#endif /* _IDPF_COMMON_RXTX_H_ */
diff --git a/drivers/net/intel/idpf/idpf_rxtx.c b/drivers/net/intel/idpf/idpf_rxtx.c
index 4796d8b862..3e2bccd279 100644
--- a/drivers/net/intel/idpf/idpf_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_rxtx.c
@@ -813,97 +813,51 @@ idpf_set_tx_function(struct rte_eth_dev *dev)
{
struct idpf_vport *vport = dev->data->dev_private;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = idpf_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
+#ifdef RTE_ARCH_X86
+ if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH)
+ req_features.simd_width = idpf_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+out:
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- }
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.single_queue) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
}
+#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
index ecdf2f0e23..425f0792a1 100644
--- a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
+++ b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define IDPF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
idpf_tx_desc_done(struct ci_tx_queue *txq, uint16_t idx)
@@ -74,9 +67,6 @@ idpf_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return IDPF_SCALAR_PATH;
- if ((txq->offloads & IDPF_TX_NO_VECTOR_FLAGS) != 0)
- return IDPF_SCALAR_PATH;
-
return IDPF_VECTOR_PATH;
}
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 06/10] net/cpfl: use common Tx path selection infrastructure
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (4 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 05/10] net/idpf: " Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 07/10] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
` (4 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* removed unnecessary tx_vec_allowed
---
drivers/net/intel/cpfl/cpfl_rxtx.c | 120 ++++++------------
drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h | 10 --
drivers/net/intel/idpf/idpf_common_device.h | 2 -
3 files changed, 37 insertions(+), 95 deletions(-)
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx.c b/drivers/net/intel/cpfl/cpfl_rxtx.c
index 453ec975d5..b6bf4094f1 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx.c
+++ b/drivers/net/intel/cpfl/cpfl_rxtx.c
@@ -1462,97 +1462,51 @@ cpfl_set_tx_function(struct rte_eth_dev *dev)
struct cpfl_vport *cpfl_vport = dev->data->dev_private;
struct idpf_vport *vport = &cpfl_vport->base;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
- struct cpfl_tx_queue *cpfl_txq;
+ struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = cpfl_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
+#ifdef RTE_ARCH_X86
+ if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH)
+ req_features.simd_width = cpfl_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+out:
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- }
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- if (cpfl_txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.single_queue) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
}
+#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
index 525ca9a6e0..f0daa1eb30 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
+++ b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define CPFL_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
cpfl_rx_vec_queue_default(struct idpf_rx_queue *rxq)
@@ -62,9 +55,6 @@ cpfl_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return CPFL_SCALAR_PATH;
- if ((txq->offloads & CPFL_TX_NO_VECTOR_FLAGS) != 0)
- return CPFL_SCALAR_PATH;
-
return CPFL_VECTOR_PATH;
}
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index eff04a83eb..b31ae0bd5f 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -164,8 +164,6 @@ struct idpf_vport {
uint16_t devarg_id;
- bool tx_vec_allowed;
-
struct virtchnl2_vport_stats eth_stats_offset;
/* Event from ipf */
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 07/10] docs: fix TSO and checksum offload feature status in ice doc
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (5 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 06/10] net/cpfl: " Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 08/10] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
` (3 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change its status to
partially supported. L3 and L4 checksum offload are enabled on scalar
and vector paths so change their statuses from partial to supported.
Fixes: f88de4694d94 ("net/ice: support Tx SSE vector")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/ice.ini | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index e9796c1eab..893d09e9ec 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -21,7 +21,7 @@ Power mgmt address monitor = Y
MTU update = Y
Buffer split on Rx = P
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
DCB = Y
@@ -34,8 +34,8 @@ Traffic manager = Y
CRC offload = Y
VLAN offload = Y
QinQ offload = P
-L3 checksum offload = P
-L4 checksum offload = P
+L3 checksum offload = Y
+L4 checksum offload = Y
Timestamp offload = P
Inner L3 checksum = P
Inner L4 checksum = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 08/10] docs: fix TSO feature status in iavf driver documentation
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (6 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 07/10] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 09/10] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
` (2 subsequent siblings)
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 319c421f3890 ("net/avf: enable SSE Rx Tx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 7695e3ff7c..6c9e97594f 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -17,7 +17,7 @@ Burst mode info = Y
Power mgmt address monitor = Y
MTU update = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 09/10] docs: fix inline crypto feature status in iavf driver doc
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (7 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 08/10] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 10:33 ` [PATCH v2 10/10] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
inline crypto is only supported on the scalar path so change its status
to partially supported.
Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 6c9e97594f..0ba6f7dfd7 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -27,7 +27,7 @@ RSS key update = Y
RSS reta update = Y
VLAN filter = Y
Traffic manager = Y
-Inline crypto = Y
+Inline crypto = P
CRC offload = Y
VLAN offload = P
QinQ offload = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v2 10/10] docs: fix TSO feature status in i40e driver documentation
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (8 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 09/10] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
@ 2025-12-12 10:33 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
10 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 10:33 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 9ed94e5bb04e ("i40e: add vector Rx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/i40e.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
index 4610444ace..fb00b69830 100644
--- a/doc/guides/nics/features/i40e.ini
+++ b/doc/guides/nics/features/i40e.ini
@@ -16,7 +16,7 @@ Runtime Tx queue setup = Y
Burst mode info = Y
Power mgmt address monitor = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 00/10] net/intel: tx path selection simplification
2025-12-12 10:33 ` [PATCH v2 00/10] net/intel: tx path selection simplification Ciara Loftus
` (9 preceding siblings ...)
2025-12-12 10:33 ` [PATCH v2 10/10] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
` (9 more replies)
10 siblings, 10 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
This series aims to simplify the process of selecting a Tx burst
function for the Intel drivers i40e, iavf, ice, idpf and cpfl by:
1. enforcing the same tx burst function for both primary and secondary
processes.
2. using a common function for selecting the tx burst function based on
maximum SIMD width, function features (context descriptor, single queue, etc.)
and requested tx offloads.
Some fixes are made to errors in the documentation that became evident
while implementing the new selection infratructure in each driver.
v3:
* Fixed cross compile issue in iavf patch.
v2:
* Consolidated the patches that enforce primary/secondary path selection
alignment and the introduction of the infrastructure per driver.
* Introduce the "simple tx" feature in patch 1 rather than later.
* Changed some types and arrangements of structs in tx.h
* Fixed some issues relating to mbuf_check and tx_pkt_prepare
* Use the same path in primary and secondary for idpf and cpfl as well.
Ciara Loftus (10):
net/intel: introduce infrastructure for Tx path selection
net/ice: use common Tx path selection infrastructure
net/iavf: use common Tx path selection infrastructure
net/i40e: use common Tx path selection infrastructure
net/idpf: use common Tx path selection infrastructure
net/cpfl: use common Tx path selection infrastructure
docs: fix TSO and checksum offload feature status in ice doc
docs: fix TSO feature status in iavf driver documentation
docs: fix inline crypto feature status in iavf driver doc
docs: fix TSO feature status in i40e driver documentation
doc/guides/nics/features/i40e.ini | 2 +-
doc/guides/nics/features/iavf.ini | 4 +-
doc/guides/nics/features/ice.ini | 6 +-
drivers/net/intel/common/tx.h | 96 +++++++
drivers/net/intel/cpfl/cpfl_rxtx.c | 120 +++------
drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h | 10 -
drivers/net/intel/i40e/i40e_ethdev.h | 14 +-
drivers/net/intel/i40e/i40e_rxtx.c | 190 +++++++-------
drivers/net/intel/i40e/i40e_rxtx.h | 20 +-
.../net/intel/i40e/i40e_rxtx_vec_altivec.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_neon.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_sse.c | 6 -
drivers/net/intel/iavf/iavf.h | 2 -
drivers/net/intel/iavf/iavf_ethdev.c | 9 +-
drivers/net/intel/iavf/iavf_rxtx.c | 240 +++++++++---------
drivers/net/intel/iavf/iavf_rxtx.h | 46 ++--
drivers/net/intel/iavf/iavf_rxtx_vec_common.h | 39 +--
drivers/net/intel/ice/ice_ethdev.c | 1 +
drivers/net/intel/ice/ice_ethdev.h | 14 +-
drivers/net/intel/ice/ice_rxtx.c | 204 ++++++++-------
drivers/net/intel/ice/ice_rxtx.h | 30 ++-
drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +--
drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
drivers/net/intel/idpf/idpf_common_device.h | 12 +-
drivers/net/intel/idpf/idpf_common_rxtx.c | 49 ++++
drivers/net/intel/idpf/idpf_common_rxtx.h | 12 +
drivers/net/intel/idpf/idpf_rxtx.c | 118 +++------
drivers/net/intel/idpf/idpf_rxtx_vec_common.h | 10 -
28 files changed, 677 insertions(+), 630 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 01/10] net/intel: introduce infrastructure for Tx path selection
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 02/10] net/ice: use common Tx path selection infrastructure Ciara Loftus
` (8 subsequent siblings)
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, Bruce Richardson
The code for determining which Tx path to select during initialisation
has become complicated in many intel drivers due to the amount of
different paths and features available within each path. This commit
aims to simplify and genericize the path selection logic.
The following information about each Tx burst function is stored and
used by the new common function to select the appropriate Tx path:
- Tx Offloads
- SIMD bitwidth
- "Simple" Tx
The implementation is based off the Rx path selection infrastructure
introduced in a previous commit.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
v2:
* Change req_features to pointer instead of passing by value
* Change num_paths from int to size_t
* Change i from int to unsigned int and define it inside the for
statement.
* Remove ci_tx_path_features_extra substructure
* Add simple tx feature in this patch rather in a later patch when it
is first used by a driver.
---
drivers/net/intel/common/tx.h | 77 +++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 5af64a4cfe..04d9aa8473 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
+#include <rte_vect.h>
/* forward declaration of the common intel (ci) queue structure */
struct ci_tx_queue;
@@ -117,6 +118,19 @@ struct ci_tx_queue {
};
};
+struct ci_tx_path_features {
+ uint32_t tx_offloads;
+ enum rte_vect_max_simd simd_width;
+ bool simple_tx;
+};
+
+struct ci_tx_path_info {
+ eth_tx_burst_t pkt_burst;
+ const char *info;
+ struct ci_tx_path_features features;
+ eth_tx_prep_t pkt_prep;
+};
+
static __rte_always_inline void
ci_tx_backlog_entry(struct ci_tx_entry *txep, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -262,4 +276,67 @@ ci_txq_release_all_mbufs(struct ci_tx_queue *txq, bool use_ctx)
memset(txq->sw_ring_vec, 0, sizeof(txq->sw_ring_vec[0]) * nb_desc);
}
+/**
+ * Select the best matching Tx path based on features
+ *
+ * @param req_features
+ * The requested features for the Tx path
+ * @param infos
+ * Array of information about the available Tx paths
+ * @param num_paths
+ * Number of available paths in the infos array
+ * @param default_path
+ * Index of the default path to use if no suitable path is found
+ *
+ * @return
+ * The packet burst function index that best matches the requested features,
+ * or default_path if no suitable path is found
+ */
+static inline int
+ci_tx_path_select(const struct ci_tx_path_features *req_features,
+ const struct ci_tx_path_info *infos,
+ size_t num_paths,
+ int default_path)
+{
+ int idx = default_path;
+ const struct ci_tx_path_features *chosen_path_features = NULL;
+
+ for (unsigned int i = 0; i < num_paths; i++) {
+ const struct ci_tx_path_features *path_features = &infos[i].features;
+
+ /* Do not use a simple tx path if not requested. */
+ if (path_features->simple_tx && !req_features->simple_tx)
+ continue;
+
+ /* Ensure the path supports the requested TX offloads. */
+ if ((path_features->tx_offloads & req_features->tx_offloads) !=
+ req_features->tx_offloads)
+ continue;
+
+ /* Ensure the path's SIMD width is compatible with the requested width. */
+ if (path_features->simd_width > req_features->simd_width)
+ continue;
+
+ /* Do not select the path if it is less suitable than the chosen path. */
+ if (chosen_path_features != NULL) {
+ /* Do not select paths with lower SIMD width than the chosen path. */
+ if (path_features->simd_width < chosen_path_features->simd_width)
+ continue;
+ /* Do not select paths with more offloads enabled than the chosen path if
+ * the SIMD widths are the same.
+ */
+ if (path_features->simd_width == chosen_path_features->simd_width &&
+ rte_popcount32(path_features->tx_offloads) >
+ rte_popcount32(chosen_path_features->tx_offloads))
+ continue;
+ }
+
+ /* Finally, select the path since it has met all the requirements. */
+ idx = i;
+ chosen_path_features = &infos[idx].features;
+ }
+
+ return idx;
+}
+
#endif /* _COMMON_INTEL_TX_H_ */
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 02/10] net/ice: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 13:40 ` Bruce Richardson
2025-12-12 11:06 ` [PATCH v3 03/10] net/iavf: " Ciara Loftus
` (7 subsequent siblings)
9 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Also let the primary process select the Tx path to be used by
all processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* Fixed mbuf_check function
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
---
drivers/net/intel/ice/ice_ethdev.c | 1 +
drivers/net/intel/ice/ice_ethdev.h | 14 +-
drivers/net/intel/ice/ice_rxtx.c | 204 ++++++++++----------
drivers/net/intel/ice/ice_rxtx.h | 30 ++-
drivers/net/intel/ice/ice_rxtx_vec_common.h | 35 +---
drivers/net/intel/ice/ice_rxtx_vec_sse.c | 6 -
6 files changed, 142 insertions(+), 148 deletions(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index c721d135f5..a805e78d03 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -3900,6 +3900,7 @@ ice_dev_configure(struct rte_eth_dev *dev)
ad->tx_simple_allowed = true;
ad->rx_func_type = ICE_RX_DEFAULT;
+ ad->tx_func_type = ICE_TX_DEFAULT;
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 72ed65f13b..7fa2db1bd2 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -208,6 +208,16 @@ enum ice_rx_func_type {
ICE_RX_AVX512_SCATTERED_OFFLOAD,
};
+enum ice_tx_func_type {
+ ICE_TX_DEFAULT,
+ ICE_TX_SIMPLE,
+ ICE_TX_SSE,
+ ICE_TX_AVX2,
+ ICE_TX_AVX2_OFFLOAD,
+ ICE_TX_AVX512,
+ ICE_TX_AVX512_OFFLOAD,
+};
+
struct ice_adapter;
/**
@@ -658,14 +668,13 @@ struct ice_adapter {
bool tx_vec_allowed;
bool tx_simple_allowed;
enum ice_rx_func_type rx_func_type;
+ enum ice_tx_func_type tx_func_type;
/* ptype mapping table */
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[ICE_MAX_PKT_TYPE];
bool is_safe_mode;
struct ice_devargs devargs;
enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
uint16_t fdir_ref_cnt;
- /* For vector PMD */
- eth_rx_burst_t tx_pkt_burst;
/* For PTP */
uint8_t ptp_tx_block;
uint8_t ptp_tx_index;
@@ -679,7 +688,6 @@ struct ice_adapter {
/* Set bit if the engine is disabled */
unsigned long disabled_engine_mask;
struct ice_parser *psr;
- enum rte_vect_max_simd tx_simd_width;
bool rx_vec_offload_support;
};
diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
index 74db0fbec9..3fdb9fbf6e 100644
--- a/drivers/net/intel/ice/ice_rxtx.c
+++ b/drivers/net/intel/ice/ice_rxtx.c
@@ -3929,6 +3929,75 @@ ice_check_empty_mbuf(struct rte_mbuf *tx_pkt)
return 0;
}
+static const struct ci_tx_path_info ice_tx_path_infos[] = {
+ [ICE_TX_DEFAULT] = {
+ .pkt_burst = ice_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+ [ICE_TX_SIMPLE] = {
+ .pkt_burst = ice_xmit_pkts_simple,
+ .info = "Scalar Simple",
+ .features = {
+ .tx_offloads = ICE_TX_SCALAR_OFFLOADS,
+ .simple_tx = true
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+#ifdef RTE_ARCH_X86
+ [ICE_TX_SSE] = {
+ .pkt_burst = ice_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX2] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx2_offload,
+ .info = "Offload Vector AVX2",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+#ifdef CC_AVX512_SUPPORT
+ [ICE_TX_AVX512] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = rte_eth_tx_pkt_prepare_dummy
+ },
+ [ICE_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = ice_xmit_pkts_vec_avx512_offload,
+ .info = "Offload Vector AVX512",
+ .features = {
+ .tx_offloads = ICE_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ },
+ .pkt_prep = ice_prep_pkts
+ },
+#endif
+#endif
+};
+
/* Tx mbuf check */
static uint16_t
ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -3941,6 +4010,7 @@ ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
const char *reason = NULL;
struct ice_adapter *adapter = txq->ice_vsi->adapter;
uint64_t ol_flags;
+ enum ice_tx_func_type tx_func_type = adapter->tx_func_type;
for (idx = 0; idx < nb_pkts; idx++) {
mb = tx_pkts[idx];
@@ -4025,7 +4095,7 @@ ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
return 0;
}
- return adapter->tx_pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return ice_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
uint16_t
@@ -4097,113 +4167,37 @@ ice_set_tx_function(struct rte_eth_dev *dev)
struct ice_adapter *ad =
ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
int mbuf_check = ad->devargs.mbuf_check;
-#ifdef RTE_ARCH_X86
- struct ci_tx_queue *txq;
- int i;
- int tx_check_ret = -1;
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ad->tx_simd_width = RTE_VECT_SIMD_DISABLED;
- tx_check_ret = ice_tx_vec_dev_check(dev);
- ad->tx_simd_width = ice_get_max_simd_bitwidth();
- if (tx_check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- ad->tx_vec_allowed = true;
-
- if (ad->tx_simd_width < RTE_VECT_SIMD_256 &&
- tx_check_ret == ICE_VECTOR_OFFLOAD_PATH)
- ad->tx_vec_allowed = false;
-
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq && ice_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- } else {
- ad->tx_vec_allowed = false;
- }
- }
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
- if (ad->tx_vec_allowed) {
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx512_offload;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = ice_xmit_pkts_vec_avx512;
- }
-#endif
- } else {
- if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) {
- PMD_DRV_LOG(NOTICE,
- "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst =
- ice_xmit_pkts_vec_avx2_offload;
- dev->tx_pkt_prepare = ice_prep_pkts;
- } else {
- PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- ice_xmit_pkts_vec_avx2 :
- ice_xmit_pkts_vec;
- }
- }
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
- return;
- }
+ req_features.simple_tx = ad->tx_simple_allowed;
+
+#ifdef RTE_ARCH_X86
+ if (ice_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = ice_get_max_simd_bitwidth();
#endif
- if (ad->tx_simple_allowed) {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts_simple;
- dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
- } else {
- PMD_INIT_LOG(DEBUG, "Normal tx finally be used.");
- dev->tx_pkt_burst = ice_xmit_pkts;
- dev->tx_pkt_prepare = ice_prep_pkts;
- }
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &ice_tx_path_infos[0],
+ RTE_DIM(ice_tx_path_infos),
+ ICE_TX_DEFAULT);
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = ice_xmit_pkts_check;
- }
-}
+out:
+ if (ice_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_128)
+ ad->tx_vec_allowed = true;
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} ice_tx_burst_infos[] = {
- { ice_xmit_pkts_simple, "Scalar Simple" },
- { ice_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { ice_xmit_pkts_vec_avx512, "Vector AVX512" },
- { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" },
-#endif
- { ice_xmit_pkts_vec_avx2, "Vector AVX2" },
- { ice_xmit_pkts_vec_avx2_offload, "Offload Vector AVX2" },
- { ice_xmit_pkts_vec, "Vector SSE" },
-#endif
-};
+ dev->tx_pkt_burst = mbuf_check ? ice_xmit_pkts_check :
+ ice_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = ice_tx_path_infos[ad->tx_func_type].pkt_prep;
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ ice_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+}
int
ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
@@ -4213,10 +4207,10 @@ ice_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(ice_tx_burst_infos); ++i) {
- if (pkt_burst == ice_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(ice_tx_path_infos); ++i) {
+ if (pkt_burst == ice_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- ice_tx_burst_infos[i].info);
+ ice_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/ice/ice_rxtx.h b/drivers/net/intel/ice/ice_rxtx.h
index 141a62a7da..d7e8c1b0c4 100644
--- a/drivers/net/intel/ice/ice_rxtx.h
+++ b/drivers/net/intel/ice/ice_rxtx.h
@@ -108,6 +108,35 @@
RTE_ETH_RX_OFFLOAD_VLAN_FILTER |\
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+/* basic scalar path */
+#define ICE_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
+/* basic vector path */
+#define ICE_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* vector offload paths */
+#define ICE_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ ICE_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)
+
/* Max header size can be 2K - 64 bytes */
#define ICE_RX_HDR_BUF_SIZE (2048 - 64)
@@ -249,7 +278,6 @@ void ice_select_rxd_to_pkt_fields_handler(struct ci_rx_queue *rxq,
int ice_rx_vec_dev_check(struct rte_eth_dev *dev);
int ice_tx_vec_dev_check(struct rte_eth_dev *dev);
int ice_rxq_vec_setup(struct ci_rx_queue *rxq);
-int ice_txq_vec_setup(struct ci_tx_queue *txq);
uint16_t ice_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
uint16_t ice_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_common.h b/drivers/net/intel/ice/ice_rxtx_vec_common.h
index 39581cb7ae..ff46a8fb49 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_common.h
+++ b/drivers/net/intel/ice/ice_rxtx_vec_common.h
@@ -51,28 +51,6 @@ _ice_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq)
memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
}
-#define ICE_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
- RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
-
-#define ICE_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define ICE_VECTOR_PATH 0
-#define ICE_VECTOR_OFFLOAD_PATH 1
-
static inline int
ice_rx_vec_queue_default(struct ci_rx_queue *rxq)
{
@@ -98,13 +76,7 @@ ice_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > ICE_TX_MAX_FREE_BUF_SZ)
return -1;
- if (txq->offloads & ICE_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (txq->offloads & ICE_TX_VECTOR_OFFLOAD)
- return ICE_VECTOR_OFFLOAD_PATH;
-
- return ICE_VECTOR_PATH;
+ return 0;
}
static inline int
@@ -130,18 +102,15 @@ ice_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret = 0;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = ice_tx_vec_queue_default(txq);
if (ret < 0)
return -1;
- if (ret == ICE_VECTOR_OFFLOAD_PATH)
- result = ret;
}
- return result;
+ return ret;
}
static inline void
diff --git a/drivers/net/intel/ice/ice_rxtx_vec_sse.c b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
index 1545bc3b6e..4fc1b7e881 100644
--- a/drivers/net/intel/ice/ice_rxtx_vec_sse.c
+++ b/drivers/net/intel/ice/ice_rxtx_vec_sse.c
@@ -718,12 +718,6 @@ ice_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-ice_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
ice_rx_vec_dev_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 03/10] net/iavf: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 01/10] net/intel: introduce infrastructure for Tx path selection Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 02/10] net/ice: use common Tx path selection infrastructure Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 14:09 ` Bruce Richardson
2025-12-12 11:06 ` [PATCH v3 04/10] net/i40e: " Ciara Loftus
` (6 subsequent siblings)
9 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Introduce two new features "disabled" and "context desc" to the common
infrastructure which represents whether or not the path is disabled, or
if it uses a context descriptor.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v3:
* Fixed cross compile issue
v2:
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
---
drivers/net/intel/common/tx.h | 14 +
drivers/net/intel/iavf/iavf.h | 2 -
drivers/net/intel/iavf/iavf_ethdev.c | 9 +-
drivers/net/intel/iavf/iavf_rxtx.c | 240 +++++++++---------
drivers/net/intel/iavf/iavf_rxtx.h | 46 ++--
drivers/net/intel/iavf/iavf_rxtx_vec_common.h | 39 +--
6 files changed, 168 insertions(+), 182 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 04d9aa8473..60b1bd642a 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -122,6 +122,8 @@ struct ci_tx_path_features {
uint32_t tx_offloads;
enum rte_vect_max_simd simd_width;
bool simple_tx;
+ bool ctx_desc;
+ bool disabled;
};
struct ci_tx_path_info {
@@ -304,10 +306,18 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
for (unsigned int i = 0; i < num_paths; i++) {
const struct ci_tx_path_features *path_features = &infos[i].features;
+ /* Do not select a disabled tx path. */
+ if (path_features->disabled)
+ continue;
+
/* Do not use a simple tx path if not requested. */
if (path_features->simple_tx && !req_features->simple_tx)
continue;
+ /* If a context descriptor is requested, ensure the path supports it. */
+ if (!path_features->ctx_desc && req_features->ctx_desc)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features->tx_offloads) !=
req_features->tx_offloads)
@@ -329,6 +339,10 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
rte_popcount32(path_features->tx_offloads) >
rte_popcount32(chosen_path_features->tx_offloads))
continue;
+
+ /* Don't use a context descriptor unless necessary */
+ if (path_features->ctx_desc && !chosen_path_features->ctx_desc)
+ continue;
}
/* Finally, select the path since it has met all the requirements. */
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index d78582e05c..921bf0a607 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -375,8 +375,6 @@ struct iavf_adapter {
struct iavf_security_ctx *security_ctx;
bool rx_bulk_alloc_allowed;
- /* For vector PMD */
- bool tx_vec_allowed;
alignas(RTE_CACHE_LINE_MIN_SIZE) uint32_t ptype_tbl[IAVF_MAX_PKT_TYPE];
bool stopped;
bool closed;
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 15e49fe248..bf1186c20f 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -666,10 +666,8 @@ iavf_dev_configure(struct rte_eth_dev *dev)
return -EIO;
ad->rx_bulk_alloc_allowed = true;
- /* Initialize to TRUE. If any of Rx queues doesn't meet the
- * vector Rx/Tx preconditions, it will be reset.
- */
- ad->tx_vec_allowed = true;
+
+ ad->tx_func_type = IAVF_TX_DEFAULT;
if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
@@ -2795,8 +2793,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->tx_pkt_prepare = &iavf_prep_pkts;
/* For secondary processes, we don't initialise any further as primary
- * has already done this work. Only check if we need a different RX
- * and TX function.
+ * has already done this work.
*/
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
iavf_set_rx_function(eth_dev);
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c b/drivers/net/intel/iavf/iavf_rxtx.c
index d8662fd815..9ba8ff0979 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -208,19 +208,6 @@ check_tx_thresh(uint16_t nb_desc, uint16_t tx_rs_thresh,
return 0;
}
-static inline bool
-check_tx_vec_allow(struct ci_tx_queue *txq)
-{
- if (!(txq->offloads & IAVF_TX_NO_VECTOR_FLAGS) &&
- txq->tx_rs_thresh >= IAVF_VPMD_TX_BURST &&
- txq->tx_rs_thresh <= IAVF_VPMD_TX_MAX_FREE_BUF) {
- PMD_INIT_LOG(DEBUG, "Vector tx can be enabled on this txq.");
- return true;
- }
- PMD_INIT_LOG(DEBUG, "Vector Tx cannot be enabled on this txq.");
- return false;
-}
-
static inline bool
check_rx_bulk_allow(struct ci_rx_queue *rxq)
{
@@ -861,12 +848,6 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
dev->data->tx_queues[queue_idx] = txq;
txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx);
- if (check_tx_vec_allow(txq) == false) {
- struct iavf_adapter *ad =
- IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- ad->tx_vec_allowed = false;
- }
-
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS &&
vf->tm_conf.committed) {
int tc;
@@ -4002,26 +3983,82 @@ iavf_rx_burst_mode_get(struct rte_eth_dev *dev,
return -EINVAL;
}
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} iavf_tx_pkt_burst_ops[] = {
- [IAVF_TX_DISABLED] = {iavf_xmit_pkts_no_poll, "Disabled"},
- [IAVF_TX_DEFAULT] = {iavf_xmit_pkts, "Scalar"},
+static const struct ci_tx_path_info iavf_tx_path_infos[] = {
+ [IAVF_TX_DISABLED] = {
+ .pkt_burst = iavf_xmit_pkts_no_poll,
+ .info = "Disabled",
+ .features = {
+ .disabled = true
+ }
+ },
+ [IAVF_TX_DEFAULT] = {
+ .pkt_burst = iavf_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = IAVF_TX_SCALAR_OFFLOADS,
+ .ctx_desc = true
+ }
+ },
#ifdef RTE_ARCH_X86
- [IAVF_TX_SSE] = {iavf_xmit_pkts_vec, "Vector SSE"},
- [IAVF_TX_AVX2] = {iavf_xmit_pkts_vec_avx2, "Vector AVX2"},
- [IAVF_TX_AVX2_OFFLOAD] = {iavf_xmit_pkts_vec_avx2_offload,
- "Vector AVX2 Offload"},
+ [IAVF_TX_SSE] = {
+ .pkt_burst = iavf_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128
+ }
+ },
+ [IAVF_TX_AVX2] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
+ [IAVF_TX_AVX2_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx2_offload,
+ .info = "Vector AVX2 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256
+ }
+ },
#ifdef CC_AVX512_SUPPORT
- [IAVF_TX_AVX512] = {iavf_xmit_pkts_vec_avx512, "Vector AVX512"},
- [IAVF_TX_AVX512_OFFLOAD] = {iavf_xmit_pkts_vec_avx512_offload,
- "Vector AVX512 Offload"},
- [IAVF_TX_AVX512_CTX] = {iavf_xmit_pkts_vec_avx512_ctx,
- "Vector AVX512 Ctx"},
+ [IAVF_TX_AVX512] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_OFFLOAD] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_offload,
+ .info = "Vector AVX512 Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IAVF_TX_AVX512_CTX] = {
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx,
+ .info = "Vector AVX512 Ctx",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .ctx_desc = true
+ }
+ },
[IAVF_TX_AVX512_CTX_OFFLOAD] = {
- iavf_xmit_pkts_vec_avx512_ctx_offload,
- "Vector AVX512 Ctx Offload"},
+ .pkt_burst = iavf_xmit_pkts_vec_avx512_ctx_offload,
+ .info = "Vector AVX512 Ctx Offload",
+ .features = {
+ .tx_offloads = IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .ctx_desc = true
+ }
+ },
#endif
#endif
};
@@ -4034,10 +4071,10 @@ iavf_tx_burst_mode_get(struct rte_eth_dev *dev,
eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
size_t i;
- for (i = 0; i < RTE_DIM(iavf_tx_pkt_burst_ops); i++) {
- if (pkt_burst == iavf_tx_pkt_burst_ops[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(iavf_tx_path_infos); i++) {
+ if (pkt_burst == iavf_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- iavf_tx_pkt_burst_ops[i].info);
+ iavf_tx_path_infos[i].info);
return 0;
}
}
@@ -4073,7 +4110,7 @@ iavf_xmit_pkts_no_poll(void *tx_queue, struct rte_mbuf **tx_pkts,
tx_func_type = txq->iavf_vsi->adapter->tx_func_type;
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue,
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue,
tx_pkts, nb_pkts);
}
@@ -4158,7 +4195,7 @@ iavf_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts,
return 0;
}
- return iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return iavf_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
/* choose rx function*/
@@ -4229,109 +4266,66 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
{
struct iavf_adapter *adapter =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- enum iavf_tx_func_type tx_func_type;
int mbuf_check = adapter->devargs.mbuf_check;
int no_poll_on_link_down = adapter->devargs.no_poll_on_link_down;
#ifdef RTE_ARCH_X86
struct ci_tx_queue *txq;
int i;
- int check_ret;
- bool use_sse = false;
- bool use_avx2 = false;
- bool use_avx512 = false;
- enum rte_vect_max_simd tx_simd_path = iavf_get_max_simd_bitwidth();
-
- check_ret = iavf_tx_vec_dev_check(dev);
-
- if (check_ret >= 0 &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- /* SSE not support offload path yet. */
- if (check_ret == IAVF_VECTOR_PATH) {
- use_sse = true;
- }
+#endif
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- use_avx2 = tx_simd_path == RTE_VECT_SIMD_256;
- use_avx512 = tx_simd_path == RTE_VECT_SIMD_512;
+#ifdef RTE_ARCH_X86
+ if (iavf_tx_vec_dev_check(dev) != -1)
+ req_features.simd_width = iavf_get_max_simd_bitwidth();
- if (!use_sse && !use_avx2 && !use_avx512)
- goto normal;
+ if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0)
+ req_features.ctx_desc = true;
- if (use_sse) {
- PMD_DRV_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_SSE;
- }
- if (!use_avx512 && use_avx2) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX2;
- PMD_DRV_LOG(DEBUG, "Using AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_OFFLOAD_PATH) {
- PMD_DRV_LOG(DEBUG,
- "AVX2 does not support requested Tx offloads.");
- goto normal;
- } else {
- tx_func_type = IAVF_TX_AVX2_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX2 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
- }
-#ifdef CC_AVX512_SUPPORT
- if (use_avx512) {
- if (check_ret == IAVF_VECTOR_PATH) {
- tx_func_type = IAVF_TX_AVX512;
- PMD_DRV_LOG(DEBUG, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_OFFLOAD_PATH) {
- tx_func_type = IAVF_TX_AVX512_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- } else if (check_ret == IAVF_VECTOR_CTX_PATH) {
- tx_func_type = IAVF_TX_AVX512_CTX;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT Vector Tx (port %d).",
- dev->data->port_id);
- } else {
- tx_func_type = IAVF_TX_AVX512_CTX_OFFLOAD;
- PMD_DRV_LOG(DEBUG, "Using AVX512 CONTEXT OFFLOAD Vector Tx (port %d).",
- dev->data->port_id);
- }
- }
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT &&
+ txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
+ req_features.ctx_desc = true;
+ }
#endif
+ adapter->tx_func_type = ci_tx_path_select(&req_features,
+ &iavf_tx_path_infos[0],
+ RTE_DIM(iavf_tx_path_infos),
+ IAVF_TX_DEFAULT);
+
+out:
+#ifdef RTE_ARCH_X86
+ if (iavf_tx_path_infos[adapter->tx_func_type].features.simd_width != 0) {
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
if (!txq)
continue;
iavf_txq_vec_setup(txq);
+ txq->use_ctx =
+ iavf_tx_path_infos[adapter->tx_func_type].features.ctx_desc;
}
-
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
- dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
- return;
}
-
-normal:
#endif
- PMD_DRV_LOG(DEBUG, "Using Basic Tx callback (port=%d).",
- dev->data->port_id);
- tx_func_type = IAVF_TX_DEFAULT;
- if (no_poll_on_link_down) {
- adapter->tx_func_type = tx_func_type;
+ if (no_poll_on_link_down)
dev->tx_pkt_burst = iavf_xmit_pkts_no_poll;
- } else if (mbuf_check) {
- adapter->tx_func_type = tx_func_type;
+ else if (mbuf_check)
dev->tx_pkt_burst = iavf_xmit_pkts_check;
- } else {
- dev->tx_pkt_burst = iavf_tx_pkt_burst_ops[tx_func_type].pkt_burst;
- }
+ else
+ dev->tx_pkt_burst = iavf_tx_path_infos[adapter->tx_func_type].pkt_burst;
+
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ iavf_tx_path_infos[adapter->tx_func_type].info, dev->data->port_id);
}
static int
diff --git a/drivers/net/intel/iavf/iavf_rxtx.h b/drivers/net/intel/iavf/iavf_rxtx.h
index 8efb3bd04e..bff456e509 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.h
+++ b/drivers/net/intel/iavf/iavf_rxtx.h
@@ -35,22 +35,38 @@
#define IAVF_VPMD_DESCS_PER_LOOP_WIDE CI_VPMD_DESCS_PER_LOOP_WIDE
#define IAVF_VPMD_TX_MAX_FREE_BUF 64
-#define IAVF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
- RTE_ETH_TX_OFFLOAD_SECURITY)
-
-#define IAVF_TX_VECTOR_OFFLOAD ( \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+/* basic scalar path */
+#define IAVF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | \
+ RTE_ETH_TX_OFFLOAD_SECURITY | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
+/* basic vector path */
+#define IAVF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+/* offload vector path */
+#define IAVF_TX_VECTOR_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
-
-#define IAVF_TX_VECTOR_OFFLOAD_CTX ( \
+/* offload vector path with context descriptor */
+#define IAVF_TX_VECTOR_CTX_OFFLOAD_OFFLOADS ( \
+ IAVF_TX_VECTOR_OFFLOADS | \
+ IAVF_TX_VECTOR_OFFLOAD_OFFLOADS | \
RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
RTE_ETH_TX_OFFLOAD_QINQ_INSERT)
diff --git a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
index 66f65b46e9..f1ea57034f 100644
--- a/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/intel/iavf/iavf_rxtx_vec_common.h
@@ -73,8 +73,6 @@ iavf_rx_vec_queue_default(struct ci_rx_queue *rxq)
static inline int
iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
{
- bool vlan_offload = false, vlan_needs_ctx = false;
-
if (!txq)
return -1;
@@ -82,35 +80,7 @@ iavf_tx_vec_queue_default(struct ci_tx_queue *txq)
txq->tx_rs_thresh > IAVF_VPMD_TX_MAX_FREE_BUF)
return -1;
- if (txq->offloads & IAVF_TX_NO_VECTOR_FLAGS)
- return -1;
-
- if (rte_pmd_iavf_tx_lldp_dynfield_offset > 0) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_PATH;
- }
-
- /* Vlan tci needs to be inserted via ctx desc, if the vlan_flag is L2TAG2. */
- if (txq->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) {
- vlan_offload = true;
- if (txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)
- vlan_needs_ctx = true;
- }
-
- /**
- * Tunneling parameters and other fields need be configured in ctx desc
- * if the outer checksum offload is enabled.
- */
- if (txq->offloads & (IAVF_TX_VECTOR_OFFLOAD | IAVF_TX_VECTOR_OFFLOAD_CTX) || vlan_offload) {
- if (txq->offloads & IAVF_TX_VECTOR_OFFLOAD_CTX || vlan_needs_ctx) {
- txq->use_ctx = 1;
- return IAVF_VECTOR_CTX_OFFLOAD_PATH;
- } else {
- return IAVF_VECTOR_OFFLOAD_PATH;
- }
- } else {
- return IAVF_VECTOR_PATH;
- }
+ return 0;
}
static inline int
@@ -137,19 +107,16 @@ iavf_tx_vec_dev_check_default(struct rte_eth_dev *dev)
int i;
struct ci_tx_queue *txq;
int ret;
- int result = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
txq = dev->data->tx_queues[i];
ret = iavf_tx_vec_queue_default(txq);
if (ret < 0)
- return -1;
- if (ret > result)
- result = ret;
+ break;
}
- return result;
+ return ret;
}
/******************************************************************************
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH v3 03/10] net/iavf: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 03/10] net/iavf: " Ciara Loftus
@ 2025-12-12 14:09 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-12 14:09 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Fri, Dec 12, 2025 at 11:06:21AM +0000, Ciara Loftus wrote:
> Replace the existing complicated logic with the use of the common
> function. Let the primary process select the Tx path to be used by all
> processes using the given device.
>
> Introduce two new features "disabled" and "context desc" to the common
> infrastructure which represents whether or not the path is disabled, or
> if it uses a context descriptor.
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 04/10] net/i40e: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (2 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 03/10] net/iavf: " Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 14:53 ` Bruce Richardson
2025-12-12 11:06 ` [PATCH v3 05/10] net/idpf: " Ciara Loftus
` (5 subsequent siblings)
9 siblings, 1 reply; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* Merged the patch which consolidates path selection among process types
with the introduction of the new infrastructure.
* Fixed mbuf_check logic
* Fixed assignment of pkt_prepare function
---
drivers/net/intel/i40e/i40e_ethdev.h | 14 +-
drivers/net/intel/i40e/i40e_rxtx.c | 190 ++++++++++--------
drivers/net/intel/i40e/i40e_rxtx.h | 20 +-
.../net/intel/i40e/i40e_rxtx_vec_altivec.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_neon.c | 6 -
drivers/net/intel/i40e/i40e_rxtx_vec_sse.c | 6 -
6 files changed, 135 insertions(+), 107 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index 3fca089d6c..1fe504d0cd 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1243,6 +1243,16 @@ enum i40e_rx_func_type {
I40E_RX_ALTIVEC_SCATTERED,
};
+enum i40e_tx_func_type {
+ I40E_TX_DEFAULT,
+ I40E_TX_SCALAR_SIMPLE,
+ I40E_TX_SSE,
+ I40E_TX_AVX2,
+ I40E_TX_AVX512,
+ I40E_TX_NEON,
+ I40E_TX_ALTIVEC,
+};
+
/*
* Structure to store private data for each PF/VF instance.
*/
@@ -1260,10 +1270,10 @@ struct i40e_adapter {
bool tx_vec_allowed;
enum i40e_rx_func_type rx_func_type;
+ enum i40e_tx_func_type tx_func_type;
uint64_t mbuf_check; /* mbuf check flags. */
uint16_t max_pkt_len; /* Maximum packet length */
- eth_tx_burst_t tx_pkt_burst;
/* For PTP */
struct rte_timecounter systime_tc;
@@ -1279,8 +1289,6 @@ struct i40e_adapter {
/* For RSS reta table update */
uint8_t rss_reta_updated;
-
- enum rte_vect_max_simd tx_simd_width;
};
/**
diff --git a/drivers/net/intel/i40e/i40e_rxtx.c b/drivers/net/intel/i40e/i40e_rxtx.c
index 255414dd03..a7d80e2bc0 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.c
+++ b/drivers/net/intel/i40e/i40e_rxtx.c
@@ -1550,6 +1550,77 @@ i40e_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
return nb_tx;
}
+static const struct ci_tx_path_info i40e_tx_path_infos[] = {
+ [I40E_TX_DEFAULT] = {
+ .pkt_burst = i40e_xmit_pkts,
+ .info = "Scalar",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ },
+ .pkt_prep = i40e_prep_pkts,
+ },
+ [I40E_TX_SCALAR_SIMPLE] = {
+ .pkt_burst = i40e_xmit_pkts_simple,
+ .info = "Scalar Simple",
+ .features = {
+ .tx_offloads = I40E_TX_SCALAR_OFFLOADS,
+ .simple_tx = true
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#ifdef RTE_ARCH_X86
+ [I40E_TX_SSE] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector SSE",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+ [I40E_TX_AVX2] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx2,
+ .info = "Vector AVX2",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#ifdef CC_AVX512_SUPPORT
+ [I40E_TX_AVX512] = {
+ .pkt_burst = i40e_xmit_pkts_vec_avx512,
+ .info = "Vector AVX512",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#endif
+#elif defined(RTE_ARCH_ARM64)
+ [I40E_TX_NEON] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector Neon",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#elif defined(RTE_ARCH_PPC_64)
+ [I40E_TX_ALTIVEC] = {
+ .pkt_burst = i40e_xmit_pkts_vec,
+ .info = "Vector AltiVec",
+ .features = {
+ .tx_offloads = I40E_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_128,
+ },
+ .pkt_prep = i40e_simple_prep_pkts,
+ },
+#endif
+};
+
/* Tx mbuf check */
static uint16_t
i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -1562,6 +1633,7 @@ i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
const char *reason = NULL;
uint16_t good_pkts = nb_pkts;
struct i40e_adapter *adapter = txq->i40e_vsi->adapter;
+ enum i40e_tx_func_type tx_func_type = adapter->tx_func_type;
for (idx = 0; idx < nb_pkts; idx++) {
mb = tx_pkts[idx];
@@ -1652,7 +1724,7 @@ i40e_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
return 0;
}
- return adapter->tx_pkt_burst(tx_queue, tx_pkts, good_pkts);
+ return i40e_tx_path_infos[tx_func_type].pkt_burst(tx_queue, tx_pkts, good_pkts);
}
/*********************************************************************
@@ -2375,8 +2447,7 @@ i40e_dev_tx_queue_setup_runtime(struct rte_eth_dev *dev,
/* check vector conflict */
if (ad->tx_vec_allowed) {
- if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ ||
- i40e_txq_vec_setup(txq)) {
+ if (txq->tx_rs_thresh > I40E_TX_MAX_FREE_BUF_SZ) {
PMD_DRV_LOG(ERR, "Failed vector tx setup.");
return -EINVAL;
}
@@ -3525,93 +3596,42 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
struct i40e_adapter *ad =
I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
uint64_t mbuf_check = ad->mbuf_check;
- int i;
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-#ifdef RTE_ARCH_X86
- ad->tx_simd_width = i40e_get_max_simd_bitwidth();
-#endif
- if (ad->tx_vec_allowed) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- struct ci_tx_queue *txq =
- dev->data->tx_queues[i];
-
- if (txq && i40e_txq_vec_setup(txq)) {
- ad->tx_vec_allowed = false;
- break;
- }
- }
- }
- }
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .simple_tx = ad->tx_simple_allowed
+ };
- if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)
- ad->tx_vec_allowed = false;
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
- if (ad->tx_simple_allowed) {
- if (ad->tx_vec_allowed) {
+ if (ad->tx_vec_allowed) {
#ifdef RTE_ARCH_X86
- if (ad->tx_simd_width == RTE_VECT_SIMD_512) {
-#ifdef CC_AVX512_SUPPORT
- PMD_DRV_LOG(NOTICE, "Using AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec_avx512;
+ req_features.simd_width = i40e_get_max_simd_bitwidth();
#else
- PMD_DRV_LOG(ERR, "Invalid Tx SIMD width reported, defaulting to "
- "using scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts;
+ req_features.simd_width = rte_vect_get_max_simd_bitwidth();
#endif
- } else {
- PMD_INIT_LOG(DEBUG, "Using %sVector Tx (port %d).",
- ad->tx_simd_width == RTE_VECT_SIMD_256 ? "avx2 " : "",
- dev->data->port_id);
- dev->tx_pkt_burst = ad->tx_simd_width == RTE_VECT_SIMD_256 ?
- i40e_xmit_pkts_vec_avx2 :
- i40e_xmit_pkts_vec;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
-#else /* RTE_ARCH_X86 */
- PMD_INIT_LOG(DEBUG, "Using Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = i40e_xmit_pkts_vec;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
-#endif /* RTE_ARCH_X86 */
- } else {
- PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts_simple;
- dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
- }
- dev->tx_pkt_prepare = i40e_simple_prep_pkts;
- } else {
- PMD_INIT_LOG(DEBUG, "Xmit tx finally be used.");
- dev->tx_pkt_burst = i40e_xmit_pkts;
- dev->tx_pkt_prepare = i40e_prep_pkts;
}
- if (mbuf_check) {
- ad->tx_pkt_burst = dev->tx_pkt_burst;
- dev->tx_pkt_burst = i40e_xmit_pkts_check;
- }
-}
+ ad->tx_func_type = ci_tx_path_select(&req_features, &i40e_tx_path_infos[0],
+ RTE_DIM(i40e_tx_path_infos), I40E_TX_DEFAULT);
-static const struct {
- eth_tx_burst_t pkt_burst;
- const char *info;
-} i40e_tx_burst_infos[] = {
- { i40e_xmit_pkts_simple, "Scalar Simple" },
- { i40e_xmit_pkts, "Scalar" },
-#ifdef RTE_ARCH_X86
-#ifdef CC_AVX512_SUPPORT
- { i40e_xmit_pkts_vec_avx512, "Vector AVX512" },
-#endif
- { i40e_xmit_pkts_vec_avx2, "Vector AVX2" },
- { i40e_xmit_pkts_vec, "Vector SSE" },
-#elif defined(RTE_ARCH_ARM64)
- { i40e_xmit_pkts_vec, "Vector Neon" },
-#elif defined(RTE_ARCH_PPC_64)
- { i40e_xmit_pkts_vec, "Vector AltiVec" },
-#endif
-};
+out:
+ dev->tx_pkt_burst = mbuf_check ? i40e_xmit_pkts_check :
+ i40e_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = i40e_tx_path_infos[ad->tx_func_type].pkt_prep;
+
+ PMD_DRV_LOG(NOTICE, "Using %s (port %d).",
+ i40e_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
+
+ if (ad->tx_func_type == I40E_TX_SCALAR_SIMPLE ||
+ ad->tx_func_type == I40E_TX_SSE ||
+ ad->tx_func_type == I40E_TX_NEON ||
+ ad->tx_func_type == I40E_TX_ALTIVEC ||
+ ad->tx_func_type == I40E_TX_AVX2)
+ dev->recycle_tx_mbufs_reuse = i40e_recycle_tx_mbufs_reuse_vec;
+}
int
i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
@@ -3621,10 +3641,10 @@ i40e_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
int ret = -EINVAL;
unsigned int i;
- for (i = 0; i < RTE_DIM(i40e_tx_burst_infos); ++i) {
- if (pkt_burst == i40e_tx_burst_infos[i].pkt_burst) {
+ for (i = 0; i < RTE_DIM(i40e_tx_path_infos); ++i) {
+ if (pkt_burst == i40e_tx_path_infos[i].pkt_burst) {
snprintf(mode->info, sizeof(mode->info), "%s",
- i40e_tx_burst_infos[i].info);
+ i40e_tx_path_infos[i].info);
ret = 0;
break;
}
diff --git a/drivers/net/intel/i40e/i40e_rxtx.h b/drivers/net/intel/i40e/i40e_rxtx.h
index b5a901794f..ed173d8f17 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.h
+++ b/drivers/net/intel/i40e/i40e_rxtx.h
@@ -91,6 +91,25 @@ enum i40e_header_split_mode {
RTE_ETH_RX_OFFLOAD_VLAN_FILTER | \
RTE_ETH_RX_OFFLOAD_RSS_HASH)
+#define I40E_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT | \
+ RTE_ETH_TX_OFFLOAD_QINQ_INSERT | \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define I40E_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
/** Offload features */
union i40e_tx_offload {
uint64_t data;
@@ -165,7 +184,6 @@ uint16_t i40e_recv_scattered_pkts_vec(void *rx_queue,
uint16_t nb_pkts);
int i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev);
int i40e_rxq_vec_setup(struct ci_rx_queue *rxq);
-int i40e_txq_vec_setup(struct ci_tx_queue *txq);
void i40e_rx_queue_release_mbufs_vec(struct ci_rx_queue *rxq);
uint16_t i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
index 87a57e7520..bbb6d907cf 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_altivec.c
@@ -547,12 +547,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue __rte_unused * txq)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
index c9098e4c1a..b5be0c1b59 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_neon.c
@@ -697,12 +697,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
diff --git a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
index c035408dcc..c209135890 100644
--- a/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
+++ b/drivers/net/intel/i40e/i40e_rxtx_vec_sse.c
@@ -704,12 +704,6 @@ i40e_rxq_vec_setup(struct ci_rx_queue *rxq)
return 0;
}
-int __rte_cold
-i40e_txq_vec_setup(struct ci_tx_queue *txq __rte_unused)
-{
- return 0;
-}
-
int __rte_cold
i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev)
{
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* Re: [PATCH v3 04/10] net/i40e: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 04/10] net/i40e: " Ciara Loftus
@ 2025-12-12 14:53 ` Bruce Richardson
0 siblings, 0 replies; 48+ messages in thread
From: Bruce Richardson @ 2025-12-12 14:53 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
On Fri, Dec 12, 2025 at 11:06:22AM +0000, Ciara Loftus wrote:
> Replace the existing complicated logic with the use of the common
> function. Let the primary process select the Tx path to be used by all
> processes using the given device.
>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 05/10] net/idpf: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (3 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 04/10] net/i40e: " Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 06/10] net/cpfl: " Ciara Loftus
` (4 subsequent siblings)
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Introduce a new feature "single queue" to the common infrastructure
which represents whether single or split queue mode is used in the given
path.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* removed unnecessary tx_vec_allowed
---
drivers/net/intel/common/tx.h | 5 +
drivers/net/intel/idpf/idpf_common_device.h | 10 ++
drivers/net/intel/idpf/idpf_common_rxtx.c | 49 ++++++++
drivers/net/intel/idpf/idpf_common_rxtx.h | 12 ++
drivers/net/intel/idpf/idpf_rxtx.c | 118 ++++++------------
drivers/net/intel/idpf/idpf_rxtx_vec_common.h | 10 --
6 files changed, 112 insertions(+), 92 deletions(-)
diff --git a/drivers/net/intel/common/tx.h b/drivers/net/intel/common/tx.h
index 60b1bd642a..24fcfbe225 100644
--- a/drivers/net/intel/common/tx.h
+++ b/drivers/net/intel/common/tx.h
@@ -124,6 +124,7 @@ struct ci_tx_path_features {
bool simple_tx;
bool ctx_desc;
bool disabled;
+ bool single_queue;
};
struct ci_tx_path_info {
@@ -318,6 +319,10 @@ ci_tx_path_select(const struct ci_tx_path_features *req_features,
if (!path_features->ctx_desc && req_features->ctx_desc)
continue;
+ /* If requested, ensure the path supports single queue TX. */
+ if (path_features->single_queue != req_features->single_queue)
+ continue;
+
/* Ensure the path supports the requested TX offloads. */
if ((path_features->tx_offloads & req_features->tx_offloads) !=
req_features->tx_offloads)
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index c32dcfbb12..eff04a83eb 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -75,6 +75,15 @@ enum idpf_rx_func_type {
IDPF_RX_MAX
};
+enum idpf_tx_func_type {
+ IDPF_TX_DEFAULT,
+ IDPF_TX_SINGLEQ,
+ IDPF_TX_SINGLEQ_AVX2,
+ IDPF_TX_AVX512,
+ IDPF_TX_SINGLEQ_AVX512,
+ IDPF_TX_MAX
+};
+
struct idpf_adapter {
struct idpf_hw hw;
struct virtchnl2_version_info virtchnl_version;
@@ -92,6 +101,7 @@ struct idpf_adapter {
uint64_t time_hw;
enum idpf_rx_func_type rx_func_type;
+ enum idpf_tx_func_type tx_func_type;
};
struct idpf_chunks_info {
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.c b/drivers/net/intel/idpf/idpf_common_rxtx.c
index a5d0795057..cfeab8a1e4 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.c
@@ -1701,3 +1701,52 @@ const struct ci_rx_path_info idpf_rx_path_infos[] = {
#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
};
+
+RTE_EXPORT_INTERNAL_SYMBOL(idpf_tx_path_infos)
+const struct ci_tx_path_info idpf_tx_path_infos[] = {
+ [IDPF_TX_DEFAULT] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts,
+ .info = "Split Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS
+ }
+ },
+ [IDPF_TX_SINGLEQ] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts,
+ .info = "Single Scalar",
+ .features = {
+ .tx_offloads = IDPF_TX_SCALAR_OFFLOADS,
+ .single_queue = true
+ }
+ },
+#ifdef RTE_ARCH_X86
+ [IDPF_TX_SINGLEQ_AVX2] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx2,
+ .info = "Single AVX2",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_256,
+ .single_queue = true
+ }
+ },
+#ifdef CC_AVX512_SUPPORT
+ [IDPF_TX_AVX512] = {
+ .pkt_burst = idpf_dp_splitq_xmit_pkts_avx512,
+ .info = "Split AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512
+ }
+ },
+ [IDPF_TX_SINGLEQ_AVX512] = {
+ .pkt_burst = idpf_dp_singleq_xmit_pkts_avx512,
+ .info = "Single AVX512",
+ .features = {
+ .tx_offloads = IDPF_TX_VECTOR_OFFLOADS,
+ .simd_width = RTE_VECT_SIMD_512,
+ .single_queue = true
+ }
+ },
+#endif /* CC_AVX512_SUPPORT */
+#endif /* RTE_ARCH_X86 */
+};
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.h b/drivers/net/intel/idpf/idpf_common_rxtx.h
index 3bc3323af4..7c6ff5d047 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.h
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.h
@@ -106,6 +106,17 @@
RTE_ETH_RX_OFFLOAD_SCATTER)
#define IDPF_RX_VECTOR_OFFLOADS 0
+#define IDPF_TX_SCALAR_OFFLOADS ( \
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO | \
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
+
+#define IDPF_TX_VECTOR_OFFLOADS RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE
+
struct idpf_rx_stats {
RTE_ATOMIC(uint64_t) mbuf_alloc_failed;
};
@@ -264,5 +275,6 @@ uint16_t idpf_dp_singleq_xmit_pkts_avx2(void *tx_queue,
uint16_t nb_pkts);
extern const struct ci_rx_path_info idpf_rx_path_infos[IDPF_RX_MAX];
+extern const struct ci_tx_path_info idpf_tx_path_infos[IDPF_TX_MAX];
#endif /* _IDPF_COMMON_RXTX_H_ */
diff --git a/drivers/net/intel/idpf/idpf_rxtx.c b/drivers/net/intel/idpf/idpf_rxtx.c
index 4796d8b862..3e2bccd279 100644
--- a/drivers/net/intel/idpf/idpf_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_rxtx.c
@@ -813,97 +813,51 @@ idpf_set_tx_function(struct rte_eth_dev *dev)
{
struct idpf_vport *vport = dev->data->dev_private;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = idpf_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
+#ifdef RTE_ARCH_X86
+ if (idpf_tx_vec_dev_check_default(dev) == IDPF_VECTOR_PATH)
+ req_features.simd_width = idpf_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+out:
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- }
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- txq = dev->data->tx_queues[i];
- if (txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(txq);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.single_queue) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
}
+#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
index ecdf2f0e23..425f0792a1 100644
--- a/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
+++ b/drivers/net/intel/idpf/idpf_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define IDPF_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
idpf_tx_desc_done(struct ci_tx_queue *txq, uint16_t idx)
@@ -74,9 +67,6 @@ idpf_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return IDPF_SCALAR_PATH;
- if ((txq->offloads & IDPF_TX_NO_VECTOR_FLAGS) != 0)
- return IDPF_SCALAR_PATH;
-
return IDPF_VECTOR_PATH;
}
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 06/10] net/cpfl: use common Tx path selection infrastructure
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (4 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 05/10] net/idpf: " Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 07/10] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
` (3 subsequent siblings)
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Replace the existing complicated logic with the use of the common
function. Let the primary process select the Tx path to be used by all
processes using the given device.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
v2:
* removed unnecessary tx_vec_allowed
---
drivers/net/intel/cpfl/cpfl_rxtx.c | 120 ++++++------------
drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h | 10 --
drivers/net/intel/idpf/idpf_common_device.h | 2 -
3 files changed, 37 insertions(+), 95 deletions(-)
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx.c b/drivers/net/intel/cpfl/cpfl_rxtx.c
index 453ec975d5..b6bf4094f1 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx.c
+++ b/drivers/net/intel/cpfl/cpfl_rxtx.c
@@ -1462,97 +1462,51 @@ cpfl_set_tx_function(struct rte_eth_dev *dev)
struct cpfl_vport *cpfl_vport = dev->data->dev_private;
struct idpf_vport *vport = &cpfl_vport->base;
#ifdef RTE_ARCH_X86
- enum rte_vect_max_simd tx_simd_width = RTE_VECT_SIMD_DISABLED;
#ifdef CC_AVX512_SUPPORT
- struct cpfl_tx_queue *cpfl_txq;
+ struct ci_tx_queue *txq;
int i;
#endif /* CC_AVX512_SUPPORT */
-
- if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH &&
- rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
- vport->tx_vec_allowed = true;
- tx_simd_width = cpfl_get_max_simd_bitwidth();
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- }
-#else
- PMD_DRV_LOG(NOTICE,
- "AVX512 is not supported in build env");
-#endif /* CC_AVX512_SUPPORT */
- } else {
- vport->tx_vec_allowed = false;
- }
#endif /* RTE_ARCH_X86 */
+ struct idpf_adapter *ad = vport->adapter;
+ struct ci_tx_path_features req_features = {
+ .tx_offloads = dev->data->dev_conf.txmode.offloads,
+ .simd_width = RTE_VECT_SIMD_DISABLED,
+ .single_queue = (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)
+ };
+
+ /* The primary process selects the tx path for all processes. */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto out;
+
+#ifdef RTE_ARCH_X86
+ if (cpfl_tx_vec_dev_check_default(dev) == CPFL_VECTOR_PATH)
+ req_features.simd_width = cpfl_get_max_simd_bitwidth();
+#endif
+
+ ad->tx_func_type = ci_tx_path_select(&req_features,
+ &idpf_tx_path_infos[0],
+ IDPF_TX_MAX,
+ IDPF_TX_DEFAULT);
+
+out:
+ dev->tx_pkt_burst = idpf_tx_path_infos[ad->tx_func_type].pkt_burst;
+ dev->tx_pkt_prepare = idpf_dp_prep_pkts;
+ PMD_DRV_LOG(NOTICE, "Using %s Tx (port %d).",
+ idpf_tx_path_infos[ad->tx_func_type].info, dev->data->port_id);
#ifdef RTE_ARCH_X86
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- if (vport->tx_vec_allowed) {
-#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- PMD_DRV_LOG(NOTICE,
- "Using Split AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- }
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- if (vport->tx_vec_allowed) {
#ifdef CC_AVX512_SUPPORT
- if (tx_simd_width == RTE_VECT_SIMD_512) {
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- cpfl_txq = dev->data->tx_queues[i];
- if (cpfl_txq == NULL)
- continue;
- idpf_qc_tx_vec_avx512_setup(&cpfl_txq->base);
- }
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX512 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx512;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
-#endif /* CC_AVX512_SUPPORT */
- if (tx_simd_width == RTE_VECT_SIMD_256) {
- PMD_DRV_LOG(NOTICE,
- "Using Single AVX2 Vector Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts_avx2;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- return;
- }
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width >= RTE_VECT_SIMD_256 &&
+ idpf_tx_path_infos[ad->tx_func_type].features.single_queue) {
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq == NULL)
+ continue;
+ if (idpf_tx_path_infos[ad->tx_func_type].features.simd_width ==
+ RTE_VECT_SIMD_512)
+ idpf_qc_tx_vec_avx512_setup(txq);
}
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- }
-#else
- if (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SPLIT) {
- PMD_DRV_LOG(NOTICE,
- "Using Split Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_splitq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
- } else {
- PMD_DRV_LOG(NOTICE,
- "Using Single Scalar Tx (port %d).",
- dev->data->port_id);
- dev->tx_pkt_burst = idpf_dp_singleq_xmit_pkts;
- dev->tx_pkt_prepare = idpf_dp_prep_pkts;
}
+#endif /* CC_AVX512_SUPPORT */
#endif /* RTE_ARCH_X86 */
}
diff --git a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
index 525ca9a6e0..f0daa1eb30 100644
--- a/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
+++ b/drivers/net/intel/cpfl/cpfl_rxtx_vec_common.h
@@ -23,13 +23,6 @@
RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
RTE_ETH_RX_OFFLOAD_TIMESTAMP)
-#define CPFL_TX_NO_VECTOR_FLAGS ( \
- RTE_ETH_TX_OFFLOAD_TCP_TSO | \
- RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
- RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | \
- RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM)
static inline int
cpfl_rx_vec_queue_default(struct idpf_rx_queue *rxq)
@@ -62,9 +55,6 @@ cpfl_tx_vec_queue_default(struct ci_tx_queue *txq)
(txq->tx_rs_thresh & 3) != 0)
return CPFL_SCALAR_PATH;
- if ((txq->offloads & CPFL_TX_NO_VECTOR_FLAGS) != 0)
- return CPFL_SCALAR_PATH;
-
return CPFL_VECTOR_PATH;
}
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index eff04a83eb..b31ae0bd5f 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -164,8 +164,6 @@ struct idpf_vport {
uint16_t devarg_id;
- bool tx_vec_allowed;
-
struct virtchnl2_vport_stats eth_stats_offset;
/* Event from ipf */
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 07/10] docs: fix TSO and checksum offload feature status in ice doc
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (5 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 06/10] net/cpfl: " Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 08/10] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
` (2 subsequent siblings)
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change its status to
partially supported. L3 and L4 checksum offload are enabled on scalar
and vector paths so change their statuses from partial to supported.
Fixes: f88de4694d94 ("net/ice: support Tx SSE vector")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/ice.ini | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index e9796c1eab..893d09e9ec 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -21,7 +21,7 @@ Power mgmt address monitor = Y
MTU update = Y
Buffer split on Rx = P
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
DCB = Y
@@ -34,8 +34,8 @@ Traffic manager = Y
CRC offload = Y
VLAN offload = Y
QinQ offload = P
-L3 checksum offload = P
-L4 checksum offload = P
+L3 checksum offload = Y
+L4 checksum offload = Y
Timestamp offload = P
Inner L3 checksum = P
Inner L4 checksum = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 08/10] docs: fix TSO feature status in iavf driver documentation
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (6 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 07/10] docs: fix TSO and checksum offload feature status in ice doc Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 09/10] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 10/10] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 319c421f3890 ("net/avf: enable SSE Rx Tx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 7695e3ff7c..6c9e97594f 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -17,7 +17,7 @@ Burst mode info = Y
Power mgmt address monitor = Y
MTU update = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 09/10] docs: fix inline crypto feature status in iavf driver doc
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (7 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 08/10] docs: fix TSO feature status in iavf driver documentation Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
2025-12-12 11:06 ` [PATCH v3 10/10] docs: fix TSO feature status in i40e driver documentation Ciara Loftus
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
inline crypto is only supported on the scalar path so change its status
to partially supported.
Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/iavf.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index 6c9e97594f..0ba6f7dfd7 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -27,7 +27,7 @@ RSS key update = Y
RSS reta update = Y
VLAN filter = Y
Traffic manager = Y
-Inline crypto = Y
+Inline crypto = P
CRC offload = Y
VLAN offload = P
QinQ offload = P
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread* [PATCH v3 10/10] docs: fix TSO feature status in i40e driver documentation
2025-12-12 11:06 ` [PATCH v3 00/10] net/intel: tx path selection simplification Ciara Loftus
` (8 preceding siblings ...)
2025-12-12 11:06 ` [PATCH v3 09/10] docs: fix inline crypto feature status in iavf driver doc Ciara Loftus
@ 2025-12-12 11:06 ` Ciara Loftus
9 siblings, 0 replies; 48+ messages in thread
From: Ciara Loftus @ 2025-12-12 11:06 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus, stable, Bruce Richardson
TSO is only supported on the scalar path so change the status to
partially supported.
Fixes: 9ed94e5bb04e ("i40e: add vector Rx")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/nics/features/i40e.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
index 4610444ace..fb00b69830 100644
--- a/doc/guides/nics/features/i40e.ini
+++ b/doc/guides/nics/features/i40e.ini
@@ -16,7 +16,7 @@ Runtime Tx queue setup = Y
Burst mode info = Y
Power mgmt address monitor = Y
Scattered Rx = Y
-TSO = Y
+TSO = P
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
--
2.43.0
^ permalink raw reply [flat|nested] 48+ messages in thread