Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/85193/?format=api
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" ] }{ "id": 85193, "url": "