From patchwork Tue Oct 21 11:29:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: miroslaw.walukiewicz@intel.com X-Patchwork-Id: 886 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id DCD147E80; Tue, 21 Oct 2014 13:21:36 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 743507E7B for ; Tue, 21 Oct 2014 13:21:33 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 21 Oct 2014 04:26:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,761,1406617200"; d="scan'208";a="622504489" Received: from gklab-18-011.igk.intel.com ([10.102.18.11]) by orsmga002.jf.intel.com with ESMTP; 21 Oct 2014 04:29:47 -0700 From: miroslaw.walukiewicz@intel.com To: dev@dpdk.org Date: Tue, 21 Oct 2014 07:29:46 -0400 Message-ID: <20141021112946.30069.67329.stgit@gklab-18-011.igk.intel.com> User-Agent: StGit/0.17-dirty MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2] pmd: Add generic support for TCP TSO (Transmit 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Miroslaw Walukiewicz The NICs supported by DPDK have a possibility to accelerate TCP traffic by sergnention offload. The application preprares a packet with valid TCP header with size up to 64K and NIC makes packet segmenation generating valid checksums and TCP segments. The patch defines a generic support for TSO offload. - Add new PKT_TX_TCP_SEG flag. Only packets with this flag set in ol_flags will be handled as TSO packets. - Add new fields in indicating TCP TSO segment size and TCP header len. The TSO requires from application setting following fields in mbuf. 1. L2 header len including MAC/VLANs/SNAP if present 2. L3 header len including IP options 3. L4 header len (new field) including TCP options 4. tso_segsz (new field) the size of TCP segment The apllication has obligation to compute the pseudo header checksum instead of full TCP checksum and put it in the TCP header csum field. Handling complexity of creation combined l2_l3_len field a new macro RTE_MBUF_TO_L2_L3_LEN() is defined to retrieve this part of rte_mbuf. Signed-off-by: Mirek Walukiewicz --- app/test-pmd/testpmd.c | 3 ++- lib/librte_mbuf/rte_mbuf.h | 27 +++++++++++++++++++++------ lib/librte_pmd_e1000/igb_rxtx.c | 2 +- lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index f76406f..d8fd025 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -408,7 +408,8 @@ testpmd_mbuf_ctor(struct rte_mempool *mp, mb->ol_flags = 0; mb->data_off = RTE_PKTMBUF_HEADROOM; mb->nb_segs = 1; - mb->l2_l3_len = 0; + mb->l2_len = 0; + mb->l3_len = 0; mb->vlan_tci = 0; mb->hash.rss = 0; } diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index ddadc21..2e2e315 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -114,6 +114,9 @@ extern "C" { /* Bit 51 - IEEE1588*/ #define PKT_TX_IEEE1588_TMST (1ULL << 51) /**< TX IEEE1588 packet to timestamp. */ +/* Bit 49 - TCP transmit segmenation offload */ +#define PKT_TX_TCP_SEG (1ULL << 49) /**< TX TSO offload */ + /* Use final bit of flags to indicate a control mbuf */ #define CTRL_MBUF_FLAG (1ULL << 63) /**< Mbuf contains control data */ @@ -189,16 +192,28 @@ struct rte_mbuf { struct rte_mbuf *next; /**< Next segment of scattered packet. */ /* fields to support TX offloads */ - union { - uint16_t l2_l3_len; /**< combined l2/l3 lengths as single var */ + /* two bytes - l2 len (including MAC/VLANs/SNAP if present) + * two bytes - l3 len (including IP options) + * two bytes - l4 len TCP/UDP header len - including TCP options + * two bytes - TCP tso segment size + */ + union{ + uint64_t l2_l3_l4_tso_seg; /**< combined for easy fetch */ struct { - uint16_t l3_len:9; /**< L3 (IP) Header Length. */ - uint16_t l2_len:7; /**< L2 (MAC) Header Length. */ + uint16_t l3_len; /**< L3 (IP) Header */ + uint16_t l2_len; /**< L2 (MAC) Header */ + uint16_t l4_len; /**< TCP/UDP header len */ + uint16_t tso_segsz; /**< TCP TSO segment size */ }; }; } __rte_cache_aligned; /** + * Given the rte_mbuf returns the l2_l3_len combined + */ +#define RTE_MBUF_TO_L2_L3_LEN(mb) (uint32_t)(((mb)->l2_len << 16) | (mb)->l3_len) + +/** * Given the buf_addr returns the pointer to corresponding mbuf. */ #define RTE_MBUF_FROM_BADDR(ba) (((struct rte_mbuf *)(ba)) - 1) @@ -545,7 +560,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m) { m->next = NULL; m->pkt_len = 0; - m->l2_l3_len = 0; + m->l2_l3_l4_tso_seg = 0; m->vlan_tci = 0; m->nb_segs = 1; m->port = 0xff; @@ -613,7 +628,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) mi->data_len = md->data_len; mi->port = md->port; mi->vlan_tci = md->vlan_tci; - mi->l2_l3_len = md->l2_l3_len; + mi->l2_l3_l4_tso_seg = md->l2_l3_l4_tso_seg; mi->hash = md->hash; mi->next = NULL; diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c index f09c525..0f3248e 100644 --- a/lib/librte_pmd_e1000/igb_rxtx.c +++ b/lib/librte_pmd_e1000/igb_rxtx.c @@ -399,7 +399,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, ol_flags = tx_pkt->ol_flags; vlan_macip_lens.f.vlan_tci = tx_pkt->vlan_tci; - vlan_macip_lens.f.l2_l3_len = tx_pkt->l2_l3_len; + vlan_macip_lens.f.l2_l3_len = RTE_MBUF_TO_L2_L3_LEN(tx_pkt); tx_ol_req = ol_flags & PKT_TX_OFFLOAD_MASK; /* If a Context Descriptor need be built . */ diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c index 123b8b3..5e92224 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c @@ -583,7 +583,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, tx_ol_req = ol_flags & PKT_TX_OFFLOAD_MASK; if (tx_ol_req) { vlan_macip_lens.f.vlan_tci = tx_pkt->vlan_tci; - vlan_macip_lens.f.l2_l3_len = tx_pkt->l2_l3_len; + vlan_macip_lens.f.l2_l3_len = RTE_MBUF_TO_L2_L3_LEN(tx_pkt); /* If new context need be built or reuse the exist ctx. */ ctx = what_advctx_update(txq, tx_ol_req,