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 0C460378B for ; Fri, 25 Mar 2016 06:59:02 +0100 (CET) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 24 Mar 2016 22:59:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,388,1455004800"; d="scan'208";a="675375626" Received: from yliu-dev.sh.intel.com ([10.239.66.49]) by FMSMGA003.fm.intel.com with ESMTP; 24 Mar 2016 22:59:00 -0700 From: Yuanhan Liu To: dev@dpdk.org Cc: huawei.xie@intel.com, Thomas Monjalon , Ksiadz MarcinX , Yuanhan Liu Date: Fri, 25 Mar 2016 14:01:32 +0800 Message-Id: <1458885694-31111-3-git-send-email-yuanhan.liu@linux.intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1458885694-31111-1-git-send-email-yuanhan.liu@linux.intel.com> References: <1458885694-31111-1-git-send-email-yuanhan.liu@linux.intel.com> Subject: [dpdk-dev] [PATCH 2/4] vhost: complete TSO settings 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: Fri, 25 Mar 2016 05:59:04 -0000 Commit d0cf91303d73 ("vhost: add Tx offload capabilities") has only done partial settings for enabling TSO, and left the following part to the application, say vhost-switch example, by commit 9fd72e3cbd29 ("examples/vhost: add virtio offload"). - Setting PKT_TX_IP_CKSUM and ipv4_hdr->hdr_checksum = 0 for IPv4. - calculate the pseudo header checksum without taking ip_len in account, and set it in the TCP header Here we complete the left part in vhost side, so that an user (such as OVS) can do minimal (or even no) changes to get TSO enabled. Signed-off-by: Yuanhan Liu --- lib/librte_vhost/vhost_rxtx.c | 47 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c index 7d1224c..a204703 100644 --- a/lib/librte_vhost/vhost_rxtx.c +++ b/lib/librte_vhost/vhost_rxtx.c @@ -602,11 +602,11 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t queue_id, } static void -parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) +parse_ethernet(struct rte_mbuf *m, void **l3_hdr, + void **l4_hdr, uint16_t *l4_proto) { struct ipv4_hdr *ipv4_hdr; struct ipv6_hdr *ipv6_hdr; - void *l3_hdr = NULL; struct ether_hdr *eth_hdr; uint16_t ethertype; @@ -622,21 +622,19 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto); } - l3_hdr = (char *)eth_hdr + m->l2_len; + *l3_hdr = (char *)eth_hdr + m->l2_len; switch (ethertype) { case ETHER_TYPE_IPv4: - ipv4_hdr = (struct ipv4_hdr *)l3_hdr; + ipv4_hdr = *l3_hdr; *l4_proto = ipv4_hdr->next_proto_id; m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4; - *l4_hdr = (char *)l3_hdr + m->l3_len; m->ol_flags |= PKT_TX_IPV4; break; case ETHER_TYPE_IPv6: - ipv6_hdr = (struct ipv6_hdr *)l3_hdr; + ipv6_hdr = *l3_hdr; *l4_proto = ipv6_hdr->proto; m->l3_len = sizeof(struct ipv6_hdr); - *l4_hdr = (char *)l3_hdr + m->l3_len; m->ol_flags |= PKT_TX_IPV6; break; default: @@ -644,16 +642,28 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) *l4_proto = 0; break; } + + *l4_hdr = (char *)*l3_hdr + m->l3_len; +} + +static uint16_t +get_psd_sum(void *l3_hdr, uint64_t ol_flags) +{ + if (ol_flags & PKT_TX_IPV4) + return rte_ipv4_phdr_cksum(l3_hdr, ol_flags); + else + return rte_ipv6_phdr_cksum(l3_hdr, ol_flags); } static inline void __attribute__((always_inline)) vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m) { - uint16_t l4_proto = 0; - void *l4_hdr = NULL; - struct tcp_hdr *tcp_hdr = NULL; + void *l3_hdr; + void *l4_hdr; + uint16_t l4_proto; + + parse_ethernet(m, &l3_hdr, &l4_hdr, &l4_proto); - parse_ethernet(m, &l4_proto, &l4_hdr); if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) { if (hdr->csum_start == (m->l2_len + m->l3_len)) { switch (hdr->csum_offset) { @@ -676,13 +686,26 @@ vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m) } if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + struct ipv4_hdr *ipv4_hdr = l3_hdr; + struct tcp_hdr *tcp_hdr = l4_hdr; + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { case VIRTIO_NET_HDR_GSO_TCPV4: + /* + * According to comments for PKT_TX_TCP_SEG + * at rte_mbuf.h, we need following settings + * for IPv4. + */ + m->ol_flags |= PKT_TX_IP_CKSUM; + ipv4_hdr->hdr_checksum = 0; + + /* Fall through */ case VIRTIO_NET_HDR_GSO_TCPV6: - tcp_hdr = (struct tcp_hdr *)l4_hdr; m->ol_flags |= PKT_TX_TCP_SEG; m->tso_segsz = hdr->gso_size; m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; + + tcp_hdr->cksum = get_psd_sum(l3_hdr, m->ol_flags); break; default: RTE_LOG(WARNING, VHOST_DATA, -- 1.9.0