get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 85193,
    "url": "https://patches.dpdk.org/api/patches/85193/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201215073119.404947-9-lizh@nvidia.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": "<20201215073119.404947-9-lizh@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201215073119.404947-9-lizh@nvidia.com",
    "date": "2020-12-15T07:31:19",
    "name": "[RFC,8/8] net/mlx5: add support of ASO meter action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "cfa3d284be1739063642a3378906a7cdbf02ec47",
    "submitter": {
        "id": 1967,
        "url": "https://patches.dpdk.org/api/people/1967/?format=api",
        "name": "Li Zhang",
        "email": "lizh@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "https://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201215073119.404947-9-lizh@nvidia.com/mbox/",
    "series": [
        {
            "id": 14302,
            "url": "https://patches.dpdk.org/api/series/14302/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14302",
            "date": "2020-12-15T07:31:11",
            "name": "net/mlx5: enhancement metering support",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14302/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/85193/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/85193/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 885F8A09E9;\n\tTue, 15 Dec 2020 08:33:46 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 124FCCA02;\n\tTue, 15 Dec 2020 08:31:54 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id F13B3C9D0\n for <dev@dpdk.org>; Tue, 15 Dec 2020 08:31:45 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n lizh@nvidia.com)\n with SMTP; 15 Dec 2020 09:31:41 +0200",
            "from nvidia.com (c-236-2-240-245.mtl.labs.mlnx [10.236.2.245])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BF7VOkK005436;\n Tue, 15 Dec 2020 09:31:41 +0200"
        ],
        "From": "Li Zhang <lizh@nvidia.com>",
        "To": "dekelp@nvidia.com, orika@nvidia.com, viacheslavo@nvidia.com,\n matan@nvidia.com",
        "Cc": "dev@dpdk.org, thomas@monjalon.net, rasland@nvidia.com,\n Shun Hao <shunh@nvidia.com>",
        "Date": "Tue, 15 Dec 2020 09:31:19 +0200",
        "Message-Id": "<20201215073119.404947-9-lizh@nvidia.com>",
        "X-Mailer": "git-send-email 2.27.0",
        "In-Reply-To": "<20201215073119.404947-1-lizh@nvidia.com>",
        "References": "<20201215073119.404947-1-lizh@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [RFC 8/8] net/mlx5: add support of ASO meter action",
        "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": "When ASO action is available, use it as the meter action\n\nSigned-off-by: Shun Hao <shunh@nvidia.com>\nSigned-off-by: Li Zhang <lizh@nvidia.com>\n---\n drivers/net/mlx5/linux/mlx5_os.c   |   4 +-\n drivers/net/mlx5/mlx5.c            |   8 ++\n drivers/net/mlx5/mlx5.h            |  18 ++---\n drivers/net/mlx5/mlx5_flow.c       |  66 +++++++++++-----\n drivers/net/mlx5/mlx5_flow_dv.c    |  74 ++++++++++--------\n drivers/net/mlx5/mlx5_flow_meter.c | 118 ++++++++++++++++++-----------\n 6 files changed, 184 insertions(+), 104 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex 01b019c28d..28e383c7e2 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -1233,7 +1233,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t\t\t\t\"required for coalescing is %d bytes\",\n \t\t\t\tconfig->hca_attr.lro_min_mss_size);\n \t\t}\n-#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER)\n+#if defined(HAVE_MLX5DV_DR) && \\\n+\t(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \\\n+\t defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))\n \t\tif (config->hca_attr.qos.sup &&\n \t\t    config->hca_attr.qos.srtcm_sup &&\n \t\t    config->dv_flow_en) {\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 9d77265e2e..224c8e3965 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -584,13 +584,21 @@ static void\n mlx5_aso_flow_mtrs_mng_close(struct mlx5_dev_ctx_shared *sh)\n {\n \tstruct mlx5_aso_mtr_pool *mtr_pool;\n+\tstruct mlx5_aso_mtr *aso_mtr;\n \tstruct mlx5_aso_mtr_pools_mng *mtrmng = sh->mtrmng;\n \tuint32_t idx;\n+\tint i;\n \n \tmlx5_aso_queue_uninit(sh, ASO_OPC_MOD_POLICER);\n \tidx = mtrmng->n_valid;\n \twhile (idx--) {\n \t\tmtr_pool = mtrmng->pools[idx];\n+\t\tfor (i = 0; i < MLX5_ASO_MTRS_PER_POOL; i++) {\n+\t\t\taso_mtr = &mtr_pool->mtrs[i];\n+\t\t\tif (aso_mtr->fm.meter_action)\n+\t\t\t\tclaim_zero(mlx5_glue->destroy_flow_action\n+\t\t\t\t\t\t(aso_mtr->fm.meter_action));\n+\t\t}\n \t\tclaim_zero(mlx5_devx_cmd_destroy\n \t\t\t\t\t\t(mtr_pool->devx_obj));\n \t\tmtrmng->n_valid--;\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 73d3698f1d..b4bd76e792 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -645,8 +645,6 @@ struct mlx5_meter_domains_infos {\n \t/**< Drop action as not matched. */\n \tvoid *count_actns[RTE_MTR_DROPPED + 1];\n \t/**< Counters for match and unmatched statistics. */\n-\tvoid *meter_action;\n-\t/**< Flow meter action. */\n };\n \n /* Meter parameter structure. */\n@@ -697,6 +695,8 @@ struct mlx5_flow_meter_info {\n \t/**< Meter shared or not. */\n \tuint32_t is_enable:1;\n \t/**< Meter disable/enable state. */\n+\tvoid *meter_action;\n+\t/**< Flow meter action. */\n };\n \n /* RFC2697 parameter structure. */\n@@ -800,7 +800,7 @@ struct mlx5_flow_tbl_resource {\n /* Tables for metering splits should be added here. */\n #define MLX5_FLOW_TABLE_LEVEL_SUFFIX (MLX5_MAX_TABLES - 3)\n #define MLX5_FLOW_TABLE_LEVEL_METER (MLX5_MAX_TABLES - 4)\n-#define MLX5_MAX_TABLES_EXTERNAL MLX5_FLOW_TABLE_LEVEL_METER\n+#define MLX5_MAX_TABLES_EXTERNAL (MLX5_FLOW_TABLE_LEVEL_METER - 1)\n #define MLX5_MAX_TABLES_FDB UINT16_MAX\n #define MLX5_FLOW_TABLE_FACTOR 10\n \n@@ -1458,13 +1458,11 @@ int mlx5_pmd_socket_init(void);\n int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);\n struct mlx5_flow_meter_info *mlx5_flow_meter_find(struct mlx5_priv *priv,\n \t\tuint32_t meter_id, uint32_t *mtr_idx);\n-struct mlx5_flow_meter_info *mlx5_flow_meter_attach\n-\t\t\t\t\t(struct mlx5_priv *priv,\n-\t\t\t\t\t uint32_t meter_id,\n-\t\t\t\t\t const struct rte_flow_attr *attr,\n-\t\t\t\t\t uint32_t *mtr_idx,\n-\t\t\t\t\t struct rte_flow_error *error);\n-void mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm);\n+uint32_t mlx5_flow_meter_attach(struct mlx5_priv *priv, uint32_t meter_id,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error);\n+void mlx5_flow_meter_detach(struct mlx5_priv *priv,\n+\t\t\t    struct mlx5_flow_meter_info *fm);\n \n /* mlx5_os.c */\n struct rte_pci_driver;\ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 2f047bbe01..0142b546df 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -4282,6 +4282,7 @@ flow_create_split_inner(struct rte_eth_dev *dev,\n  */\n static int\n flow_meter_split_prep(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_attr *attr,\n \t\t const struct rte_flow_item items[],\n \t\t struct rte_flow_item sfx_items[],\n \t\t const struct rte_flow_action actions[],\n@@ -4300,33 +4301,44 @@ flow_meter_split_prep(struct rte_eth_dev *dev,\n \tuint32_t tag_id = 0;\n \tuint32_t reg_id = 0;\n \tbool copy_vlan = false;\n+\tstruct rte_flow_action *hw_mtr_action;\n+\tstruct rte_flow_action_jump *jump_data;\n+\t/* For ASO meter, meter must be before tag in TX direction. */\n+\tbool mtr_first = priv->sh->meter_aso_en &&\n+\t\t\t (attr->egress ||\n+\t\t\t  (attr->transfer && priv->representor_id != -1));\n+\tstruct rte_flow_action *action_pre_head =\n+\t\t\t\t\tmtr_first ? actions_pre++ : NULL;\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+\t\tstruct rte_flow_action *action_cur = NULL;\n \n \t\tswitch (actions->type) {\n \t\tcase RTE_FLOW_ACTION_TYPE_METER:\n-\t\t\t/* Add the extra tag action first. */\n-\t\t\ttag_action = actions_pre;\n+\t\t\tif (mtr_first) {\n+\t\t\t\taction_cur = action_pre_head;\n+\t\t\t\ttag_action = actions_pre++;\n+\t\t\t} else {\n+\t\t\t\ttag_action = actions_pre++;\n+\t\t\t\taction_cur = actions_pre++;\n+\t\t\t}\n \t\t\ttag_action->type = (enum rte_flow_action_type)\n \t\t\t\t\t   MLX5_RTE_FLOW_ACTION_TYPE_TAG;\n-\t\t\tactions_pre++;\n-\t\t\taction_cur = &actions_pre;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n \t\tcase RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:\n-\t\t\taction_cur = &actions_pre;\n+\t\t\taction_cur = actions_pre++;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_RAW_ENCAP:\n \t\t\traw_encap = actions->conf;\n \t\t\tif (raw_encap->size < MLX5_ENCAPSULATION_DECISION_SIZE)\n-\t\t\t\taction_cur = &actions_pre;\n+\t\t\t\taction_cur = actions_pre++;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_RAW_DECAP:\n \t\t\traw_decap = actions->conf;\n \t\t\tif (raw_decap->size > MLX5_ENCAPSULATION_DECISION_SIZE)\n-\t\t\t\taction_cur = &actions_pre;\n+\t\t\t\taction_cur = actions_pre++;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:\n \t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:\n@@ -4336,14 +4348,30 @@ flow_meter_split_prep(struct rte_eth_dev *dev,\n \t\t\tbreak;\n \t\t}\n \t\tif (!action_cur)\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\t\taction_cur = actions_sfx++;\n+\t\tmemcpy(action_cur, actions, sizeof(struct rte_flow_action));\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-\tactions_pre++;\n+\tif (priv->sh->meter_aso_en) {\n+\t\t/** For ASO meter, need to add an extra jump action explicitly,\n+\t\t *  to jump from meter to policer table.\n+\t\t */\n+\t\thw_mtr_action = actions_pre;\n+\t\thw_mtr_action->type = RTE_FLOW_ACTION_TYPE_JUMP;\n+\t\tactions_pre++;\n+\t\tactions_pre->type = RTE_FLOW_ACTION_TYPE_END;\n+\t\tactions_pre++;\n+\t\tjump_data = (void *)actions_pre;\n+\t\tjump_data->group = attr->transfer ?\n+\t\t\t\t(MLX5_FLOW_TABLE_LEVEL_METER - 1) :\n+\t\t\t\t MLX5_FLOW_TABLE_LEVEL_METER;\n+\t\thw_mtr_action->conf = jump_data;\n+\t\tactions_pre++;\n+\t} else {\n+\t\tactions_pre->type = RTE_FLOW_ACTION_TYPE_END;\n+\t\tactions_pre++;\n+\t}\n \t/* Set the tag. */\n \tset_tag = (void *)actions_pre;\n \treg_id = mlx5_flow_get_reg_id(dev, MLX5_MTR_SFX, 0, &error);\n@@ -5116,12 +5144,16 @@ flow_create_split_meter(struct rte_eth_dev *dev,\n \tsize_t item_size;\n \tint actions_n = 0;\n \tint ret;\n+\tuint8_t pre_action_num;\n \n \tif (priv->mtr_en)\n \t\tactions_n = flow_check_meter_action(actions, &mtr);\n \tif (mtr) {\n \t\t/* The five prefix actions: meter, decap, encap, tag, end. */\n-\t\tact_size = sizeof(struct rte_flow_action) * (actions_n + 5) +\n+\t\t/* For aso meter, need 2 more space for jump. */\n+\t\tpre_action_num = priv->sh->meter_aso_en ? 7 : 5;\n+\t\tact_size = sizeof(struct rte_flow_action) *\n+\t\t\t   (actions_n + pre_action_num) +\n \t\t\t   sizeof(struct mlx5_rte_flow_action_set_tag);\n \t\t/* tag, vlan, port id, end. */\n #define METER_SUFFIX_ITEM 4\n@@ -5137,9 +5169,9 @@ flow_create_split_meter(struct rte_eth_dev *dev,\n \t\tsfx_items = (struct rte_flow_item *)((char *)sfx_actions +\n \t\t\t     act_size);\n \t\tpre_actions = sfx_actions + actions_n;\n-\t\tmtr_tag_id = flow_meter_split_prep(dev, items, sfx_items,\n-\t\t\t\t\t\t   actions, sfx_actions,\n-\t\t\t\t\t\t   pre_actions);\n+\t\tmtr_tag_id = flow_meter_split_prep(dev, &sfx_attr, items,\n+\t\t\t\t\t\t   sfx_items, actions,\n+\t\t\t\t\t\t   sfx_actions, pre_actions);\n \t\tif (!mtr_tag_id) {\n \t\t\tret = -rte_errno;\n \t\t\tgoto exit;\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex cc84cb3a52..b0803e4847 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -4213,9 +4213,11 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,\n \t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n \t\t\t\t\t  \"Meter not found\");\n-\tif (fm->ref_cnt && (!(fm->transfer == attr->transfer ||\n+\t/* aso meter can always be shared by different domains */\n+\tif (fm->ref_cnt && !priv->sh->meter_aso_en &&\n+\t    !(fm->transfer == attr->transfer ||\n \t      (!fm->ingress && !attr->ingress && attr->egress) ||\n-\t      (!fm->egress && !attr->egress && attr->ingress))))\n+\t      (!fm->egress && !attr->egress && attr->ingress)))\n \t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n \t\t\t\t\t  \"Flow attributes are either invalid \"\n@@ -5394,6 +5396,8 @@ flow_dv_mtr_alloc(struct rte_eth_dev *dev)\n \tstruct mlx5_aso_mtr *mtr_free = NULL;\n \tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n \tstruct mlx5_aso_mtr_pool *pool;\n+\tstruct rte_flow_error error;\n+\tuint8_t reg_id;\n \tuint32_t mtr_idx = 0;\n \n \tif (!priv->config.devx) {\n@@ -5416,6 +5420,20 @@ flow_dv_mtr_alloc(struct rte_eth_dev *dev)\n \t\t\t\t\tstruct mlx5_aso_mtr_pool,\n \t\t\t\t\tmtrs[mtr_free->offset]);\n \tmtr_idx = MLX5_MAKE_MTR_IDX(pool->index, mtr_free->offset);\n+\tif (!mtr_free->fm.meter_action) {\n+\t\treg_id = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, &error);\n+\t\tmtr_free->fm.meter_action =\n+\t\t\tmlx5_glue->dv_create_flow_action_aso\n+\t\t\t\t\t\t(priv->sh->rx_domain,\n+\t\t\t\t\t\t pool->devx_obj->obj,\n+\t\t\t\t\t\t mtr_free->offset,\n+\t\t\t\t\t\t (1 << MLX5_FLOW_COLOR_GREEN),\n+\t\t\t\t\t\t reg_id - REG_C_0);\n+\t\tif (!mtr_free->fm.meter_action) {\n+\t\t\tflow_dv_aso_mtr_release_to_pool(dev, mtr_idx);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n \treturn mtr_idx;\n }\n \n@@ -10317,7 +10335,6 @@ flow_dv_translate(struct rte_eth_dev *dev,\n \t\tconst struct rte_flow_action *found_action = NULL;\n \t\tstruct mlx5_flow_meter_info *fm = NULL;\n \t\tuint32_t jump_group = 0;\n-\t\tuint32_t mtr_idx;\n \n \t\tif (!mlx5_flow_os_action_supported(action_type))\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n@@ -10743,32 +10760,23 @@ flow_dv_translate(struct rte_eth_dev *dev,\n \t\tcase RTE_FLOW_ACTION_TYPE_METER:\n \t\t\tmtr = actions->conf;\n \t\t\tif (!flow->meter) {\n-\t\t\t\tfm = mlx5_flow_meter_attach(priv, mtr->mtr_id,\n-\t\t\t\t\t\tattr, &mtr_idx, error);\n-\t\t\t\tif (!fm)\n-\t\t\t\t\treturn rte_flow_error_set(error,\n-\t\t\t\t\t\trte_errno,\n-\t\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION,\n-\t\t\t\t\t\tNULL,\n-\t\t\t\t\t\t\"meter not found \"\n-\t\t\t\t\t\t\"or invalid parameters\");\n-\t\t\t\tflow->meter = mtr_idx;\n-\t\t\t\twks->mtr_idx = mtr_idx;\n+\t\t\t\tflow->meter =\n+\t\t\t\t\tmlx5_flow_meter_attach(priv,\n+\t\t\t\t\t\t\t       mtr->mtr_id,\n+\t\t\t\t\t\t\t       attr,\n+\t\t\t\t\t\t\t       error);\n+\t\t\t\tif (!flow->meter)\n+\t\t\t\t\treturn -rte_errno;\n+\t\t\t\twks->mtr_idx = flow->meter;\n \t\t\t}\n-\t\t\t/* Set the meter action. */\n-\t\t\tif (!fm) {\n-\t\t\t\tfm = flow_dv_meter_find_by_idx(priv,\n-\t\t\t\t\twks->mtr_idx);\n-\t\t\t\tif (!fm)\n-\t\t\t\t\treturn rte_flow_error_set(error,\n-\t\t\t\t\t\trte_errno,\n+\t\t\tfm = flow_dv_meter_find_by_idx(priv, wks->mtr_idx);\n+\t\t\tif (!fm)\n+\t\t\t\treturn rte_flow_error_set(error, ENOENT,\n \t\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t\t\tNULL,\n-\t\t\t\t\t\t\"meter not found \"\n-\t\t\t\t\t\t\"or invalid parameters\");\n-\t\t\t}\n-\t\t\tdev_flow->dv.actions[actions_n++] =\n-\t\t\t\tfm->mfts->meter_action;\n+\t\t\t\t\t\t\"failed to get flow meter.\");\n+\t\t\t/* Set the meter action. */\n+\t\t\tdev_flow->dv.actions[actions_n++] = fm->meter_action;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_METER;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:\n@@ -11888,7 +11896,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n \n \t\tfm = flow_dv_meter_find_by_idx(priv, flow->meter);\n \t\tif (fm)\n-\t\t\tmlx5_flow_meter_detach(fm);\n+\t\t\tmlx5_flow_meter_detach(priv, fm);\n \t\tflow->meter = 0;\n \t}\n \tif (flow->age)\n@@ -12678,10 +12686,12 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev,\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_dev_ctx_shared *sh = priv->sh;\n \tstruct mlx5_flow_dv_match_params mask = {\n-\t\t.size = sizeof(mask.buf),\n+\t\t.size = sizeof(mask.buf) -\n+\t\t\tMLX5_ST_SZ_BYTES(fte_match_set_misc4),\n \t};\n \tstruct mlx5_flow_dv_match_params value = {\n-\t\t.size = sizeof(value.buf),\n+\t\t.size = sizeof(value.buf) -\n+\t\t\tMLX5_ST_SZ_BYTES(fte_match_set_misc4),\n \t};\n \tstruct mlx5dv_flow_matcher_attr dv_attr = {\n \t\t.type = IBV_FLOW_ATTR_NORMAL,\n@@ -12901,10 +12911,12 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter_info *fm,\n \t\t\t\t    uint8_t mtr_reg_c)\n {\n \tstruct mlx5_flow_dv_match_params matcher = {\n-\t\t.size = sizeof(matcher.buf),\n+\t\t.size = sizeof(matcher.buf) -\n+\t\t\tMLX5_ST_SZ_BYTES(fte_match_set_misc4),\n \t};\n \tstruct mlx5_flow_dv_match_params value = {\n-\t\t.size = sizeof(value.buf),\n+\t\t.size = sizeof(value.buf) -\n+\t\t\tMLX5_ST_SZ_BYTES(fte_match_set_misc4),\n \t};\n \tstruct mlx5_meter_domains_infos *mtb = fm->mfts;\n \tvoid *actions[METER_ACTIONS];\ndiff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c\nindex 31bbe00173..b01aae2301 100644\n--- a/drivers/net/mlx5/mlx5_flow_meter.c\n+++ b/drivers/net/mlx5/mlx5_flow_meter.c\n@@ -598,9 +598,9 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n \t\t\t\tebs_mantissa, val);\n \t\t}\n \t\t/* Apply modifications to meter only if it was created. */\n-\t\tif (fm->mfts->meter_action) {\n+\t\tif (fm->meter_action) {\n \t\t\tret = mlx5_glue->dv_modify_flow_action_meter\n-\t\t\t\t\t(fm->mfts->meter_action, &mod_attr,\n+\t\t\t\t\t(fm->meter_action, &mod_attr,\n \t\t\t\t\trte_cpu_to_be_64(modify_bits));\n \t\t\tif (ret)\n \t\t\t\treturn ret;\n@@ -1268,74 +1268,102 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id,\n  * @param [out] error\n  *  Pointer to error structure.\n  *\n- * @return the flow meter pointer, NULL otherwise.\n+ * @return\n+ *   The meter idx on success, 0 otherwise and rte_errno is set.\n  */\n-struct mlx5_flow_meter_info *\n-mlx5_flow_meter_attach(struct mlx5_priv *priv, uint32_t meter_id,\n-\t\t       const struct rte_flow_attr *attr, uint32_t *mtr_idx,\n-\t\t       struct rte_flow_error *error)\n+uint32_t mlx5_flow_meter_attach(struct mlx5_priv *priv, uint32_t meter_id,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tstruct mlx5_flow_meter_info *fm;\n+\tstruct mlx5_aso_mtr *aso_mtr;\n+\tuint32_t mtr_idx;\n \tint ret = 0;\n \n-\tfm = mlx5_flow_meter_find(priv, meter_id, mtr_idx);\n-\tif (fm == NULL) {\n+\tfm = mlx5_flow_meter_find(priv, meter_id, &mtr_idx);\n+\tif (!fm) {\n \t\trte_flow_error_set(error, ENOENT,\n-\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t   \"Meter object id not valid\");\n-\t\treturn fm;\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t   NULL, \"Meter not found \");\n+\t\treturn 0;\n \t}\n-\trte_spinlock_lock(&fm->sl);\n-\tif (fm->mfts->meter_action) {\n-\t\tif (fm->shared &&\n-\t\t    attr->transfer == fm->transfer &&\n-\t\t    attr->ingress == fm->ingress &&\n-\t\t    attr->egress == fm->egress)\n+\tif (priv->sh->meter_aso_en) {\n+\t\taso_mtr = container_of(fm, struct mlx5_aso_mtr, fm);\n+\t\tif (mlx5_aso_mtr_wait(priv->sh, aso_mtr)) {\n+\t\t\trte_flow_error_set(error, ENOENT,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t   NULL,\n+\t\t\t\t\t   \"Timeout in meter configuration\");\n+\t\t\treturn 0;\n+\t\t}\n+\t\trte_spinlock_lock(&fm->sl);\n+\t\tif (fm->shared || !fm->ref_cnt) {\n \t\t\tfm->ref_cnt++;\n-\t\telse\n+\t\t} else {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Meter cannot be shared\");\n \t\t\tret = -1;\n+\t\t}\n+\t\trte_spinlock_unlock(&fm->sl);\n \t} else {\n-\t\tfm->ingress = attr->ingress;\n-\t\tfm->egress = attr->egress;\n-\t\tfm->transfer = attr->transfer;\n-\t\t fm->ref_cnt = 1;\n-\t\t/* This also creates the meter object. */\n-\t\tfm->mfts->meter_action = mlx5_flow_meter_action_create(priv,\n-\t\t\t\t\t\t\t\t       fm);\n-\t\tif (!fm->mfts->meter_action) {\n-\t\t\tfm->ref_cnt = 0;\n-\t\t\tfm->ingress = 0;\n-\t\t\tfm->egress = 0;\n-\t\t\tfm->transfer = 0;\n-\t\t\tret = -1;\n-\t\t\tDRV_LOG(ERR, \"Meter action create failed.\");\n+\t\trte_spinlock_lock(&fm->sl);\n+\t\tif (fm->meter_action) {\n+\t\t\tif (fm->shared &&\n+\t\t\t    attr->transfer == fm->transfer &&\n+\t\t\t    attr->ingress == fm->ingress &&\n+\t\t\t    attr->egress == fm->egress) {\n+\t\t\t\tfm->ref_cnt++;\n+\t\t\t} else {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\tfm->shared ?\n+\t\t\t\t\t\"Meter attr not match.\" :\n+\t\t\t\t\t\"Meter cannot be shared.\");\n+\t\t\t\tret = -1;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tfm->ingress = attr->ingress;\n+\t\t\tfm->egress = attr->egress;\n+\t\t\tfm->transfer = attr->transfer;\n+\t\t\tfm->ref_cnt = 1;\n+\t\t\t/* This also creates the meter object. */\n+\t\t\tfm->meter_action = mlx5_flow_meter_action_create(priv,\n+\t\t\t\t\t\t\t\t\t fm);\n+\t\t\tif (!fm->meter_action) {\n+\t\t\t\tfm->ref_cnt = 0;\n+\t\t\t\tfm->ingress = 0;\n+\t\t\t\tfm->egress = 0;\n+\t\t\t\tfm->transfer = 0;\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t\"Meter action create failed.\");\n+\t\t\t\tret = -1;\n+\t\t\t}\n \t\t}\n+\t\trte_spinlock_unlock(&fm->sl);\n \t}\n-\trte_spinlock_unlock(&fm->sl);\n-\tif (ret)\n-\t\trte_flow_error_set(error, EINVAL,\n-\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t   fm->mfts->meter_action ?\n-\t\t\t\t   \"Meter attr not match\" :\n-\t\t\t\t   \"Meter action create failed\");\n-\treturn ret ? NULL : fm;\n+\treturn (ret < 0) ? 0 : mtr_idx;\n }\n \n /**\n  * Detach meter from flow.\n  *\n+ * @param [in] priv\n+ *  Pointer to mlx5 private data.\n  * @param [in] fm\n  *  Pointer to flow meter.\n  */\n void\n-mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm)\n+mlx5_flow_meter_detach(struct mlx5_priv *priv,\n+\t\t       struct mlx5_flow_meter_info *fm)\n {\n #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER\n \trte_spinlock_lock(&fm->sl);\n \tMLX5_ASSERT(fm->ref_cnt);\n-\tif (--fm->ref_cnt == 0) {\n-\t\tmlx5_glue->destroy_flow_action(fm->mfts->meter_action);\n-\t\tfm->mfts->meter_action = NULL;\n+\tif (--fm->ref_cnt == 0 && !priv->sh->meter_aso_en) {\n+\t\tmlx5_glue->destroy_flow_action(fm->meter_action);\n+\t\tfm->meter_action = NULL;\n \t\tfm->ingress = 0;\n \t\tfm->egress = 0;\n \t\tfm->transfer = 0;\n",
    "prefixes": [
        "RFC",
        "8/8"
    ]
}