[dpdk-dev] [PATCH 2/2] i40e:enable TSO support

David Marchand david.marchand at 6wind.com
Mon Feb 9 10:10:51 CET 2015


Hello,

This patch does two things at the same time.
Please split this to make it easier to understand (see comments below).


On Mon, Feb 9, 2015 at 7:32 AM, Jijiang Liu <jijiang.liu at intel.com> wrote:

> This patch enables i40e TSO feature for both non-tunneling packet and
> tunneling packet.
>
> Signed-off-by: Jijiang Liu <jijiang.liu at intel.com>
> Signed-off-by: Miroslaw Walukiewicz <miroslaw.walukiewicz at intel.com>
> ---
>  lib/librte_pmd_i40e/i40e_rxtx.c |   99
> ++++++++++++++++++++++++++++-----------
>  lib/librte_pmd_i40e/i40e_rxtx.h |   13 +++++
>  2 files changed, 85 insertions(+), 27 deletions(-)
>
> diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c
> b/lib/librte_pmd_i40e/i40e_rxtx.c
> index 349c1e5..9b9bdcd 100644
> --- a/lib/librte_pmd_i40e/i40e_rxtx.c
> +++ b/lib/librte_pmd_i40e/i40e_rxtx.c
> @@ -465,16 +465,13 @@ static inline void
>  i40e_txd_enable_checksum(uint64_t ol_flags,
>                         uint32_t *td_cmd,
>                         uint32_t *td_offset,
> -                       uint8_t l2_len,
> -                       uint16_t l3_len,
> -                       uint8_t outer_l2_len,
> -                       uint16_t outer_l3_len,
> +                       union i40e_tx_offload tx_offload,
>                         uint32_t *cd_tunneling)
>  {
>         /* UDP tunneling packet TX checksum offload */
>         if (unlikely(ol_flags & PKT_TX_OUTER_IP_CKSUM)) {
>
> -               *td_offset |= (outer_l2_len >> 1)
> +               *td_offset |= (tx_offload.outer_l2_len >> 1)
>                                 << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
>
>                 if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
> @@ -485,25 +482,35 @@ i40e_txd_enable_checksum(uint64_t ol_flags,
>                         *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;
>
>                 /* Now set the ctx descriptor fields */
> -               *cd_tunneling |= (outer_l3_len >> 2) <<
> +               *cd_tunneling |= (tx_offload.outer_l3_len >> 2) <<
>                                 I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
> -                               (l2_len >> 1) <<
> +                               (tx_offload.l2_len >> 1) <<
>                                 I40E_TXD_CTX_QW0_NATLEN_SHIFT;
>
>         } else
> -               *td_offset |= (l2_len >> 1)
> +               *td_offset |= (tx_offload.l2_len >> 1)
>                         << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
>
>         /* Enable L3 checksum offloads */
>         if (ol_flags & PKT_TX_IP_CKSUM) {
>                 *td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4_CSUM;
> -               *td_offset |= (l3_len >> 2) <<
> I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
> +               *td_offset |= (tx_offload.l3_len >> 2)
> +                       << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
>         } else if (ol_flags & PKT_TX_IPV4) {
>                 *td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
> -               *td_offset |= (l3_len >> 2) <<
> I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
> +               *td_offset |= (tx_offload.l3_len >> 2)
> +                        << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
>         } else if (ol_flags & PKT_TX_IPV6) {
>                 *td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
> -               *td_offset |= (l3_len >> 2) <<
> I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
> +               *td_offset |= (tx_offload.l3_len >> 2)
> +                        << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
> +       }
>

This first part is a rework to me.
Please split.



> +
> +       if (ol_flags & PKT_TX_TCP_SEG) {
> +               *td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
> +               *td_offset |= (tx_offload.l4_len >> 2)
> +                       << I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
> +               return;
>         }
>
>         /* Enable L4 checksum offloads */
> @@ -1154,7 +1161,7 @@ i40e_calc_context_desc(uint64_t flags)
>  {
>         uint64_t mask = 0ULL;
>
> -       mask |= PKT_TX_OUTER_IP_CKSUM;
> +       mask |= (PKT_TX_OUTER_IP_CKSUM | PKT_TX_TCP_SEG);
>

You are adding this offload flag in an unconditional way.
Is this intended ?


>  #ifdef RTE_LIBRTE_IEEE1588
>         mask |= PKT_TX_IEEE1588_TMST;
> @@ -1165,6 +1172,41 @@ i40e_calc_context_desc(uint64_t flags)
>         return 0;
>  }
>
> +/* set i40e TSO context descriptor */
> +static inline uint64_t
> +i40e_set_tso_ctx(struct rte_mbuf *mbuf, union i40e_tx_offload tx_offload)
> +{
> +
> +       uint64_t ctx_desc = 0;
> +       uint32_t cd_cmd, hdr_len, cd_tso_len;
> +
> +
> +       if (!tx_offload.l4_len) {
> +               PMD_DRV_LOG(DEBUG, "L4 length set to 0");
> +               return ctx_desc;
> +       }
> +
> +       /**
> +        * in case of tunneling packet, the outer_l2_len and
> +        * outer_l3_len must be 0.
> +        */
> +       hdr_len = tx_offload.outer_l2_len +
> +               tx_offload.outer_l3_len +
> +               tx_offload.l2_len +
> +               tx_offload.l3_len +
> +               tx_offload.l4_len;
> +
> +       cd_cmd = I40E_TX_CTX_DESC_TSO;
> +       cd_tso_len = mbuf->pkt_len - hdr_len;
> +       ctx_desc |= ((uint64_t)cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
> +                               ((uint64_t)cd_tso_len <<
> +                                I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
> +                               ((uint64_t)mbuf->tso_segsz <<
> +                               I40E_TXD_CTX_QW1_MSS_SHIFT);
> +
> +       return ctx_desc;
> +}
> +
>



>  uint16_t
>  i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
> nb_pkts)
>  {
> @@ -1183,15 +1225,12 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>         uint32_t tx_flags;
>         uint32_t td_tag;
>         uint64_t ol_flags;
> -       uint8_t l2_len;
> -       uint16_t l3_len;
> -       uint8_t outer_l2_len;
> -       uint16_t outer_l3_len;
>         uint16_t nb_used;
>         uint16_t nb_ctx;
>         uint16_t tx_last;
>         uint16_t slen;
>         uint64_t buf_dma_addr;
> +       union i40e_tx_offload tx_offload = { .data = 0 };
>
>         txq = tx_queue;
>         sw_ring = txq->sw_ring;
> @@ -1213,10 +1252,12 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>                 RTE_MBUF_PREFETCH_TO_FREE(txe->mbuf);
>
>                 ol_flags = tx_pkt->ol_flags;
> -               l2_len = tx_pkt->l2_len;
> -               l3_len = tx_pkt->l3_len;
> -               outer_l2_len = tx_pkt->outer_l2_len;
> -               outer_l3_len = tx_pkt->outer_l3_len;
> +               tx_offload.l2_len = tx_pkt->l2_len;
> +               tx_offload.l3_len = tx_pkt->l3_len;
> +               tx_offload.l4_len = tx_pkt->l4_len;
> +               tx_offload.tso_segsz = tx_pkt->tso_segsz;
> +               tx_offload.outer_l2_len = tx_pkt->outer_l2_len;
> +               tx_offload.outer_l3_len = tx_pkt->outer_l3_len;
>


Idem, with the split stuff.


>
>                 /* Calculate the number of context descriptors needed. */
>                 nb_ctx = i40e_calc_context_desc(ol_flags);
> @@ -1267,9 +1308,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>                 cd_tunneling_params = 0;
>                 if (ol_flags & I40E_TX_CKSUM_OFFLOAD_MASK) {
>                         i40e_txd_enable_checksum(ol_flags, &td_cmd,
> &td_offset,
> -                               l2_len, l3_len, outer_l2_len,
> -                               outer_l3_len,
> -                               &cd_tunneling_params);
> +                               tx_offload, &cd_tunneling_params);
>                 }
>
>                 if (unlikely(nb_ctx)) {
>

Idem.


> @@ -1287,12 +1326,18 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>                                 rte_pktmbuf_free_seg(txe->mbuf);
>                                 txe->mbuf = NULL;
>                         }
> -#ifdef RTE_LIBRTE_IEEE1588
> -                       if (ol_flags & PKT_TX_IEEE1588_TMST)
> +                       /* TSO enabled means no timestamp */
> +                       if (ol_flags & PKT_TX_TCP_SEG) {
>                                 cd_type_cmd_tso_mss |=
> -                                       ((uint64_t)I40E_TX_CTX_DESC_TSYN <<
> -
>  I40E_TXD_CTX_QW1_CMD_SHIFT);
> +                                       i40e_set_tso_ctx(tx_pkt,
> tx_offload);
> +                       } else {
> +#ifdef RTE_LIBRTE_IEEE1588
> +                               if (ol_flags & PKT_TX_IEEE1588_TMST)
> +                                       cd_type_cmd_tso_mss |=
> +
>  ((uint64_t)I40E_TX_CTX_DESC_TSYN <<
> +
>  I40E_TXD_CTX_QW1_CMD_SHIFT);
>  #endif
> +                       }
>                         ctx_txd->tunneling_params =
>                                 rte_cpu_to_le_32(cd_tunneling_params);
>                         ctx_txd->l2tag2 = rte_cpu_to_le_16(cd_l2tag2);
> diff --git a/lib/librte_pmd_i40e/i40e_rxtx.h
> b/lib/librte_pmd_i40e/i40e_rxtx.h
> index af932e3..f1033ef 100644
> --- a/lib/librte_pmd_i40e/i40e_rxtx.h
> +++ b/lib/librte_pmd_i40e/i40e_rxtx.h
> @@ -154,6 +154,19 @@ struct i40e_tx_queue {
>         bool tx_deferred_start; /**< don't start this queue in dev start */
>  };
>
> +/** Offload features */
> +union i40e_tx_offload {
> +       uint64_t data;
> +       struct {
> +               uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
> +               uint64_t l3_len:9; /**< L3 (IP) Header Length. */
> +               uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
> +               uint64_t tso_segsz:16; /**< TCP TSO segment size */
> +               uint64_t outer_l2_len:8; /**< L2 outer Header Length */
> +               uint64_t outer_l3_len:16; /**< L3 outer Header Length */
> +       };
> +};
> +
>

Idem.



-- 
David Marchand


More information about the dev mailing list