{"id":809042,"url":"http://patchwork.ozlabs.org/api/1.2/patches/809042/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/patch/20170902050234.17169-1-sysugaozhenyu@gmail.com/","project":{"id":47,"url":"http://patchwork.ozlabs.org/api/1.2/projects/47/?format=json","name":"Open vSwitch","link_name":"openvswitch","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"git@github.com:openvswitch/ovs.git","webscm_url":"https://github.com/openvswitch/ovs","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170902050234.17169-1-sysugaozhenyu@gmail.com>","list_archive_url":null,"date":"2017-09-02T05:02:34","name":"[ovs-dev,v4] netdev-dpdk: Implement TCP/UDP TX cksum in ovs-dpdk side","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":false,"hash":"a83a90af7582163424e0e49e182afbdfa7221e5b","submitter":{"id":70513,"url":"http://patchwork.ozlabs.org/api/1.2/people/70513/?format=json","name":"Gao Zhenyu","email":"sysugaozhenyu@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/openvswitch/patch/20170902050234.17169-1-sysugaozhenyu@gmail.com/mbox/","series":[{"id":1138,"url":"http://patchwork.ozlabs.org/api/1.2/series/1138/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/list/?series=1138","date":"2017-09-02T05:02:34","name":"[ovs-dev,v4] netdev-dpdk: Implement TCP/UDP TX cksum in ovs-dpdk side","version":4,"mbox":"http://patchwork.ozlabs.org/series/1138/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/809042/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/809042/checks/","tags":{},"related":[],"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","ovs-dev@mail.linuxfoundation.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=openvswitch.org\n\t(client-ip=140.211.169.12; helo=mail.linuxfoundation.org;\n\tenvelope-from=ovs-dev-bounces@openvswitch.org;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"a8n98L1O\"; dkim-atps=neutral"],"Received":["from mail.linuxfoundation.org (mail.linuxfoundation.org\n\t[140.211.169.12])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkkWb049Gz9s4q\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 15:02:49 +1000 (AEST)","from mail.linux-foundation.org (localhost [127.0.0.1])\n\tby mail.linuxfoundation.org (Postfix) with ESMTP id A4734E08;\n\tSat,  2 Sep 2017 05:02:46 +0000 (UTC)","from smtp1.linuxfoundation.org (smtp1.linux-foundation.org\n\t[172.17.192.35])\n\tby mail.linuxfoundation.org (Postfix) with ESMTPS id 2F306DE3\n\tfor <dev@openvswitch.org>; Sat,  2 Sep 2017 05:02:45 +0000 (UTC)","from mail-pg0-f67.google.com (mail-pg0-f67.google.com\n\t[74.125.83.67])\n\tby smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6D33F79\n\tfor <dev@openvswitch.org>; Sat,  2 Sep 2017 05:02:44 +0000 (UTC)","by mail-pg0-f67.google.com with SMTP id 63so1265761pgc.1\n\tfor <dev@openvswitch.org>; Fri, 01 Sep 2017 22:02:44 -0700 (PDT)","from vultr.guest ([45.77.33.88]) by smtp.gmail.com with ESMTPSA id\n\ta21sm2236028pfj.89.2017.09.01.22.02.41\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tFri, 01 Sep 2017 22:02:42 -0700 (PDT)"],"X-Greylist":"whitelisted by SQLgrey-1.7.6","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id;\n\tbh=PFMchPNUIbpEcPM2GhJqiYAb9QQVje0rALTn2v9Emd0=;\n\tb=a8n98L1OqVOgwIk+QFby/aEfrKrv007sB3S2ufguaIG6KdcPPaegIQr31QnQMXd9cD\n\tLvLm2hrhCX0Dm2oTtk20T1OMA/EQbwmSF5hNL+c/j3wDtoqtPO0gerb6ndptVerHRlgn\n\tL2MX3KU72tV/Cl7dXb01CyJWuvGh5eMCd9zGACelzYUs1nfOaiYPQgv/ai8+BGMS3VIY\n\tdNCrPLAkpNJ82mAaDBRbfOtllxCu6fvwqABIsJofC6xDPLlGCSkWOoBjbkJ2GaGMVeLp\n\t+DpHQ3j5p4JqP7yzEJiLZ+DqHyP/AchPP+gyzJoqO10LHCu0Oq9eG3iz2SzVA/AovxZY\n\tNW/g==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id;\n\tbh=PFMchPNUIbpEcPM2GhJqiYAb9QQVje0rALTn2v9Emd0=;\n\tb=p5NRtZ3eOpRGqF6uNqLsWtkMpOUXF1iufWlmU4qJcIIzYTKBCeiecPpo0tBv8ym+zX\n\tFfUWI8bJB+swy04JPeZooMjUzkPD8z/IjGeyncVZp5Ka0oeHA+q2N6JvHQe80MiuqjHS\n\tAMKi7pK47TDowFGRmpQ90zLHJV1BzJndqBe0embCxh0b1gMb1g1YXrxhHYNFvxpbIdIO\n\tpmHO11vOfUOWB+Eslfcl4JDtd7fACQar2gkmSNI/JqdrEKk4CQITMnNg1r1HYGFeKu9Y\n\tXNnXB4iOLeW0uK8bJGQS+eHlyQ+kTyOgouFwCkHc15jvHVNjnOEs9ZrjCi+bkOEtJ2nC\n\tyrCA==","X-Gm-Message-State":"AHPjjUgEy10jtBaGivCfRP5Tmw58mvCcZXsbUba61j9bGQR5MN9Lxhfp\n\tErKr/P2FZt5m6g==","X-Google-Smtp-Source":"ADKCNb7onmEMcIBVbgiMeabWWCV55kP5dZ4iyx4UCqzMor11W2NdesKgh2Ppdcb8htz0elb/cmJ52w==","X-Received":"by 10.98.215.80 with SMTP id v16mr4704772pfl.342.1504328563909; \n\tFri, 01 Sep 2017 22:02:43 -0700 (PDT)","From":"Zhenyu Gao <sysugaozhenyu@gmail.com>","To":"ciara.loftus@intel.com, sugesh.chandran@intel.com, dev@openvswitch.org","Date":"Sat,  2 Sep 2017 05:02:34 +0000","Message-Id":"<20170902050234.17169-1-sysugaozhenyu@gmail.com>","X-Mailer":"git-send-email 2.11.0","X-Spam-Status":"No, score=0.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,\n\tDKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM\n\tautolearn=disabled version=3.3.1","X-Spam-Checker-Version":"SpamAssassin 3.3.1 (2010-03-16) on\n\tsmtp1.linux-foundation.org","Subject":"[ovs-dev] [PATCH v4] netdev-dpdk: Implement TCP/UDP TX cksum in\n\tovs-dpdk side","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.12","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"ovs-dev-bounces@openvswitch.org","Errors-To":"ovs-dev-bounces@openvswitch.org"},"content":"Currently, the dpdk-vhost side in ovs doesn't support tcp/udp tx cksum.\nSo L4 packets's cksum were calculated in VM side but performance is not\ngood.\nImplementing tcp/udp tx cksum in ovs-dpdk side improves throughput in\nVM->phy->phy->VM situation. And it makes virtio-net frontend-driver\nsupport NETIF_F_SG(feature scatter-gather) as well.\n\nSigned-off-by: Zhenyu Gao <sysugaozhenyu@gmail.com>\n---\n\nHere is some performance number:\n\nSetup:\n\n qperf client\n+---------+\n|   VM    |\n+---------+\n     |\n     |                          qperf server\n+--------------+              +------------+\n| vswitch+dpdk |              | bare-metal |\n+--------------+              +------------+\n       |                            |\n       |                            |\n      pNic---------PhysicalSwitch----\n\ndo cksum in ovs-dpdk: Applied this patch and execute 'ethtool -K eth0 tx on' in VM side.\n                      It offload cksum job to ovs-dpdk side.\n\ndo cksum in VM: Applied this patch and execute 'ethtool -K eth0 tx off' in VM side.\n                VM calculate cksum for tcp/udp packets.\n\nWe can see huge improvment in TCP throughput if we leverage ovs-dpdk cksum.\n\n[root@localhost ~]# qperf -t 10 -oo msg_size:1:64K:*2  host-qperf-server01 tcp_bw tcp_lat udp_bw udp_lat\n  do cksum in ovs-dpdk          do cksum in VM             without this patch\ntcp_bw:        \n    bw  =  1.9 MB/sec         bw  =  1.92 MB/sec        bw  =  1.95 MB/sec\ntcp_bw:        \n    bw  =  3.97 MB/sec        bw  =  3.99 MB/sec        bw  =  3.98 MB/sec\ntcp_bw:        \n    bw  =  7.75 MB/sec        bw  =  7.79 MB/sec        bw  =  7.89 MB/sec\ntcp_bw:        \n    bw  =  14.7 MB/sec        bw  =  14.7 MB/sec        bw  =  14.9 MB/sec\ntcp_bw:        \n    bw  =  27.7 MB/sec        bw  =  27.4 MB/sec        bw  =  28 MB/sec\ntcp_bw:        \n    bw  =  51.1 MB/sec        bw  =  51.3 MB/sec        bw  =  51.8 MB/sec\ntcp_bw:        \n    bw  =  86.2 MB/sec        bw  =  84.4 MB/sec        bw  =  87.6 MB/sec\ntcp_bw:        \n    bw  =  141 MB/sec         bw  =  142 MB/sec        bw  =  141 MB/sec\ntcp_bw:        \n    bw  =  203 MB/sec         bw  =  201 MB/sec        bw  =  211 MB/sec\ntcp_bw:        \n    bw  =  267 MB/sec         bw  =  250 MB/sec        bw  =  260 MB/sec\ntcp_bw:        \n    bw  =  324 MB/sec         bw  =  295 MB/sec        bw  =  302 MB/sec\ntcp_bw:        \n    bw  =  397 MB/sec         bw  =  363 MB/sec        bw  =  347 MB/sec\ntcp_bw:        \n    bw  =  765 MB/sec         bw  =  510 MB/sec        bw  =  383 MB/sec\ntcp_bw:        \n    bw  =  850 MB/sec         bw  =  710 MB/sec        bw  =  417 MB/sec\ntcp_bw:        \n    bw  =  1.09 GB/sec        bw  =  860 MB/sec        bw  =  444 MB/sec\ntcp_bw:        \n    bw  =  1.17 GB/sec        bw  =  979 MB/sec        bw  =  447 MB/sec\ntcp_bw:        \n    bw  =  1.17 GB/sec        bw  =  1.07 GB/sec       bw  =  462 MB/sec\ntcp_lat:        \n    latency  =  29.1 us       latency  =  28.7 us        latency  =  29.1 us\ntcp_lat:        \n    latency  =  29 us         latency  =  28.8 us        latency  =  29 us\ntcp_lat:        \n    latency  =  29 us         latency  =  28.8 us        latency  =  29 us\ntcp_lat:        \n    latency  =  29 us         latency  =  28.9 us        latency  =  29 us\ntcp_lat:        \n    latency  =  29.2 us       latency  =  28.9 us        latency  =  29.1 us\ntcp_lat:        \n    latency  =  29.1 us       latency  =  29.1 us        latency  =  29.1 us\ntcp_lat:        \n    latency  =  29.5 us       latency  =  29.5 us        latency  =  29.5 us\ntcp_lat:        \n    latency  =  29.8 us       latency  =  29.8 us        latency  =  29.9 us\ntcp_lat:        \n    latency  =  30.7 us       latency  =  30.7 us        latency  =  30.7 us\ntcp_lat:        \n    latency  =  47.1 us       latency  =  46.2 us        latency  =  47.1 us\ntcp_lat:        \n    latency  =  52.1 us       latency  =  52.3 us        latency  =  53.3 us\ntcp_lat:        \n    latency  =  44 us         latency  =  43.8 us        latency  =  43.2 us\ntcp_lat:        \n    latency  =  50 us         latency  =  46.6 us        latency  =  47.8 us\ntcp_lat:        \n     latency  =  79.2 us      latency  =  77.9 us        latency  =  78.9 us\ntcp_lat:        \n    latency  =  82.3 us       latency  =  81.7 us        latency  =  82.2 us\ntcp_lat:        \n    latency  =  96.7 us       latency  =  90.8 us        latency  =  127 us\ntcp_lat:        \n    latency  =  215 us        latency  =  177 us        latency  =  225 us\nudp_bw:        \n    send_bw  =  422 KB/sec        send_bw  =  415 KB/sec        send_bw  =  405 KB/sec\n    recv_bw  =  402 KB/sec        recv_bw  =  404 KB/sec        recv_bw  =  403 KB/sec\nudp_bw:        \n    send_bw  =  845 KB/sec        send_bw  =  835 KB/sec        send_bw  =  802 KB/sec\n    recv_bw  =  831 KB/sec        recv_bw  =  804 KB/sec        recv_bw  =  802 KB/sec\nudp_bw:        \n    send_bw  =  1.69 MB/sec       send_bw  =  1.66 MB/sec        send_bw  =  1.62 MB/sec\n    recv_bw  =  1.45 MB/sec       recv_bw  =  1.63 MB/sec        recv_bw  =   1.6 MB/sec\nudp_bw:        \n    send_bw  =  3.38 MB/sec       send_bw  =  3.33 MB/sec        send_bw  =  3.24 MB/sec\n    recv_bw  =  3.32 MB/sec       recv_bw  =  3.25 MB/sec        recv_bw  =  3.24 MB/sec\nudp_bw:        \n    send_bw  =  6.76 MB/sec       send_bw  =  6.63 MB/sec        send_bw  =  6.47 MB/sec\n    recv_bw  =  6.42 MB/sec       recv_bw  =  5.59 MB/sec        recv_bw  =  6.45 MB/sec\nudp_bw:        \n    send_bw  =  13.5 MB/sec       send_bw  =  13.3 MB/sec        send_bw  =  13 MB/sec\n    recv_bw  =  13.4 MB/sec       recv_bw  =  12.1 MB/sec        recv_bw  =  13 MB/sec\nudp_bw:        \n    send_bw  =    27 MB/sec       send_bw  =  26.5 MB/sec        send_bw  =  25.9 MB/sec\n    recv_bw  =  26.4 MB/sec       recv_bw  =  21.5 MB/sec        recv_bw  =  25.9 MB/sec\nudp_bw:        \n    send_bw  =  53.8 MB/sec       send_bw  =  52.9 MB/sec        send_bw  =  51.7 MB/sec\n    recv_bw  =  49.1 MB/sec       recv_bw  =  47.6 MB/sec        recv_bw  =  51.1 MB/sec\nudp_bw:        \n    send_bw  =   108 MB/sec       send_bw  =  105 MB/sec         send_bw  =  102 MB/sec\n    recv_bw  =  91.1 MB/sec       recv_bw  =  101 MB/sec         recv_bw  =  100 MB/sec\nudp_bw:        \n    send_bw  =  212 MB/sec        send_bw  =  208 MB/sec         send_bw  =  203 MB/sec\n    recv_bw  =  204 MB/sec        recv_bw  =  204 MB/sec         recv_bw  =  169 MB/sec\nudp_bw:        \n    send_bw  =  414 MB/sec        send_bw  =  407 MB/sec         send_bw  =  398 MB/sec\n    recv_bw  =  403 MB/sec        recv_bw  =  312 MB/sec         recv_bw  =  343 MB/sec\nudp_bw:        \n    send_bw  =  555 MB/sec        send_bw  =  561 MB/sec         send_bw  =  557 MB/sec\n    recv_bw  =  354 MB/sec        recv_bw  =  368 MB/sec         recv_bw  =  360 MB/sec\nudp_bw:        \n    send_bw  =  877 MB/sec        send_bw  =  880 MB/sec         send_bw  =  868 MB/sec\n    recv_bw  =  551 MB/sec        recv_bw  =  542 MB/sec         recv_bw  =  562 MB/sec\nudp_bw:        \n    send_bw  =  1.1 GB/sec        send_bw  =  1.08 GB/sec        send_bw  =  1.09 GB/sec\n    recv_bw  =  805 MB/sec        recv_bw  =   785 MB/sec        recv_bw  =   766 MB/sec\nudp_bw:        \n    send_bw  =  1.21 GB/sec       send_bw  =  1.19 GB/sec        send_bw  =  1.22 GB/sec\n    recv_bw  =   899 MB/sec       recv_bw  =   715 MB/sec        recv_bw  =   700 MB/sec\nudp_bw:        \n    send_bw  =  1.31 GB/sec       send_bw  =  1.31 GB/sec        send_bw  =  1.31 GB/sec\n    recv_bw  =   614 MB/sec       recv_bw  =   622 MB/sec        recv_bw  =   661 MB/sec\nudp_bw:        \n    send_bw  =  0 bytes/sec       send_bw  =  0 bytes/sec        send_bw  =  0 bytes/sec\n    recv_bw  =  0 bytes/sec       recv_bw  =  0 bytes/sec        recv_bw  =  0 bytes/sec\nudp_lat:        \n    latency  =  25.9 us        latency  =  26.5 us        latency  =  26.5 us\nudp_lat:        \n    latency  =  26.3 us        latency  =  26.4 us        latency  =  26.5 us\nudp_lat:        \n    latency  =  26 us          latency  =  26.4 us        latency  =  26.6 us\nudp_lat:        \n    latency  =  26.1 us        latency  =  26.2 us        latency  =  26.4 us\nudp_lat:        \n    latency  =  26.3 us        latency  =  26.5 us        latency  =  26.7 us\nudp_lat:        \n    latency  =  26.3 us        latency  =  26.4 us        latency  =  26.5 us\nudp_lat:        \n    latency  =  26.3 us        latency  =  26.7 us        latency  =  26.9 us\nudp_lat:        \n    latency  =  27.1 us        latency  =  27.1 us        latency  =  27.2 us\nudp_lat:        \n    latency  =  27.5 us        latency  =  27.8 us        latency  =  28.1 us\nudp_lat:        \n    latency  =  28.7 us        latency  =  28.9 us        latency  =  29.1 us\nudp_lat:        \n    latency  =  30.4 us        latency  =  30.5 us        latency  =  30.9 us\nudp_lat:        \n    latency  =  41.2 us        latency  =  41.3 us        latency  =  41.1 us\nudp_lat:        \n    latency  =  41.3 us        latency  =  41.5 us        latency  =  41.5 us\nudp_lat:        \n    latency  =  64.4 us        latency  =  64.5 us        latency  =  64.2 us\nudp_lat:        \n    latency  =  71.5 us        latency  =  71.5 us        latency  =  71.7 us\nudp_lat:        \n    latency  =  120 us         latency  =  120 us         latency  =  120 us\nudp_lat:        \n    latency  =  0 ns           latency  =  0 ns           latency  =  0 ns\n\n lib/netdev-dpdk.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++---\n 1 file changed, 75 insertions(+), 4 deletions(-)","diff":"diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c\nindex f58e9be..0f91def 100644\n--- a/lib/netdev-dpdk.c\n+++ b/lib/netdev-dpdk.c\n@@ -31,6 +31,7 @@\n #include <rte_errno.h>\n #include <rte_eth_ring.h>\n #include <rte_ethdev.h>\n+#include <rte_ip.h>\n #include <rte_malloc.h>\n #include <rte_mbuf.h>\n #include <rte_meter.h>\n@@ -992,8 +993,7 @@ netdev_dpdk_vhost_construct(struct netdev *netdev)\n \n     err = rte_vhost_driver_disable_features(dev->vhost_id,\n                                 1ULL << VIRTIO_NET_F_HOST_TSO4\n-                                | 1ULL << VIRTIO_NET_F_HOST_TSO6\n-                                | 1ULL << VIRTIO_NET_F_CSUM);\n+                                | 1ULL << VIRTIO_NET_F_HOST_TSO6);\n     if (err) {\n         VLOG_ERR(\"rte_vhost_driver_disable_features failed for vhost user \"\n                  \"port: %s\\n\", name);\n@@ -1455,6 +1455,76 @@ netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq)\n     rte_free(rx);\n }\n \n+static inline void\n+netdev_dpdk_vhost_refill_l4_cksum(const char *data, struct dp_packet *pkt,\n+                                  uint8_t l4_proto, bool is_ipv4)\n+{\n+    void *l3hdr = (void *)(data + pkt->mbuf.l2_len);\n+\n+    if (l4_proto == IPPROTO_TCP) {\n+        struct tcp_header *tcp_hdr = (struct tcp_header *)(data +\n+                                         pkt->mbuf.l2_len + pkt->mbuf.l3_len);\n+\n+        tcp_hdr->tcp_csum = 0;\n+        if (is_ipv4) {\n+            tcp_hdr->tcp_csum = rte_ipv4_udptcp_cksum(l3hdr, tcp_hdr);\n+        } else {\n+            tcp_hdr->tcp_csum = rte_ipv6_udptcp_cksum(l3hdr, tcp_hdr);\n+        }\n+    } else if (l4_proto == IPPROTO_UDP) {\n+        struct udp_header *udp_hdr = (struct udp_header *)(data +\n+                                         pkt->mbuf.l2_len + pkt->mbuf.l3_len);\n+        /* do not recalculate udp cksum if it was 0 */\n+        if (udp_hdr->udp_csum != 0) {\n+            udp_hdr->udp_csum = 0;\n+            if (is_ipv4) {\n+                /*do not calculate udp cksum if it was a fragment IP*/\n+                if (IP_IS_FRAGMENT(((struct ipv4_hdr *)l3hdr)->\n+                                      fragment_offset)) {\n+                    return;\n+                }\n+\n+                udp_hdr->udp_csum = rte_ipv4_udptcp_cksum(l3hdr, udp_hdr);\n+            } else {\n+                udp_hdr->udp_csum = rte_ipv6_udptcp_cksum(l3hdr, udp_hdr);\n+            }\n+        }\n+    }\n+\n+    pkt->mbuf.ol_flags &= ~PKT_TX_L4_MASK;\n+}\n+\n+static inline void\n+netdev_dpdk_vhost_tx_csum(struct dp_packet **pkts, int pkt_cnt)\n+{\n+    int i;\n+\n+    for (i = 0; i < pkt_cnt; i++) {\n+        ovs_be16 dl_type;\n+        struct dp_packet *pkt = (struct dp_packet *)pkts[i];\n+        const char *data = dp_packet_data(pkt);\n+        void *l3hdr = (char *)(data + pkt->mbuf.l2_len);\n+\n+        if (!(pkt->mbuf.ol_flags & PKT_TX_L4_MASK)) {\n+            /* DPDK vhost tags PKT_TX_L4_MASK if a L4 packet need cksum. */\n+            continue;\n+        }\n+\n+        if (OVS_UNLIKELY(pkt->mbuf.l2_len == 0 || pkt->mbuf.l3_len == 0)) {\n+            continue;\n+        }\n+\n+        dl_type = *(ovs_be16 *)(data + pkt->mbuf.l2_len - sizeof dl_type);\n+        if (dl_type == htons(ETH_TYPE_IP)) {\n+            uint8_t l4_proto = ((struct ipv4_hdr *)l3hdr)->next_proto_id;\n+            netdev_dpdk_vhost_refill_l4_cksum(data, pkt, l4_proto, true);\n+        } else if (dl_type == htons(ETH_TYPE_IPV6)) {\n+            uint8_t l4_proto = ((struct ipv6_hdr *)l3hdr)->proto;\n+            netdev_dpdk_vhost_refill_l4_cksum(data, pkt, l4_proto, false);\n+        }\n+    }\n+}\n+\n /* Tries to transmit 'pkts' to txq 'qid' of device 'dev'.  Takes ownership of\n  * 'pkts', even in case of failure.\n  *\n@@ -1646,6 +1716,8 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,\n \n     dp_packet_batch_init_cutlen(batch);\n     batch->count = (int) nb_rx;\n+    netdev_dpdk_vhost_tx_csum(batch->packets, batch->count);\n+\n     return 0;\n }\n \n@@ -3288,8 +3360,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)\n \n         err = rte_vhost_driver_disable_features(dev->vhost_id,\n                                     1ULL << VIRTIO_NET_F_HOST_TSO4\n-                                    | 1ULL << VIRTIO_NET_F_HOST_TSO6\n-                                    | 1ULL << VIRTIO_NET_F_CSUM);\n+                                    | 1ULL << VIRTIO_NET_F_HOST_TSO6);\n         if (err) {\n             VLOG_ERR(\"rte_vhost_driver_disable_features failed for vhost user \"\n                      \"client port: %s\\n\", dev->up.name);\n","prefixes":["ovs-dev","v4"]}