get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 31031,
    "url": "https://patches.dpdk.org/api/patches/31031/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1509358049-18854-6-git-send-email-matan@mellanox.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1509358049-18854-6-git-send-email-matan@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1509358049-18854-6-git-send-email-matan@mellanox.com",
    "date": "2017-10-30T10:07:27",
    "name": "[dpdk-dev,v3,5/7] net/mlx4: separate Tx segment cases",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e4a4f995795473d49d6f2fd3471f388f6cc72d1b",
    "submitter": {
        "id": 796,
        "url": "https://patches.dpdk.org/api/people/796/?format=api",
        "name": "Matan Azrad",
        "email": "matan@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1509358049-18854-6-git-send-email-matan@mellanox.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/31031/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/31031/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 4F2991B33E;\n\tMon, 30 Oct 2017 11:08:14 +0100 (CET)",
            "from EUR02-HE1-obe.outbound.protection.outlook.com\n\t(mail-eopbgr10045.outbound.protection.outlook.com [40.107.1.45])\n\tby dpdk.org (Postfix) with ESMTP id E10CE1B2A0\n\tfor <dev@dpdk.org>; Mon, 30 Oct 2017 11:08:03 +0100 (CET)",
            "from mellanox.com (37.142.13.130) by\n\tVI1PR0502MB3662.eurprd05.prod.outlook.com (2603:10a6:803:f::17) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.178.6;\n\tMon, 30 Oct 2017 10:08:01 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=PyMfALOarSbKCqtYyW+KgrLZvBGPDoutLJV6v31J4eo=;\n\tb=XHL5KEg0VTkY9FSN36tsq2x3fgpg958Jnakm5Ic2UG3RqQSSpHFTXTGRsk40mmoVICFzCFw17AnDCXUBATJ+NJz1KnMYUfMJqR50RwKHqjnlCZHMjy7zeLwj6IpRBVvPMFaDZMum+ecSdRIyLDPF3dB4M46juSDWI06JgwEwXV0=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=matan@mellanox.com; ",
        "From": "Matan Azrad <matan@mellanox.com>",
        "To": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "Cc": "dev@dpdk.org,\n\tOphir Munk <ophirmu@mellanox.com>",
        "Date": "Mon, 30 Oct 2017 10:07:27 +0000",
        "Message-Id": "<1509358049-18854-6-git-send-email-matan@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1509358049-18854-1-git-send-email-matan@mellanox.com>",
        "References": "<1508768520-4810-1-git-send-email-ophirmu@mellanox.com>\n\t<1509358049-18854-1-git-send-email-matan@mellanox.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[37.142.13.130]",
        "X-ClientProxiedBy": "VI1PR08CA0217.eurprd08.prod.outlook.com\n\t(2603:10a6:802:15::26) To VI1PR0502MB3662.eurprd05.prod.outlook.com\n\t(2603:10a6:803:f::17)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "2a431332-c1c3-4903-6e92-08d51f7e1b2a",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0;\n\tRULEID:(22001)(48565401081)(4534020)(4602075)(2017052603199);\n\tSRVR:VI1PR0502MB3662; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; VI1PR0502MB3662;\n\t3:QTJvME+8Yf9MBeO89C/4E8MmxsNxV1ORbPV2+EQkJ0jjtqjyzUpcjpAlZbNAgwD3iSapGdlstpcVH25VEEyz37Q5MeZZeiPxW+YCfL2Tu1pMG6xeIicufXWc3fbqRG+hNN08lFQgQXsNXxfymHMsjiBca72UWroQIWWfHkLZqbyD9pj2XVtL/iYLIuff4gOMJeFTViWU5WUhtXUdbHg6KHWN6BNvILeyfpp/+5TN6mlahPZ4qF+Y9WCDBJflcvlK;\n\t25:LYYV4YzX70MgflZiPD06IIeo3KiAwrjclYtuEmlMw/sM4zt0GlatV0hlxv2pi1SkzOhfgXdbn40XJwPgq6TltvptP9cluOn9aSMScuHSfOz85kQICz38zzMxkDorGDvgaj5stm75L0JqiYJ/taSfqZB+17JIqHLdVmT3jRcdtGoPs1XXc2SBFbRfgLcB7O5y26TqVcLmsD7UWVqhrbHCIKjrknNKPxz9w8qJT4Ud2EZc0xVULhZob8HVYElsaiMbUAYgZ0CUWgBY3nCoAKk+O0raFdE4ZyfTwTueYpyJxm+KlmrHsYd+Yz3FqmdTwgHG1vBqk1a3GNNgtAJoQA8bSg==;\n\t31:tFqO9J1KvZSAXt+ZJ4xzcfQi0asJU3hQ/w2h7W0HRjTdv5x1aZ28HDm5BBR6c9/AgsPGfOIKxIBe4ZD9DrSFEhVF59dB34s6tGK9CH4McmlAS1tmhWL6Dn2PUa1+kmG0R5vhj7DMVHykJjel1qOwLXVTWmLivoSBemkpOQNXY4IB25FcwMrAB1I12ECzIgG9IE+V5UNeC7nhVhkhSnyvMJfM0foeabDOPMamdegWF0A=",
            "1; VI1PR0502MB3662;\n\t20:xD1og9d+YnTJtjFhyCh9JUn3PZgBB5pELvixBSd/jwU6ws7PC4a1FThv5Nhed2affTvV+DULmXpThuum/ql2UdY5elHwzdQSHWyfjUV81EgqiYzvFoQfhvp//kyzuyxT+sCdvInCNbF1xEpHeu4DSTXq/40XkWEWEvGofvCSmizAZG/LHIIOmAL0Bm6boDENrv24dVHlFQAKYO89xMFeVBsWzGJi6MDn/Q4FP++nZILaUGv989lbbP6ARwqLXhIrcWDL3SEzQQVnw73efGwscShO3rbrRW7Y43M0ryLfbe91C1GDKwMrawGq+q3mp6Wpy4PLW2ntdk1a9s/pl5owQiG7mSNH6qyUHO2cbG1254lZzFdirHVuojABhHzNm+WZJEyZcBifOvmG21dMNnTX7ePsggI7mzzDqXObt8qharpXhLnGqraFMef46x/4E+6O+hUeJlzYMikMmiGzMswIzSX0kRJaT5Ir0CSk6VwhnvIDAQst7ryk/o0N03N1Hj/m;\n\t4:IMiRs6rzq6tJei1snfTwzpb6YP+LgZR5gdSgKLfR6uddCxJd6eaDwbiAXyauz2GHPCkoOD2D12pNa670M3No2dkChKvhr9yJIbB3RZglzNVL6DuUzxphBcaz37DmnC2hqD5okmU0I+oohPf51D0bCU0xMlvdQcM19u1UL2I4cuj1rAt92tYT4dGUj9vrXb+5VbxriwiqSqnu+12r7se4YeFQRbTgMOhMUn9aRVkpqnL2o71LQ3J0LjZRLNb2XlSOe04lNyhehg1PDN9qoiNm0K0d3d99VQMNn1lnWVwu/Jkil+Dz2Sql1ZO4JIq//lIn",
            "=?us-ascii?Q?1; VI1PR0502MB3662;\n\t23:mdoUcDmXw8dSCTE/YH83BdVx73OxxVRuheh5WWx?=\n\tyYKgwBxccFjeT+JO32aqegdNFUNn/5mgTO1tZfmggflGDadUqP2HwDHD4X+n5pE1SNXjGe4T1CjAqXg47payh1aqoYOvmgCfySv2O5Z53Yhza0Gza3hNxADkblrbzVe7sI9Y81kdkBM6VLhxbGd3OTsZVxO8xatxed2IqHZn+cmicanQOjkusetScS2dPFtXvcnU3kKaUFblvVqyr1/8PSihBcXmYdQrbHVFssEJQ1Q4fewhWFsUhS56rpOqVR+MmA3ggwZ+0H56jrXv8M0y8K8VpZcqF+lh7ouRSRb2HmZNdX+ZNK7SCOKAIjZ4BcrqvlMYeRW3ZYg3hZsad4qIeW5y287qQPmMrS0sSLcUaVdMMHbTTjXtn9EEZlcgn29+1TrNS6CRFr0HoSF6r+YW7NR+Iw/w2Nkbd1iAN7meC0xYOnQusjZyVG/90VOZUVXkMN223MZuVDsX0s9o3t4H1+IrJkDGZjo4Z31W0aHhTNWHvOxtJGuYqaZjTCZyqOjQxKbCzKA5XukfmesTcCWNPe/XNMcQy4hDPbHr1AF+ST+YwRs/+oswWj/TPQwlr5rDrG1RAuOWW8hC0br5Cqf1kXOGVK9rcBPkBLxWHROIrrJp4ndbaw8UQFseaou5nbHNqAmmuJAJsbKfePSkZncnaA/nbFxGJ4wBl9qfweEjPFRK7+VKxgJuwvsLXPzIWUrxJ0I8xUVYaShU0SzRL/7E0WrD+buxcJVSn+B9mSIhiPeqNzcDkvUbq9AoecpGqDB1JbObEJyOfT9xknyN1Or/L3NJyJ22uew0OOgKIEHpH3CdjuF5xzKv3UOHhHPpT58EC6UoY7yR26O8URFIh3HXMtkH9b7VfwY/oaG18MZu4JR71o3PUpXfJ4cNuNnO0O6FKa77nxIElNlZAog2tBMKMwJcTVidfdjWq5OzkMlPptz768GjRiTTi8LVWZx6813Mao3nA8RFVtbVsNnDJpeNQSKMndIaGEUa5l0sp+sWAwIbc3X6fbDAtiEhwU9mQW9LotkOyozimcwE8Cf4u0pzEELedUPYAs1qOSPN4+0HzywC6sABTzH11TpKOw+kzEs2oDNz5EU7X3f0QCK/BFKzObZYIK3+7ArrJxCibP0KuircF9Q==",
            "1; VI1PR0502MB3662;\n\t6:6lD+QQPW+5EM987mGDpxI7YpZVoKUjZof2uRwA4LgoFmQCTK0kntG469HPKoO6JrVQ6CCBGvFtCuX/M2MgX9qQhHP1gDPDhCQPdTbuNVq7xEv1qSALqpW3qMu0dDwdO54K8wqbhkoCIsL5Bg1Vxn1k/27/SjAEOztAEVGEoZ/sYCC7wS02E8YChYge+93HzvyTzm2xqJhjwXVfWf9Js0b5mowyIh1HKQ1eMJqcP4+jDbxI1Svltzr0AvZi/ZyXA2HbkixpZM6dASfhD5RBcoazQ37sXs8KE4hNdysbhxQIFNbr1BQiSl+VKOSy1++24Hdg9/TL3s0jGfNekyJyefzFkPMJohwWIvC4VmfKPeTlE=;\n\t5:5PldJdGkMF4NxAccYDYK5vut9PyG3iywFoQFioxynuZXwaTLSMqk2aUK/lRz8azzk5lLbhMdFm8XAKAYpGUwdtlIuWx2MeOBuipsL7BcZLR13sQ8QP/obDU+tPzRLu73pqo2LuAXIeey+pfAD0DGa6kO3cmOQeUtIdB/hw/J+9c=;\n\t24:s0E8/OOpPRtA2EkPDs/K9GV5XlhCRK9Js9NpnUf03WMfqnJqqseovcpKNioHjZ7VDDAlEFknA57OlLLobbVIxb2U4S//NE3UDcp7TzgNeYQ=;\n\t7:kwfCWvMZyY2Gd+UQua4Kj+lLZiczT7AXY+474oliNoHqsjZdO6mUgmAp6XC5xTF+t6SrRCjWHRSryVrc+RXFSRrQ+KNc/Bzin3zsva/IbpPNG8AKxIRoxx4ZtvkPdnV9B8RTtSKwXR5onMTz+aTAnpSdd6M0KRMKrw6GYuXGUZpbE2L4Wje7dCT0L5aIFC/m2Z3Sbyw1y7F36X2YOxAWn+sUp28nO5yxUMhD+ZvdlLt8+hQeMaCZi8obazUQA6mA"
        ],
        "X-MS-TrafficTypeDiagnostic": "VI1PR0502MB3662:",
        "X-LD-Processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "X-Exchange-Antispam-Report-Test": "UriScan:(60795455431006);",
        "X-Microsoft-Antispam-PRVS": "<VI1PR0502MB3662A88C79920F0AAA7109F8D2590@VI1PR0502MB3662.eurprd05.prod.outlook.com>",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(3002001)(93006095)(93001095)(3231020)(10201501046)(100000703101)(100105400095)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123555025)(20161123562025)(20161123560025)(20161123564025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:VI1PR0502MB3662; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:VI1PR0502MB3662; ",
        "X-Forefront-PRVS": "0476D4AB88",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(6009001)(39860400002)(376002)(346002)(199003)(189002)(16526018)(97736004)(66066001)(47776003)(21086003)(5660300001)(4326008)(50226002)(316002)(53936002)(55016002)(4720700003)(6666003)(16586007)(6916009)(48376002)(36756003)(50466002)(2906002)(7736002)(305945005)(2950100002)(106356001)(101416001)(6116002)(3846002)(69596002)(68736007)(33026002)(81156014)(81166006)(8676002)(105586002)(189998001)(33646002)(107886003)(478600001)(8936002)(5003940100001)(25786009)(86362001)(76176999)(50986999);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0502MB3662; H:mellanox.com; FPR:;\n\tSPF:None; \n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ",
        "Received-SPF": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "30 Oct 2017 10:08:01.9117\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "2a431332-c1c3-4903-6e92-08d51f7e1b2a",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "VI1PR0502MB3662",
        "Subject": "[dpdk-dev] [PATCH v3 5/7] net/mlx4: separate Tx segment cases",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://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": "<http://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": "Since single segment packets shouldn't use additional memory to\nsave segments byte count we can prevent additional memory\nunnecessary usage in this case; Prevent loop management.\n\nCall a dedicated function for handling multi segments case.\n\nSigned-off-by: Matan Azrad <matan@mellanox.com>\nSigned-off-by: Ophir Munk <ophirmu@mellanox.com>\n---\n drivers/net/mlx4/mlx4_rxtx.c | 247 +++++++++++++++++++++++++++----------------\n 1 file changed, 158 insertions(+), 89 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx4/mlx4_rxtx.c b/drivers/net/mlx4/mlx4_rxtx.c\nindex 8ce70d6..8ea8851 100644\n--- a/drivers/net/mlx4/mlx4_rxtx.c\n+++ b/drivers/net/mlx4/mlx4_rxtx.c\n@@ -62,6 +62,9 @@\n #include \"mlx4_rxtx.h\"\n #include \"mlx4_utils.h\"\n \n+#define WQE_ONE_DATA_SEG_SIZE \\\n+\t(sizeof(struct mlx4_wqe_ctrl_seg) + sizeof(struct mlx4_wqe_data_seg))\n+\n /**\n  * Pointer-value pair structure used in tx_post_send for saving the first\n  * DWORD (32 byte) of a TXBB.\n@@ -140,22 +143,19 @@ struct pv {\n  * @return\n  *   0 on success, -1 on failure.\n  */\n-static int\n-mlx4_txq_complete(struct txq *txq)\n+static inline int\n+mlx4_txq_complete(struct txq *txq, const unsigned int elts_n,\n+\t\t\t\tstruct mlx4_sq *sq)\n {\n \tunsigned int elts_comp = txq->elts_comp;\n \tunsigned int elts_tail = txq->elts_tail;\n-\tconst unsigned int elts_n = txq->elts_n;\n \tstruct mlx4_cq *cq = &txq->mcq;\n-\tstruct mlx4_sq *sq = &txq->msq;\n \tstruct mlx4_cqe *cqe;\n \tuint32_t cons_index = cq->cons_index;\n \tuint16_t new_index;\n \tuint16_t nr_txbbs = 0;\n \tint pkts = 0;\n \n-\tif (unlikely(elts_comp == 0))\n-\t\treturn 0;\n \t/*\n \t * Traverse over all CQ entries reported and handle each WQ entry\n \t * reported by them.\n@@ -238,6 +238,122 @@ struct pv {\n \treturn buf->pool;\n }\n \n+static int handle_multi_segs(struct rte_mbuf *buf,\n+\t\t\t    struct txq *txq,\n+\t\t\t    struct mlx4_wqe_ctrl_seg **pctrl)\n+{\n+\tint wqe_real_size;\n+\tint nr_txbbs;\n+\tstruct pv *pv = (struct pv *)txq->bounce_buf;\n+\tstruct mlx4_sq *sq = &txq->msq;\n+\tuint32_t head_idx = sq->head & sq->txbb_cnt_mask;\n+\tstruct mlx4_wqe_ctrl_seg *ctrl;\n+\tstruct mlx4_wqe_data_seg *dseg;\n+\tuint32_t lkey;\n+\tuintptr_t addr;\n+\tuint32_t byte_count;\n+\tint pv_counter = 0;\n+\n+\t/* Calculate the needed work queue entry size for this packet. */\n+\twqe_real_size = sizeof(struct mlx4_wqe_ctrl_seg) +\n+\t\tbuf->nb_segs * sizeof(struct mlx4_wqe_data_seg);\n+\tnr_txbbs = MLX4_SIZE_TO_TXBBS(wqe_real_size);\n+\t/*\n+\t * Check that there is room for this WQE in the send queue and that\n+\t * the WQE size is legal.\n+\t */\n+\tif (((sq->head - sq->tail) + nr_txbbs +\n+\t\t\t\tsq->headroom_txbbs) >= sq->txbb_cnt ||\n+\t\t\tnr_txbbs > MLX4_MAX_WQE_TXBBS) {\n+\t\treturn -1;\n+\t}\n+\n+\t/* Get the control and data entries of the WQE. */\n+\tctrl = (struct mlx4_wqe_ctrl_seg *)mlx4_get_send_wqe(sq, head_idx);\n+\tdseg = (struct mlx4_wqe_data_seg *)((uintptr_t)ctrl +\n+\t\t\tsizeof(struct mlx4_wqe_ctrl_seg));\n+\t*pctrl = ctrl;\n+\t/* Fill the data segments with buffer information. */\n+\tstruct rte_mbuf *sbuf;\n+\n+\tfor (sbuf = buf; sbuf != NULL; sbuf = sbuf->next, dseg++) {\n+\t\taddr = rte_pktmbuf_mtod(sbuf, uintptr_t);\n+\t\trte_prefetch0((volatile void *)addr);\n+\t\t/* Handle WQE wraparound. */\n+\t\tif (dseg >= (struct mlx4_wqe_data_seg *)sq->eob)\n+\t\t\tdseg = (struct mlx4_wqe_data_seg *)sq->buf;\n+\t\tdseg->addr = rte_cpu_to_be_64(addr);\n+\t\t/* Memory region key (big endian) for this memory pool. */\n+\t\tlkey = mlx4_txq_mp2mr(txq, mlx4_txq_mb2mp(sbuf));\n+\t\tdseg->lkey = rte_cpu_to_be_32(lkey);\n+#ifndef NDEBUG\n+\t\t/* Calculate the needed work queue entry size for this packet */\n+\t\tif (unlikely(dseg->lkey == rte_cpu_to_be_32((uint32_t)-1))) {\n+\t\t\t/* MR does not exist. */\n+\t\t\tDEBUG(\"%p: unable to get MP <-> MR association\",\n+\t\t\t\t\t(void *)txq);\n+\t\t\t/*\n+\t\t\t * Restamp entry in case of failure.\n+\t\t\t * Make sure that size is written correctly\n+\t\t\t * Note that we give ownership to the SW, not the HW.\n+\t\t\t */\n+\t\t\twqe_real_size = sizeof(struct mlx4_wqe_ctrl_seg) +\n+\t\t\t\tbuf->nb_segs * sizeof(struct mlx4_wqe_data_seg);\n+\t\t\tctrl->fence_size = (wqe_real_size >> 4) & 0x3f;\n+\t\t\tmlx4_txq_stamp_freed_wqe(sq, head_idx,\n+\t\t\t\t\t(sq->head & sq->txbb_cnt) ? 0 : 1);\n+\t\t\treturn -1;\n+\t\t}\n+#endif /* NDEBUG */\n+\t\tif (likely(sbuf->data_len)) {\n+\t\t\tbyte_count = rte_cpu_to_be_32(sbuf->data_len);\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * Zero length segment is treated as inline segment\n+\t\t\t * with zero data.\n+\t\t\t */\n+\t\t\tbyte_count = RTE_BE32(0x80000000);\n+\t\t}\n+\t\t/*\n+\t\t * If the data segment is not at the beginning of a\n+\t\t * Tx basic block (TXBB) then write the byte count,\n+\t\t * else postpone the writing to just before updating the\n+\t\t * control segment.\n+\t\t */\n+\t\tif ((uintptr_t)dseg & (uintptr_t)(MLX4_TXBB_SIZE - 1)) {\n+\t\t\t/*\n+\t\t\t * Need a barrier here before writing the byte_count\n+\t\t\t * fields to make sure that all the data is visible\n+\t\t\t * before the byte_count field is set.\n+\t\t\t * Otherwise, if the segment begins a new cacheline,\n+\t\t\t * the HCA prefetcher could grab the 64-byte chunk and\n+\t\t\t * get a valid (!= 0xffffffff) byte count but stale\n+\t\t\t * data, and end up sending the wrong data.\n+\t\t\t */\n+\t\t\trte_io_wmb();\n+\t\t\tdseg->byte_count = byte_count;\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * This data segment starts at the beginning of a new\n+\t\t\t * TXBB, so we need to postpone its byte_count writing\n+\t\t\t * for later.\n+\t\t\t */\n+\t\t\tpv[pv_counter].dseg = dseg;\n+\t\t\tpv[pv_counter++].val = byte_count;\n+\t\t}\n+\t}\n+\t/* Write the first DWORD of each TXBB save earlier. */\n+\tif (pv_counter) {\n+\t\t/* Need a barrier here before writing the byte_count. */\n+\t\trte_io_wmb();\n+\t\tfor (--pv_counter; pv_counter  >= 0; pv_counter--)\n+\t\t\tpv[pv_counter].dseg->byte_count = pv[pv_counter].val;\n+\t}\n+\t/* Fill the control parameters for this packet. */\n+\tctrl->fence_size = (wqe_real_size >> 4) & 0x3f;\n+\n+\treturn nr_txbbs;\n+}\n /**\n  * DPDK callback for Tx.\n  *\n@@ -261,10 +377,11 @@ struct pv {\n \tunsigned int i;\n \tunsigned int max;\n \tstruct mlx4_sq *sq = &txq->msq;\n-\tstruct pv *pv = (struct pv *)txq->bounce_buf;\n+\tint nr_txbbs;\n \n \tassert(txq->elts_comp_cd != 0);\n-\tmlx4_txq_complete(txq);\n+\tif (likely(txq->elts_comp != 0))\n+\t\tmlx4_txq_complete(txq, elts_n, sq);\n \tmax = (elts_n - (elts_head - txq->elts_tail));\n \tif (max > elts_n)\n \t\tmax -= elts_n;\n@@ -283,7 +400,6 @@ struct pv {\n \t\tuint32_t owner_opcode = MLX4_OPCODE_SEND;\n \t\tstruct mlx4_wqe_ctrl_seg *ctrl;\n \t\tstruct mlx4_wqe_data_seg *dseg;\n-\t\tstruct rte_mbuf *sbuf;\n \t\tunion {\n \t\t\tuint32_t flags;\n \t\t\tuint16_t flags16[2];\n@@ -291,10 +407,6 @@ struct pv {\n \t\tuint32_t head_idx = sq->head & sq->txbb_cnt_mask;\n \t\tuint32_t lkey;\n \t\tuintptr_t addr;\n-\t\tuint32_t byte_count;\n-\t\tint wqe_real_size;\n-\t\tint nr_txbbs;\n-\t\tint pv_counter = 0;\n \n \t\t/* Clean up old buffer. */\n \t\tif (likely(elt->buf != NULL)) {\n@@ -313,40 +425,29 @@ struct pv {\n \t\t\t} while (tmp != NULL);\n \t\t}\n \t\tRTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);\n-\n-\t\t/*\n-\t\t * Calculate the needed work queue entry size\n-\t\t * for this packet.\n-\t\t */\n-\t\twqe_real_size = sizeof(struct mlx4_wqe_ctrl_seg) +\n-\t\t\t\tbuf->nb_segs * sizeof(struct mlx4_wqe_data_seg);\n-\t\tnr_txbbs = MLX4_SIZE_TO_TXBBS(wqe_real_size);\n-\t\t/*\n-\t\t * Check that there is room for this WQE in the send\n-\t\t * queue and that the WQE size is legal.\n-\t\t */\n-\t\tif (((sq->head - sq->tail) + nr_txbbs +\n-\t\t     sq->headroom_txbbs) >= sq->txbb_cnt ||\n-\t\t    nr_txbbs > MLX4_MAX_WQE_TXBBS) {\n-\t\t\telt->buf = NULL;\n-\t\t\tbreak;\n-\t\t}\n-\t\t/* Get the control and data entries of the WQE. */\n-\t\tctrl = (struct mlx4_wqe_ctrl_seg *)\n-\t\t\t\tmlx4_get_send_wqe(sq, head_idx);\n-\t\tdseg = (struct mlx4_wqe_data_seg *)((uintptr_t)ctrl +\n-\t\t\t\tsizeof(struct mlx4_wqe_ctrl_seg));\n-\t\t/* Fill the data segments with buffer information. */\n-\t\tfor (sbuf = buf; sbuf != NULL; sbuf = sbuf->next, dseg++) {\n-\t\t\taddr = rte_pktmbuf_mtod(sbuf, uintptr_t);\n+\t\tif (buf->nb_segs == 1) {\n+\t\t\t/*\n+\t\t\t * Check that there is room for this WQE in the send\n+\t\t\t * queue and that the WQE size is legal\n+\t\t\t */\n+\t\t\tif (((sq->head - sq->tail) + 1 + sq->headroom_txbbs) >=\n+\t\t\t     sq->txbb_cnt || 1 > MLX4_MAX_WQE_TXBBS) {\n+\t\t\t\telt->buf = NULL;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\t/* Get the control and data entries of the WQE. */\n+\t\t\tctrl = (struct mlx4_wqe_ctrl_seg *)\n+\t\t\t\t\tmlx4_get_send_wqe(sq, head_idx);\n+\t\t\tdseg = (struct mlx4_wqe_data_seg *)((uintptr_t)ctrl +\n+\t\t\t\t\tsizeof(struct mlx4_wqe_ctrl_seg));\n+\t\t\taddr = rte_pktmbuf_mtod(buf, uintptr_t);\n \t\t\trte_prefetch0((volatile void *)addr);\n \t\t\t/* Handle WQE wraparound. */\n-\t\t\tif (unlikely(dseg >=\n-\t\t\t    (struct mlx4_wqe_data_seg *)sq->eob))\n+\t\t\tif (dseg >= (struct mlx4_wqe_data_seg *)sq->eob)\n \t\t\t\tdseg = (struct mlx4_wqe_data_seg *)sq->buf;\n \t\t\tdseg->addr = rte_cpu_to_be_64(addr);\n \t\t\t/* Memory region key (big endian). */\n-\t\t\tlkey = mlx4_txq_mp2mr(txq, mlx4_txq_mb2mp(sbuf));\n+\t\t\tlkey = mlx4_txq_mp2mr(txq, mlx4_txq_mb2mp(buf));\n \t\t\tdseg->lkey = rte_cpu_to_be_32(lkey);\n #ifndef NDEBUG\n \t\t\tif (unlikely(dseg->lkey ==\n@@ -360,61 +461,28 @@ struct pv {\n \t\t\t\t * Note that we give ownership to the SW,\n \t\t\t\t * not the HW.\n \t\t\t\t */\n-\t\t\t\tctrl->fence_size = (wqe_real_size >> 4) & 0x3f;\n+\t\t\t\tctrl->fence_size =\n+\t\t\t\t\t(WQE_ONE_DATA_SEG_SIZE >> 4) & 0x3f;\n \t\t\t\tmlx4_txq_stamp_freed_wqe(sq, head_idx,\n \t\t\t\t\t     (sq->head & sq->txbb_cnt) ? 0 : 1);\n \t\t\t\telt->buf = NULL;\n \t\t\t\tbreak;\n \t\t\t}\n #endif /* NDEBUG */\n-\t\t\tif (likely(sbuf->data_len)) {\n-\t\t\t\tbyte_count = rte_cpu_to_be_32(sbuf->data_len);\n-\t\t\t} else {\n-\t\t\t\t/*\n-\t\t\t\t * Zero length segment is treated as inline\n-\t\t\t\t * segment with zero data.\n-\t\t\t\t */\n-\t\t\t\tbyte_count = RTE_BE32(0x80000000);\n-\t\t\t}\n-\t\t\t/*\n-\t\t\t * If the data segment is not at the beginning\n-\t\t\t * of a Tx basic block (TXBB) then write the\n-\t\t\t * byte count, else postpone the writing to\n-\t\t\t * just before updating the control segment.\n-\t\t\t */\n-\t\t\tif ((uintptr_t)dseg & (uintptr_t)(MLX4_TXBB_SIZE - 1)) {\n-\t\t\t\t/*\n-\t\t\t\t * Need a barrier here before writing the\n-\t\t\t\t * byte_count fields to make sure that all the\n-\t\t\t\t * data is visible before the byte_count field\n-\t\t\t\t * is set. otherwise, if the segment begins a\n-\t\t\t\t * new cacheline, the HCA prefetcher could grab\n-\t\t\t\t * the 64-byte chunk and get a valid\n-\t\t\t\t * (!= 0xffffffff) byte count but stale data,\n-\t\t\t\t * and end up sending the wrong data.\n-\t\t\t\t */\n-\t\t\t\trte_io_wmb();\n-\t\t\t\tdseg->byte_count = byte_count;\n-\t\t\t} else {\n-\t\t\t\t/*\n-\t\t\t\t * This data segment starts at the beginning of\n-\t\t\t\t * a new TXBB, so we need to postpone its\n-\t\t\t\t * byte_count writing for later.\n-\t\t\t\t */\n-\t\t\t\tpv[pv_counter].dseg = dseg;\n-\t\t\t\tpv[pv_counter++].val = byte_count;\n-\t\t\t}\n-\t\t}\n-\t\t/* Write the first DWORD of each TXBB save earlier. */\n-\t\tif (pv_counter) {\n-\t\t\t/* Need a barrier before writing the byte_count. */\n+\t\t\t/* Need a barrier here before byte count store. */\n \t\t\trte_io_wmb();\n-\t\t\tfor (--pv_counter; pv_counter  >= 0; pv_counter--)\n-\t\t\t\tpv[pv_counter].dseg->byte_count =\n-\t\t\t\t\t\tpv[pv_counter].val;\n+\t\t\tdseg->byte_count = rte_cpu_to_be_32(buf->data_len);\n+\n+\t\t\t/* Fill the control parameters for this packet. */\n+\t\t\tctrl->fence_size = (WQE_ONE_DATA_SEG_SIZE >> 4) & 0x3f;\n+\t\t\tnr_txbbs = 1;\n+\t\t} else {\n+\t\t\tnr_txbbs = handle_multi_segs(buf, txq, &ctrl);\n+\t\t\tif (nr_txbbs < 0) {\n+\t\t\t\telt->buf = NULL;\n+\t\t\t\tbreak;\n+\t\t\t}\n \t\t}\n-\t\t/* Fill the control parameters for this packet. */\n-\t\tctrl->fence_size = (wqe_real_size >> 4) & 0x3f;\n \t\t/*\n \t\t * For raw Ethernet, the SOLICIT flag is used to indicate\n \t\t * that no ICRC should be calculated.\n@@ -469,6 +537,7 @@ struct pv {\n \t\tctrl->owner_opcode = rte_cpu_to_be_32(owner_opcode |\n \t\t\t\t\t      ((sq->head & sq->txbb_cnt) ?\n \t\t\t\t\t\t       MLX4_BIT_WQE_OWN : 0));\n+\n \t\tsq->head += nr_txbbs;\n \t\telt->buf = buf;\n \t\tbytes_sent += buf->pkt_len;\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "5/7"
    ]
}