get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/41013/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 41013,
    "url": "http://patches.dpdk.org/api/patches/41013/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1528821108-12405-3-git-send-email-ophirmu@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1528821108-12405-3-git-send-email-ophirmu@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1528821108-12405-3-git-send-email-ophirmu@mellanox.com",
    "date": "2018-06-12T16:31:48",
    "name": "[v4,2/2] net/tap: support TSO (TCP Segment Offload)",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bd7934b6e38f8e356266c0ffb52bac4637c5be3a",
    "submitter": {
        "id": 793,
        "url": "http://patches.dpdk.org/api/people/793/?format=api",
        "name": "Ophir Munk",
        "email": "ophirmu@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1528821108-12405-3-git-send-email-ophirmu@mellanox.com/mbox/",
    "series": [
        {
            "id": 97,
            "url": "http://patches.dpdk.org/api/series/97/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=97",
            "date": "2018-06-12T16:31:47",
            "name": "TAP TSO",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/97/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41013/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/41013/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 718921EA0D;\n\tTue, 12 Jun 2018 18:32:17 +0200 (CEST)",
            "from EUR01-VE1-obe.outbound.protection.outlook.com\n\t(mail-ve1eur01hn0230.outbound.protection.outlook.com [104.47.1.230])\n\tby dpdk.org (Postfix) with ESMTP id 4C4671E9FA\n\tfor <dev@dpdk.org>; Tue, 12 Jun 2018 18:32:14 +0200 (CEST)",
            "from mellanox.com (37.142.13.130) by\n\tHE1PR0501MB2314.eurprd05.prod.outlook.com (2603:10a6:3:27::19) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.841.17; Tue, 12 Jun 2018 16:32:04 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=42EwGFjp2tC4fj862VMaoOIe5NRiSs0q5nc8n2xGHqk=;\n\tb=nDw+nw86DrGP9SDf3VhXJM1gixjy5MCE7pBN74xTI3Ki5SUBGKOPaK7B2eJSt5Aa5gGerDFEUTRSz7kPJtSfz0qaUZhJDXwJtoe4h6F5HwPVIOuhtkgh+8xCMKalws0TGB9QhVr0SPgamjs0w0jxyf8nphqsMhl7wdKgLIy56dw=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=ophirmu@mellanox.com; ",
        "From": "Ophir Munk <ophirmu@mellanox.com>",
        "To": "dev@dpdk.org, Pascal Mazon <pascal.mazon@6wind.com>,\n\tKeith Wiles <keith.wiles@intel.com>",
        "Cc": "Thomas Monjalon <thomas@monjalon.net>, Olga Shern <olgas@mellanox.com>, \n\tOphir Munk <ophirmu@mellanox.com>",
        "Date": "Tue, 12 Jun 2018 16:31:48 +0000",
        "Message-Id": "<1528821108-12405-3-git-send-email-ophirmu@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1528821108-12405-1-git-send-email-ophirmu@mellanox.com>",
        "References": "<1520629826-23055-2-git-send-email-ophirmu@mellanox.com>\n\t<1528821108-12405-1-git-send-email-ophirmu@mellanox.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[37.142.13.130]",
        "X-ClientProxiedBy": "VI1PR08CA0183.eurprd08.prod.outlook.com\n\t(2603:10a6:800:d2::13) To HE1PR0501MB2314.eurprd05.prod.outlook.com\n\t(2603:10a6:3:27::19)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0;\n\tRULEID:(7020095)(4652020)(48565401081)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020);\n\tSRVR:HE1PR0501MB2314; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; HE1PR0501MB2314;\n\t3:XKSjyjzKa1ye5UbYJ3bzsw3iRpMWjR4xYgq4pOsesa46DwJ5hmlojLe2L7l0bSLQOEjkR94+JzWd827U/W+UuGUEArn2uzFaUM/UqbRNgJlneL7tS/de6YDJijlA/1ijUkMqCTnzxevWnOsBbon1jvxyc+7B+yAzwtoryeUgZvq+sp+RpAnm/mSzoEMRXTJP4XOBRw2SXWHUGM78iMmyUy/wHQkMpx7RVVzDZps0/Mn55AVpTr+qT9b5GTGSJQM1;\n\t25:1QnuY92LMVB5/poKkjhd6p2zxD2n9/n39OywSzN8Qxss5x6pOOCIG2GEzgKCtBGsY5RtQzEnk9en+BX68G5kVaQ+M5oCTcjdxm/UX3VIaOyomS+CHHRkYxS9sMN6kL7go0RmywKlBxqbprZji9vdY7zJNOdLUyJFL9+oYSiYfQnqG8vemDYunja/S6VX7x2eD/CSQ9B9OuiMPdtoTm+JbS7B/7r9DrRNJQHKVR2MDvIvsjG3ElwFPTp1JI5blnvC/Z0vIGxXFhyfIyYLIU7fGfhAvYnKsO5FNoN8ioFEnP8rf2aPaauoZTLbwi0+4ryLPwZ7e0/qLzI3lN4bzPsZ0Q==;\n\t31:VTqdS/bMQNFW73TqQnhBCYaanOkaWfwoCDgB4dap8AJaCLblMGYHAqPOSshYmAiaLqoMn6nbSv6IeaPUblpf1rQ0gZneHVG0a7OENO7uHJHtvNEFwtdSXlqAzPdIrL2mEx+CurPmYVf6ZErdILbL7aWChLLQMA1xp+uCj7FuAer8AS4XqkhJkhu/pk0HfGW6Rab/Xt8huD/YnbJO1HuiwU0fTSiBIQkOIEvjq7ysLMg=",
            "1; HE1PR0501MB2314;\n\t20:Ud9Atc1BT5reQsKNtRWidUCHRla3sXvhT9LLZ6DTEIgd3bUb2ohyEFFRFJmLoMojpZVezDgYIJl3FTKVqKrObibl+rFLcFjtlZg/KTcNsw/9UpbUb8KbpwYCZCYNQNOmOB+Jq5T1xyX65bsDoUtvYqj8w0lM4DIi250kcmDMLm8beBOf7Whon2LkzIue4N8vXoCYzxM80Q4BhCZgHM0gmdKN/pDVJx8JuNoC3xqR2X0qXeRNHUpTuoZ+Vmt9fG29qXTKJ0rWcuXtnbXMvbumkC+o33vUB0Pcyvm7spNys6s74K6XdQ5lujojc06BLwFOVSFO0joSfS4VFD6OdgRnZLkyfdSGVPzZkArUZG+ltnmwuV/VCIjIuwzscQ+YGnHXj85ZnrEjfvY38QFdmK+OxN7YcnwzxBr4Mw1+PHW1wPnviS721FtUTEZF91kG+HSWWdXQnfpDJQCPnE807hZMc1WoWS6Ttcc+bMo+rsp+7ELqCO5bmT3g5hbN5Qvq6//O;\n\t4:KFMlAglAAE4vyvAt5lyqcI7a4ILSKihwQEHtxXFKbH0aQC4/ZTOf4dqnstVFpOLiRL4ypDp6tkjwCD/eOmdqEMyQn5vWg9OjGAdfz3omb1lS6ADjDez5fdvvcZAlzGWBv7hcd7sKqcdQ4BaJin21jrtrFVD53GppTTTNkZgUN2A1oUnnR4jCn+n9Wu5ni7uT8lNxyI7iyuyxnFXyN+gphrPl9srMNvH5JBFVvZJOGqRQIlN93+RyaLIWpfZDuCrcwqUSvenEfGk18IAp+tYzLNO/ZFeHYTukN9MABfqd2VkIuRml9Ob+CmZAPMTadxia",
            "=?us-ascii?Q?1; HE1PR0501MB2314;\n\t23:VDdo8UiJ86b92Tdo0MzH/n62BlvGSckojAwgtHQ?=\n\tnc13N6VD+B1jmI3ZFEavhttCr1HWr+PBJBnB1fQhAvaUV4ilnDaMFv3/d2NRi6EEFxZDCnewHMK+wcj23gad2vliNf5k+7fFGxem+HKeXcIpCwrdNaVfLUlimM42wywTaZflL346kd4vIpwvw9j3f0VLysYmr49gwN4wQfSHkW8ED4rUD/EbDMl4TJahlXowxLhPKERv1iaMzk66c64C1tBzTCc4VcoavEkQLLXXWcH8ZE2+9Av9nnPAnBddeeyrHYw7+yxmseDC1o2U2bhVJf5h+lepJU4joXm0BnjE/Ll7j6ungjmb3N+oy8ZFrbTy+7xCiTk5watFubficZA54SoKTEwNKJ9733vpYGOyOHslDGWYZ4b6+lAWCPS9MRAyOm6wEgUBzQUte3TfXh6caltSfwtKjukQyu3UxglwTZmedAW0Nfo9LgAnxXVngKuYockWeotK8weWT2S+YtUt6pBw+0rIAj+8OzxlXuqg19JUPNF4/FyUruEAzIJhtFhEXosavxllZLJ0z2yC4Jhtrjfb4Hg+ZmGfDd8wrZ9jFAp42gG43v3oHb/vEIfTLAzXkiwfua1gwJWQA1do3sf1Byjvo23BiwVJ/+bzFRiu+IEQpsi3TvdiFvDm1QXYrMbPgsTbVOfHKRC7Dh4DEG3Cz2Lw1gGp6O0vT4VLHA9rmtVVvAb2mw/NX/TgRdk8aGIQ+bRI0eVxPPrRWTSUA6n5Apfa250PTo2e5IzzJogVZMPQkwW4TQSTEPrPwPzYcrXDDJ1pn4T/lQAuNVGTSY9rico5F/vHm7/qnD114/3dUc2XgWWZnlILU53iGgrR0VPhjSjFzajg7tNfXBJjU2uOLo4DqoldyElVSpyjNVFQOkgVKxf5I/8KQrRUVFV4+gq9VuGtJWfxT4GqUkJeszu+mq8zV+CNYKgbNnZDOtJsxSOXbNrmO2rwELXtzrNVrvwMIazvrmniYbmkQBLbRv3vpr0ad6WEUz7T0DmSYHqkfGKuxuTephQ9gzbKl7bydx1nYuIm+2Nmhucko52EeH52Z1FJpgdcorROL1TDl1DpHuRXphk99JIOTlHI/4AMaP8g8hTflzfbpFAnO5yDb/C+iG5ayedz3SRwn0T+YhOOO71XoSFiFi+fGlq85UhZDWRW9l0zWyM6R12GqWlAbz/GhbODa92ZNHCXXwYd9eKemi6XAniCsYqQK50eKJTlhCrEVMkHX1YEp4PsbERBC0LvSl444YSel5wP9x7zmFl9bLKOmnn4VNbUz6ogRcxa/Xuo2u4JylRkRZdRacUInu/Rg4BS/3E7uzT4K99GJN1aaEhSbz2czehgj4ZNADXMPkdi2lmo=",
            "1; HE1PR0501MB2314;\n\t23:xAvzfhmEXZcrTmTv9GPyrvFUyIYN+7rEXcWS1L7Bb+W33B7MdI9ps51fU20g+PdaVZEwH8Ouz8ep8/JKyHsmqoVn8HSpw22YIQ+3ZWXsdSL00UNhys8pglqZPd4G/syrQriXPNxmVy7HckGr69w6NQ==;\n\t6:csTA0F0feeFG6NL+XoFS3a1Pzq8QJ+2TQjAS+3zdfqOObfgQls0PfjSZfCVjbYGKWD5OWSm4VbnmtOLyxhZfzuoOSRrilK1ODajR+RHQcT0twRWaWtHyphuUwjWnlCoPUcYd2VFvf02TYBpdnhm4ayvP/9Vy1vW1Dp4wnirlU17+ZuvQ8ceFRBfcUFOhUuH+bvRKmdDnRkvNvzYamQB6JOma90ETqqEY+P7Cnw767/o6xou0Jm6AtH4yGqErxESVlkufaXx5vU3ttX0jUBaAka5J6Uc2dR6eCePDlu4dj+BjX5/1fBDbw5bdA9aemKi6n7eVUvSESXQ0G8xbBSszcOsHZ1KzHckPhSEEGHsGQ5WAjJdkduNheDlotUQ8Nc3mIqcan5U5c8WB0NtSAxuYM96XCqoE6Nf7gurDh1ulozx9cHOqViIa4khhOgTE8aTJdhntA2pPHYfZGdCQdj0vTlDrSFO3FazI5jxABVkN5zc534Ik5O75eULAVPeEDKMU;\n\t5:7PadP97HsZHRxaa7WIqINJfBqZuS1zL7jrM+rkWRnCY4GxJ+asV28rn66ZFu+QaxjBQ/CXkm76KryHC26AOB5n2kmiumHtZK42DlGG2R3F60B2l2Zay7K06DAXqdMcO0RFEfGvM/1d7IMfOGSN5m/zEh3jX0h29sTktCtz1ER9A=",
            "1; HE1PR0501MB2314;\n\t7:aEM2QG/z5BG/0CKiYxSSi4DQF2QTwwpXbHcTZXx6SFPOVAGjzvcVfvvSmeIrof57XNeZNlc0LEs4VbrNs0nGk5io09mA+A8G40/P4gJfHROGKVr3UI9ydLFr0FLUDqNIUK5NEsrjhse2X99DOf25nYft7Vj8S6TX4oieUW1QdvzTYQxWKoHUCsbhFFizzFNh0pfoz5n+3vjJ5wvWunBjpJ9J1FiquVzn11P/HjwksaxX5Jk/5cDwyztl99e69jSN"
        ],
        "X-MS-TrafficTypeDiagnostic": "HE1PR0501MB2314:|HE1PR0501MB2314:",
        "X-LD-Processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "X-Microsoft-Antispam-PRVS": "<HE1PR0501MB231479C34B0AD25D07C8F165D17F0@HE1PR0501MB2314.eurprd05.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:(66839620246622);",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(3002001)(3231254)(2232076)(944501410)(52105095)(6055026)(149027)(150027)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011)(7699016);\n\tSRVR:HE1PR0501MB2314; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0501MB2314; ",
        "X-Forefront-PRVS": "07013D7479",
        "X-Forefront-Antispam-Report": "SFV:SPM;\n\tSFS:(10009020)(376002)(366004)(346002)(396003)(39860400002)(39380400002)(199004)(189003)(575784001)(478600001)(2906002)(33026002)(69596002)(106356001)(16586007)(316002)(48376002)(110136005)(86362001)(105586002)(54906003)(21086003)(66066001)(47776003)(50466002)(6116002)(3846002)(68736007)(446003)(55016002)(186003)(81156014)(107886003)(2616005)(52116002)(956004)(11346002)(7736002)(476003)(76176011)(7696005)(26005)(486006)(51416003)(4720700003)(53936002)(386003)(36756003)(5660300001)(97736004)(8676002)(16526019)(81166006)(8936002)(305945005)(50226002)(25786009)(6666003)(4326008)(59010400001);\n\tDIR:OUT; SFP:1501; SCL:5; SRVR:HE1PR0501MB2314; H:mellanox.com; FPR:;\n\tSPF:None; \n\tLANG:en; PTR:InfoNoRecords; A:1; MX:1; ",
        "Received-SPF": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "X-Microsoft-Antispam-Message-Info": "NFApwuy+lUQHSFQ/5sEc5ktMxkg8OPbFwZ+sFZS5Ogf98yxrHQnR/Ggv6//xi84hZAtcpd238nnvujFGCQJMFSBC1BT4V8H+I4x/t6AqZlASzXyu6UknS+VNo83AyzrBzKvLv6CLiKSZ+hsSiTbLSuHhxSd1xDzyKIwAJKkDpn6hm2p7GQ7Toofyuh6I8OANvGZuf4jNogAASgAMkOx1uv3dgxuv6EheQleb6tEnjDRMGs51gF+vjw9FcZSB+Njwk+a+MAeIKP0eFOhRsP6KN2D9YIkaqqjMNg8HwfkL1nsiAkibhjiaS3Hz+IEfV1Ne0wVSKuyAM/u5jZnXqSZ1p4HI64kVpcawRW+PvK6rKeNqvfh8S9BX9jhrXqIOZIe8NqH0tdirre+8ZaBONtQacc8+visI/T3qfMcS8B+5oVjc8VDhE+ehZ48HKnHJAXTmbKBOiULGOO1szgodWOSxsPHA76OT+rgww3iuVfEA+saiKwNjP4rmDrkAOA/4E7trG8ldJ9yTk0YveWfNH+hkkwwVoZRNHcfncXjYho/EIqQ=",
        "SpamDiagnosticOutput": "1:22",
        "X-MS-Office365-Filtering-Correlation-Id": "7be90f73-1ed7-4015-56da-08d5d08208f8",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "12 Jun 2018 16:32:04.5111\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "7be90f73-1ed7-4015-56da-08d5d08208f8",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "HE1PR0501MB2314",
        "Subject": "[dpdk-dev] [PATCH v4 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 <dev.dpdk.org>",
        "List-Unsubscribe": "<https://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit implements TCP segmentation offload in TAP.\nlibrte_gso library is used to segment large TCP payloads (e.g. packets\nof 64K bytes size) into smaller MTU size buffers.\nBy supporting TSO offload capability in software a TAP device can be used\nas a failsafe sub device and be paired with another PCI device which\nsupports TSO capability in HW.\n\nFor more details on librte_gso implementation please refer to dpdk\ndocumentation.\nThe number of newly generated TCP TSO segments is limited to 64.\n\nReviewed-by: Raslan Darawsheh <rasland@mellanox.com>\nSigned-off-by: Ophir Munk <ophirmu@mellanox.com>\n---\n drivers/net/tap/Makefile      |   2 +-\n drivers/net/tap/rte_eth_tap.c | 159 +++++++++++++++++++++++++++++++++++-------\n drivers/net/tap/rte_eth_tap.h |   3 +\n mk/rte.app.mk                 |   4 +-\n 4 files changed, 138 insertions(+), 30 deletions(-)",
    "diff": "diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile\nindex ccc5c5f..3243365 100644\n--- a/drivers/net/tap/Makefile\n+++ b/drivers/net/tap/Makefile\n@@ -24,7 +24,7 @@ CFLAGS += -I.\n CFLAGS += $(WERROR_FLAGS)\n LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash\n-LDLIBS += -lrte_bus_vdev\n+LDLIBS += -lrte_bus_vdev -lrte_gso\n \n CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)\n \ndiff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c\nindex c19f053..62b931f 100644\n--- a/drivers/net/tap/rte_eth_tap.c\n+++ b/drivers/net/tap/rte_eth_tap.c\n@@ -17,6 +17,7 @@\n #include <rte_ip.h>\n #include <rte_string_fns.h>\n \n+#include <assert.h>\n #include <sys/types.h>\n #include <sys/stat.h>\n #include <sys/socket.h>\n@@ -55,6 +56,9 @@\n #define ETH_TAP_CMP_MAC_FMT     \"0123456789ABCDEFabcdef\"\n #define ETH_TAP_MAC_ARG_FMT     ETH_TAP_MAC_FIXED \"|\" ETH_TAP_USR_MAC_FMT\n \n+#define TAP_GSO_MBUFS_NUM\t128\n+#define TAP_GSO_MBUF_SEG_SIZE\t128\n+\n static struct rte_vdev_driver pmd_tap_drv;\n static struct rte_vdev_driver pmd_tun_drv;\n \n@@ -412,7 +416,8 @@ tap_tx_offload_get_queue_capa(void)\n \treturn DEV_TX_OFFLOAD_MULTI_SEGS |\n \t       DEV_TX_OFFLOAD_IPV4_CKSUM |\n \t       DEV_TX_OFFLOAD_UDP_CKSUM |\n-\t       DEV_TX_OFFLOAD_TCP_CKSUM;\n+\t       DEV_TX_OFFLOAD_TCP_CKSUM |\n+\t       DEV_TX_OFFLOAD_TCP_TSO;\n }\n \n /* Finalize l4 checksum calculation */\n@@ -479,23 +484,15 @@ tap_tx_l3_cksum(char *packet, uint64_t ol_flags, unsigned int l2_len,\n \t}\n }\n \n-/* Callback to handle sending packets from the tap interface\n- */\n-static uint16_t\n-pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n+static inline void\n+tap_write_mbufs(struct tx_queue *txq, uint16_t num_mbufs,\n+\t\t\tstruct rte_mbuf **pmbufs, uint16_t l234_hlen,\n+\t\t\tuint16_t *num_packets, unsigned long *num_tx_bytes)\n {\n-\tstruct tx_queue *txq = queue;\n-\tuint16_t num_tx = 0;\n-\tunsigned long num_tx_bytes = 0;\n-\tuint32_t max_size;\n \tint i;\n \n-\tif (unlikely(nb_pkts == 0))\n-\t\treturn 0;\n-\n-\tmax_size = *txq->mtu + (ETHER_HDR_LEN + ETHER_CRC_LEN + 4);\n-\tfor (i = 0; i < nb_pkts; i++) {\n-\t\tstruct rte_mbuf *mbuf = bufs[num_tx];\n+\tfor (i = 0; i < num_mbufs; i++) {\n+\t\tstruct rte_mbuf *mbuf = pmbufs[i];\n \t\tstruct iovec iovecs[mbuf->nb_segs + 2];\n \t\tstruct tun_pi pi = { .flags = 0, .proto = 0x00 };\n \t\tstruct rte_mbuf *seg = mbuf;\n@@ -503,8 +500,7 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n \t\tint proto;\n \t\tint n;\n \t\tint j;\n-\t\tint k; /* first index in iovecs for copying segments */\n-\t\tuint16_t l234_hlen; /* length of layers 2,3,4 headers */\n+\t\tint k; /* current index in iovecs for copying segments */\n \t\tuint16_t seg_len; /* length of first segment */\n \t\tuint16_t nb_segs;\n \t\tuint16_t *l4_cksum; /* l4 checksum (pseudo header + payload) */\n@@ -512,10 +508,6 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n \t\tuint16_t l4_phdr_cksum = 0; /* TCP/UDP pseudo header checksum */\n \t\tuint16_t is_cksum = 0; /* in case cksum should be offloaded */\n \n-\t\t/* stats.errs will be incremented */\n-\t\tif (rte_pktmbuf_pkt_len(mbuf) > max_size)\n-\t\t\tbreak;\n-\n \t\tl4_cksum = NULL;\n \t\tif (txq->type == ETH_TUNTAP_TYPE_TUN) {\n \t\t\t/*\n@@ -554,9 +546,8 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n \t\t\tl234_hlen = mbuf->l2_len + mbuf->l3_len + mbuf->l4_len;\n \t\t\tif (seg_len < l234_hlen)\n \t\t\t\tbreak;\n-\n-\t\t\t/* To change checksums, work on a\n-\t\t\t * copy of l2, l3 l4 headers.\n+\t\t\t/* To change checksums, work on a * copy of l2, l3\n+\t\t\t * headers + l4 pseudo header\n \t\t\t */\n \t\t\trte_memcpy(m_copy, rte_pktmbuf_mtod(mbuf, void *),\n \t\t\t\t\tl234_hlen);\n@@ -598,13 +589,80 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n \t\tn = writev(txq->fd, iovecs, j);\n \t\tif (n <= 0)\n \t\t\tbreak;\n+\t\t(*num_packets)++;\n+\t\t(*num_tx_bytes) += rte_pktmbuf_pkt_len(mbuf);\n+\t}\n+}\n+\n+/* Callback to handle sending packets from the tap interface\n+ */\n+static uint16_t\n+pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\n+{\n+\tstruct tx_queue *txq = queue;\n+\tuint16_t num_tx = 0;\n+\tuint16_t num_packets = 0;\n+\tunsigned long num_tx_bytes = 0;\n+\tuint16_t tso_segsz = 0;\n+\tuint16_t hdrs_len;\n+\tuint32_t max_size;\n+\tint i;\n+\tuint64_t tso;\n+\tint ret;\n \n+\tif (unlikely(nb_pkts == 0))\n+\t\treturn 0;\n+\n+\tstruct rte_mbuf *gso_mbufs[MAX_GSO_MBUFS];\n+\tmax_size = *txq->mtu + (ETHER_HDR_LEN + ETHER_CRC_LEN + 4);\n+\tfor (i = 0; i < nb_pkts; i++) {\n+\t\tstruct rte_mbuf *mbuf_in = bufs[num_tx];\n+\t\tstruct rte_mbuf **mbuf;\n+\t\tuint16_t num_mbufs;\n+\n+\t\ttso = mbuf_in->ol_flags & PKT_TX_TCP_SEG;\n+\t\tif (tso) {\n+\t\t\tstruct rte_gso_ctx *gso_ctx = &txq->gso_ctx;\n+\t\t\tassert(gso_ctx != NULL);\n+\t\t\t/* TCP segmentation implies TCP checksum offload */\n+\t\t\tmbuf_in->ol_flags |= PKT_TX_TCP_CKSUM;\n+\t\t\t/* gso size is calculated without ETHER_CRC_LEN */\n+\t\t\thdrs_len = mbuf_in->l2_len + mbuf_in->l3_len +\n+\t\t\t\t\tmbuf_in->l4_len;\n+\t\t\ttso_segsz = mbuf_in->tso_segsz + hdrs_len;\n+\t\t\tif (unlikely(tso_segsz == hdrs_len) ||\n+\t\t\t\ttso_segsz > *txq->mtu) {\n+\t\t\t\ttxq->stats.errs++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tgso_ctx->gso_size = tso_segsz;\n+\t\t\tret = rte_gso_segment(mbuf_in, /* packet to segment */\n+\t\t\t\tgso_ctx, /* gso control block */\n+\t\t\t\t(struct rte_mbuf **)&gso_mbufs, /* out mbufs */\n+\t\t\t\tRTE_DIM(gso_mbufs)); /* max tso mbufs */\n+\n+\t\t\t/* ret contains the number of new created mbufs */\n+\t\t\tif (ret < 0)\n+\t\t\t\tbreak;\n+\n+\t\t\tmbuf = gso_mbufs;\n+\t\t\tnum_mbufs = ret;\n+\t\t} else {\n+\t\t\t/* stats.errs will be incremented */\n+\t\t\tif (rte_pktmbuf_pkt_len(mbuf_in) > max_size)\n+\t\t\t\tbreak;\n+\n+\t\t\tmbuf = &mbuf_in;\n+\t\t\tnum_mbufs = 1;\n+\t\t}\n+\n+\t\ttap_write_mbufs(txq, num_mbufs, mbuf, hdrs_len,\n+\t\t\t\t&num_packets, &num_tx_bytes);\n \t\tnum_tx++;\n-\t\tnum_tx_bytes += mbuf->pkt_len;\n-\t\trte_pktmbuf_free(mbuf);\n+\t\trte_pktmbuf_free(mbuf_in);\n \t}\n \n-\ttxq->stats.opackets += num_tx;\n+\ttxq->stats.opackets += num_packets;\n \ttxq->stats.errs += nb_pkts - num_tx;\n \ttxq->stats.obytes += num_tx_bytes;\n \n@@ -1066,31 +1124,73 @@ tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)\n }\n \n static int\n+tap_gso_ctx_setup(struct rte_gso_ctx *gso_ctx, struct rte_eth_dev *dev)\n+{\n+\tuint32_t gso_types;\n+\tchar pool_name[64];\n+\n+\t/*\n+\t * Create private mbuf pool with TAP_GSO_MBUF_SEG_SIZE bytes\n+\t * size per mbuf use this pool for both direct and indirect mbufs\n+\t */\n+\n+\tstruct rte_mempool *mp;      /* Mempool for GSO packets */\n+\t/* initialize GSO context */\n+\tgso_types = DEV_TX_OFFLOAD_TCP_TSO;\n+\tsnprintf(pool_name, sizeof(pool_name), \"mp_%s\", dev->device->name);\n+\tmp = rte_mempool_lookup((const char *)pool_name);\n+\tif (!mp) {\n+\t\tmp = rte_pktmbuf_pool_create(pool_name, TAP_GSO_MBUFS_NUM,\n+\t\t\t0, 0, RTE_PKTMBUF_HEADROOM + TAP_GSO_MBUF_SEG_SIZE,\n+\t\t\tSOCKET_ID_ANY);\n+\t\tif (!mp) {\n+\t\t\tstruct pmd_internals *pmd = dev->data->dev_private;\n+\t\t\tRTE_LOG(DEBUG, PMD, \"%s: failed to create mbuf pool for device %s\\n\",\n+\t\t\t\tpmd->name, dev->device->name);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tgso_ctx->direct_pool = mp;\n+\tgso_ctx->indirect_pool = mp;\n+\tgso_ctx->gso_types = gso_types;\n+\tgso_ctx->gso_size = 0; /* gso_size is set in tx_burst() per packet */\n+\tgso_ctx->flag = 0;\n+\n+\treturn 0;\n+}\n+\n+static int\n tap_setup_queue(struct rte_eth_dev *dev,\n \t\tstruct pmd_internals *internals,\n \t\tuint16_t qid,\n \t\tint is_rx)\n {\n+\tint ret;\n \tint *fd;\n \tint *other_fd;\n \tconst char *dir;\n \tstruct pmd_internals *pmd = dev->data->dev_private;\n \tstruct rx_queue *rx = &internals->rxq[qid];\n \tstruct tx_queue *tx = &internals->txq[qid];\n+\tstruct rte_gso_ctx *gso_ctx;\n \n \tif (is_rx) {\n \t\tfd = &rx->fd;\n \t\tother_fd = &tx->fd;\n \t\tdir = \"rx\";\n+\t\tgso_ctx = NULL;\n \t} else {\n \t\tfd = &tx->fd;\n \t\tother_fd = &rx->fd;\n \t\tdir = \"tx\";\n+\t\tgso_ctx = &tx->gso_ctx;\n \t}\n \tif (*fd != -1) {\n \t\t/* fd for this queue already exists */\n \t\tTAP_LOG(DEBUG, \"%s: fd %d for %s queue qid %d exists\",\n \t\t\tpmd->name, *fd, dir, qid);\n+\t\tgso_ctx = NULL;\n \t} else if (*other_fd != -1) {\n \t\t/* Only other_fd exists. dup it */\n \t\t*fd = dup(*other_fd);\n@@ -1115,6 +1215,11 @@ tap_setup_queue(struct rte_eth_dev *dev,\n \n \ttx->mtu = &dev->data->mtu;\n \trx->rxmode = &dev->data->dev_conf.rxmode;\n+\tif (gso_ctx) {\n+\t\tret = tap_gso_ctx_setup(gso_ctx, dev);\n+\t\tif (ret)\n+\t\t\treturn -1;\n+\t}\n \n \ttx->type = pmd->type;\n \ndiff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h\nindex 7b21d0d..44e2773 100644\n--- a/drivers/net/tap/rte_eth_tap.h\n+++ b/drivers/net/tap/rte_eth_tap.h\n@@ -15,6 +15,7 @@\n \n #include <rte_ethdev_driver.h>\n #include <rte_ether.h>\n+#include <rte_gso.h>\n #include \"tap_log.h\"\n \n #ifdef IFF_MULTI_QUEUE\n@@ -22,6 +23,7 @@\n #else\n #define RTE_PMD_TAP_MAX_QUEUES\t1\n #endif\n+#define MAX_GSO_MBUFS 64\n \n enum rte_tuntap_type {\n \tETH_TUNTAP_TYPE_UNKNOWN,\n@@ -59,6 +61,7 @@ struct tx_queue {\n \tuint16_t *mtu;                  /* Pointer to MTU from dev_data */\n \tuint16_t csum:1;                /* Enable checksum offloading */\n \tstruct pkt_stats stats;         /* Stats for this TX queue */\n+\tstruct rte_gso_ctx gso_ctx;     /* GSO context */\n };\n \n struct pmd_internals {\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 1e32c83..e2ee879 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -38,8 +38,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PORT)           += -lrte_port\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PDUMP)          += -lrte_pdump\n _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR)    += -lrte_distributor\n _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        += -lrte_ip_frag\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_GRO)            += -lrte_gro\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO)            += -lrte_gso\n _LDLIBS-$(CONFIG_RTE_LIBRTE_METER)          += -lrte_meter\n _LDLIBS-$(CONFIG_RTE_LIBRTE_LPM)            += -lrte_lpm\n # librte_acl needs --whole-archive because of weak functions\n@@ -61,6 +59,8 @@ endif\n _LDLIBS-y += --whole-archive\n \n _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE)        += -lrte_cfgfile\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_GRO)            += -lrte_gro\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO)            += -lrte_gso\n _LDLIBS-$(CONFIG_RTE_LIBRTE_HASH)           += -lrte_hash\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMBER)         += -lrte_member\n _LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST)          += -lrte_vhost\n",
    "prefixes": [
        "v4",
        "2/2"
    ]
}