> On Jul 21, 2019, at 7:24 AM, Viacheslav Ovsiienko <viachesl...@mellanox.com> > wrote: > > Mellanox NICs support the wide set of Tx offloads. The supported > offloads are reported by the mlx5 PMD in rte_eth_dev_info tx_offload_capa > field. An application may choose any combination of supported offloads > and configure the device appropriately. Some of Tx offloads may be > not requested by application, or ever all of them may be omitted. > Most of the Tx offloads require some code branches in tx_burst routine > to support ones. If Tx offload is not requested the tx_burst routine > code may be significantly simplified and consume less CPU cycles. > > For example, if application does not engage TSO offload this code > can be omitted, if multi-segment packet is not supposed the tx_burst > may assume single mbuf packets only, etc. > > Currently, the mlx5 PMD implements multiple tx_burst subroutines > for most common combinations of requested Tx offloads, each branch > has its own dedicated implementation. It is not very easy to update, > support and develop such kind of code - multiple branches impose > the multiple points to process. Also many of frequently requested > offload combinations are not supported yet. That leads to selecting of > not completely matching tx_burst routine and harms the performance. > > This patch introduces the new approach for tx_burst code. It is proposed > to develop the unified template for tx_burst routine, which supports > all the Tx offloads and takes the compile time defined parameter > describing the supposed set of supported offloads. On the base > of this template, the compiler is able to generate multiple tx_burst > routines highly optimized for the statically specified set of Tx offloads. > Next, in runtime, at Tx queue configuration the best matching optimized > implementation of tx_burst is chosen. > > This patch intentionally omits the template internal implementation, > but just introduces the template itself to emboss the approach of > the multiple specially tuned tx_burst routines. > > Signed-off-by: Viacheslav Ovsiienko <viachesl...@mellanox.com> > ---
Acked-by: Yongseok Koh <ys...@mellanox.com> > drivers/net/mlx5/mlx5_rxtx.c | 520 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 516 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c > index 13f9431..16be493 100644 > --- a/drivers/net/mlx5/mlx5_rxtx.c > +++ b/drivers/net/mlx5/mlx5_rxtx.c > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: BSD-3-Clause > * Copyright 2015 6WIND S.A. > - * Copyright 2015 Mellanox Technologies, Ltd > + * Copyright 2015-2019 Mellanox Technologies, Ltd > */ > > #include <assert.h> > @@ -34,6 +34,57 @@ > #include "mlx5_defs.h" > #include "mlx5_prm.h" > > +/* TX burst subroutines return codes. */ > +enum mlx5_txcmp_code { > + MLX5_TXCMP_CODE_EXIT = 0, > + MLX5_TXCMP_CODE_ERROR, > + MLX5_TXCMP_CODE_SINGLE, > + MLX5_TXCMP_CODE_MULTI, > + MLX5_TXCMP_CODE_TSO, > + MLX5_TXCMP_CODE_EMPW, > +}; > + > +/* > + * These defines are used to configure Tx burst routine option set > + * supported at compile time. The not specified options are optimized out > + * out due to if conditions can be explicitly calculated at compile time. > + * The offloads with bigger runtime check (require more CPU cycles to > + * skip) overhead should have the bigger index - this is needed to > + * select the better matching routine function if no exact match and > + * some offloads are not actually requested. > + */ > +#define MLX5_TXOFF_CONFIG_MULTI (1u << 0) /* Multi-segment packets.*/ > +#define MLX5_TXOFF_CONFIG_TSO (1u << 1) /* TCP send offload supported.*/ > +#define MLX5_TXOFF_CONFIG_SWP (1u << 2) /* Tunnels/SW Parser offloads.*/ > +#define MLX5_TXOFF_CONFIG_CSUM (1u << 3) /* Check Sums offloaded. */ > +#define MLX5_TXOFF_CONFIG_INLINE (1u << 4) /* Data inlining supported. */ > +#define MLX5_TXOFF_CONFIG_VLAN (1u << 5) /* VLAN insertion supported.*/ > +#define MLX5_TXOFF_CONFIG_METADATA (1u << 6) /* Flow metadata. */ > +#define MLX5_TXOFF_CONFIG_EMPW (1u << 8) /* Enhanced MPW supported.*/ > + > +/* The most common offloads groups. */ > +#define MLX5_TXOFF_CONFIG_NONE 0 > +#define MLX5_TXOFF_CONFIG_FULL (MLX5_TXOFF_CONFIG_MULTI | \ > + MLX5_TXOFF_CONFIG_TSO | \ > + MLX5_TXOFF_CONFIG_SWP | \ > + MLX5_TXOFF_CONFIG_CSUM | \ > + MLX5_TXOFF_CONFIG_INLINE | \ > + MLX5_TXOFF_CONFIG_VLAN | \ > + MLX5_TXOFF_CONFIG_METADATA) > + > +#define MLX5_TXOFF_CONFIG(mask) (olx & MLX5_TXOFF_CONFIG_##mask) > + > +#define MLX5_TXOFF_DECL(func, olx) \ > +static uint16_t mlx5_tx_burst_##func(void *txq, \ > + struct rte_mbuf **pkts, \ > + uint16_t pkts_n) \ > +{ \ > + return mlx5_tx_burst_tmpl((struct mlx5_txq_data *restrict)txq, \ > + pkts, pkts_n, (olx)); \ > +} > + > +#define MLX5_TXOFF_INFO(func, olx) {mlx5_tx_burst_##func, olx}, > + > static __rte_always_inline uint32_t > rxq_cq_to_pkt_type(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe); > > @@ -1531,7 +1582,323 @@ > } > > /** > - * Configure the TX function to use. > + * DPDK Tx callback template. This is configured template > + * used to generate routines optimized for specified offload setup. > + * One of this generated functions is chosen at SQ configuration > + * time. > + * > + * @param txq > + * Generic pointer to TX queue structure. > + * @param[in] pkts > + * Packets to transmit. > + * @param pkts_n > + * Number of packets in array. > + * @param olx > + * Configured offloads mask, presents the bits of MLX5_TXOFF_CONFIG_xxx > + * values. Should be static to take compile time static configuration > + * advantages. > + * > + * @return > + * Number of packets successfully transmitted (<= pkts_n). > + */ > +static __rte_always_inline uint16_t > +mlx5_tx_burst_tmpl(struct mlx5_txq_data *restrict txq, > + struct rte_mbuf **restrict pkts, > + uint16_t pkts_n, > + unsigned int olx) > +{ > + (void)txq; > + (void)pkts; > + (void)pkts_n; > + (void)olx; > + return 0; > +} > + > +/* Generate routines with Enhanced Multi-Packet Write support. */ > +MLX5_TXOFF_DECL(full_empw, > + MLX5_TXOFF_CONFIG_FULL | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(none_empw, > + MLX5_TXOFF_CONFIG_NONE | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(md_empw, > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(mt_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(mtsc_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(mti_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(mtv_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(mtiv_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(sc_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(sci_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(scv_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(sciv_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(i_empw, > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(v_empw, > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_DECL(iv_empw, > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +/* Generate routines without Enhanced Multi-Packet Write support. */ > +MLX5_TXOFF_DECL(full, > + MLX5_TXOFF_CONFIG_FULL) > + > +MLX5_TXOFF_DECL(none, > + MLX5_TXOFF_CONFIG_NONE) > + > +MLX5_TXOFF_DECL(md, > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(mt, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(mtsc, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(mti, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > + > +MLX5_TXOFF_DECL(mtv, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > + > +MLX5_TXOFF_DECL(mtiv, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(sc, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(sci, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > + > +MLX5_TXOFF_DECL(scv, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > + > +MLX5_TXOFF_DECL(sciv, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(i, > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(v, > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_DECL(iv, > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +/* > + * Array of declared and compiled Tx burst function and corresponding > + * supported offloads set. The array is used to select the Tx burst > + * function for specified offloads set at Tx queue configuration time. > + */ > +const struct { > + eth_tx_burst_t func; > + unsigned int olx; > +} txoff_func[] = { > +MLX5_TXOFF_INFO(full_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(none_empw, > + MLX5_TXOFF_CONFIG_NONE | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(md_empw, > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(mt_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(mtsc_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(mti_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(mtv_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(mtiv_empw, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(sc_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(sci_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(scv_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(sciv_empw, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(i_empw, > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(v_empw, > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(iv_empw, > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW) > + > +MLX5_TXOFF_INFO(full, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(none, > + MLX5_TXOFF_CONFIG_NONE) > + > +MLX5_TXOFF_INFO(md, > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(mt, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(mtsc, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(mti, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > + > +MLX5_TXOFF_INFO(mtv, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(mtiv, > + MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(sc, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(sci, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(scv, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(sciv, > + MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM | > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(i, > + MLX5_TXOFF_CONFIG_INLINE | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(v, > + MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > + > +MLX5_TXOFF_INFO(iv, > + MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN | > + MLX5_TXOFF_CONFIG_METADATA) > +}; > + > +/** > + * Configure the Tx function to use. The routine checks configured > + * Tx offloads for the device and selects appropriate Tx burst > + * routine. There are multiple Tx burst routines compiled from > + * the same template in the most optimal way for the dedicated > + * Tx offloads set. > * > * @param dev > * Pointer to private data structure. > @@ -1542,8 +1909,153 @@ > eth_tx_burst_t > mlx5_select_tx_function(struct rte_eth_dev *dev) > { > - (void)dev; > - return removed_tx_burst; > + struct mlx5_priv *priv = dev->data->dev_private; > + struct mlx5_dev_config *config = &priv->config; > + uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; > + unsigned int diff = 0, olx = 0, i, m; > + > + static_assert(MLX5_WQE_SIZE_MAX / MLX5_WSEG_SIZE <= > + MLX5_DSEG_MAX, "invalid WQE max size"); > + static_assert(MLX5_WQE_CSEG_SIZE == MLX5_WSEG_SIZE, > + "invalid WQE Control Segment size"); > + static_assert(MLX5_WQE_ESEG_SIZE == MLX5_WSEG_SIZE, > + "invalid WQE Ethernet Segment size"); > + static_assert(MLX5_WQE_DSEG_SIZE == MLX5_WSEG_SIZE, > + "invalid WQE Data Segment size"); > + static_assert(MLX5_WQE_SIZE == 4 * MLX5_WSEG_SIZE, > + "invalid WQE size"); > + assert(priv); > + if (tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS) { > + /* We should support Multi-Segment Packets. */ > + olx |= MLX5_TXOFF_CONFIG_MULTI; > + } > + if (tx_offloads & (DEV_TX_OFFLOAD_TCP_TSO | > + DEV_TX_OFFLOAD_VXLAN_TNL_TSO | > + DEV_TX_OFFLOAD_GRE_TNL_TSO | > + DEV_TX_OFFLOAD_IP_TNL_TSO | > + DEV_TX_OFFLOAD_UDP_TNL_TSO)) { > + /* We should support TCP Send Offload. */ > + olx |= MLX5_TXOFF_CONFIG_TSO; > + } > + if (tx_offloads & (DEV_TX_OFFLOAD_IP_TNL_TSO | > + DEV_TX_OFFLOAD_UDP_TNL_TSO | > + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)) { > + /* We should support Software Parser for Tunnels. */ > + olx |= MLX5_TXOFF_CONFIG_SWP; > + } > + if (tx_offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM | > + DEV_TX_OFFLOAD_UDP_CKSUM | > + DEV_TX_OFFLOAD_TCP_CKSUM | > + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)) { > + /* We should support IP/TCP/UDP Checksums. */ > + olx |= MLX5_TXOFF_CONFIG_CSUM; > + } > + if (tx_offloads & DEV_TX_OFFLOAD_VLAN_INSERT) { > + /* We should support VLAN insertion. */ > + olx |= MLX5_TXOFF_CONFIG_VLAN; > + } > + if (priv->txqs_n && (*priv->txqs)[0]) { > + struct mlx5_txq_data *txd = (*priv->txqs)[0]; > + > + if (txd->inlen_send) { > + /* > + * Check the data inline requirements. Data inline > + * is enabled on per device basis, we can check > + * the first Tx queue only. > + * > + * If device does not support VLAN insertion in WQE > + * and some queues are requested to perform VLAN > + * insertion offload than inline must be enabled. > + */ > + olx |= MLX5_TXOFF_CONFIG_INLINE; > + } > + } > + if (config->mps == MLX5_MPW_ENHANCED && > + config->txq_inline_min <= 0) { > + /* > + * The NIC supports Enhanced Multi-Packet Write. > + * We do not support legacy MPW due to its > + * hardware related problems, so we just ignore > + * legacy MLX5_MPW settings. There should be no > + * minimal required inline data. > + */ > + olx |= MLX5_TXOFF_CONFIG_EMPW; > + } > + if (tx_offloads & DEV_TX_OFFLOAD_MATCH_METADATA) { > + /* We should support Flow metadata. */ > + olx |= MLX5_TXOFF_CONFIG_METADATA; > + } > + /* > + * Scan the routines table to find the minimal > + * satisfying routine with requested offloads. > + */ > + m = RTE_DIM(txoff_func); > + for (i = 0; i < RTE_DIM(txoff_func); i++) { > + unsigned int tmp; > + > + tmp = txoff_func[i].olx; > + if (tmp == olx) { > + /* Meets requested offloads exactly.*/ > + m = i; > + break; > + } > + if ((tmp & olx) != olx) { > + /* Does not meet requested offloads at all. */ > + continue; > + } > + if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_EMPW) > + /* Do not enable eMPW if not configured. */ > + continue; > + if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_INLINE) > + /* Do not enable inlining if not configured. */ > + continue; > + /* > + * Some routine meets the requirements. > + * Check whether it has minimal amount > + * of not requested offloads. > + */ > + tmp = __builtin_popcountl(tmp & ~olx); > + if (m >= RTE_DIM(txoff_func) || tmp < diff) { > + /* First or better match, save and continue. */ > + m = i; > + diff = tmp; > + continue; > + } > + if (tmp == diff) { > + tmp = txoff_func[i].olx ^ txoff_func[m].olx; > + if (__builtin_ffsl(txoff_func[i].olx & ~tmp) < > + __builtin_ffsl(txoff_func[m].olx & ~tmp)) { > + /* Lighter not requested offload. */ > + m = i; > + } > + } > + } > + if (m >= RTE_DIM(txoff_func)) { > + DRV_LOG(DEBUG, "port %u has no selected Tx function" > + " for requested offloads %04X", > + dev->data->port_id, olx); > + return NULL; > + } > + DRV_LOG(DEBUG, "port %u has selected Tx function" > + " supporting offloads %04X/%04X", > + dev->data->port_id, olx, txoff_func[m].olx); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_MULTI) > + DRV_LOG(DEBUG, "\tMULTI (multi segment)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_TSO) > + DRV_LOG(DEBUG, "\tTSO (TCP send offload)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_SWP) > + DRV_LOG(DEBUG, "\tSWP (software parser)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_CSUM) > + DRV_LOG(DEBUG, "\tCSUM (checksum offload)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_INLINE) > + DRV_LOG(DEBUG, "\tINLIN (inline data)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_VLAN) > + DRV_LOG(DEBUG, "\tVLANI (VLAN insertion)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_METADATA) > + DRV_LOG(DEBUG, "\tMETAD (tx Flow metadata)"); > + if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_EMPW) > + DRV_LOG(DEBUG, "\tEMPW (Enhanced MPW)"); > + return txoff_func[m].func; > } > > > -- > 1.8.3.1 >