From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01hn0239.outbound.protection.outlook.com [104.47.1.239]) by dpdk.org (Postfix) with ESMTP id 1C0172C72 for ; Mon, 7 May 2018 23:54:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=ReBXeruYcWs8Z4OdObOk8bwRDN/Pk/0KSfcOn4X4Dvk=; b=gJqGa7c5LzHwH1MM9tpTLU963klXy3gqON02KyQynxReC3qM7jEYSZu0mUfaIZ7vK0qGGrF/5A+S0WrOjX8H2iMYagBwyqvTNmyU0DUhBidafmwnfDoVGfsDfSHu7UzGrFxFRMMV3hrQF15vrosqsO3PdPdeK87i3H741hLU6co= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=ophirmu@mellanox.com; Received: from mellanox.com (37.142.13.130) by VI1PR0501MB2320.eurprd05.prod.outlook.com (2603:10a6:800:2c::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.735.18; Mon, 7 May 2018 21:54:36 +0000 From: Ophir Munk To: dev@dpdk.org, Pascal Mazon Cc: Thomas Monjalon , Olga Shern , Ophir Munk Date: Mon, 7 May 2018 21:54:23 +0000 Message-Id: <1525730063-28366-3-git-send-email-ophirmu@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1525730063-28366-1-git-send-email-ophirmu@mellanox.com> References: <1524396611-22391-2-git-send-email-ophirmu@mellanox.com> <1525730063-28366-1-git-send-email-ophirmu@mellanox.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [37.142.13.130] X-ClientProxiedBy: VI1P194CA0041.EURP194.PROD.OUTLOOK.COM (2603:10a6:803:3c::30) To VI1PR0501MB2320.eurprd05.prod.outlook.com (2603:10a6:800:2c::21) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(48565401081)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0501MB2320; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2320; 3:WhhcVDyDt9L/7xjfu/5GcNSjCkUhrxMchAI/iH/nbeYQkehdQzTm2F/RyGa0ZFimQPpHXOyYnnxWY1gaPqSeu3AJc8WljSIuK/lXwaSzkEYskt6ehUy7xOxftKHSGBU28UCQsax/Ji6rCnQpUsFQMfgPBqYsiacGy0rgLCnY1eMqmVpxwZFyfkHtyrRp5H9X+ebO3J65BGImnGw22ozmewip9CdWHJx6cUx4VV4Snp3/3Rfjipk+UqW56E7wQiFj; 25:mXoFDmRYjZfDrKYDOAChjA9jsCuqYw26nzINo+uadtNCplF1uE3S0G5/HHbDCk2XE0AzNeQeZnaCDZDmVVeAOI01MJbZ2lTJxo8OzwbiuFa+bXu7St1l/g5FaaIk2pajPhfxOEaq4UiLKTo9vgHysHuAeOOPJ6l4rWhM5PubTtrF0sDaqR1qqShre+Ea3pZdDmGlx+62aQZMdG2aWOv1YkxWGjLJ7VJIpLZeuimNCl1XZHVUcx1oQ9IHEtVTnvxRgGBkNokjd/r438VBmYOyw2uKOcFkwgN4Dc9xIGbiJj3t1Uy4kSpqr1FOBoJeYGUFYRT/kaZxgPa+EiNm0biPLg==; 31:8Q6DkWDjKSFx04zMv1NYZ9Wj9nZbRr9X629aWceBSZnt3wXqFwG9Ly4AvGAeCRNjyJ2ANHG5/jNdo2ca3qDBmWOJ2jZyvOw3CZtMgMF886IrpxUKltBgGp9XXmeYXWxrVW0rpUJsKKFSM8yBBo0GB5pzBy+a11Drot7t8+AdI9cYKyn4MNAkmrzCoDSSJHQwxkq/dnO9uSDVhq6MDlxOTIzB/UrFRPxZ8OKDJXtyDV4= X-MS-TrafficTypeDiagnostic: VI1PR0501MB2320:|VI1PR0501MB2320: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2320; 20:nwt8eXZdBeXTE6RqsWt5UZn+g5CaKWVK3B9puSuKU2hslfhQ7QpZz8EQWbpZJCJencNSs3RNyEnPOCDLPjvjzzcZQgGUKtFeAKj6gqXjyAM6iK+YNC17U32FqLNheVRLowvdmdqUVMTK0MlHt/rSNzhN6roR6VWkS4pFeMUw7DTzLHLt1RYJ62K07M6opgHkG0qX+5i5DMm7zC2/SFy5kX/jxfxa1xvyt+5UhuLs6Y78jOY7bT3TFSvtvbPqxPgyUVlksx/rw5oFZtieAmgSkuQ6xbo4LGpxG2j6gTVQOtKvRqmb4v7K8wcL4xEvMCj7x8o3xF3RzUBAEZkbuh2SawcsnqQ6s2KS9fJ25cAaxCAqcAJQwN6VK9zasa2H5RMsn7xZx01nHm/avSN2mT2Io4xYY6bfmuEqFoOnii1rE+rE8nYVqgYfxZsb+rhO4PtuXH/8duhhx1hV+449u1FXH/ctLVX2voo9uQKhI4bgF3x37tSSRsD7jxJqcg/v6BFF; 4:cccNoIJ+0JTmtOTKDICkyBURrqg8XB6KqGvcZvg9BQfaLQebK4V5f9owVi6qUGeEsV6q2k5w6178nKM9dSxircz9BBtSQm9TfwVZTn5x9GiaglYhsnq/Or87orZ4QdjBI6rj8UiHL4vegqfAcZXBM2bEMom+YwmjZR97tJGdCWcU95wNdQIvFQ5x16jHxfv8T7+mYAvQ0O5iesyagE1MNct5PlUxiw6do2vIpZ417rqY+KgR20Rpl4Sc0kIfhxVVH33lqRqpor4D2VYeABteZKJZyOKzwRM+dEBEh9idUHkZ2LxAyDKobfWmjtbYRCyx X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(66839620246622); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3231254)(2232076)(944501410)(52105095)(93006095)(93001095)(3002001)(6055026)(149027)(150027)(6041310)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123562045)(20161123564045)(6072148)(201708071742011); SRVR:VI1PR0501MB2320; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0501MB2320; X-Forefront-PRVS: 066517B35B X-Forefront-Antispam-Report: SFV:SPM; SFS:(10009020)(39860400002)(396003)(346002)(376002)(39380400002)(366004)(199004)(189003)(4720700003)(97736004)(6916009)(81166006)(6666003)(7736002)(106356001)(8676002)(81156014)(305945005)(105586002)(5660300001)(54906003)(16586007)(21086003)(8936002)(316002)(33026002)(3846002)(478600001)(2906002)(6116002)(50226002)(48376002)(2616005)(36756003)(50466002)(51416003)(7696005)(52116002)(76176011)(4326008)(47776003)(86362001)(107886003)(59450400001)(486006)(386003)(476003)(956004)(446003)(69596002)(11346002)(66066001)(68736007)(53936002)(26005)(186003)(25786009)(55016002)(16526019)(59010400001); DIR:OUT; SFP:1501; SCL:5; SRVR:VI1PR0501MB2320; H:mellanox.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR0501MB2320; 23:o9ilNmBLgsRPF9mp6mfaGfc/vGujpfT9C+W48OI?= =?us-ascii?Q?TZmZqlJusO6irmz8AhNJxmLXFx9P1iAAuyXInTE9cpSkvkhpnLXEPoio2zAi?= =?us-ascii?Q?YqJ3nE55cRv2JVsQ51JSoCZ79ha1nKiF/Br20ZVwnQKG8nUwxiFLyXoFfNWN?= =?us-ascii?Q?NtJkO0d8rrVt8PwXQspbqfygbsmLShVlF3Frte9aa0tS5WB+Avsl4f81La4q?= =?us-ascii?Q?dTS2HeLMSpdojL1NokVFcoVEgh8XnoEvGUqRchNugeDxsb/hBW+vRvOPECBr?= =?us-ascii?Q?xtdGIZ6dHc5q3pPw/u2TQPCqkGZeY5bDNuAvgDS6ppfxSfbc2vRrWROsyz/3?= =?us-ascii?Q?eqBnJscVbtUKsIcsSr783guSHNbrKEn2myE5G1Ug2+XI7wcBKqyEwCjUO1KG?= =?us-ascii?Q?mjXJH5zwJ1zyztMboQWPozpZQhwVv+dglKgMehg4Nlytkfn4h5kRbE7gy589?= =?us-ascii?Q?vWbgGi3U2DojetSgnYpiHTMUWf4d4ekbJlSbMm5+5iEhBe8hAVfHZhAOBzjE?= =?us-ascii?Q?1oZ7OvqZ2kRli/oaOapzXDw/rbDWI9efiLAg2BBW0GCbmc4NcIsb7xSiFaPA?= =?us-ascii?Q?+FN9JpWuusQqhRse1bRyDMIbPkAihVc61+Ibv0D0apTK9CrYDQhGsgTnro/2?= =?us-ascii?Q?Pmb1ssRvMFHJh/z1riVyEFWr98Bm7/J18wkXISs0Adb3O7fjc3dhGAb8c8La?= =?us-ascii?Q?Dql0NSiv6Jh5WpUS2X7IaXSQqzk4eKeiOxf1+MT5bo7fHDVwgiJ7/OjL6wfR?= =?us-ascii?Q?Lz23mBa1BBk5YMCkopnqAMLgx6AC7DRJHu2diTt8CuB7EKtJDAnTdCZ0M2JT?= =?us-ascii?Q?f163Vchgk3xochqiHtrGilS0QA6kBLEPfeSZiRpZvwzKHAG1Ca0LEWq1GVJd?= =?us-ascii?Q?ekB+fbYF/6cXru9S+w9HAQ0xRyTePA0CThrcgrRex/y7Tvx3lvHS3WWGMwwX?= =?us-ascii?Q?0CODGo2cFUBNih4grMPFPvK89WmeheLwim/ayv5zbYErlsdvVIzIseyZUU1J?= =?us-ascii?Q?7WaRAoe11dGKKWMcw9yrMsFCEFG+0E9G2lGpEsZuU4lxlqW6ZF3itSPiwVm7?= =?us-ascii?Q?b6cpPel1OgS8aGHmpMhGCtKxpCIZjbBItVyspD6kvOhi/BuN90By9h1U69Lk?= =?us-ascii?Q?BPtmdA4IKj6M6kOy0e9ccdJpn9XY2murB09S5GjRobXQpJrXzW6lw7bK/aK0?= =?us-ascii?Q?LojczikLMUC0+e0oqct6qJvFOpI0jsm8N7nWPBuP5yadeT/K+xKjDiPkv/XV?= =?us-ascii?Q?R5mc86558SVnlm0xkID8NVjI9Ib9TfB6Kbs0fuqMk4xC15CnoQqkURk6fbrb?= =?us-ascii?Q?7vXUbjTkKvntZDOZy01+lGsYkCLiLMMlWw1KckYQYqbu+jhYu9cMJZn9L9w/?= =?us-ascii?Q?BeDl5/yyHfWb2hW9tUUPyw9gid6U=3D?= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2320; 23:47KXvgrZVPpqhtmWtecZPYbdkNnv1osOEyoNt7bO9rkpiF2kIfrYxVV/Lty70Qh/as9SFNRPjz6GOneUU7WlILMsP+v3xHbmNwTxEoN+kExqlvHAbdUliHg4QK0h22G9u9eECD2Szjw5uwV4gpmUZw==; 6:cUomxruQH6/mby3XbBLu5HxF2mpKmkiGGmTqq7i1hby34WB+t4YvC614i44OCy2bKxCpvHXHeRU5XL5F3ClSAdxInZov+8szxKnJhHkcUv6HXm/zqYVeH1Pu8tyvVrPUFHnL0xRUvZTnCo4+tpWvXHrisnAtet8QTms32jk1rhR8l774Xp1PH+85UJqZT9HsnsLpagMhcaJcK92NQUZ9xXNK+L6P9e0ApoSunq7lWkz/kmIKSM2mjSLuTtR6odDnRX32sMuMiT3ZR03KnSKzogBr1LGO+kzED5D3eAwfgNFUtAafzzAZZreCzupgGQSHBP/AdgBW0w282zMUONIWST+Tqk4DAgl2j7awpu11JQfOShZPMEXtSmNaWlD1Znds1IrE67sb6+0opm9sOPpMO9lPoTu6JBbVm/zlI84m/xRXfdjYnt77zx68vGVcx9o1KkzDIE3f3dLfhwvqmKndj52oA/YXOHr5Rbb9+bKRLb/PsMZYiCnIaUP1TTU3ujt9; 5:LUDIF6yRx8zhLUW0SXd3fjEFSmr21fsMwLF6EpyLTLkYxDKLfJTGJ4z85WGHg0Fw7icMiCm7/YO8LtPcpgHArEC2mJTvT6QpM+hyT1yarinS8p5uk+4OCU0YnG4bCXB54wYh4BwHpGa7q5MluceKxQ82wmLX9Y00ewtUGQY1EWI= X-Microsoft-Antispam-Message-Info: SIcL8C6SPEj4W3ZJ7vQ8zNO6IwysX9epqoFa31FavzD/D6IcBb+UzHUkphOpQynCw15cVtDVWy5BP2xk94Quac5Vq3UXjsPXKJMOsaJ3MakKZ9yxfbvFAqtIxp8Yc+o2ulvfd0uvrPED9dd1TKOvSA2Z5oSUWA9mXOoiBPCnk7GDi1gLN1HmS0I1o/IT+fNhoqpmubhWncyJFcitMM9fnaKTqIimjFK2gN1teyxDlIJGY2sp7tzQ4b26MO+LIymewczERBNUalV35fsKj/NuTR0wnAt8zxZOng+zvfI1Z7ot6DOZC2b/95+dcpwYAx4+SX7O7GQR0KLRMM/mp1cG+hcA2W1pO5HlfFdlvOcKhhfwfR0pqqlJlmIlIv5v1np7NvYHvMTcQyPyPtFlqafIeok4RctegxBgrofFVQNSdGqFfylGddhvb1PmPmuqjnb30FdcO0OmwGy9+zshizbYz1c4AKkjwxnkGoaTNd07QzfK1IUfYCh7rY0mMTuz8LPMpdJhZYusIIszho76CGw/Q0EAfW8RxUT348DsUdLcQKU= SpamDiagnosticOutput: 1:22 X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2320; 7:DOnsQy1od3x7+DNVpvF1Zk9BUc2A3CRN8Mb4ONdPvt4yv2fyL4zPeeifmCx7w6c7VuHGKwrRQ/bqvo53Qpx+XtrFBZViE7n5Dds5V9OPdkWI6tvC9VaPGi+uxFT/eho3fmupdzwFA5E1kgNtQ7b9iIXV58ns1FNihCa5xbgLAJTeLY+bwMwtsyNSatHjYkBY1x7uT97Ar8W8I6gNECMfmu59+SHi+DVBP6z2CgngW50znhwIfayQuteriaaDa9aa X-MS-Office365-Filtering-Correlation-Id: 31dfee02-575e-4d97-8144-08d5b46520a4 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2018 21:54:36.7485 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 31dfee02-575e-4d97-8144-08d5b46520a4 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0501MB2320 Subject: [dpdk-dev] [PATCH v3 2/2] net/tap: support TSO (TCP Segment Offload) X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 May 2018 21:54:47 -0000 This commit implements TCP segmentation offload in TAP. librte_gso library is used to segment large TCP payloads (e.g. packets of 64K bytes size) into smaller MTU size buffers. By supporting TSO offload capability in software a TAP device can be used as a failsafe sub device and be paired with another PCI device which supports TSO capability in HW. For more details on librte_gso implementation please refer to dpdk documentation. The number of newly generated TCP TSO segments is limited to 64. Reviewed-by: Raslan Darawsheh Signed-off-by: Ophir Munk --- drivers/net/tap/Makefile | 2 +- drivers/net/tap/rte_eth_tap.c | 158 +++++++++++++++++++++++++++++++++++------- drivers/net/tap/rte_eth_tap.h | 4 ++ mk/rte.app.mk | 4 +- 4 files changed, 139 insertions(+), 29 deletions(-) diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile index ccc5c5f..3243365 100644 --- a/drivers/net/tap/Makefile +++ b/drivers/net/tap/Makefile @@ -24,7 +24,7 @@ CFLAGS += -I. CFLAGS += $(WERROR_FLAGS) LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash -LDLIBS += -lrte_bus_vdev +LDLIBS += -lrte_bus_vdev -lrte_gso CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 538acae..c535418 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,9 @@ #define ETH_TAP_CMP_MAC_FMT "0123456789ABCDEFabcdef" #define ETH_TAP_MAC_ARG_FMT ETH_TAP_MAC_FIXED "|" ETH_TAP_USR_MAC_FMT +#define TAP_GSO_MBUFS_NUM 128 +#define TAP_GSO_MBUF_SEG_SIZE 128 + static struct rte_vdev_driver pmd_tap_drv; static struct rte_vdev_driver pmd_tun_drv; @@ -405,7 +409,8 @@ tap_tx_offload_get_queue_capa(void) return DEV_TX_OFFLOAD_MULTI_SEGS | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM; + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO; } static bool @@ -488,23 +493,15 @@ tap_tx_l3_cksum(char *packet, uint64_t ol_flags, unsigned int l2_len, } } -/* Callback to handle sending packets from the tap interface - */ -static uint16_t -pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) +static inline void +tap_write_mbufs(struct tx_queue *txq, uint16_t num_mbufs, + struct rte_mbuf **pmbufs, uint16_t l234_hlen, + uint16_t *num_packets, unsigned long *num_tx_bytes) { - struct tx_queue *txq = queue; - uint16_t num_tx = 0; - unsigned long num_tx_bytes = 0; - uint32_t max_size; int i; - if (unlikely(nb_pkts == 0)) - return 0; - - max_size = *txq->mtu + (ETHER_HDR_LEN + ETHER_CRC_LEN + 4); - for (i = 0; i < nb_pkts; i++) { - struct rte_mbuf *mbuf = bufs[num_tx]; + for (i = 0; i < num_mbufs; i++) { + struct rte_mbuf *mbuf = pmbufs[i]; struct iovec iovecs[mbuf->nb_segs + 2]; struct tun_pi pi = { .flags = 0, .proto = 0x00 }; struct rte_mbuf *seg = mbuf; @@ -512,8 +509,7 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) int proto; int n; int j; - int k; /* first index in iovecs for copying segments */ - uint16_t l234_hlen; /* length of layers 2,3,4 headers */ + int k; /* current index in iovecs for copying segments */ uint16_t seg_len; /* length of first segment */ uint16_t nb_segs; uint16_t *l4_cksum; /* l4 checksum (pseudo header + payload) */ @@ -521,9 +517,6 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) uint16_t l4_phdr_cksum = 0; /* TCP/UDP pseudo header checksum */ uint16_t is_cksum = 0; /* in case cksum should be offloaded */ - /* stats.errs will be incremented */ - if (rte_pktmbuf_pkt_len(mbuf) > max_size) - break; l4_cksum = NULL; /* * TUN and TAP are created with IFF_NO_PI disabled. @@ -557,9 +550,8 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) l234_hlen = mbuf->l2_len + mbuf->l3_len + mbuf->l4_len; if (seg_len < l234_hlen) break; - - /* To change checksums, work on a - * copy of l2, l3 l4 headers. + /* To change checksums, work on a * copy of l2, l3 + * headers + l4 pseudo header */ rte_memcpy(m_copy, rte_pktmbuf_mtod(mbuf, void *), l234_hlen); @@ -601,13 +593,80 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) n = writev(txq->fd, iovecs, j); if (n <= 0) break; + (*num_packets)++; + (*num_tx_bytes) += rte_pktmbuf_pkt_len(mbuf); + } +} +/* Callback to handle sending packets from the tap interface + */ +static uint16_t +pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) +{ + struct tx_queue *txq = queue; + uint16_t num_tx = 0; + uint16_t num_packets = 0; + unsigned long num_tx_bytes = 0; + uint16_t tso_segsz = 0; + uint16_t hdrs_len; + uint32_t max_size; + int i; + uint64_t tso; + int ret; + + if (unlikely(nb_pkts == 0)) + return 0; + + struct rte_mbuf *gso_mbufs[MAX_GSO_MBUFS]; + max_size = *txq->mtu + (ETHER_HDR_LEN + ETHER_CRC_LEN + 4); + for (i = 0; i < nb_pkts; i++) { + struct rte_mbuf *mbuf_in = bufs[num_tx]; + struct rte_mbuf **mbuf; + uint16_t num_mbufs; + + tso = mbuf_in->ol_flags & PKT_TX_TCP_SEG; + if (tso) { + struct rte_gso_ctx *gso_ctx = &txq->gso_ctx; + assert(gso_ctx != NULL); + /* TCP segmentation implies TCP checksum offload */ + mbuf_in->ol_flags |= PKT_TX_TCP_CKSUM; + /* gso size is calculated without ETHER_CRC_LEN */ + hdrs_len = mbuf_in->l2_len + mbuf_in->l3_len + + mbuf_in->l4_len; + tso_segsz = mbuf_in->tso_segsz + hdrs_len; + if (unlikely(tso_segsz == hdrs_len) || + tso_segsz > *txq->mtu) { + txq->stats.errs++; + break; + } + gso_ctx->gso_size = tso_segsz; + ret = rte_gso_segment(mbuf_in, /* packet to segment */ + gso_ctx, /* gso control block */ + (struct rte_mbuf **)&gso_mbufs, /* out mbufs */ + RTE_DIM(gso_mbufs)); /* max tso mbufs */ + + /* ret contains the number of new created mbufs */ + if (ret < 0) + break; + + mbuf = gso_mbufs; + num_mbufs = ret; + } else { + /* stats.errs will be incremented */ + if (rte_pktmbuf_pkt_len(mbuf_in) > max_size) + break; + + mbuf = &mbuf_in; + num_mbufs = 1; + } + + tap_write_mbufs(txq, num_mbufs, mbuf, hdrs_len, + &num_packets, &num_tx_bytes); num_tx++; - num_tx_bytes += mbuf->pkt_len; - rte_pktmbuf_free(mbuf); + rte_pktmbuf_free(mbuf_in); } - txq->stats.opackets += num_tx; + txq->stats.opackets += num_packets; txq->stats.errs += nb_pkts - num_tx; txq->stats.obytes += num_tx_bytes; @@ -1060,31 +1119,73 @@ tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) } static int +tap_gso_ctx_setup(struct rte_gso_ctx *gso_ctx, struct rte_eth_dev *dev) +{ + uint32_t gso_types; + char pool_name[64]; + + /* + * Create private mbuf pool with TAP_GSO_MBUF_SEG_SIZE bytes + * size per mbuf use this pool for both direct and indirect mbufs + */ + + struct rte_mempool *mp; /* Mempool for GSO packets */ + /* initialize GSO context */ + gso_types = DEV_TX_OFFLOAD_TCP_TSO; + snprintf(pool_name, sizeof(pool_name), "mp_%s", dev->device->name); + mp = rte_mempool_lookup((const char *)pool_name); + if (!mp) { + mp = rte_pktmbuf_pool_create(pool_name, TAP_GSO_MBUFS_NUM, + 0, 0, RTE_PKTMBUF_HEADROOM + TAP_GSO_MBUF_SEG_SIZE, + SOCKET_ID_ANY); + if (!mp) { + struct pmd_internals *pmd = dev->data->dev_private; + RTE_LOG(DEBUG, PMD, "%s: failed to create mbuf pool for device %s\n", + pmd->name, dev->device->name); + return -1; + } + } + + gso_ctx->direct_pool = mp; + gso_ctx->indirect_pool = mp; + gso_ctx->gso_types = gso_types; + gso_ctx->gso_size = 0; /* gso_size is set in tx_burst() per packet */ + gso_ctx->flag = 0; + + return 0; +} + +static int tap_setup_queue(struct rte_eth_dev *dev, struct pmd_internals *internals, uint16_t qid, int is_rx) { + int ret; int *fd; int *other_fd; const char *dir; struct pmd_internals *pmd = dev->data->dev_private; struct rx_queue *rx = &internals->rxq[qid]; struct tx_queue *tx = &internals->txq[qid]; + struct rte_gso_ctx *gso_ctx; if (is_rx) { fd = &rx->fd; other_fd = &tx->fd; dir = "rx"; + gso_ctx = NULL; } else { fd = &tx->fd; other_fd = &rx->fd; dir = "tx"; + gso_ctx = &tx->gso_ctx; } if (*fd != -1) { /* fd for this queue already exists */ TAP_LOG(DEBUG, "%s: fd %d for %s queue qid %d exists", pmd->name, *fd, dir, qid); + gso_ctx = NULL; } else if (*other_fd != -1) { /* Only other_fd exists. dup it */ *fd = dup(*other_fd); @@ -1109,6 +1210,11 @@ tap_setup_queue(struct rte_eth_dev *dev, tx->mtu = &dev->data->mtu; rx->rxmode = &dev->data->dev_conf.rxmode; + if (gso_ctx) { + ret = tap_gso_ctx_setup(gso_ctx, dev); + if (ret) + return -1; + } return *fd; } diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index 67c9d4b..babe42d 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -15,6 +15,7 @@ #include #include +#include #include "tap_log.h" #ifdef IFF_MULTI_QUEUE @@ -23,6 +24,8 @@ #define RTE_PMD_TAP_MAX_QUEUES 1 #endif +#define MAX_GSO_MBUFS 64 + struct pkt_stats { uint64_t opackets; /* Number of output packets */ uint64_t ipackets; /* Number of input packets */ @@ -51,6 +54,7 @@ struct tx_queue { uint16_t *mtu; /* Pointer to MTU from dev_data */ uint16_t csum:1; /* Enable checksum offloading */ struct pkt_stats stats; /* Stats for this TX queue */ + struct rte_gso_ctx gso_ctx; /* GSO context */ }; struct pmd_internals { diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 29a2a60..62819a4 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -66,8 +66,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PORT) += -lrte_port _LDLIBS-$(CONFIG_RTE_LIBRTE_PDUMP) += -lrte_pdump _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag -_LDLIBS-$(CONFIG_RTE_LIBRTE_GRO) += -lrte_gro -_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO) += -lrte_gso _LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lrte_meter _LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm # librte_acl needs --whole-archive because of weak functions @@ -85,6 +83,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EFD) += -lrte_efd _LDLIBS-y += --whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile +_LDLIBS-$(CONFIG_RTE_LIBRTE_GRO) += -lrte_gro +_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO) += -lrte_gso _LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMBER) += -lrte_member _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost -- 2.7.4