get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41432,
    "url": "http://patches.dpdk.org/api/patches/41432/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1529795861-1361-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": "<1529795861-1361-3-git-send-email-ophirmu@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1529795861-1361-3-git-send-email-ophirmu@mellanox.com",
    "date": "2018-06-23T23:17:41",
    "name": "[v5,2/2] net/tap: support TSO (TCP Segment Offload)",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "1ccb28abaefa75274300d732fb074e4135699a8f",
    "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/1529795861-1361-3-git-send-email-ophirmu@mellanox.com/mbox/",
    "series": [
        {
            "id": 215,
            "url": "http://patches.dpdk.org/api/series/215/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=215",
            "date": "2018-06-23T23:17:40",
            "name": "TAP TSO",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/215/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41432/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/41432/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 DAAD41BB52;\n\tSun, 24 Jun 2018 01:18:09 +0200 (CEST)",
            "from EUR01-HE1-obe.outbound.protection.outlook.com\n\t(mail-he1eur01hn0235.outbound.protection.outlook.com [104.47.0.235])\n\tby dpdk.org (Postfix) with ESMTP id 52AA51BB6F\n\tfor <dev@dpdk.org>; Sun, 24 Jun 2018 01:18:08 +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.884.23; Sat, 23 Jun 2018 23:17:58 +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=YUzKGuEagx4Hi9ZUM6dBn0g+6IGQzEVb6L3UQvk0cMA=;\n\tb=WMTxGa2ZEM3DNG5gNjKg2cZpimlMxTxy1Tnhqg+5jkgk/iahVcAdtGmSXA7HZtAHvA9VJh2WmHrZuPFxLD3vXhmx0vPg4AVm/htro/2x2beAueR52nyzPnN9OUZQIC4IYbaP2bzrOZjchJem2TlP1H+Wc4+7JvUUemLoLeX8rU4=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=ophirmu@mellanox.com; ",
        "From": "Ophir Munk <ophirmu@mellanox.com>",
        "To": "dev@dpdk.org,\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": "Sat, 23 Jun 2018 23:17:41 +0000",
        "Message-Id": "<1529795861-1361-3-git-send-email-ophirmu@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1529795861-1361-1-git-send-email-ophirmu@mellanox.com>",
        "References": "<1528821108-12405-3-git-send-email-ophirmu@mellanox.com>\n\t<1529795861-1361-1-git-send-email-ophirmu@mellanox.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[37.142.13.130]",
        "X-ClientProxiedBy": "VI1PR0901CA0090.eurprd09.prod.outlook.com\n\t(2603:10a6:800:7e::16) To HE1PR0501MB2314.eurprd05.prod.outlook.com\n\t(2603:10a6:3:27::19)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "926d9c86-0df7-41c9-5930-08d5d95f8f56",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0;\n\tRULEID:(7020095)(4652020)(8989117)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600026)(711020)(48565401081)(2017052603328)(7153060)(7193020);\n\tSRVR:HE1PR0501MB2314; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; HE1PR0501MB2314;\n\t3:qHAP5vRaV9Jo4NVNBb6J2xOmsYZ45coCzjOdrPqqF5hp5xYgXzDVTXOfJvpaSoSzidO9e9KSUPxeFwVDVctLv9jT2+Byt1pJbF7i1TyumSb68rOnSGn/tn53eDdSP+0q9MoTGNPEavDWMsKbrCLE0KNR3iWGXfGPRLvt87AyzCEpBCKtrVew/EMU3nkcjn2G8D+l2yl0ZHkhb2xpRZHLxUrgnb6Lp7qTYVaNmOINVx6ukEL93imwfGWoA6dzogjl;\n\t25:Zt/ar63mRinay9LYCbcH7B7XD9fUb5uEHsColVgc/XHMSn7Cnic8uvhlt+3tYVd7XWEI27+aZdkDAZ/Jn+KjrvsqD/853geew5DsNiV5mMbQmZ41/6gJk0h60vMxEDupliNMVL4ReNNMfyatB3u+AYLxNy95HlqeVGcz5gOs3pm+G1mWQHf+fvCSeiNR/L5cNVOssMABjdzi5Ta798/hZjNo08bmhslNkvew76Tpc4UnI/PXbbWqp0/ExYHHMwvyr1q+JlFVZbCew+dZK+UzOyh8+Y8elgZFH+0iLgSezY8fIGxRiUukV2UAPF/34ophVA1EKXYwltd870m7ojFXXg==;\n\t31:W734Ju/ToGmgdrLjGCYGg/fmQVNQvRbzbest1/CrT5OBG2FncvhKoAbGT1beFXzw84MzI9Y1Lzq1uzwqkPvxQ5GskWOZWDvdLwwLTij6uaoVqiRvpTMyPZ3QmzdbzVTUYhiLnCsuWMwP/80DQy/obWjCoV7yCs6EethHJiuMiaU7LT6UrVRucdUfBOiZOiySpXbGw7NQsnMGBbqZtjibe4uiuOu8Ne1QvhsFvG5aEFk=",
            "1; HE1PR0501MB2314;\n\t20:787nLNCAT/NMmUQyyXNPiBia0PuYRwqhQtMVu7FHCxsDV476Fq5XFZjdxR1/Ged40cFDZymFUqVSoJYox04/gRYxhX0pqc/iave0DG7lsAbitALNtYylPqqlpYgu8TZcQZZ5RcmEsMezn7csaUYeRwr8yiFRO2JaArk6uSA4udWvxAGF+PLl796GBmGq+BoubCfTPDWxWrdi/xJXz85li5cpgUPlXPlDQQxaPzcoDdQGLnhjzIqzYKHLXi4W3gmnHiPK35FqSFgtdEg1rZTwRUnYLQpr8eE6zXQa0FfCCOR26Hx2ioHWEdF7O2Rl2tG4YvUYEPQ+j94jac65oJEYfrbNZguF3rfBKVXai+GTl22jgvF8IDRZqoU5tZYnmHpRZHH8y6rPV3CS+OiLkfhTOu92yOu6VwRKBw5osBynOyN/YsC2V+eef1Iovdma1Ypmygsgoy9QjEnBQbSJh2o/EaZsyDGpvlrCk/d9E+8uuDQayVXKWv+bMIQvNQdgxz6i;\n\t4:bDDgDNYCwQdOpXplSNFXjnEkgoN/Npko/TG5gDtp7klhmR0Il0VirbgotEbiCWKb99EPznoTeEPLpIIXmzTI80/3plNFt/EpVYebAxCpRAexGnIMN9fwTwJJnKEK9MfgZJQ418OTSnf6RIlev3rVteUhmJOWdf5ebTDTfffOAyaohsoaNFobVEfiedon4QFvq39d5E9V/Z8U4KTp+gjx91dD+1iEbOlcBnbbAgdap25viY+t+rPfhwk1bXCrRE/2xHoLMezIu3HvXlqF+PAsIel59aCm0ISx2CPosHdzw1PMu151kLhl1+ZTBa/+2cwn",
            "=?us-ascii?Q?1; HE1PR0501MB2314;\n\t23:D67tKjeY7HiJpQKnTLRWDXcQe89kzTJsaAN1pxx?=\n\t7Wl88OUV2cnmBkB8ApZGf+K1oUgLk+VIOhH2aY/fEbvMlJarhiKaTRVYCMO6z9kJmGVDVyk2+I6Plia790JZ+LK7MxLZfa6SP98WdDypwz/ul6Gp4KG/UxpR/9KLJPEid0nb1SMoWhRFjt2HH7+7RPSHTO31O2sfcSAnwhPW89nAFUJsd6qQFOpfSHziJexRGDX6t0/KzaEo95QMgpUbM1CEGmIgQ8JAd/KbSJBthWOJ1Bt95aunn1MbdE9U1tc2RnlsuiK+GnynL0LKXBmhTDJCYg5UXLkgP1+EjD3U2NPm6yo43YjExRb6Etb4JqccS5RyzAIEodqcvnduyfeguuF7vC/C8tEZmlVc7yNuLFclK8EYIY2N6SMlUFmRpCBlb1EVaeZzvojVSVcove7fEn+Bhv8vF63Dz/Ochwfwn4qqjQ3A25lvTWHK8yghH4WRIP+f2xt656k+v9UQQ2+UmeAiK2a8BQVXOppCMR5wa5sFqBK+XGK0z2gePLuE90EJcest5qEKlKM67l4oIVTKq/SNtzodGq36OA3pqfhlhqbrWfiLW68SiBT6mPrn3pObAJfLjVvKHQaczjEk1FwiqEtVqTms6U4o7acrgIAXXd6rjb9hpeK2TXo9OEU8G+EEL+VKgLBLB3dRH41Ghay0PnyRsO+95f/Jztwjb6ROR19Hr8o/wAbBJVkYfif0ai0S8bloI+3uBkWqkjPCUONQDVGtvi9UCghz56A3KywFBTnNmkKz6UFEdnjjKjgczOSCFBRdz54xX8uZVvHAk22PmpWcaHSe3yDzLE+Xw8wgb1MbCpnLJ8ZoG6wj7duuNOBTcnxA/Wi7QPuGYYH4O6wt09j+C0OQR/IfR9rGAJU/uszPsPzRzFZmR3UT5jeFubDO6SW6y/n+cdTwSoCuX78+0LDq2/9HRd5TTxWD95dX1h9Jr/IK/LDmLmhgRi/cHqZ/9zpqh7x9JP1FZkWpsqcj1vDOQzQEkOmXZpU2AtM861pxdRrfNzxN0+LGgHQQ2yhRdHithxE3gapLGEFttkQsfx2Obq8h2SvX7O8syeTNEk48H6mnkKIC1ngKIOyssqJoFu2yjMwz8yOPzwTtuorif+Z4aHCK40xd6cY+3ZihFuKc6uUAixx0Vs2Am8rV8oU8H5f5RWt8enr54ZcyZgh5KjjT9VaFWFuLmTv2QqmDyjSo/v9jfx4rxLZ02oFIDJl+oo0xyde9UsfSzu8klS8nmdZfs83gvII5SGy508FMNCNa+wnfaeFi0ppFMKvmfrx4UXOTJZ/AX470la8pjp1oo24KeM2fn60aHIIc40rdxpkaggG5nFccCzMEn53BgGuI2hFU=",
            "1; HE1PR0501MB2314;\n\t23:KyfGf76CBb/u1x3LCfQ7xdZ8ytDNh3EijwdnINFZt4Mn2a9HLvZh7AKjAveY8U273uaBeBY2/77c3sLMLoofpgMn9ThQ6jAB81Hp2Mr19mWhCKENoIYTSBLRcUUMDjOOxdZnlx48RmcsQhnurLJYcg==;\n\t6:RiwWnmm6DZAObtiJ5t2rotxJ2XKmw3CHJAWz+h++I1CrXdqpRLCP9RHBZchTtQ3cUYF78/X1oqep+pcTd+jdgatThaRCFYsdGK0P2HlgZSFNCZYsNxq7qLglT9bH1E/lr51V/5bocGkbRdbS66Pk8/oIK+mnOPgD9y9DGX+odz5dNme9fFwfSFhlPoWWbwj/05bTjTMvNKdRdlPGpI14ZrhDT+xb3BfW242dFdYzWCkxxeMc1xfSpmQKq3eP6aqmBd2REt/dwmr2bSytxeJ0xlz0mj06+r8mDw5r7nZLkPp15OJ/KLrzyP036rEi96c7oqlvvkz3NF56rlRAqPqG67dt+X3AorrwLaaAK1mKLC2x0xtZA9lQu/1IjuiKOnfHUtPgPO0TeXumQ9/P0lWFriqd1DYXe7TkwQ1f2qJeXRATl11q0LeKpE3DyV5s0fcLL2IsteA9AqDdy/5bmLJqZHZTatFgNx2v4Wco3Ql9VePcuuY3C2oCfua/d1SLODpc;\n\t5:9zNlFrkkDa5+vJDdxDKfSs1L+3dqzqfdwzeqPTejOJjfr1JeZzMSmuK/QsWI2FUSJDqvYe2DQMoBuoQ9aP2uuoio5KZ9TSvCksXrLGOdoT6PbWLGd7TVKoT0PROKstoHRBdte6U83qnuhYNBbgza9h44g6XEE9HfrAYYzcrGywA=",
            "1; HE1PR0501MB2314;\n\t7:ofmOQz69/KowKgkyxfrbccWs/3+33JbaghuLP8lz5B7oNYhpa32MgRfHR1VRweYN5mwXUYsmMULA1TXJxZ9AoRotSc7XIN15CVKV9Izvo243ZKFpgrenRIVqanm8LNWRGmQsIC5OjTXoQYitmSBYtVKwYHOY1b72Os8rNis60qXwu2sWMQBZDQ/pnoX72BHAND7oyzk8M8u84iF68LujBpFxbFrwQK4fPqJPvdq+OUdGklVj1/4EvNlF+LXzavMS"
        ],
        "X-MS-TrafficTypeDiagnostic": "HE1PR0501MB2314:|HE1PR0501MB2314:",
        "X-LD-Processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "X-Microsoft-Antispam-PRVS": "<HE1PR0501MB23146D53ED4C1014A713506CD1740@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)(5005006)(8121501046)(3231254)(2232096)(944501410)(52105095)(93006095)(93001095)(10201501046)(3002001)(6055026)(149027)(150027)(6041310)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011)(7699016);\n\tSRVR:HE1PR0501MB2314; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0501MB2314; ",
        "X-Forefront-PRVS": "07126E493C",
        "X-Forefront-Antispam-Report": "SFV:SPM;\n\tSFS:(10009020)(366004)(396003)(39860400002)(346002)(39380400002)(376002)(199004)(189003)(575784001)(26005)(86362001)(7696005)(16526019)(51416003)(7736002)(52116002)(55016002)(6666003)(2906002)(107886003)(4326008)(8936002)(4720700003)(16586007)(21086003)(186003)(36756003)(69596002)(3846002)(6116002)(76176011)(386003)(66066001)(47776003)(5660300001)(106356001)(316002)(105586002)(6916009)(53936002)(956004)(476003)(68736007)(48376002)(446003)(486006)(54906003)(50466002)(8676002)(81156014)(2616005)(81166006)(478600001)(11346002)(50226002)(25786009)(305945005)(33026002)(97736004)(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": "tQyKgTp5RxTQRYsD4fWHpDkf9eqX8HN/a2bcQtoBNtScln/idBbcoCqq3p8KH/jpXNx+wfzmWkI8A1gPB7iMCWgFUP+3IbsigaEQds1G9ZeQ0wixIuzwiGBp+I6PFP4yTFfsSqtB/etSoeAvhYAwfAD+FpZSoX5AnhsYF7jg1le2pvLJ/1paS48O+yulaXCuIGp+y++wOpngkK1g62SNesRlFHNMHr7p3KD4KywV/TOD7OoQrf9NSkNohN+Siwt4BuOUNvK50sWqjvDr74esLt6oVHd0wjJb5CBAYYADWi/jQw8LJIIm0/bQQVIpZXs7Q/AOBNLCadmRcjBmdz3CEikux6Lug+ZCMoG20TyS6rY47wwcMBJeFkbQJadpqA9dvwk86JhjW4ewVfwjKgzHD8YrfWEllBkcZ9imxtfY4cFBjxKB4i1YFXFuhSKh0XVFQeKi9gvhV4D7EpSA6IBgCu3fhGwEG/25vdkwALhATjOiUt8Ni/+jcvu7jGP5kM0UAz96h8LprbtAqa3Qbcw4n+YbUleAkBgB/jp/JdAQMKjx70ud+lG0Tx7gRae+4VgrzPpW4ifPkmNcQD0kEg9bQccAPabvtMbeHrbIxxO53cO9282oSfthMY5i0hXHU/e1qmOw7uTDV3Y+LspteVDjbtcvSZoSg4sBoE31ak5jI38r0CC/CO8vs+Rv3Zn0zNqwa56EKCdQ77lKPooiGNSDbg==",
        "SpamDiagnosticOutput": "1:22",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "23 Jun 2018 23:17:58.2606\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "926d9c86-0df7-41c9-5930-08d5d95f8f56",
        "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 v5 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://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/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 | 174 +++++++++++++++++++++++++++++++++++-------\n drivers/net/tap/rte_eth_tap.h |   3 +\n mk/rte.app.mk                 |   4 +-\n 4 files changed, 154 insertions(+), 29 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 8903646..d137f58 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,12 @@\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_PER_CORE\t128\n+#define TAP_GSO_MBUF_SEG_SIZE\t128\n+#define TAP_GSO_MBUF_CACHE_SIZE\t4\n+#define TAP_GSO_MBUFS_NUM \\\n+\t(TAP_GSO_MBUFS_PER_CORE * TAP_GSO_MBUF_CACHE_SIZE)\n+\n static struct rte_vdev_driver pmd_tap_drv;\n static struct rte_vdev_driver pmd_tun_drv;\n \n@@ -412,7 +419,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@@ -480,23 +488,16 @@ 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,\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+\tuint16_t l234_hlen;\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@@ -504,8 +505,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@@ -513,10 +513,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@@ -558,8 +554,8 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)\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@@ -603,13 +599,90 @@ 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+\tuint32_t max_size;\n+\tint i;\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 = 0;\n+\t\tuint16_t tso_segsz = 0;\n+\t\tint ret;\n+\t\tuint16_t hdrs_len;\n+\t\tint j;\n+\t\tuint64_t tso;\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+\n+\t\t\tassert(gso_ctx != NULL);\n+\n+\t\t\t/* TCP segmentation implies TCP checksum offload */\n+\t\t\tmbuf_in->ol_flags |= PKT_TX_TCP_CKSUM;\n+\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\t/* ret 0 indicates no new mbufs were created */\n+\t\t\tret = 0;\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,\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\t/* free original mbuf */\n+\t\trte_pktmbuf_free(mbuf_in);\n+\t\t/* free tso mbufs */\n+\t\tfor (j = 0; j < ret; j++)\n+\t\t\trte_pktmbuf_free(mbuf[j]);\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@@ -1071,31 +1144,75 @@ 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+\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\tTAP_GSO_MBUF_CACHE_SIZE, 0,\n+\t\t\tRTE_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@@ -1120,6 +1237,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": [
        "v5",
        "2/2"
    ]
}