get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45531,
    "url": "https://patches.dpdk.org/api/patches/45531/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1538057935-34663-1-git-send-email-dekelp@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": "<1538057935-34663-1-git-send-email-dekelp@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1538057935-34663-1-git-send-email-dekelp@mellanox.com",
    "date": "2018-09-27T14:18:55",
    "name": "[v2] net/mlx5: support metadata as flow rule criteria",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c80f32c5d7c46a2dc09e085782beac82fd20e09a",
    "submitter": {
        "id": 1082,
        "url": "https://patches.dpdk.org/api/people/1082/?format=api",
        "name": "Dekel Peled",
        "email": "dekelp@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "https://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1538057935-34663-1-git-send-email-dekelp@mellanox.com/mbox/",
    "series": [
        {
            "id": 1553,
            "url": "https://patches.dpdk.org/api/series/1553/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=1553",
            "date": "2018-09-27T14:18:55",
            "name": "[v2] net/mlx5: support metadata as flow rule criteria",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/1553/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/45531/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/45531/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 7DFAA1B45D;\n\tThu, 27 Sep 2018 16:20:25 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id B1AF11B448\n\tfor <dev@dpdk.org>; Thu, 27 Sep 2018 16:20:24 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\tdekelp@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 27 Sep 2018 16:24:52 +0200",
            "from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx\n\t[10.128.130.87])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w8REKIj8000460;\n\tThu, 27 Sep 2018 17:20:18 +0300"
        ],
        "From": "Dekel Peled <dekelp@mellanox.com>",
        "To": "dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com",
        "Cc": "orika@mellanox.com",
        "Date": "Thu, 27 Sep 2018 17:18:55 +0300",
        "Message-Id": "<1538057935-34663-1-git-send-email-dekelp@mellanox.com>",
        "X-Mailer": "git-send-email 1.7.1",
        "In-Reply-To": "<1537105328-9367-1-git-send-email-dekelp@mellanox.com>",
        "References": "<1537105328-9367-1-git-send-email-dekelp@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v2] net/mlx5: support metadata as flow rule\n\tcriteria",
        "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": "As described in series starting at [1], it adds option to set\nmetadata value as match pattern when creating a new flow rule.\n\nThis patch adds metadata support in mlx5 driver, in two parts:\n- Add the setting of metadata value in matcher when creating\n  a new flow rule.\n- Add the passing of metadata value from mbuf to wqe when\n  indicated by ol_flag, in different burst functions.\n\n[1] \"ethdev: support metadata as flow rule criteria\"\n    http://mails.dpdk.org/archives/dev/2018-September/113270.html\n\t\nSigned-off-by: Dekel Peled <dekelp@mellanox.com>\n---\nV2:\nSplit the support of egress rules to a different patch.\n---\n drivers/net/mlx5/mlx5_flow.c          |  2 +-\n drivers/net/mlx5/mlx5_flow.h          |  8 +++\n drivers/net/mlx5/mlx5_flow_dv.c       | 96 +++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_prm.h           |  2 +-\n drivers/net/mlx5/mlx5_rxtx.c          | 35 +++++++++++--\n drivers/net/mlx5/mlx5_rxtx_vec.c      | 31 ++++++++---\n drivers/net/mlx5/mlx5_rxtx_vec.h      |  1 +\n drivers/net/mlx5/mlx5_rxtx_vec_neon.h |  4 +-\n drivers/net/mlx5/mlx5_rxtx_vec_sse.h  |  4 +-\n drivers/net/mlx5/mlx5_txq.c           |  6 +++\n 10 files changed, 174 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 8007bf1..9581691 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -417,7 +417,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n  * @return\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n-static int\n+int\n mlx5_flow_item_acceptable(const struct rte_flow_item *item,\n \t\t\t  const uint8_t *mask,\n \t\t\t  const uint8_t *nic_mask,\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 10d700a..d91ae17 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -42,6 +42,9 @@\n #define MLX5_FLOW_LAYER_GRE (1u << 14)\n #define MLX5_FLOW_LAYER_MPLS (1u << 15)\n \n+/* General pattern items bits. */\n+#define MLX5_FLOW_ITEM_METADATA (1u << 16)\n+\n /* Outer Masks. */\n #define MLX5_FLOW_LAYER_OUTER_L3 \\\n \t(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)\n@@ -299,6 +302,11 @@ int mlx5_flow_validate_action_rss(const struct rte_flow_action *action,\n int mlx5_flow_validate_attributes(struct rte_eth_dev *dev,\n \t\t\t\t  const struct rte_flow_attr *attributes,\n \t\t\t\t  struct rte_flow_error *error);\n+int mlx5_flow_item_acceptable(const struct rte_flow_item *item,\n+\t\t\t      const uint8_t *mask,\n+\t\t\t      const uint8_t *nic_mask,\n+\t\t\t      unsigned int size,\n+\t\t\t      struct rte_flow_error *error);\n int mlx5_flow_validate_item_eth(const struct rte_flow_item *item,\n \t\t\t\tuint64_t item_flags,\n \t\t\t\tstruct rte_flow_error *error);\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex cf663cd..2439f5e 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -36,6 +36,55 @@\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \n /**\n+ * Validate META item.\n+ *\n+ * @param[in] item\n+ *   Item specification.\n+ * @param[in] attr\n+ *   Attributes of flow that includes this item.\n+ * @param[out] error\n+ *   Pointer to error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_flow_validate_item_meta(const struct rte_flow_item *item,\n+\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\tstruct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_meta *spec = item->spec;\n+\tconst struct rte_flow_item_meta *mask = item->mask;\n+\n+\tconst struct rte_flow_item_meta nic_mask = {\n+\t\t.data = RTE_BE32(UINT32_MAX)\n+\t};\n+\n+\tint ret;\n+\n+\tif (!spec)\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM_SPEC,\n+\t\t\t\t\t  item->spec,\n+\t\t\t\t\t  \"data cannot be empty\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_meta_mask;\n+\tret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,\n+\t\t\t\t\t(const uint8_t *)&nic_mask,\n+\t\t\t\t\tsizeof(struct rte_flow_item_meta),\n+\t\t\t\t\terror);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tif (attr->ingress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"pattern not supported for ingress\");\n+\treturn 0;\n+}\n+\n+/**\n  * Verify the @p attributes will be correctly understood by the NIC and store\n  * them in the @p flow if everything is correct.\n  *\n@@ -216,6 +265,12 @@\n \t\t\t\treturn ret;\n \t\t\titem_flags |= MLX5_FLOW_LAYER_MPLS;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_META:\n+\t\t\tret = mlx5_flow_validate_item_meta(items, attr, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_ITEM_METADATA;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM,\n@@ -853,6 +908,43 @@\n }\n \n /**\n+ * Add META item to matcher\n+ *\n+ * @param[in, out] matcher\n+ *   Flow matcher.\n+ * @param[in, out] key\n+ *   Flow matcher value.\n+ * @param[in] item\n+ *   Flow pattern to translate.\n+ * @param[in] inner\n+ *   Item is inner pattern.\n+ */\n+static void\n+flow_dv_translate_item_meta(void *matcher, void *key,\n+\t\t\t\tconst struct rte_flow_item *item)\n+{\n+\tconst struct rte_flow_item_meta *metam;\n+\tconst struct rte_flow_item_meta *metav;\n+\n+\tvoid *misc2_m =\n+\t\tMLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2);\n+\tvoid *misc2_v =\n+\t\tMLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);\n+\n+\tmetam = (const void *)item->mask;\n+\tif (!metam)\n+\t\tmetam = &rte_flow_item_meta_mask;\n+\n+\tmetav = (const void *)item->spec;\n+\tif (metav) {\n+\t\tMLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,\n+\t\t\tRTE_BE32(metam->data));\n+\t\tMLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,\n+\t\t\tRTE_BE32(metav->data));\n+\t}\n+}\n+\n+/**\n  * Update the matcher and the value based the selected item.\n  *\n  * @param[in, out] matcher\n@@ -938,6 +1030,10 @@\n \t\tflow_dv_translate_item_vxlan(tmatcher->mask.buf, key, item,\n \t\t\t\t\t     inner);\n \t\tbreak;\n+\tcase RTE_FLOW_ITEM_TYPE_META:\n+\t\tflow_dv_translate_item_meta(tmatcher->mask.buf, key, item);\n+\t\tbreak;\n+\n \tdefault:\n \t\tbreak;\n \t}\ndiff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h\nindex 4e2f9f4..a905397 100644\n--- a/drivers/net/mlx5/mlx5_prm.h\n+++ b/drivers/net/mlx5/mlx5_prm.h\n@@ -159,7 +159,7 @@ struct mlx5_wqe_eth_seg_small {\n \tuint8_t\tcs_flags;\n \tuint8_t\trsvd1;\n \tuint16_t mss;\n-\tuint32_t rsvd2;\n+\tuint32_t flow_table_metadata;\n \tuint16_t inline_hdr_sz;\n \tuint8_t inline_hdr[2];\n } __rte_aligned(MLX5_WQE_DWORD_SIZE);\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c\nindex 558e6b6..d596e4e 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.c\n+++ b/drivers/net/mlx5/mlx5_rxtx.c\n@@ -523,6 +523,7 @@\n \t\tuint8_t tso = txq->tso_en && (buf->ol_flags & PKT_TX_TCP_SEG);\n \t\tuint32_t swp_offsets = 0;\n \t\tuint8_t swp_types = 0;\n+\t\tuint32_t metadata = 0;\n \t\tuint16_t tso_segsz = 0;\n #ifdef MLX5_PMD_SOFT_COUNTERS\n \t\tuint32_t total_length = 0;\n@@ -566,6 +567,9 @@\n \t\tcs_flags = txq_ol_cksum_to_cs(buf);\n \t\ttxq_mbuf_to_swp(txq, buf, (uint8_t *)&swp_offsets, &swp_types);\n \t\traw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;\n+\t\t/* Copy metadata from mbuf if valid */\n+\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\tmetadata = buf->hash.fdir.hi;\n \t\t/* Replace the Ethernet type by the VLAN if necessary. */\n \t\tif (buf->ol_flags & PKT_TX_VLAN_PKT) {\n \t\t\tuint32_t vlan = rte_cpu_to_be_32(0x81000000 |\n@@ -781,7 +785,7 @@\n \t\t\t\tswp_offsets,\n \t\t\t\tcs_flags | (swp_types << 8) |\n \t\t\t\t(rte_cpu_to_be_16(tso_segsz) << 16),\n-\t\t\t\t0,\n+\t\t\t\trte_cpu_to_be_32(metadata),\n \t\t\t\t(ehdr << 16) | rte_cpu_to_be_16(tso_header_sz),\n \t\t\t};\n \t\t} else {\n@@ -795,7 +799,7 @@\n \t\t\twqe->eseg = (rte_v128u32_t){\n \t\t\t\tswp_offsets,\n \t\t\t\tcs_flags | (swp_types << 8),\n-\t\t\t\t0,\n+\t\t\t\trte_cpu_to_be_32(metadata),\n \t\t\t\t(ehdr << 16) | rte_cpu_to_be_16(pkt_inline_sz),\n \t\t\t};\n \t\t}\n@@ -861,7 +865,7 @@\n \tmpw->wqe->eseg.inline_hdr_sz = 0;\n \tmpw->wqe->eseg.rsvd0 = 0;\n \tmpw->wqe->eseg.rsvd1 = 0;\n-\tmpw->wqe->eseg.rsvd2 = 0;\n+\tmpw->wqe->eseg.flow_table_metadata = 0;\n \tmpw->wqe->ctrl[0] = rte_cpu_to_be_32((MLX5_OPC_MOD_MPW << 24) |\n \t\t\t\t\t     (txq->wqe_ci << 8) |\n \t\t\t\t\t     MLX5_OPCODE_TSO);\n@@ -971,6 +975,8 @@\n \t\tif ((mpw.state == MLX5_MPW_STATE_OPENED) &&\n \t\t    ((mpw.len != length) ||\n \t\t     (segs_n != 1) ||\n+\t\t     (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t     (mpw.wqe->eseg.cs_flags != cs_flags)))\n \t\t\tmlx5_mpw_close(txq, &mpw);\n \t\tif (mpw.state == MLX5_MPW_STATE_CLOSED) {\n@@ -984,6 +990,8 @@\n \t\t\tmax_wqe -= 2;\n \t\t\tmlx5_mpw_new(txq, &mpw, length);\n \t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t}\n \t\t/* Multi-segment packets must be alone in their MPW. */\n \t\tassert((segs_n == 1) || (mpw.pkts_n == 0));\n@@ -1082,7 +1090,7 @@\n \tmpw->wqe->eseg.cs_flags = 0;\n \tmpw->wqe->eseg.rsvd0 = 0;\n \tmpw->wqe->eseg.rsvd1 = 0;\n-\tmpw->wqe->eseg.rsvd2 = 0;\n+\tmpw->wqe->eseg.flow_table_metadata = 0;\n \tinl = (struct mlx5_wqe_inl_small *)\n \t\t(((uintptr_t)mpw->wqe) + 2 * MLX5_WQE_DWORD_SIZE);\n \tmpw->data.raw = (uint8_t *)&inl->raw;\n@@ -1199,12 +1207,16 @@\n \t\tif (mpw.state == MLX5_MPW_STATE_OPENED) {\n \t\t\tif ((mpw.len != length) ||\n \t\t\t    (segs_n != 1) ||\n+\t\t\t    (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags))\n \t\t\t\tmlx5_mpw_close(txq, &mpw);\n \t\t} else if (mpw.state == MLX5_MPW_INL_STATE_OPENED) {\n \t\t\tif ((mpw.len != length) ||\n \t\t\t    (segs_n != 1) ||\n \t\t\t    (length > inline_room) ||\n+\t\t\t    (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags)) {\n \t\t\t\tmlx5_mpw_inline_close(txq, &mpw);\n \t\t\t\tinline_room =\n@@ -1224,12 +1236,21 @@\n \t\t\t\tmax_wqe -= 2;\n \t\t\t\tmlx5_mpw_new(txq, &mpw, length);\n \t\t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n+\n \t\t\t} else {\n \t\t\t\tif (unlikely(max_wqe < wqe_inl_n))\n \t\t\t\t\tbreak;\n \t\t\t\tmax_wqe -= wqe_inl_n;\n \t\t\t\tmlx5_mpw_inline_new(txq, &mpw, length);\n \t\t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t\t}\n \t\t}\n \t\t/* Multi-segment packets must be alone in their MPW. */\n@@ -1482,6 +1503,8 @@\n \t\t\t    (length <= txq->inline_max_packet_sz &&\n \t\t\t     inl_pad + sizeof(inl_hdr) + length >\n \t\t\t     mpw_room) ||\n+\t\t\t     (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags))\n \t\t\t\tmax_wqe -= mlx5_empw_close(txq, &mpw);\n \t\t}\n@@ -1505,6 +1528,10 @@\n \t\t\t\t    sizeof(inl_hdr) + length <= mpw_room &&\n \t\t\t\t    !txq->mpw_hdr_dseg;\n \t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t} else {\n \t\t\t/* Evaluate whether the next packet can be inlined.\n \t\t\t * Inlininig is possible when:\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec.c b/drivers/net/mlx5/mlx5_rxtx_vec.c\nindex 0a4aed8..132943a 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec.c\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec.c\n@@ -41,6 +41,8 @@\n \n /**\n  * Count the number of packets having same ol_flags and calculate cs_flags.\n+ * If PKT_TX_METADATA is set in ol_flags, packets must have same metadata\n+ * as well.\n  *\n  * @param pkts\n  *   Pointer to array of packets.\n@@ -48,25 +50,38 @@\n  *   Number of packets.\n  * @param cs_flags\n  *   Pointer of flags to be returned.\n+ * @param txq_offloads\n+ *   Offloads enabled on Tx queue\n  *\n  * @return\n- *   Number of packets having same ol_flags.\n+ *   Number of packets having same ol_flags and metadata, if relevant.\n  */\n static inline unsigned int\n-txq_calc_offload(struct rte_mbuf **pkts, uint16_t pkts_n, uint8_t *cs_flags)\n+txq_calc_offload(struct rte_mbuf **pkts, uint16_t pkts_n, uint8_t *cs_flags,\n+\t\tconst uint64_t txq_offloads)\n {\n \tunsigned int pos;\n \tconst uint64_t ol_mask =\n \t\tPKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM |\n \t\tPKT_TX_UDP_CKSUM | PKT_TX_TUNNEL_GRE |\n-\t\tPKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM;\n+\t\tPKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM | PKT_TX_METADATA;\n \n \tif (!pkts_n)\n \t\treturn 0;\n \t/* Count the number of packets having same ol_flags. */\n-\tfor (pos = 1; pos < pkts_n; ++pos)\n-\t\tif ((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask)\n+\tfor (pos = 1; pos < pkts_n; ++pos) {\n+\t\tif ((txq_offloads & MLX5_VEC_TX_CKSUM_OFFLOAD_CAP) &&\n+\t\t\t((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask))\n \t\t\tbreak;\n+\t\t/* If the metadata ol_flag is set,\n+\t\t *  metadata must be same in all packets.\n+\t\t */\n+\t\tif ((txq_offloads & DEV_TX_OFFLOAD_MATCH_METADATA) &&\n+\t\t\t(pkts[pos]->ol_flags & PKT_TX_METADATA) &&\n+\t\t\tpkts[0]->hash.fdir.hi != pkts[pos]->hash.fdir.hi)\n+\t\t\tbreak;\n+\t}\n+\n \t*cs_flags = txq_ol_cksum_to_cs(pkts[0]);\n \treturn pos;\n }\n@@ -137,8 +152,10 @@\n \t\tn = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST);\n \t\tif (txq->offloads & DEV_TX_OFFLOAD_MULTI_SEGS)\n \t\t\tn = txq_count_contig_single_seg(&pkts[nb_tx], n);\n-\t\tif (txq->offloads & MLX5_VEC_TX_CKSUM_OFFLOAD_CAP)\n-\t\t\tn = txq_calc_offload(&pkts[nb_tx], n, &cs_flags);\n+\t\tif (txq->offloads & (MLX5_VEC_TX_CKSUM_OFFLOAD_CAP |\n+\t\t\t\tDEV_TX_OFFLOAD_MATCH_METADATA))\n+\t\t\tn = txq_calc_offload(&pkts[nb_tx], n,\n+\t\t\t\t\t&cs_flags, txq->offloads);\n \t\tret = txq_burst_v(txq, &pkts[nb_tx], n, cs_flags);\n \t\tnb_tx += ret;\n \t\tif (!ret)\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec.h b/drivers/net/mlx5/mlx5_rxtx_vec.h\nindex fb884f9..fda7004 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec.h\n@@ -22,6 +22,7 @@\n /* HW offload capabilities of vectorized Tx. */\n #define MLX5_VEC_TX_OFFLOAD_CAP \\\n \t(MLX5_VEC_TX_CKSUM_OFFLOAD_CAP | \\\n+\t DEV_TX_OFFLOAD_MATCH_METADATA | \\\n \t DEV_TX_OFFLOAD_MULTI_SEGS)\n \n /*\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\nindex b37b738..20c9427 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\n@@ -237,6 +237,7 @@\n \tuint8x16_t *t_wqe;\n \tuint8_t *dseg;\n \tuint8x16_t ctrl;\n+\tuint32_t md; /* metadata */\n \n \t/* Make sure all packets can fit into a single WQE. */\n \tassert(elts_n > pkts_n);\n@@ -293,10 +294,11 @@\n \tctrl = vqtbl1q_u8(ctrl, ctrl_shuf_m);\n \tvst1q_u8((void *)t_wqe, ctrl);\n \t/* Fill ESEG in the header. */\n+\tmd = pkts[0]->hash.fdir.hi;\n \tvst1q_u8((void *)(t_wqe + 1),\n \t\t ((uint8x16_t) { 0, 0, 0, 0,\n \t\t\t\t cs_flags, 0, 0, 0,\n-\t\t\t\t 0, 0, 0, 0,\n+\t\t\t\t md >> 24, md >> 16, md >> 8, md,\n \t\t\t\t 0, 0, 0, 0 }));\n #ifdef MLX5_PMD_SOFT_COUNTERS\n \ttxq->stats.opackets += pkts_n;\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\nindex 54b3783..7c8535c 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\n@@ -236,6 +236,7 @@\n \t\t\t      0,  1,  2,  3  /* bswap32 */);\n \t__m128i *t_wqe, *dseg;\n \t__m128i ctrl;\n+\tuint32_t md; /* metadata */\n \n \t/* Make sure all packets can fit into a single WQE. */\n \tassert(elts_n > pkts_n);\n@@ -292,9 +293,10 @@\n \tctrl = _mm_shuffle_epi8(ctrl, shuf_mask_ctrl);\n \t_mm_store_si128(t_wqe, ctrl);\n \t/* Fill ESEG in the header. */\n+\tmd = pkts[0]->hash.fdir.hi;\n \t_mm_store_si128(t_wqe + 1,\n \t\t\t_mm_set_epi8(0, 0, 0, 0,\n-\t\t\t\t     0, 0, 0, 0,\n+\t\t\t\t     md, md >> 8, md >> 16, md >> 24,\n \t\t\t\t     0, 0, 0, cs_flags,\n \t\t\t\t     0, 0, 0, 0));\n #ifdef MLX5_PMD_SOFT_COUNTERS\ndiff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c\nindex f9bc473..7263fb1 100644\n--- a/drivers/net/mlx5/mlx5_txq.c\n+++ b/drivers/net/mlx5/mlx5_txq.c\n@@ -128,6 +128,12 @@\n \t\t\toffloads |= (DEV_TX_OFFLOAD_VXLAN_TNL_TSO |\n \t\t\t\t     DEV_TX_OFFLOAD_GRE_TNL_TSO);\n \t}\n+\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tif (config->dv_flow_en)\n+\t\toffloads |= DEV_TX_OFFLOAD_MATCH_METADATA;\n+#endif\n+\n \treturn offloads;\n }\n \n",
    "prefixes": [
        "v2"
    ]
}