get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 77004,
    "url": "http://patches.dpdk.org/api/patches/77004/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1599634114-148013-6-git-send-email-jiaweiw@nvidia.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": "<1599634114-148013-6-git-send-email-jiaweiw@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1599634114-148013-6-git-send-email-jiaweiw@nvidia.com",
    "date": "2020-09-09T06:48:27",
    "name": "[v6,05/12] net/mlx5: split sample flow into two sub flows",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0876afc573f3aaaff288d9aab01b7a25e14a00ea",
    "submitter": {
        "id": 1939,
        "url": "http://patches.dpdk.org/api/people/1939/?format=api",
        "name": "Jiawei Wang",
        "email": "jiaweiw@nvidia.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/1599634114-148013-6-git-send-email-jiaweiw@nvidia.com/mbox/",
    "series": [
        {
            "id": 12045,
            "url": "http://patches.dpdk.org/api/series/12045/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12045",
            "date": "2020-09-09T06:48:29",
            "name": "support the flow-based traffic sampling",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/12045/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/77004/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/77004/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 DC726A04B1;\n\tWed,  9 Sep 2020 08:49:34 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2F25A1C11D;\n\tWed,  9 Sep 2020 08:48:46 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 7E0EB1BF8F\n for <dev@dpdk.org>; Wed,  9 Sep 2020 08:48:36 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n jiaweiw@nvidia.com) with SMTP; 9 Sep 2020 09:48:34 +0300",
            "from nvidia.com (gen-l-vrt-280.mtl.labs.mlnx [10.237.45.1])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0896mYG0029471;\n Wed, 9 Sep 2020 09:48:34 +0300"
        ],
        "From": "Jiawei Wang <jiaweiw@nvidia.com>",
        "To": "orika@nvidia.com, viacheslavo@nvidia.com, matan@nvidia.com,\n thomas@monjalon.net, ferruh.yigit@intel.com, marko.kovacevic@intel.com,\n arybchenko@solarflare.com",
        "Cc": "dev@dpdk.org, rasland@nvidia.com, ian.stokes@intel.com, fbl@redhat.com,\n asafp@nvidia.com",
        "Date": "Wed,  9 Sep 2020 09:48:27 +0300",
        "Message-Id": "<1599634114-148013-6-git-send-email-jiaweiw@nvidia.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1599634114-148013-1-git-send-email-jiaweiw@nvidia.com>",
        "References": "<1598540492-406340-1-git-send-email-jiaweiw@nvidia.com>\n <1599634114-148013-1-git-send-email-jiaweiw@nvidia.com>",
        "Subject": "[dpdk-dev] [PATCH v6 05/12] net/mlx5: split sample flow into two\n\tsub flows",
        "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": "Add the sampler action resource structs definition.\n\nThe flow with sample action will be splited into two sub flows,\nthe prefix flow with sample action, the suffix flow with the left\nactions.\n\nFor the prefix flow, add the extra the tag action with unique id\nto metadata register, and suffix flow will add the extra tag item\nto match that unique id.\n\nSigned-off-by: Jiawei Wang <jiaweiw@nvidia.com>\n---\n drivers/net/mlx5/mlx5.c      |  11 ++\n drivers/net/mlx5/mlx5.h      |   3 +\n drivers/net/mlx5/mlx5_flow.c | 306 ++++++++++++++++++++++++++++++++++++++++---\n drivers/net/mlx5/mlx5_flow.h |  37 ++++++\n 4 files changed, 341 insertions(+), 16 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 4a807fb..8d5f517 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -241,6 +241,17 @@ static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list =\n \t\t.free = mlx5_free,\n \t\t.type = \"mlx5_jump_ipool\",\n \t},\n+\t{\n+\t\t.size = sizeof(struct mlx5_flow_dv_sample_resource),\n+\t\t.trunk_size = 64,\n+\t\t.grow_trunk = 3,\n+\t\t.grow_shift = 2,\n+\t\t.need_lock = 0,\n+\t\t.release_mem_en = 1,\n+\t\t.malloc = mlx5_malloc,\n+\t\t.free = mlx5_free,\n+\t\t.type = \"mlx5_sample_ipool\",\n+\t},\n #endif\n \t{\n \t\t.size = sizeof(struct mlx5_flow_meter),\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 8e42483..9115391 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -39,6 +39,7 @@ enum mlx5_ipool_index {\n \tMLX5_IPOOL_TAG, /* Pool for tag resource. */\n \tMLX5_IPOOL_PORT_ID, /* Pool for port id resource. */\n \tMLX5_IPOOL_JUMP, /* Pool for jump resource. */\n+\tMLX5_IPOOL_SAMPLE, /* Pool for sample resource. */\n #endif\n \tMLX5_IPOOL_MTR, /* Pool for meter resource. */\n \tMLX5_IPOOL_MCP, /* Pool for metadata resource. */\n@@ -512,6 +513,7 @@ struct mlx5_flow_tbl_resource {\n /* Tables for metering splits should be added here. */\n #define MLX5_MAX_TABLES_EXTERNAL (MLX5_MAX_TABLES - 3)\n #define MLX5_MAX_TABLES_FDB UINT16_MAX\n+#define MLX5_FLOW_TABLE_FACTOR 10\n \n /* ID generation structure. */\n struct mlx5_flow_id_pool {\n@@ -640,6 +642,7 @@ struct mlx5_dev_ctx_shared {\n \tstruct mlx5_hlist *tag_table;\n \tuint32_t port_id_action_list; /* List of port ID actions. */\n \tuint32_t push_vlan_action_list; /* List of push VLAN actions. */\n+\tuint32_t sample_action_list; /* List of sample actions. */\n \tstruct mlx5_flow_counter_mng cmng; /* Counters management structure. */\n \tstruct mlx5_flow_default_miss_resource default_miss;\n \t/* Default miss action resource structure. */\ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 4c29898..b5eec48 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -3543,6 +3543,8 @@ struct mlx5_flow_tunnel_info {\n  *   Pointer to return the created subflow, may be NULL.\n  * @param[in] prefix_layers\n  *   Prefix subflow layers, may be 0.\n+ * @param[in] prefix_mark\n+ *   Prefix subflow mark flag, may be 0.\n  * @param[in] attr\n  *   Flow rule attributes.\n  * @param[in] items\n@@ -3563,6 +3565,7 @@ struct mlx5_flow_tunnel_info {\n \t\t\tstruct rte_flow *flow,\n \t\t\tstruct mlx5_flow **sub_flow,\n \t\t\tuint64_t prefix_layers,\n+\t\t\tuint32_t prefix_mark,\n \t\t\tconst struct rte_flow_attr *attr,\n \t\t\tconst struct rte_flow_item items[],\n \t\t\tconst struct rte_flow_action actions[],\n@@ -3582,10 +3585,13 @@ struct mlx5_flow_tunnel_info {\n \t\t      dev_flow->handle, next);\n \t/*\n \t * If dev_flow is as one of the suffix flow, some actions in suffix\n-\t * flow may need some user defined item layer flags.\n+\t * flow may need some user defined item layer flags, and pass the\n+\t * Metadate rxq mark flag to suffix flow as well.\n \t */\n \tif (prefix_layers)\n \t\tdev_flow->handle->layers = prefix_layers;\n+\tif (prefix_mark)\n+\t\tdev_flow->handle->mark = 1;\n \tif (sub_flow)\n \t\t*sub_flow = dev_flow;\n \treturn flow_drv_translate(dev, dev_flow, attr, items, actions, error);\n@@ -3915,6 +3921,143 @@ struct mlx5_flow_tunnel_info {\n \treturn 0;\n }\n \n+\n+/**\n+ * Check the match action from the action list.\n+ *\n+ * @param[in] actions\n+ *   Pointer to the list of actions.\n+ * @param[in] action\n+ *   The action to be check if exist.\n+ *\n+ * @return\n+ *   > 0 the total number of actions.\n+ *   0 if not found match action in action list.\n+ */\n+static int\n+flow_check_match_action(const struct rte_flow_action actions[],\n+\t\t\t\t\tenum rte_flow_action_type action)\n+{\n+\tint actions_n = 0;\n+\tint flag = 0;\n+\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {\n+\t\tif (actions->type == action)\n+\t\t\tflag = 1;\n+\t\tactions_n++;\n+\t}\n+\t/* Count RTE_FLOW_ACTION_TYPE_END. */\n+\treturn flag ? actions_n + 1 : 0;\n+}\n+\n+/**\n+ * Split the sample flow.\n+ *\n+ * As sample flow will split to two sub flow, sample flow with\n+ * sample action, the other actions will move to new suffix flow.\n+ *\n+ * Also add unique tag id with tag action in the sample flow,\n+ * the same tag id will be as match in the suffix flow.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\n+ * @param[in] attr\n+ *   Flow rule attributes.\n+ * @param[out] sfx_items\n+ *   Suffix flow match items (list terminated by the END pattern item).\n+ * @param[in] actions\n+ *   Associated actions (list terminated by the END action).\n+ * @param[out] actions_sfx\n+ *   Suffix flow actions.\n+ * @param[out] actions_pre\n+ *   Prefix flow actions.\n+ *\n+ * @return\n+ *   0 on success, or unique flow_id, a negative errno value\n+ *   otherwise and rte_errno is set.\n+ */\n+static int\n+flow_sample_split_prep(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n+\t\t struct rte_flow_item sfx_items[],\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_action actions_sfx[],\n+\t\t struct rte_flow_action actions_pre[])\n+{\n+\tstruct mlx5_rte_flow_action_set_tag *set_tag;\n+\tstruct mlx5_rte_flow_item_tag *tag_spec;\n+\tstruct mlx5_rte_flow_item_tag *tag_mask;\n+\tstruct rte_flow_item *tag_item;\n+\tstruct rte_flow_action *tag_action = NULL;\n+\tbool pre_sample = true;\n+\tstruct rte_flow_error error;\n+\tuint32_t tag_id = 0;\n+\tint ret;\n+\n+\t/* Prepare the actions for prefix and suffix flow. */\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {\n+\t\tstruct rte_flow_action **action_cur = NULL;\n+\n+\t\tswitch (actions->type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_SAMPLE:\n+\t\t\tif (!attr->transfer) {\n+\t\t\t\t/* Add the extra tag action first for NIC-RX. */\n+\t\t\t\ttag_action = actions_pre;\n+\t\t\t\ttag_action->type = (enum rte_flow_action_type)\n+\t\t\t\t\t\tMLX5_RTE_FLOW_ACTION_TYPE_TAG;\n+\t\t\t\tactions_pre++;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\tcase RTE_FLOW_ACTION_TYPE_METER:\n+\t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n+\t\t\taction_cur = &actions_sfx;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (pre_sample && !action_cur)\n+\t\t\taction_cur = &actions_pre;\n+\t\telse\n+\t\t\taction_cur = &actions_sfx;\n+\t\tmemcpy(*action_cur, actions, sizeof(struct rte_flow_action));\n+\t\t(*action_cur)++;\n+\t\tif (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE)\n+\t\t\tpre_sample = false;\n+\t}\n+\t/* Add end action to the actions. */\n+\tactions_sfx->type = RTE_FLOW_ACTION_TYPE_END;\n+\tactions_pre->type = RTE_FLOW_ACTION_TYPE_END;\n+\tif (!attr->transfer) {\n+\t\tactions_pre++;\n+\t\t/* Set the tag. */\n+\t\tset_tag = (void *)actions_pre;\n+\t\tret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, &error);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t\tset_tag->id = ret;\n+\t\ttag_id = flow_qrss_get_id(dev);\n+\t\tset_tag->data = tag_id;\n+\t\tassert(tag_action);\n+\t\ttag_action->conf = set_tag;\n+\t\t/* Prepare the suffix subflow items. */\n+\t\ttag_item = sfx_items++;\n+\t\tsfx_items->type = RTE_FLOW_ITEM_TYPE_END;\n+\t\tsfx_items++;\n+\t\ttag_spec = (struct mlx5_rte_flow_item_tag *)sfx_items;\n+\t\ttag_spec->data = tag_id;\n+\t\ttag_spec->id = set_tag->id;\n+\t\ttag_mask = tag_spec + 1;\n+\t\ttag_mask->data = UINT32_MAX;\n+\t\ttag_item->type = (enum rte_flow_item_type)\n+\t\t\t\tMLX5_RTE_FLOW_ITEM_TYPE_TAG;\n+\t\ttag_item->spec = tag_spec;\n+\t\ttag_item->last = NULL;\n+\t\ttag_item->mask = tag_mask;\n+\t}\n+\treturn tag_id;\n+}\n+\n /**\n  * The splitting for metadata feature.\n  *\n@@ -3931,6 +4074,8 @@ struct mlx5_flow_tunnel_info {\n  *   Parent flow structure pointer.\n  * @param[in] prefix_layers\n  *   Prefix flow layer flags.\n+ * @param[in] prefix_mark\n+ *   Prefix subflow mark flag, may be 0.\n  * @param[in] attr\n  *   Flow rule attributes.\n  * @param[in] items\n@@ -3950,6 +4095,7 @@ struct mlx5_flow_tunnel_info {\n flow_create_split_metadata(struct rte_eth_dev *dev,\n \t\t\t   struct rte_flow *flow,\n \t\t\t   uint64_t prefix_layers,\n+\t\t\t   uint32_t prefix_mark,\n \t\t\t   const struct rte_flow_attr *attr,\n \t\t\t   const struct rte_flow_item items[],\n \t\t\t   const struct rte_flow_action actions[],\n@@ -3973,8 +4119,9 @@ struct mlx5_flow_tunnel_info {\n \t    config->dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||\n \t    !mlx5_flow_ext_mreg_supported(dev))\n \t\treturn flow_create_split_inner(dev, flow, NULL, prefix_layers,\n-\t\t\t\t\t       attr, items, actions, external,\n-\t\t\t\t\t       flow_idx, error);\n+\t\t\t\t\t       prefix_mark, attr, items,\n+\t\t\t\t\t       actions, external, flow_idx,\n+\t\t\t\t\t       error);\n \tactions_n = flow_parse_metadata_split_actions_info(actions, &qrss,\n \t\t\t\t\t\t\t   &encap_idx);\n \tif (qrss) {\n@@ -4059,7 +4206,8 @@ struct mlx5_flow_tunnel_info {\n \t\t\tgoto exit;\n \t}\n \t/* Add the unmodified original or prefix subflow. */\n-\tret = flow_create_split_inner(dev, flow, &dev_flow, prefix_layers, attr,\n+\tret = flow_create_split_inner(dev, flow, &dev_flow, prefix_layers,\n+\t\t\t\t      prefix_mark, attr,\n \t\t\t\t      items, ext_actions ? ext_actions :\n \t\t\t\t      actions, external, flow_idx, error);\n \tif (ret < 0)\n@@ -4122,7 +4270,7 @@ struct mlx5_flow_tunnel_info {\n \t\t}\n \t\tdev_flow = NULL;\n \t\t/* Add suffix subflow to execute Q/RSS. */\n-\t\tret = flow_create_split_inner(dev, flow, &dev_flow, layers,\n+\t\tret = flow_create_split_inner(dev, flow, &dev_flow, layers, 0,\n \t\t\t\t\t      &q_attr, mtr_sfx ? items :\n \t\t\t\t\t      q_items, q_actions,\n \t\t\t\t\t      external, flow_idx, error);\n@@ -4158,6 +4306,10 @@ struct mlx5_flow_tunnel_info {\n  *   Pointer to Ethernet device.\n  * @param[in] flow\n  *   Parent flow structure pointer.\n+ * @param[in] prefix_layers\n+ *   Prefix subflow layers, may be 0.\n+ * @param[in] prefix_mark\n+ *   Prefix subflow mark flag, may be 0.\n  * @param[in] attr\n  *   Flow rule attributes.\n  * @param[in] items\n@@ -4175,12 +4327,14 @@ struct mlx5_flow_tunnel_info {\n  */\n static int\n flow_create_split_meter(struct rte_eth_dev *dev,\n-\t\t\t   struct rte_flow *flow,\n-\t\t\t   const struct rte_flow_attr *attr,\n-\t\t\t   const struct rte_flow_item items[],\n-\t\t\t   const struct rte_flow_action actions[],\n-\t\t\t   bool external, uint32_t flow_idx,\n-\t\t\t   struct rte_flow_error *error)\n+\t\t\tstruct rte_flow *flow,\n+\t\t\tuint64_t prefix_layers,\n+\t\t\tuint32_t prefix_mark,\n+\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\tconst struct rte_flow_item items[],\n+\t\t\tconst struct rte_flow_action actions[],\n+\t\t\tbool external, uint32_t flow_idx,\n+\t\t\tstruct rte_flow_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct rte_flow_action *sfx_actions = NULL;\n@@ -4223,8 +4377,10 @@ struct mlx5_flow_tunnel_info {\n \t\t\tgoto exit;\n \t\t}\n \t\t/* Add the prefix subflow. */\n-\t\tret = flow_create_split_inner(dev, flow, &dev_flow, 0, attr,\n-\t\t\t\t\t      items, pre_actions, external,\n+\t\tret = flow_create_split_inner(dev, flow, &dev_flow,\n+\t\t\t\t\t      prefix_layers, 0,\n+\t\t\t\t\t      attr, items,\n+\t\t\t\t\t      pre_actions, external,\n \t\t\t\t\t      flow_idx, error);\n \t\tif (ret) {\n \t\t\tret = -rte_errno;\n@@ -4239,8 +4395,10 @@ struct mlx5_flow_tunnel_info {\n \t/* Add the prefix subflow. */\n \tret = flow_create_split_metadata(dev, flow, dev_flow ?\n \t\t\t\t\t flow_get_prefix_layer_flags(dev_flow) :\n-\t\t\t\t\t 0, &sfx_attr,\n-\t\t\t\t\t sfx_items ? sfx_items : items,\n+\t\t\t\t\t prefix_layers, dev_flow ?\n+\t\t\t\t\t dev_flow->handle->mark : prefix_mark,\n+\t\t\t\t\t &sfx_attr, sfx_items ?\n+\t\t\t\t\t sfx_items : items,\n \t\t\t\t\t sfx_actions ? sfx_actions : actions,\n \t\t\t\t\t external, flow_idx, error);\n exit:\n@@ -4250,6 +4408,122 @@ struct mlx5_flow_tunnel_info {\n }\n \n /**\n+ * The splitting for sample feature.\n+ *\n+ * The sample flow will be split to two flows as prefix and\n+ * suffix flow.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\n+ * @param[in] flow\n+ *   Parent flow structure pointer.\n+ * @param[in] attr\n+ *   Flow rule attributes.\n+ * @param[in] items\n+ *   Pattern specification (list terminated by the END pattern item).\n+ * @param[in] actions\n+ *   Associated actions (list terminated by the END action).\n+ * @param[in] external\n+ *   This flow rule is created by request external to PMD.\n+ * @param[in] flow_idx\n+ *   This memory pool index to the flow.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ * @return\n+ *   0 on success, negative value otherwise\n+ */\n+static int\n+flow_create_split_sample(struct rte_eth_dev *dev,\n+\t\t\t   struct rte_flow *flow,\n+\t\t\t   const struct rte_flow_attr *attr,\n+\t\t\t   const struct rte_flow_item items[],\n+\t\t\t   const struct rte_flow_action actions[],\n+\t\t\t   bool external, uint32_t flow_idx,\n+\t\t\t   struct rte_flow_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct rte_flow_action *sfx_actions = NULL;\n+\tstruct rte_flow_action *pre_actions = NULL;\n+\tstruct rte_flow_item *sfx_items = NULL;\n+\tstruct mlx5_flow *dev_flow = NULL;\n+\tstruct rte_flow_attr sfx_attr = *attr;\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tstruct mlx5_flow_dv_sample_resource *sample_res;\n+\tstruct mlx5_flow_tbl_data_entry *sfx_tbl_data;\n+\tstruct mlx5_flow_tbl_resource *sfx_tbl;\n+\tunion mlx5_flow_tbl_key sfx_table_key;\n+#endif\n+\tsize_t act_size;\n+\tsize_t item_size;\n+\tint32_t tag_id = 0;\n+\tint actions_n = 0;\n+\tint ret = 0;\n+\n+\tif (priv->sampler_en)\n+\t\tactions_n = flow_check_match_action(actions,\n+\t\t\t\t\tRTE_FLOW_ACTION_TYPE_SAMPLE);\n+\tif (actions_n) {\n+\t\t/* The prefix actions must includes sample, tag, end. */\n+\t\tact_size = sizeof(struct rte_flow_action) * (actions_n * 2 + 1)\n+\t\t\t   + sizeof(struct mlx5_rte_flow_action_set_tag);\n+\t\t/* tag, end. */\n+#define SAMPLE_SUFFIX_ITEM 2\n+\t\titem_size = sizeof(struct rte_flow_item) * SAMPLE_SUFFIX_ITEM +\n+\t\t\t    sizeof(struct mlx5_rte_flow_item_tag) * 2;\n+\t\tsfx_actions = rte_zmalloc(__func__, (act_size + item_size), 0);\n+\t\tif (!sfx_actions)\n+\t\t\treturn rte_flow_error_set(error, ENOMEM,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  NULL, \"no memory to split \"\n+\t\t\t\t\t\t  \"sample flow\");\n+\t\tif (!attr->transfer)\n+\t\t\tsfx_items = (struct rte_flow_item *)((char *)sfx_actions\n+\t\t\t\t\t+ act_size);\n+\t\tpre_actions = sfx_actions + actions_n;\n+\t\ttag_id = flow_sample_split_prep(dev, attr, sfx_items,\n+\t\t\t\t\t\tactions, sfx_actions,\n+\t\t\t\t\t\tpre_actions);\n+\t\tif (tag_id < 0 || (!attr->transfer && !tag_id)) {\n+\t\t\tret = -rte_errno;\n+\t\t\tgoto exit;\n+\t\t}\n+\t\t/* Add the prefix subflow. */\n+\t\tret = flow_create_split_inner(dev, flow, &dev_flow, 0, 0, attr,\n+\t\t\t\t\t      items, pre_actions, external,\n+\t\t\t\t\t      flow_idx, error);\n+\t\tif (ret) {\n+\t\t\tret = -rte_errno;\n+\t\t\tgoto exit;\n+\t\t}\n+\t\tdev_flow->handle->split_flow_id = tag_id;\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\t\t/* Set the sfx group attr. */\n+\t\tsample_res = (struct mlx5_flow_dv_sample_resource *)\n+\t\t\t\t\tdev_flow->dv.sample_res;\n+\t\tsfx_tbl = (struct mlx5_flow_tbl_resource *)\n+\t\t\t\t\tsample_res->normal_path_tbl;\n+\t\tsfx_tbl_data = container_of(sfx_tbl,\n+\t\t\t\t\tstruct mlx5_flow_tbl_data_entry, tbl);\n+\t\tsfx_table_key.v64 = sfx_tbl_data->entry.key;\n+\t\tsfx_attr.group = sfx_attr.transfer ?\n+\t\t\t\t\t(sfx_table_key.table_id - 1) :\n+\t\t\t\t\tsfx_table_key.table_id;\n+#endif\n+\t}\n+\t/* Add the suffix subflow. */\n+\tret = flow_create_split_meter(dev, flow, dev_flow ?\n+\t\t\t\t flow_get_prefix_layer_flags(dev_flow) : 0,\n+\t\t\t\t dev_flow ? dev_flow->handle->mark : 0,\n+\t\t\t\t &sfx_attr, sfx_items ? sfx_items : items,\n+\t\t\t\t sfx_actions ? sfx_actions : actions,\n+\t\t\t\t external, flow_idx, error);\n+exit:\n+\tif (sfx_actions)\n+\t\trte_free(sfx_actions);\n+\treturn ret;\n+}\n+\n+/**\n  * Split the flow to subflow set. The splitters might be linked\n  * in the chain, like this:\n  * flow_create_split_outer() calls:\n@@ -4297,7 +4571,7 @@ struct mlx5_flow_tunnel_info {\n {\n \tint ret;\n \n-\tret = flow_create_split_meter(dev, flow, attr, items,\n+\tret = flow_create_split_sample(dev, flow, attr, items,\n \t\t\t\t\t actions, external, flow_idx, error);\n \tMLX5_ASSERT(ret <= 0);\n \treturn ret;\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 41404de..9c609cb 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -507,6 +507,39 @@ struct mlx5_flow_tbl_data_entry {\n \tuint32_t idx; /**< index for the indexed mempool. */\n };\n \n+/* Sub rdma-core actions list. */\n+struct mlx5_flow_sub_actions_list {\n+\tuint32_t actions_num; /**< Number of sample actions. */\n+\tuint64_t action_flags;\n+\tvoid *dr_queue_action;\n+\tvoid *dr_tag_action;\n+\tvoid *dr_cnt_action;\n+};\n+\n+/* Sample sub-actions resource list. */\n+struct mlx5_flow_sub_actions_idx {\n+\tuint32_t rix_hrxq; /**< Hash Rx queue object index. */\n+\tuint32_t rix_tag; /**< Index to the tag action. */\n+\tuint32_t cnt;\n+};\n+\n+/* Sample action resource structure. */\n+struct mlx5_flow_dv_sample_resource {\n+\tILIST_ENTRY(uint32_t)next; /**< Pointer to next element. */\n+\trte_atomic32_t refcnt; /**< Reference counter. */\n+\tvoid *verbs_action; /**< Verbs sample action object. */\n+\tuint8_t ft_type; /** Flow Table Type */\n+\tuint32_t ft_id; /** Flow Table Level */\n+\tuint32_t ratio;   /** Sample Ratio */\n+\tuint64_t set_action; /** Restore reg_c0 value */\n+\tvoid *normal_path_tbl; /** Flow Table pointer */\n+\tvoid *default_miss; /** default_miss dr_action. */\n+\tstruct mlx5_flow_sub_actions_idx sample_idx;\n+\t/**< Action index resources. */\n+\tstruct mlx5_flow_sub_actions_list sample_act;\n+\t/**< Action resources. */\n+};\n+\n /* Verbs specification header. */\n struct ibv_spec_header {\n \tenum ibv_flow_spec_type type;\n@@ -539,6 +572,8 @@ struct mlx5_flow_handle_dv {\n \t/**< Index to push VLAN action resource in cache. */\n \tuint32_t rix_tag;\n \t/**< Index to the tag action. */\n+\tuint32_t rix_sample;\n+\t/**< Index to sample action resource in cache. */\n } __rte_packed;\n \n /** Device flow handle structure: used both for creating & destroying. */\n@@ -604,6 +639,8 @@ struct mlx5_flow_dv_workspace {\n \t/**< Pointer to the jump action resource. */\n \tstruct mlx5_flow_dv_match_params value;\n \t/**< Holds the value that the packet is compared to. */\n+\tstruct mlx5_flow_dv_sample_resource *sample_res;\n+\t/**< Pointer to the sample action resource. */\n };\n \n /*\n",
    "prefixes": [
        "v6",
        "05/12"
    ]
}