From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id BD6415912 for ; Mon, 17 Nov 2014 19:18:42 +0100 (CET) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 17 Nov 2014 10:23:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,404,1413270000"; d="scan'208";a="609245931" Received: from irsmsx103.ger.corp.intel.com ([163.33.3.157]) by orsmga001.jf.intel.com with ESMTP; 17 Nov 2014 10:26:19 -0800 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.101]) by IRSMSX103.ger.corp.intel.com ([169.254.3.134]) with mapi id 14.03.0195.001; Mon, 17 Nov 2014 18:26:18 +0000 From: "Ananyev, Konstantin" To: Olivier Matz , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH v2 11/13] ixgbe: support TCP segmentation offload Thread-Index: AQHQAC1Z0xUYuhtgvUuJUGfQ9/2sOpxlJKOw Date: Mon, 17 Nov 2014 18:26:18 +0000 Message-ID: <2601191342CEEE43887BDE71AB977258213AE582@IRSMSX105.ger.corp.intel.com> References: <1415635166-1364-1-git-send-email-olivier.matz@6wind.com> <1415984609-2484-1-git-send-email-olivier.matz@6wind.com> <1415984609-2484-12-git-send-email-olivier.matz@6wind.com> In-Reply-To: <1415984609-2484-12-git-send-email-olivier.matz@6wind.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [163.33.239.180] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Cc: "jigsaw@gmail.com" Subject: Re: [dpdk-dev] [PATCH v2 11/13] ixgbe: support TCP segmentation offload X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Nov 2014 18:18:43 -0000 > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz > Sent: Friday, November 14, 2014 5:03 PM > To: dev@dpdk.org > Cc: jigsaw@gmail.com > Subject: [dpdk-dev] [PATCH v2 11/13] ixgbe: support TCP segmentation offl= oad >=20 > Implement TSO (TCP segmentation offload) in ixgbe driver. The driver is > now able to use PKT_TX_TCP_SEG mbuf flag and mbuf hardware offload infos > (l2_len, l3_len, l4_len, tso_segsz) to configure the hardware support of > TCP segmentation. >=20 > In ixgbe, when doing TSO, the IP length must not be included in the TCP > pseudo header checksum. A new function ixgbe_fix_tcp_phdr_cksum() is > used to fix the pseudo header checksum of the packet before giving it to > the hardware. >=20 > In the patch, the tx_desc_cksum_flags_to_olinfo() and > tx_desc_ol_flags_to_cmdtype() functions have been reworked to make them > clearer. This should not impact performance as gcc (version 4.8 in my > case) is smart enough to convert the tests into a code that does not > contain any branch instruction. >=20 > Signed-off-by: Olivier Matz Acked-by: Konstantin Ananyev Just one thing - double semicolon - looks like a typo: > + /* check if TCP segmentation required for this packet */ > + if (ol_flags & PKT_TX_TCP_SEG) { > + /* implies IP cksum and TCP cksum */ > + type_tucmd_mlhl =3D IXGBE_ADVTXD_TUCMD_IPV4 | > + IXGBE_ADVTXD_TUCMD_L4T_TCP | > + IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;; =20 > --- > lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 3 +- > lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 169 ++++++++++++++++++++++--------= ------ > lib/librte_pmd_ixgbe/ixgbe_rxtx.h | 19 ++-- > 3 files changed, 117 insertions(+), 74 deletions(-) >=20 > diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/i= xgbe_ethdev.c > index 2eb609c..2c2ecc0 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > @@ -1964,7 +1964,8 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct = rte_eth_dev_info *dev_info) > DEV_TX_OFFLOAD_IPV4_CKSUM | > DEV_TX_OFFLOAD_UDP_CKSUM | > DEV_TX_OFFLOAD_TCP_CKSUM | > - DEV_TX_OFFLOAD_SCTP_CKSUM; > + DEV_TX_OFFLOAD_SCTP_CKSUM | > + DEV_TX_OFFLOAD_TCP_TSO; >=20 > dev_info->default_rxconf =3D (struct rte_eth_rxconf) { > .rx_thresh =3D { > diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixg= be_rxtx.c > index 2df3385..19e3b73 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c > +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c > @@ -94,7 +94,8 @@ > #define IXGBE_TX_OFFLOAD_MASK ( \ > PKT_TX_VLAN_PKT | \ > PKT_TX_IP_CKSUM | \ > - PKT_TX_L4_MASK) > + PKT_TX_L4_MASK | \ > + PKT_TX_TCP_SEG) >=20 > static inline struct rte_mbuf * > rte_rxmbuf_alloc(struct rte_mempool *mp) > @@ -363,59 +364,84 @@ ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_m= buf **tx_pkts, > static inline void > ixgbe_set_xmit_ctx(struct igb_tx_queue* txq, > volatile struct ixgbe_adv_tx_context_desc *ctx_txd, > - uint64_t ol_flags, uint32_t vlan_macip_lens) > + uint64_t ol_flags, union ixgbe_tx_offload tx_offload) > { > uint32_t type_tucmd_mlhl; > - uint32_t mss_l4len_idx; > + uint32_t mss_l4len_idx =3D 0; > uint32_t ctx_idx; > - uint32_t cmp_mask; > + uint32_t vlan_macip_lens; > + union ixgbe_tx_offload tx_offload_mask; >=20 > ctx_idx =3D txq->ctx_curr; > - cmp_mask =3D 0; > + tx_offload_mask.data =3D 0; > type_tucmd_mlhl =3D 0; >=20 > + /* Specify which HW CTX to upload. */ > + mss_l4len_idx |=3D (ctx_idx << IXGBE_ADVTXD_IDX_SHIFT); > + > if (ol_flags & PKT_TX_VLAN_PKT) { > - cmp_mask |=3D TX_VLAN_CMP_MASK; > + tx_offload_mask.vlan_tci =3D ~0; > } >=20 > - if (ol_flags & PKT_TX_IP_CKSUM) { > - type_tucmd_mlhl =3D IXGBE_ADVTXD_TUCMD_IPV4; > - cmp_mask |=3D TX_MACIP_LEN_CMP_MASK; > - } > + /* check if TCP segmentation required for this packet */ > + if (ol_flags & PKT_TX_TCP_SEG) { > + /* implies IP cksum and TCP cksum */ > + type_tucmd_mlhl =3D IXGBE_ADVTXD_TUCMD_IPV4 | > + IXGBE_ADVTXD_TUCMD_L4T_TCP | > + IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;; > + > + tx_offload_mask.l2_len =3D ~0; > + tx_offload_mask.l3_len =3D ~0; > + tx_offload_mask.l4_len =3D ~0; > + tx_offload_mask.tso_segsz =3D ~0; > + mss_l4len_idx |=3D tx_offload.tso_segsz << IXGBE_ADVTXD_MSS_SHIFT; > + mss_l4len_idx |=3D tx_offload.l4_len << IXGBE_ADVTXD_L4LEN_SHIFT; > + } else { /* no TSO, check if hardware checksum is needed */ > + if (ol_flags & PKT_TX_IP_CKSUM) { > + type_tucmd_mlhl =3D IXGBE_ADVTXD_TUCMD_IPV4; > + tx_offload_mask.l2_len =3D ~0; > + tx_offload_mask.l3_len =3D ~0; > + } >=20 > - /* Specify which HW CTX to upload. */ > - mss_l4len_idx =3D (ctx_idx << IXGBE_ADVTXD_IDX_SHIFT); > - switch (ol_flags & PKT_TX_L4_MASK) { > - case PKT_TX_UDP_CKSUM: > - type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_UDP | > + switch (ol_flags & PKT_TX_L4_MASK) { > + case PKT_TX_UDP_CKSUM: > + type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_UDP | > IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT; > - mss_l4len_idx |=3D sizeof(struct udp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT; > - cmp_mask |=3D TX_MACIP_LEN_CMP_MASK; > - break; > - case PKT_TX_TCP_CKSUM: > - type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_TCP | > + mss_l4len_idx |=3D sizeof(struct udp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT= ; > + tx_offload_mask.l2_len =3D ~0; > + tx_offload_mask.l3_len =3D ~0; > + break; > + case PKT_TX_TCP_CKSUM: > + type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_TCP | > IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT; > - mss_l4len_idx |=3D sizeof(struct tcp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT; > - cmp_mask |=3D TX_MACIP_LEN_CMP_MASK; > - break; > - case PKT_TX_SCTP_CKSUM: > - type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_SCTP | > + mss_l4len_idx |=3D sizeof(struct tcp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT= ; > + tx_offload_mask.l2_len =3D ~0; > + tx_offload_mask.l3_len =3D ~0; > + tx_offload_mask.l4_len =3D ~0; > + break; > + case PKT_TX_SCTP_CKSUM: > + type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_SCTP | > IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT; > - mss_l4len_idx |=3D sizeof(struct sctp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT= ; > - cmp_mask |=3D TX_MACIP_LEN_CMP_MASK; > - break; > - default: > - type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_RSV | > + mss_l4len_idx |=3D sizeof(struct sctp_hdr) << IXGBE_ADVTXD_L4LEN_SHIF= T; > + tx_offload_mask.l2_len =3D ~0; > + tx_offload_mask.l3_len =3D ~0; > + break; > + default: > + type_tucmd_mlhl |=3D IXGBE_ADVTXD_TUCMD_L4T_RSV | > IXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT; > - break; > + break; > + } > } >=20 > txq->ctx_cache[ctx_idx].flags =3D ol_flags; > - txq->ctx_cache[ctx_idx].cmp_mask =3D cmp_mask; > - txq->ctx_cache[ctx_idx].vlan_macip_lens.data =3D > - vlan_macip_lens & cmp_mask; > + txq->ctx_cache[ctx_idx].tx_offload.data =3D > + tx_offload_mask.data & tx_offload.data; > + txq->ctx_cache[ctx_idx].tx_offload_mask =3D tx_offload_mask; >=20 > ctx_txd->type_tucmd_mlhl =3D rte_cpu_to_le_32(type_tucmd_mlhl); > + vlan_macip_lens =3D tx_offload.l3_len; > + vlan_macip_lens |=3D (tx_offload.l2_len << IXGBE_ADVTXD_MACLEN_SHIFT); > + vlan_macip_lens |=3D ((uint32_t)tx_offload.vlan_tci << IXGBE_ADVTXD_VLA= N_SHIFT); > ctx_txd->vlan_macip_lens =3D rte_cpu_to_le_32(vlan_macip_lens); > ctx_txd->mss_l4len_idx =3D rte_cpu_to_le_32(mss_l4len_idx); > ctx_txd->seqnum_seed =3D 0; > @@ -427,20 +453,20 @@ ixgbe_set_xmit_ctx(struct igb_tx_queue* txq, > */ > static inline uint32_t > what_advctx_update(struct igb_tx_queue *txq, uint64_t flags, > - uint32_t vlan_macip_lens) > + union ixgbe_tx_offload tx_offload) > { > /* If match with the current used context */ > if (likely((txq->ctx_cache[txq->ctx_curr].flags =3D=3D flags) && > - (txq->ctx_cache[txq->ctx_curr].vlan_macip_lens.data =3D=3D > - (txq->ctx_cache[txq->ctx_curr].cmp_mask & vlan_macip_lens)))) { > + (txq->ctx_cache[txq->ctx_curr].tx_offload.data =3D=3D > + (txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)= ))) { > return txq->ctx_curr; > } >=20 > /* What if match with the next context */ > txq->ctx_curr ^=3D 1; > if (likely((txq->ctx_cache[txq->ctx_curr].flags =3D=3D flags) && > - (txq->ctx_cache[txq->ctx_curr].vlan_macip_lens.data =3D=3D > - (txq->ctx_cache[txq->ctx_curr].cmp_mask & vlan_macip_lens)))) { > + (txq->ctx_cache[txq->ctx_curr].tx_offload.data =3D=3D > + (txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)= ))) { > return txq->ctx_curr; > } >=20 > @@ -451,20 +477,25 @@ what_advctx_update(struct igb_tx_queue *txq, uint64= _t flags, > static inline uint32_t > tx_desc_cksum_flags_to_olinfo(uint64_t ol_flags) > { > - static const uint32_t l4_olinfo[2] =3D {0, IXGBE_ADVTXD_POPTS_TXSM}; > - static const uint32_t l3_olinfo[2] =3D {0, IXGBE_ADVTXD_POPTS_IXSM}; > - uint32_t tmp; > - > - tmp =3D l4_olinfo[(ol_flags & PKT_TX_L4_MASK) !=3D PKT_TX_L4_NO_CKSUM= ]; > - tmp |=3D l3_olinfo[(ol_flags & PKT_TX_IP_CKSUM) !=3D 0]; > + uint32_t tmp =3D 0; > + if ((ol_flags & PKT_TX_L4_MASK) !=3D PKT_TX_L4_NO_CKSUM) > + tmp |=3D IXGBE_ADVTXD_POPTS_TXSM; > + if (ol_flags & PKT_TX_IP_CKSUM) > + tmp |=3D IXGBE_ADVTXD_POPTS_IXSM; > + if (ol_flags & PKT_TX_TCP_SEG) > + tmp |=3D IXGBE_ADVTXD_POPTS_TXSM; > return tmp; > } >=20 > static inline uint32_t > -tx_desc_vlan_flags_to_cmdtype(uint64_t ol_flags) > +tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags) > { > - static const uint32_t vlan_cmd[2] =3D {0, IXGBE_ADVTXD_DCMD_VLE}; > - return vlan_cmd[(ol_flags & PKT_TX_VLAN_PKT) !=3D 0]; > + uint32_t cmdtype =3D 0; > + if (ol_flags & PKT_TX_VLAN_PKT) > + cmdtype |=3D IXGBE_ADVTXD_DCMD_VLE; > + if (ol_flags & PKT_TX_TCP_SEG) > + cmdtype |=3D IXGBE_ADVTXD_DCMD_TSE; > + return cmdtype; > } >=20 > /* Default RS bit threshold values */ > @@ -545,14 +576,6 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx= _pkts, > volatile union ixgbe_adv_tx_desc *txd; > struct rte_mbuf *tx_pkt; > struct rte_mbuf *m_seg; > - union ixgbe_vlan_macip vlan_macip_lens; > - union { > - uint16_t u16; > - struct { > - uint16_t l3_len:9; > - uint16_t l2_len:7; > - }; > - } l2_l3_len; > uint64_t buf_dma_addr; > uint32_t olinfo_status; > uint32_t cmd_type_len; > @@ -566,6 +589,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_= pkts, > uint64_t tx_ol_req; > uint32_t ctx =3D 0; > uint32_t new_ctx; > + union ixgbe_tx_offload tx_offload =3D { .data =3D 0 }; >=20 > txq =3D tx_queue; > sw_ring =3D txq->sw_ring; > @@ -595,14 +619,15 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **t= x_pkts, > /* If hardware offload required */ > tx_ol_req =3D ol_flags & IXGBE_TX_OFFLOAD_MASK; > if (tx_ol_req) { > - l2_l3_len.l2_len =3D tx_pkt->l2_len; > - l2_l3_len.l3_len =3D tx_pkt->l3_len; > - vlan_macip_lens.f.vlan_tci =3D tx_pkt->vlan_tci; > - vlan_macip_lens.f.l2_l3_len =3D l2_l3_len.u16; > + tx_offload.l2_len =3D tx_pkt->l2_len; > + tx_offload.l3_len =3D tx_pkt->l3_len; > + tx_offload.l4_len =3D tx_pkt->l4_len; > + tx_offload.vlan_tci =3D tx_pkt->vlan_tci; > + tx_offload.tso_segsz =3D tx_pkt->tso_segsz; >=20 > /* If new context need be built or reuse the exist ctx. */ > ctx =3D what_advctx_update(txq, tx_ol_req, > - vlan_macip_lens.data); > + tx_offload); > /* Only allocate context descriptor if required*/ > new_ctx =3D (ctx =3D=3D IXGBE_CTX_NUM); > ctx =3D txq->ctx_curr; > @@ -717,13 +742,22 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **t= x_pkts, > */ > cmd_type_len =3D IXGBE_ADVTXD_DTYP_DATA | > IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT; > - olinfo_status =3D (pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT); > + > #ifdef RTE_LIBRTE_IEEE1588 > if (ol_flags & PKT_TX_IEEE1588_TMST) > cmd_type_len |=3D IXGBE_ADVTXD_MAC_1588; > #endif >=20 > + olinfo_status =3D 0; > if (tx_ol_req) { > + > + if (ol_flags & PKT_TX_TCP_SEG) { > + /* when TSO is on, paylen in descriptor is the > + * not the packet len but the tcp payload len */ > + pkt_len -=3D (tx_offload.l2_len + > + tx_offload.l3_len + tx_offload.l4_len); > + } > + > /* > * Setup the TX Advanced Context Descriptor if required > */ > @@ -744,7 +778,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_= pkts, > } >=20 > ixgbe_set_xmit_ctx(txq, ctx_txd, tx_ol_req, > - vlan_macip_lens.data); > + tx_offload); >=20 > txe->last_id =3D tx_last; > tx_id =3D txe->next_id; > @@ -756,11 +790,13 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **t= x_pkts, > * This path will go through > * whatever new/reuse the context descriptor > */ > - cmd_type_len |=3D tx_desc_vlan_flags_to_cmdtype(ol_flags); > + cmd_type_len |=3D tx_desc_ol_flags_to_cmdtype(ol_flags); > olinfo_status |=3D tx_desc_cksum_flags_to_olinfo(ol_flags); > olinfo_status |=3D ctx << IXGBE_ADVTXD_IDX_SHIFT; > } >=20 > + olinfo_status |=3D (pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT); > + > m_seg =3D tx_pkt; > do { > txd =3D &txr[tx_id]; > @@ -3611,9 +3647,10 @@ ixgbe_dev_tx_init(struct rte_eth_dev *dev) > PMD_INIT_FUNC_TRACE(); > hw =3D IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); >=20 > - /* Enable TX CRC (checksum offload requirement) */ > + /* Enable TX CRC (checksum offload requirement) and hw padding > + * (TSO requirement) */ > hlreg0 =3D IXGBE_READ_REG(hw, IXGBE_HLREG0); > - hlreg0 |=3D IXGBE_HLREG0_TXCRCEN; > + hlreg0 |=3D (IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_TXPADEN); > IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); >=20 > /* Setup the Base and Length of the Tx Descriptor Rings */ > diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.h b/lib/librte_pmd_ixgbe/ixg= be_rxtx.h > index eb89715..13099af 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.h > +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.h > @@ -145,13 +145,16 @@ enum ixgbe_advctx_num { > }; >=20 > /** Offload features */ > -union ixgbe_vlan_macip { > - uint32_t data; > +union ixgbe_tx_offload { > + uint64_t data; > struct { > - uint16_t l2_l3_len; /**< combined 9-bit l3, 7-bit l2 lengths */ > - uint16_t vlan_tci; > + 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 vlan_tci:16; > /**< VLAN Tag Control Identifier (CPU order). */ > - } f; > + }; > }; >=20 > /* > @@ -170,8 +173,10 @@ union ixgbe_vlan_macip { >=20 > struct ixgbe_advctx_info { > uint64_t flags; /**< ol_flags for context build. */ > - uint32_t cmp_mask; /**< compare mask for vlan_macip_lens */ > - union ixgbe_vlan_macip vlan_macip_lens; /**< vlan, mac ip length. */ > + /**< tx offload: vlan, tso, l2-l3-l4 lengths. */ > + union ixgbe_tx_offload tx_offload; > + /** compare mask for tx offload. */ > + union ixgbe_tx_offload tx_offload_mask; > }; >=20 > /** > -- > 2.1.0