get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 56851,
    "url": "http://patches.dpdk.org/api/patches/56851/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1563786795-14027-26-git-send-email-matan@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": "<1563786795-14027-26-git-send-email-matan@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1563786795-14027-26-git-send-email-matan@mellanox.com",
    "date": "2019-07-22T09:13:12",
    "name": "[25/28] net/mlx5: handle LRO packets in Rx queue",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "62e87d0d8ba1908315953e4364030609340ad4ed",
    "submitter": {
        "id": 796,
        "url": "http://patches.dpdk.org/api/people/796/?format=api",
        "name": "Matan Azrad",
        "email": "matan@mellanox.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1563786795-14027-26-git-send-email-matan@mellanox.com/mbox/",
    "series": [
        {
            "id": 5639,
            "url": "http://patches.dpdk.org/api/series/5639/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5639",
            "date": "2019-07-22T09:12:48",
            "name": "net/mlx5: support LRO",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/5639/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/56851/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/56851/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 3D29C1BE95;\n\tMon, 22 Jul 2019 11:14:27 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id D73541BDF5\n\tfor <dev@dpdk.org>; Mon, 22 Jul 2019 11:13:30 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE2 (envelope-from\n\tmatan@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 22 Jul 2019 12:13:24 +0300",
            "from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx\n\t[10.210.16.112])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x6M9DMjo010084;\n\tMon, 22 Jul 2019 12:13:24 +0300"
        ],
        "From": "Matan Azrad <matan@mellanox.com>",
        "To": "Shahaf Shuler <shahafs@mellanox.com>, Yongseok Koh <yskoh@mellanox.com>, \n\tViacheslav Ovsiienko <viacheslavo@mellanox.com>",
        "Cc": "dev@dpdk.org, Dekel Peled <dekelp@mellanox.com>",
        "Date": "Mon, 22 Jul 2019 09:13:12 +0000",
        "Message-Id": "<1563786795-14027-26-git-send-email-matan@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1563786795-14027-1-git-send-email-matan@mellanox.com>",
        "References": "<1563786795-14027-1-git-send-email-matan@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH 25/28] net/mlx5: handle LRO packets in Rx queue",
        "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": "When LRO offload is configured in Rx queue, the HW may coalesce TCP\npackets from same TCP connection into single packet.\n\nIn this case the SW should fix the relevant packet headers because the\nHW doesn't update them according to the new created packet\ncharacteristics.\n\nAdd update header code to the mprq Rx burst function to support LRO\nfeature.\n\nSigned-off-by: Matan Azrad <matan@mellanox.com>\n---\n drivers/net/mlx5/mlx5_prm.h  |  15 ++++++\n drivers/net/mlx5/mlx5_rxtx.c | 113 +++++++++++++++++++++++++++++++++++++++++--\n 2 files changed, 123 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h\nindex 3f73a28..32bc7a6 100644\n--- a/drivers/net/mlx5/mlx5_prm.h\n+++ b/drivers/net/mlx5/mlx5_prm.h\n@@ -155,6 +155,21 @@\n /* Tunnel packet bit in the CQE. */\n #define MLX5_CQE_RX_TUNNEL_PACKET (1u << 0)\n \n+/* Mask for LRO push flag in the CQE lro_tcppsh_abort_dupack field. */\n+#define MLX5_CQE_LRO_PUSH_MASK 0x40\n+\n+/* Mask for L4 type in the CQE hdr_type_etc field. */\n+#define MLX5_CQE_L4_TYPE_MASK 0x70\n+\n+/* The bit index of L4 type in CQE hdr_type_etc field. */\n+#define MLX5_CQE_L4_TYPE_SHIFT 0x4\n+\n+/* L4 type to indicate TCP packet without acknowledgment. */\n+#define MLX5_L4_HDR_TYPE_TCP_EMPTY_ACK 0x3\n+\n+/* L4 type to indicate TCP packet with acknowledgment. */\n+#define MLX5_L4_HDR_TYPE_TCP_WITH_ACL 0x4\n+\n /* Inner L3 checksum offload (Tunneled packets only). */\n #define MLX5_ETH_WQE_L3_INNER_CSUM (1u << 4)\n \ndiff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c\nindex 241e01b..c7487ac 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.c\n+++ b/drivers/net/mlx5/mlx5_rxtx.c\n@@ -1374,6 +1374,101 @@ enum mlx5_txcmp_code {\n \treturn i;\n }\n \n+/**\n+ * Update LRO packet TCP header.\n+ * The HW LRO feature doesn't update the TCP header after coalescing the\n+ * TCP segments but supplies information in CQE to fill it by SW.\n+ *\n+ * @param tcp\n+ *   Pointer to the TCP header.\n+ * @param cqe\n+ *   Pointer to the completion entry..\n+ * @param phcsum\n+ *   The L3 pseudo-header checksum.\n+ */\n+static inline void\n+mlx5_lro_update_tcp_hdr(struct rte_tcp_hdr *restrict tcp,\n+\t\t\tvolatile struct mlx5_cqe *restrict cqe,\n+\t\t\tuint32_t phcsum)\n+{\n+\tuint8_t l4_type = (rte_be_to_cpu_16(cqe->hdr_type_etc) &\n+\t\t\t   MLX5_CQE_L4_TYPE_MASK) >> MLX5_CQE_L4_TYPE_SHIFT;\n+\t/*\n+\t * The HW calculates only the TCP payload checksum, need to complete\n+\t * the TCP header checksum and the L3 pseudo-header checksum.\n+\t */\n+\tuint32_t csum = phcsum + cqe->csum;\n+\n+\tif (l4_type == MLX5_L4_HDR_TYPE_TCP_EMPTY_ACK ||\n+\t    l4_type == MLX5_L4_HDR_TYPE_TCP_WITH_ACL) {\n+\t\ttcp->tcp_flags |= RTE_TCP_ACK_FLAG;\n+\t\ttcp->recv_ack = cqe->lro_ack_seq_num;\n+\t\ttcp->rx_win = cqe->lro_tcp_win;\n+\t}\n+\tif (cqe->lro_tcppsh_abort_dupack & MLX5_CQE_LRO_PUSH_MASK)\n+\t\ttcp->tcp_flags |= RTE_TCP_PSH_FLAG;\n+\ttcp->cksum = 0;\n+\tcsum += rte_raw_cksum(tcp, (tcp->data_off & 0xF) * 4);\n+\tcsum = ((csum & 0xffff0000) >> 16) + (csum & 0xffff);\n+\tcsum = (~csum) & 0xffff;\n+\tif (csum == 0)\n+\t\tcsum = 0xffff;\n+\ttcp->cksum = csum;\n+}\n+\n+/**\n+ * Update LRO packet headers.\n+ * The HW LRO feature doesn't update the L3/TCP headers after coalescing the\n+ * TCP segments but supply information in CQE to fill it by SW.\n+ *\n+ * @param padd\n+ *   The packet address.\n+ * @param cqe\n+ *   Pointer to the completion entry..\n+ * @param len\n+ *   The packet length.\n+ */\n+static inline void\n+mlx5_lro_update_hdr(uint8_t *restrict padd,\n+\t\t    volatile struct mlx5_cqe *restrict cqe,\n+\t\t    uint32_t len)\n+{\n+\tunion {\n+\t\tstruct rte_ether_hdr *eth;\n+\t\tstruct rte_vlan_hdr *vlan;\n+\t\tstruct rte_ipv4_hdr *ipv4;\n+\t\tstruct rte_ipv6_hdr *ipv6;\n+\t\tstruct rte_tcp_hdr *tcp;\n+\t\tuint8_t *hdr;\n+\t} h = {\n+\t\t\t.hdr = padd,\n+\t};\n+\tuint16_t proto = h.eth->ether_type;\n+\tuint32_t phcsum;\n+\n+\th.eth++;\n+\twhile (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||\n+\t       proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {\n+\t\tproto = h.vlan->eth_proto;\n+\t\th.vlan++;\n+\t}\n+\tif (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {\n+\t\th.ipv4->time_to_live = cqe->lro_min_ttl;\n+\t\th.ipv4->total_length = rte_cpu_to_be_16(len - (h.hdr - padd));\n+\t\th.ipv4->hdr_checksum = 0;\n+\t\th.ipv4->hdr_checksum = rte_ipv4_cksum(h.ipv4);\n+\t\tphcsum = rte_ipv4_phdr_cksum(h.ipv4, 0);\n+\t\th.ipv4++;\n+\t} else {\n+\t\th.ipv6->hop_limits = cqe->lro_min_ttl;\n+\t\th.ipv6->payload_len = rte_cpu_to_be_16(len - (h.hdr - padd) -\n+\t\t\t\t\t\t       sizeof(*h.ipv6));\n+\t\tphcsum = rte_ipv6_phdr_cksum(h.ipv6, 0);\n+\t\th.ipv6++;\n+\t}\n+\tmlx5_lro_update_tcp_hdr(h.tcp, cqe, phcsum);\n+}\n+\n void\n mlx5_mprq_buf_free_cb(void *addr __rte_unused, void *opaque)\n {\n@@ -1458,6 +1553,7 @@ enum mlx5_txcmp_code {\n \t\tuint32_t byte_cnt;\n \t\tvolatile struct mlx5_mini_cqe8 *mcqe = NULL;\n \t\tuint32_t rss_hash_res = 0;\n+\t\tuint8_t lro_num_seg;\n \n \t\tif (consumed_strd == strd_n) {\n \t\t\t/* Replace WQE only if the buffer is still in use. */\n@@ -1503,6 +1599,7 @@ enum mlx5_txcmp_code {\n \t\t}\n \t\tassert(strd_idx < strd_n);\n \t\tassert(!((rte_be_to_cpu_16(cqe->wqe_id) ^ rq_ci) & wq_mask));\n+\t\tlro_num_seg = cqe->lro_num_seg;\n \t\t/*\n \t\t * Currently configured to receive a packet per a stride. But if\n \t\t * MTU is adjusted through kernel interface, device could\n@@ -1510,7 +1607,7 @@ enum mlx5_txcmp_code {\n \t\t * case, the packet should be dropped because it is bigger than\n \t\t * the max_rx_pkt_len.\n \t\t */\n-\t\tif (unlikely(strd_cnt > 1)) {\n+\t\tif (unlikely(!lro_num_seg && strd_cnt > 1)) {\n \t\t\t++rxq->stats.idropped;\n \t\t\tcontinue;\n \t\t}\n@@ -1547,19 +1644,20 @@ enum mlx5_txcmp_code {\n \t\t\trte_iova_t buf_iova;\n \t\t\tstruct rte_mbuf_ext_shared_info *shinfo;\n \t\t\tuint16_t buf_len = strd_cnt * strd_sz;\n+\t\t\tvoid *buf_addr;\n \n \t\t\t/* Increment the refcnt of the whole chunk. */\n \t\t\trte_atomic16_add_return(&buf->refcnt, 1);\n \t\t\tassert((uint16_t)rte_atomic16_read(&buf->refcnt) <=\n \t\t\t       strd_n + 1);\n-\t\t\taddr = RTE_PTR_SUB(addr, RTE_PKTMBUF_HEADROOM);\n+\t\t\tbuf_addr = RTE_PTR_SUB(addr, RTE_PKTMBUF_HEADROOM);\n \t\t\t/*\n \t\t\t * MLX5 device doesn't use iova but it is necessary in a\n \t\t\t * case where the Rx packet is transmitted via a\n \t\t\t * different PMD.\n \t\t\t */\n \t\t\tbuf_iova = rte_mempool_virt2iova(buf) +\n-\t\t\t\t   RTE_PTR_DIFF(addr, buf);\n+\t\t\t\t   RTE_PTR_DIFF(buf_addr, buf);\n \t\t\tshinfo = &buf->shinfos[strd_idx];\n \t\t\trte_mbuf_ext_refcnt_set(shinfo, 1);\n \t\t\t/*\n@@ -1568,8 +1666,8 @@ enum mlx5_txcmp_code {\n \t\t\t * will be added below by calling rxq_cq_to_mbuf().\n \t\t\t * Other fields will be overwritten.\n \t\t\t */\n-\t\t\trte_pktmbuf_attach_extbuf(pkt, addr, buf_iova, buf_len,\n-\t\t\t\t\t\t  shinfo);\n+\t\t\trte_pktmbuf_attach_extbuf(pkt, buf_addr, buf_iova,\n+\t\t\t\t\t\t  buf_len, shinfo);\n \t\t\trte_pktmbuf_reset_headroom(pkt);\n \t\t\tassert(pkt->ol_flags == EXT_ATTACHED_MBUF);\n \t\t\t/*\n@@ -1583,6 +1681,11 @@ enum mlx5_txcmp_code {\n \t\t\t}\n \t\t}\n \t\trxq_cq_to_mbuf(rxq, pkt, cqe, rss_hash_res);\n+\t\tif (lro_num_seg > 1) {\n+\t\t\tmlx5_lro_update_hdr(addr, cqe, len);\n+\t\t\tpkt->ol_flags |= PKT_RX_LRO;\n+\t\t\tpkt->tso_segsz = strd_sz;\n+\t\t}\n \t\tPKT_LEN(pkt) = len;\n \t\tDATA_LEN(pkt) = len;\n \t\tPORT(pkt) = rxq->port_id;\n",
    "prefixes": [
        "25/28"
    ]
}