get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 68083,
    "url": "http://patchwork.dpdk.org/api/patches/68083/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1586467444-15197-3-git-send-email-akozyrev@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<1586467444-15197-3-git-send-email-akozyrev@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1586467444-15197-3-git-send-email-akozyrev@mellanox.com",
    "date": "2020-04-09T21:24:03",
    "name": "[v3,2/3] net/mlx5: enable MPRQ multi-stride operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ed810a77cbf33279a1414d53c5085bdc4f26caa5",
    "submitter": {
        "id": 1573,
        "url": "http://patchwork.dpdk.org/api/people/1573/?format=api",
        "name": "Alexander Kozyrev",
        "email": "akozyrev@mellanox.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/1586467444-15197-3-git-send-email-akozyrev@mellanox.com/mbox/",
    "series": [
        {
            "id": 9278,
            "url": "http://patchwork.dpdk.org/api/series/9278/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=9278",
            "date": "2020-04-09T21:24:01",
            "name": "net/mlx5: add large packet size support to MPRQ",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/9278/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/68083/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/68083/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 3E31FA0597;\n\tThu,  9 Apr 2020 23:24:32 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 6DACC1C2F8;\n\tThu,  9 Apr 2020 23:24:25 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 46D5E1C2EC\n for <dev@dpdk.org>; Thu,  9 Apr 2020 23:24:23 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n akozyrev@mellanox.com)\n with ESMTPS (AES256-SHA encrypted); 10 Apr 2020 00:24:21 +0300",
            "from pegasus02.mtr.labs.mlnx. (pegasus02.mtr.labs.mlnx\n [10.210.16.122])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 039LOItn026643;\n Fri, 10 Apr 2020 00:24:20 +0300"
        ],
        "From": "Alexander Kozyrev <akozyrev@mellanox.com>",
        "To": "dev@dpdk.org",
        "Cc": "rasland@mellanox.com, matan@mellanox.com, viacheslavo@mellanox.com,\n stable@dpdk.org",
        "Date": "Thu,  9 Apr 2020 21:24:03 +0000",
        "Message-Id": "<1586467444-15197-3-git-send-email-akozyrev@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1586467444-15197-1-git-send-email-akozyrev@mellanox.com>",
        "References": "<1585691559-17409-1-git-send-email-akozyrev@mellanox.com>\n <1586467444-15197-1-git-send-email-akozyrev@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v3 2/3] net/mlx5: enable MPRQ multi-stride\n\toperations",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "MPRQ feature should be updated to allow a packet to be received\ninto multiple strides in order to support the MTU exceeding 8KB.\nSpecial care is needed to prevent the headroom corruption in the\nmulti-stride mode since the headroom space is borrowed by the PMD\nfrom the tail of the preceding stride. Copy the whole packet into\na separate mbuf in this case or just the overlapping data if the\nRx scattering is supported by an application.\n\nCc: stable@dpdk.org\n\nSigned-off-by: Alexander Kozyrev <akozyrev@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5_rxq.c  | 28 ++++--------------\n drivers/net/mlx5/mlx5_rxtx.c | 68 +++++++++++++++++++-------------------------\n drivers/net/mlx5/mlx5_rxtx.h |  2 +-\n 3 files changed, 36 insertions(+), 62 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c\nindex 7adeabc..08e4ccb 100644\n--- a/drivers/net/mlx5/mlx5_rxq.c\n+++ b/drivers/net/mlx5/mlx5_rxq.c\n@@ -1797,7 +1797,6 @@ struct mlx5_rxq_ctrl *\n \tunsigned int mprq_stride_size;\n \tunsigned int mprq_stride_cap;\n \tstruct mlx5_dev_config *config = &priv->config;\n-\tunsigned int strd_headroom_en;\n \t/*\n \t * Always allocate extra slots, even if eventually\n \t * the vector Rx will not be used.\n@@ -1843,26 +1842,11 @@ struct mlx5_rxq_ctrl *\n \ttmpl->socket = socket;\n \tif (dev->data->dev_conf.intr_conf.rxq)\n \t\ttmpl->irq = 1;\n-\t/*\n-\t * LRO packet may consume all the stride memory, hence we cannot\n-\t * guaranty head-room near the packet memory in the stride.\n-\t * In this case scatter is, for sure, enabled and an empty mbuf may be\n-\t * added in the start for the head-room.\n-\t */\n-\tif (lro_on_queue && RTE_PKTMBUF_HEADROOM > 0 &&\n-\t    non_scatter_min_mbuf_size > mb_len) {\n-\t\tstrd_headroom_en = 0;\n-\t\tmprq_stride_size = RTE_MIN(max_rx_pkt_len,\n-\t\t\t\t\t1u << config->mprq.max_stride_size_n);\n-\t} else {\n-\t\tstrd_headroom_en = 1;\n-\t\tmprq_stride_size = non_scatter_min_mbuf_size;\n-\t}\n \tmprq_stride_nums = config->mprq.stride_num_n ?\n \t\tconfig->mprq.stride_num_n : MLX5_MPRQ_STRIDE_NUM_N;\n-\tmprq_stride_size = (mprq_stride_size <=\n-\t\t\t(1U << config->mprq.max_stride_size_n)) ?\n-\t\tlog2above(mprq_stride_size) : MLX5_MPRQ_STRIDE_SIZE_N;\n+\tmprq_stride_size = non_scatter_min_mbuf_size <=\n+\t\t(1U << config->mprq.max_stride_size_n) ?\n+\t\tlog2above(non_scatter_min_mbuf_size) : MLX5_MPRQ_STRIDE_SIZE_N;\n \tmprq_stride_cap = (config->mprq.stride_num_n ?\n \t\t(1U << config->mprq.stride_num_n) : (1U << mprq_stride_nums)) *\n \t\t\t(config->mprq.stride_size_n ?\n@@ -1879,8 +1863,7 @@ struct mlx5_rxq_ctrl *\n \t *  Otherwise, enable Rx scatter if necessary.\n \t */\n \tif (mprq_en && desc > (1U << mprq_stride_nums) &&\n-\t    (non_scatter_min_mbuf_size -\n-\t     (lro_on_queue ? RTE_PKTMBUF_HEADROOM : 0) <=\n+\t    (non_scatter_min_mbuf_size <=\n \t     (1U << config->mprq.max_stride_size_n) ||\n \t     (config->mprq.stride_size_n &&\n \t      non_scatter_min_mbuf_size <= mprq_stride_cap))) {\n@@ -1893,7 +1876,8 @@ struct mlx5_rxq_ctrl *\n \t\ttmpl->rxq.strd_sz_n = config->mprq.stride_size_n ?\n \t\t\tconfig->mprq.stride_size_n : mprq_stride_size;\n \t\ttmpl->rxq.strd_shift_en = MLX5_MPRQ_TWO_BYTE_SHIFT;\n-\t\ttmpl->rxq.strd_headroom_en = strd_headroom_en;\n+\t\ttmpl->rxq.strd_scatter_en =\n+\t\t\t\t!!(offloads & DEV_RX_OFFLOAD_SCATTER);\n \t\ttmpl->rxq.mprq_max_memcpy_len = RTE_MIN(first_mb_free_size,\n \t\t\t\tconfig->mprq.max_memcpy_len);\n \t\tmax_lro_size = RTE_MIN(max_rx_pkt_len,\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c\nindex f3bf763..4c27952 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.c\n+++ b/drivers/net/mlx5/mlx5_rxtx.c\n@@ -1658,21 +1658,20 @@ enum mlx5_txcmp_code {\n \tunsigned int i = 0;\n \tuint32_t rq_ci = rxq->rq_ci;\n \tuint16_t consumed_strd = rxq->consumed_strd;\n-\tuint16_t headroom_sz = rxq->strd_headroom_en * RTE_PKTMBUF_HEADROOM;\n \tstruct mlx5_mprq_buf *buf = (*rxq->mprq_bufs)[rq_ci & wq_mask];\n \n \twhile (i < pkts_n) {\n \t\tstruct rte_mbuf *pkt;\n \t\tvoid *addr;\n \t\tint ret;\n-\t\tunsigned int len;\n+\t\tuint32_t len;\n \t\tuint16_t strd_cnt;\n \t\tuint16_t strd_idx;\n \t\tuint32_t offset;\n \t\tuint32_t byte_cnt;\n+\t\tint32_t hdrm_overlap;\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@@ -1719,18 +1718,6 @@ enum mlx5_txcmp_code {\n \t\tMLX5_ASSERT(strd_idx < strd_n);\n \t\tMLX5_ASSERT(!((rte_be_to_cpu_16(cqe->wqe_id) ^ rq_ci) &\n \t\t\t    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-\t\t * consume multiple strides without raising an error. In this\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(!lro_num_seg && strd_cnt > 1)) {\n-\t\t\t++rxq->stats.idropped;\n-\t\t\tcontinue;\n-\t\t}\n \t\tpkt = rte_pktmbuf_alloc(rxq->mp);\n \t\tif (unlikely(pkt == NULL)) {\n \t\t\t++rxq->stats.rx_nombuf;\n@@ -1742,12 +1729,16 @@ enum mlx5_txcmp_code {\n \t\t\tlen -= RTE_ETHER_CRC_LEN;\n \t\toffset = strd_idx * strd_sz + strd_shift;\n \t\taddr = RTE_PTR_ADD(mlx5_mprq_buf_addr(buf, strd_n), offset);\n+\t\thdrm_overlap = len + RTE_PKTMBUF_HEADROOM - strd_cnt * strd_sz;\n \t\t/*\n \t\t * Memcpy packets to the target mbuf if:\n \t\t * - The size of packet is smaller than mprq_max_memcpy_len.\n \t\t * - Out of buffer in the Mempool for Multi-Packet RQ.\n+\t\t * - There is no space for a headroom and scatter is disabled.\n \t\t */\n-\t\tif (len <= rxq->mprq_max_memcpy_len || rxq->mprq_repl == NULL) {\n+\t\tif (len <= rxq->mprq_max_memcpy_len ||\n+\t\t    rxq->mprq_repl == NULL ||\n+\t\t    (hdrm_overlap > 0 && !rxq->strd_scatter_en)) {\n \t\t\t/*\n \t\t\t * When memcpy'ing packet due to out-of-buffer, the\n \t\t\t * packet must be smaller than the target mbuf.\n@@ -1769,7 +1760,7 @@ enum mlx5_txcmp_code {\n \t\t\trte_atomic16_add_return(&buf->refcnt, 1);\n \t\t\tMLX5_ASSERT((uint16_t)rte_atomic16_read(&buf->refcnt) <=\n \t\t\t\t    strd_n + 1);\n-\t\t\tbuf_addr = RTE_PTR_SUB(addr, headroom_sz);\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@@ -1788,43 +1779,42 @@ enum mlx5_txcmp_code {\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\t/* Set mbuf head-room. */\n-\t\t\tpkt->data_off = headroom_sz;\n+\t\t\tSET_DATA_OFF(pkt, RTE_PKTMBUF_HEADROOM);\n \t\t\tMLX5_ASSERT(pkt->ol_flags == EXT_ATTACHED_MBUF);\n-\t\t\t/*\n-\t\t\t * Prevent potential overflow due to MTU change through\n-\t\t\t * kernel interface.\n-\t\t\t */\n-\t\t\tif (unlikely(rte_pktmbuf_tailroom(pkt) < len)) {\n-\t\t\t\trte_pktmbuf_free_seg(pkt);\n-\t\t\t\t++rxq->stats.idropped;\n-\t\t\t\tcontinue;\n-\t\t\t}\n+\t\t\tMLX5_ASSERT(rte_pktmbuf_tailroom(pkt) <\n+\t\t\t\tlen - (hdrm_overlap > 0 ? hdrm_overlap : 0));\n \t\t\tDATA_LEN(pkt) = len;\n \t\t\t/*\n-\t\t\t * LRO packet may consume all the stride memory, in this\n-\t\t\t * case packet head-room space is not guaranteed so must\n-\t\t\t * to add an empty mbuf for the head-room.\n+\t\t\t * Copy the last fragment of a packet (up to headroom\n+\t\t\t * size bytes) in case there is a stride overlap with\n+\t\t\t * a next packet's headroom. Allocate a separate mbuf\n+\t\t\t * to store this fragment and link it. Scatter is on.\n \t\t\t */\n-\t\t\tif (!rxq->strd_headroom_en) {\n-\t\t\t\tstruct rte_mbuf *headroom_mbuf =\n-\t\t\t\t\t\trte_pktmbuf_alloc(rxq->mp);\n+\t\t\tif (hdrm_overlap > 0) {\n+\t\t\t\tMLX5_ASSERT(rxq->strd_scatter_en);\n+\t\t\t\tstruct rte_mbuf *seg =\n+\t\t\t\t\trte_pktmbuf_alloc(rxq->mp);\n \n-\t\t\t\tif (unlikely(headroom_mbuf == NULL)) {\n+\t\t\t\tif (unlikely(seg == NULL)) {\n \t\t\t\t\trte_pktmbuf_free_seg(pkt);\n \t\t\t\t\t++rxq->stats.rx_nombuf;\n \t\t\t\t\tbreak;\n \t\t\t\t}\n-\t\t\t\tPORT(pkt) = rxq->port_id;\n-\t\t\t\tNEXT(headroom_mbuf) = pkt;\n-\t\t\t\tpkt = headroom_mbuf;\n+\t\t\t\tSET_DATA_OFF(seg, 0);\n+\t\t\t\trte_memcpy(rte_pktmbuf_mtod(seg, void *),\n+\t\t\t\t\tRTE_PTR_ADD(addr, len - hdrm_overlap),\n+\t\t\t\t\thdrm_overlap);\n+\t\t\t\tDATA_LEN(seg) = hdrm_overlap;\n+\t\t\t\tDATA_LEN(pkt) = len - hdrm_overlap;\n+\t\t\t\tNEXT(pkt) = seg;\n \t\t\t\tNB_SEGS(pkt) = 2;\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\tif (cqe->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\tpkt->tso_segsz = len / cqe->lro_num_seg;\n \t\t}\n \t\tPKT_LEN(pkt) = len;\n \t\tPORT(pkt) = rxq->port_id;\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex 939778a..d155c24 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -119,7 +119,7 @@ struct mlx5_rxq_data {\n \tunsigned int strd_sz_n:4; /* Log 2 of stride size. */\n \tunsigned int strd_shift_en:1; /* Enable 2bytes shift on a stride. */\n \tunsigned int err_state:2; /* enum mlx5_rxq_err_state. */\n-\tunsigned int strd_headroom_en:1; /* Enable mbuf headroom in MPRQ. */\n+\tunsigned int strd_scatter_en:1; /* Scattered packets from a stride. */\n \tunsigned int lro:1; /* Enable LRO. */\n \tunsigned int :1; /* Remaining bits. */\n \tvolatile uint32_t *rq_db;\n",
    "prefixes": [
        "v3",
        "2/3"
    ]
}