get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 91590,
    "url": "https://patches.dpdk.org/api/patches/91590/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210415151135.2098674-10-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": "<20210415151135.2098674-10-lizh@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210415151135.2098674-10-lizh@nvidia.com",
    "date": "2021-04-15T15:11:29",
    "name": "[v5,09/14] net/mlx5: flow meter pool to manage meter object",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8bc4bf9ccf9fd12dc6d751d666462b52a7b94f9c",
    "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/20210415151135.2098674-10-lizh@nvidia.com/mbox/",
    "series": [
        {
            "id": 16417,
            "url": "https://patches.dpdk.org/api/series/16417/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=16417",
            "date": "2021-04-15T15:11:20",
            "name": "Add ASO meter support in MLX5 PMD",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/16417/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/91590/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/91590/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 640EFA0C3F;\n\tThu, 15 Apr 2021 17:13:13 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BCAF816234E;\n\tThu, 15 Apr 2021 17:12:06 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 5FAB8162303\n for <dev@dpdk.org>; Thu, 15 Apr 2021 17:11:51 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n lizh@nvidia.com)\n with SMTP; 15 Apr 2021 18:11:47 +0300",
            "from nvidia.com (c-235-17-1-009.mtl.labs.mlnx [10.235.17.9])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 13FFBjPO032677;\n Thu, 15 Apr 2021 18:11:47 +0300"
        ],
        "From": "Li Zhang <lizh@nvidia.com>",
        "To": "dekelp@nvidia.com, orika@nvidia.com, viacheslavo@nvidia.com,\n matan@nvidia.com, shahafs@nvidia.com",
        "Cc": "dev@dpdk.org, thomas@monjalon.net, rasland@nvidia.com, roniba@nvidia.com",
        "Date": "Thu, 15 Apr 2021 18:11:29 +0300",
        "Message-Id": "<20210415151135.2098674-10-lizh@nvidia.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20210415151135.2098674-1-lizh@nvidia.com>",
        "References": "<20210331073632.1443011-1-lizh@nvidia.com>\n <20210415151135.2098674-1-lizh@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v5 09/14] net/mlx5: flow meter pool to manage\n meter object",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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 ASO flow meter pool to manage meter object\n\nSigned-off-by: Li Zhang <lizh@nvidia.com>\nAcked-by: Matan Azrad <matan@nvidia.com>\n---\n drivers/net/mlx5/mlx5.c            |   2 +-\n drivers/net/mlx5/mlx5.h            | 207 ++++++++++++-\n drivers/net/mlx5/mlx5_flow.c       |  70 ++++-\n drivers/net/mlx5/mlx5_flow.h       | 196 +++----------\n drivers/net/mlx5/mlx5_flow_dv.c    | 203 ++++++++++++-\n drivers/net/mlx5/mlx5_flow_meter.c | 450 ++++++++++++++++++-----------\n 6 files changed, 769 insertions(+), 359 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex a6cc2d3108..69dcb2d760 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -282,7 +282,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {\n \t\t * for meter idx, so not set grow_trunk to avoid meter index\n \t\t * not jump continually.\n \t\t */\n-\t\t.size = sizeof(struct mlx5_flow_meter),\n+\t\t.size = sizeof(struct mlx5_legacy_flow_meter),\n \t\t.trunk_size = 64,\n \t\t.need_lock = 1,\n \t\t.release_mem_en = 1,\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex c4a04716f7..29fdb14e15 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -20,6 +20,7 @@\n #include <rte_interrupts.h>\n #include <rte_errno.h>\n #include <rte_flow.h>\n+#include <rte_mtr.h>\n \n #include <mlx5_glue.h>\n #include <mlx5_devx_cmds.h>\n@@ -573,6 +574,193 @@ struct mlx5_dev_shared_port {\n \t/* Aging information for per port. */\n };\n \n+/*ASO flow meter structures*/\n+/* Modify this value if enum rte_mtr_color changes. */\n+#define RTE_MTR_DROPPED RTE_COLORS\n+\n+/* Meter policer statistics */\n+struct mlx5_flow_policer_stats {\n+\tuint32_t pass_cnt;\n+\t/**< Color counter for pass. */\n+\tuint32_t drop_cnt;\n+\t/**< Color counter for drop. */\n+};\n+\n+/* Meter table structure. */\n+struct mlx5_meter_domain_info {\n+\tstruct mlx5_flow_tbl_resource *tbl;\n+\t/**< Meter table. */\n+\tstruct mlx5_flow_tbl_resource *sfx_tbl;\n+\t/**< Meter suffix table. */\n+\tstruct mlx5_flow_dv_matcher *drop_matcher;\n+\t/**< Matcher for Drop. */\n+\tstruct mlx5_flow_dv_matcher *color_matcher;\n+\t/**< Matcher for Color. */\n+\tvoid *jump_actn;\n+\t/**< Meter match action. */\n+\tvoid *green_rule;\n+\t/**< Meter green rule. */\n+\tvoid *drop_rule;\n+\t/**< Meter drop rule. */\n+};\n+\n+/* Meter table set for TX RX FDB. */\n+struct mlx5_meter_domains_infos {\n+\tuint32_t ref_cnt;\n+\t/**< Table user count. */\n+\tstruct mlx5_meter_domain_info egress;\n+\t/**< TX meter table. */\n+\tstruct mlx5_meter_domain_info ingress;\n+\t/**< RX meter table. */\n+\tstruct mlx5_meter_domain_info transfer;\n+\t/**< FDB meter table. */\n+\tvoid *drop_actn;\n+\t/**< Drop action as not matched. */\n+\tvoid *green_count;\n+\t/**< Counters for green rule. */\n+\tvoid *drop_count;\n+\t/**< Counters for green rule. */\n+\tvoid *meter_action;\n+\t/**< Flow meter action. */\n+};\n+\n+/* Meter parameter structure. */\n+struct mlx5_flow_meter_info {\n+\tuint32_t meter_id;\n+\t/**< Meter id. */\n+\tstruct mlx5_flow_meter_profile *profile;\n+\t/**< Meter profile parameters. */\n+\trte_spinlock_t sl; /**< Meter action spinlock. */\n+\t/** Policer actions (per meter output color). */\n+\tenum rte_mtr_policer_action action[RTE_COLORS];\n+\t/** Set of stats counters to be enabled.\n+\t * @see enum rte_mtr_stats_type\n+\t */\n+\tuint32_t green_bytes:1;\n+\t/** Set green bytes stats to be enabled. */\n+\tuint32_t green_pkts:1;\n+\t/** Set green packets stats to be enabled. */\n+\tuint32_t red_bytes:1;\n+\t/** Set red bytes stats to be enabled. */\n+\tuint32_t red_pkts:1;\n+\t/** Set red packets stats to be enabled. */\n+\tuint32_t bytes_dropped:1;\n+\t/** Set bytes dropped stats to be enabled. */\n+\tuint32_t pkts_dropped:1;\n+\t/** Set packets dropped stats to be enabled. */\n+\tuint32_t active_state:1;\n+\t/**< Meter hw active state. */\n+\tuint32_t shared:1;\n+\t/**< Meter shared or not. */\n+\tuint32_t is_enable:1;\n+\t/**< Meter disable/enable state. */\n+\tuint32_t ingress:1;\n+\t/**< Rule applies to egress traffic. */\n+\tuint32_t egress:1;\n+\t/**\n+\t * Instead of simply matching the properties of traffic as it would\n+\t * appear on a given DPDK port ID, enabling this attribute transfers\n+\t * a flow rule to the lowest possible level of any device endpoints\n+\t * found in the pattern.\n+\t *\n+\t * When supported, this effectively enables an application to\n+\t * re-route traffic not necessarily intended for it (e.g. coming\n+\t * from or addressed to different physical ports, VFs or\n+\t * applications) at the device level.\n+\t *\n+\t * It complements the behavior of some pattern items such as\n+\t * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.\n+\t *\n+\t * When transferring flow rules, ingress and egress attributes keep\n+\t * their original meaning, as if processing traffic emitted or\n+\t * received by the application.\n+\t */\n+\tuint32_t transfer:1;\n+\tstruct mlx5_meter_domains_infos *mfts;\n+\t/**< Flow table created for this meter. */\n+\tstruct mlx5_flow_policer_stats policer_stats;\n+\t/**< Meter policer statistics. */\n+\tuint32_t ref_cnt;\n+\t/**< Use count. */\n+\tstruct mlx5_indexed_pool *flow_ipool;\n+\t/**< Index pool for flow id. */\n+};\n+\n+/* RFC2697 parameter structure. */\n+struct mlx5_flow_meter_srtcm_rfc2697_prm {\n+\trte_be32_t cbs_cir;\n+\t/*\n+\t * bit 24-28: cbs_exponent, bit 16-23 cbs_mantissa,\n+\t * bit 8-12: cir_exponent, bit 0-7 cir_mantissa.\n+\t */\n+\trte_be32_t ebs_eir;\n+\t/*\n+\t * bit 24-28: ebs_exponent, bit 16-23 ebs_mantissa,\n+\t * bit 8-12: eir_exponent, bit 0-7 eir_mantissa.\n+\t */\n+};\n+\n+/* Flow meter profile structure. */\n+struct mlx5_flow_meter_profile {\n+\tTAILQ_ENTRY(mlx5_flow_meter_profile) next;\n+\t/**< Pointer to the next flow meter structure. */\n+\tuint32_t id; /**< Profile id. */\n+\tstruct rte_mtr_meter_profile profile; /**< Profile detail. */\n+\tunion {\n+\t\tstruct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;\n+\t\t/**< srtcm_rfc2697 struct. */\n+\t};\n+\tuint32_t ref_cnt; /**< Use count. */\n+};\n+\n+/* 2 meters in each ASO cache line */\n+#define MLX5_MTRS_CONTAINER_RESIZE 64\n+/*\n+ * The pool index and offset of meter in the pool array makes up the\n+ * meter index. In case the meter is from pool 0 and offset 0, it\n+ * should plus 1 to avoid index 0, since 0 means invalid meter index\n+ * currently.\n+ */\n+#define MLX5_MAKE_MTR_IDX(pi, offset) \\\n+\t\t((pi) * MLX5_ASO_MTRS_PER_POOL + (offset) + 1)\n+\n+/*aso flow meter state*/\n+enum mlx5_aso_mtr_state {\n+\tASO_METER_FREE, /* In free list. */\n+\tASO_METER_WAIT, /* ACCESS_ASO WQE in progress. */\n+\tASO_METER_READY, /* CQE received. */\n+};\n+\n+/* Generic aso_flow_meter information. */\n+struct mlx5_aso_mtr {\n+\tLIST_ENTRY(mlx5_aso_mtr) next;\n+\tstruct mlx5_flow_meter_info fm;\n+\t/**< Pointer to the next aso flow meter structure. */\n+\tuint8_t state; /**< ASO flow meter state. */\n+\tuint8_t offset;\n+};\n+\n+/* Generic aso_flow_meter pool structure. */\n+struct mlx5_aso_mtr_pool {\n+\tstruct mlx5_aso_mtr mtrs[MLX5_ASO_MTRS_PER_POOL];\n+\t/*Must be the first in pool*/\n+\tstruct mlx5_devx_obj *devx_obj;\n+\t/* The devx object of the minimum aso flow meter ID. */\n+\tuint32_t index; /* Pool index in management structure. */\n+};\n+\n+LIST_HEAD(aso_meter_list, mlx5_aso_mtr);\n+/* Pools management structure for ASO flow meter pools. */\n+struct mlx5_aso_mtr_pools_mng {\n+\tvolatile uint16_t n_valid; /* Number of valid pools. */\n+\tuint16_t n; /* Number of pools. */\n+\trte_spinlock_t mtrsl; /* The ASO flow meter free list lock. */\n+\tstruct mlx5_l3t_tbl *mtr_idx_tbl; /* Meter index lookup table. */\n+\tstruct aso_meter_list meters; /* Free ASO flow meter list. */\n+\tstruct mlx5_aso_sq sq; /*SQ using by ASO flow meter. */\n+\tstruct mlx5_aso_mtr_pool **pools; /* ASO flow meter pool array. */\n+};\n+\n /* Table key of the hash organization. */\n union mlx5_flow_tbl_key {\n \tstruct {\n@@ -699,6 +887,7 @@ struct mlx5_dev_ctx_shared {\n \tuint32_t rq_ts_format:2; /* RQ timestamp formats supported. */\n \tuint32_t sq_ts_format:2; /* SQ timestamp formats supported. */\n \tuint32_t qp_ts_format:2; /* QP timestamp formats supported. */\n+\tuint32_t meter_aso_en:1; /* Flow Meter ASO is supported. */\n \tuint32_t max_port; /* Maximal IB device port index. */\n \tstruct mlx5_bond_info bond; /* Bonding information. */\n \tvoid *ctx; /* Verbs/DV/DevX context. */\n@@ -759,6 +948,8 @@ struct mlx5_dev_ctx_shared {\n \tstruct mlx5_geneve_tlv_option_resource *geneve_tlv_option_resource;\n \t/* Management structure for geneve tlv option */\n \trte_spinlock_t geneve_tlv_opt_sl; /* Lock for geneve tlv resource */\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng;\n+\t/* Meter pools management structure. */\n \tstruct mlx5_dev_shared_port port[]; /* per device port data array. */\n };\n \n@@ -776,7 +967,7 @@ struct mlx5_proc_priv {\n /* MTR profile list. */\n TAILQ_HEAD(mlx5_mtr_profiles, mlx5_flow_meter_profile);\n /* MTR list. */\n-TAILQ_HEAD(mlx5_flow_meters, mlx5_flow_meter);\n+TAILQ_HEAD(mlx5_legacy_flow_meters, mlx5_legacy_flow_meter);\n \n /* RSS description. */\n struct mlx5_flow_rss_desc {\n@@ -994,7 +1185,7 @@ struct mlx5_priv {\n \tuint8_t mtr_sfx_reg; /* Meter prefix-suffix flow match REG_C. */\n \tuint8_t mtr_color_reg; /* Meter color match REG_C. */\n \tstruct mlx5_mtr_profiles flow_meter_profiles; /* MTR profile list. */\n-\tstruct mlx5_flow_meters flow_meters; /* MTR list. */\n+\tstruct mlx5_legacy_flow_meters flow_meters; /* MTR list. */\n \tuint8_t skip_default_rss_reta; /* Skip configuration of default reta. */\n \tuint8_t fdb_def_rule; /* Whether fdb jump to table 1 is configured. */\n \tstruct mlx5_mp_id mp_id; /* ID of a multi-process process */\n@@ -1273,13 +1464,15 @@ int mlx5_pmd_socket_init(void);\n /* mlx5_flow_meter.c */\n \n int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);\n-struct mlx5_flow_meter *mlx5_flow_meter_find(struct mlx5_priv *priv,\n-\t\t\t\t\t     uint32_t meter_id);\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 *\n+flow_dv_meter_find_by_idx(struct mlx5_priv *priv, uint32_t idx);\n int mlx5_flow_meter_attach(struct mlx5_priv *priv,\n-\t\t\t   struct mlx5_flow_meter *fm,\n+\t\t\t   struct mlx5_flow_meter_info *fm,\n \t\t\t   const struct rte_flow_attr *attr,\n \t\t\t   struct rte_flow_error *error);\n-void mlx5_flow_meter_detach(struct mlx5_flow_meter *fm);\n+void mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm);\n \n /* mlx5_os.c */\n struct rte_pci_driver;\n@@ -1324,7 +1517,7 @@ void mlx5_txpp_interrupt_handler(void *cb_arg);\n \n eth_tx_burst_t mlx5_select_tx_function(struct rte_eth_dev *dev);\n \n-/* mlx5_flow_age.c */\n+/* mlx5_flow_aso.c */\n \n int mlx5_aso_queue_init(struct mlx5_dev_ctx_shared *sh);\n int mlx5_aso_queue_start(struct mlx5_dev_ctx_shared *sh);\ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 643254e835..7f34f47e9f 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -4360,6 +4360,8 @@ flow_create_split_inner(struct rte_eth_dev *dev,\n  *\n  * @param[in] dev\n  *   Pointer to Ethernet device.\n+ * @param[in] flow\n+ *   Parent flow structure pointer.\n  * @param[in] fm\n  *   Pointer to flow meter structure.\n  * @param[in] items\n@@ -4372,10 +4374,6 @@ flow_create_split_inner(struct rte_eth_dev *dev,\n  *   Suffix flow actions.\n  * @param[out] actions_pre\n  *   Prefix flow actions.\n- * @param[out] pattern_sfx\n- *   The pattern items for the suffix flow.\n- * @param[out] tag_sfx\n- *   Pointer to suffix flow tag.\n  * @param[out] error\n  *   Perform verbose error reporting if not NULL.\n  *\n@@ -4384,7 +4382,8 @@ flow_create_split_inner(struct rte_eth_dev *dev,\n  */\n static uint32_t\n flow_meter_split_prep(struct rte_eth_dev *dev,\n-\t\t      struct mlx5_flow_meter *fm,\n+\t\t      struct rte_flow *flow,\n+\t\t      struct mlx5_flow_meter_info *fm,\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@@ -4505,7 +4504,7 @@ flow_meter_split_prep(struct rte_eth_dev *dev,\n \t\t\t\t\t\t\t    0, error),\n \t\t.offset = mtr_id_offset,\n \t\t.length = mtr_reg_bits,\n-\t\t.data = fm->idx,\n+\t\t.data = flow->meter,\n \t};\n \t/*\n \t * The color Reg bits used by flow_id are growing from\n@@ -5233,9 +5232,10 @@ flow_create_split_meter(struct rte_eth_dev *dev,\n \tstruct rte_flow_item *sfx_items = NULL;\n \tstruct mlx5_flow *dev_flow = NULL;\n \tstruct rte_flow_attr sfx_attr = *attr;\n-\tstruct mlx5_flow_meter *fm = NULL;\n+\tstruct mlx5_flow_meter_info *fm = NULL;\n \tbool has_mtr = false;\n \tuint32_t meter_id;\n+\tuint32_t mtr_idx = 0;\n \tuint32_t mtr_tag_id = 0;\n \tsize_t act_size;\n \tsize_t item_size;\n@@ -5247,14 +5247,13 @@ flow_create_split_meter(struct rte_eth_dev *dev,\n \t\t\t\t\t\t    &meter_id);\n \tif (has_mtr) {\n \t\tif (flow->meter) {\n-\t\t\tfm = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR],\n-\t\t\t\t\t    flow->meter);\n+\t\t\tfm = flow_dv_meter_find_by_idx(priv, flow->meter);\n \t\t\tif (!fm)\n \t\t\t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n \t\t\t\t\t\tNULL, \"Meter not found.\");\n \t\t} else {\n-\t\t\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\t\t\tfm = mlx5_flow_meter_find(priv, meter_id, &mtr_idx);\n \t\t\tif (!fm)\n \t\t\t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n@@ -5263,7 +5262,7 @@ flow_create_split_meter(struct rte_eth_dev *dev,\n \t\t\t\t\t\t     &sfx_attr, error);\n \t\t\tif (ret)\n \t\t\t\treturn -rte_errno;\n-\t\t\tflow->meter = fm->idx;\n+\t\t\tflow->meter = mtr_idx;\n \t\t}\n \t\twks->fm = fm;\n \t\t/* The prefix actions: meter, decap, encap, tag, end. */\n@@ -5283,9 +5282,10 @@ 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, fm, items, sfx_items,\n-\t\t\t\t\t\t   actions, sfx_actions,\n-\t\t\t\t\t\t   pre_actions, error);\n+\t\tmtr_tag_id = flow_meter_split_prep(dev, flow, fm, items,\n+\t\t\t\t\t\t   sfx_items, actions,\n+\t\t\t\t\t\t   sfx_actions, pre_actions,\n+\t\t\t\t\t\t   error);\n \t\tif (!mtr_tag_id) {\n \t\t\tret = -rte_errno;\n \t\t\tgoto exit;\n@@ -6622,7 +6622,7 @@ mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev,\n  */\n int\n mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t       struct mlx5_flow_meter *fm,\n+\t\t\t       struct mlx5_flow_meter_info *fm,\n \t\t\t       const struct rte_flow_attr *attr)\n {\n \tconst struct mlx5_flow_driver_ops *fops;\n@@ -6644,7 +6644,7 @@ mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,\n  */\n int\n mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t\tstruct mlx5_flow_meter *fm,\n+\t\t\t\tstruct mlx5_flow_meter_info *fm,\n \t\t\t\tconst struct rte_flow_attr *attr)\n {\n \tconst struct mlx5_flow_driver_ops *fops;\n@@ -6653,6 +6653,44 @@ mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,\n \treturn fops->destroy_policer_rules(dev, fm, attr);\n }\n \n+/**\n+ * Allocate the needed aso flow meter id.\n+ *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n+ *\n+ * @return\n+ *   Index to aso flow meter on success, NULL otherwise.\n+ */\n+uint32_t\n+mlx5_flow_mtr_alloc(struct rte_eth_dev *dev)\n+{\n+\tconst struct mlx5_flow_driver_ops *fops;\n+\n+\tfops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);\n+\treturn fops->create_meter(dev);\n+}\n+\n+/**\n+ * Free the aso flow meter id.\n+ *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n+ * @param[in] mtr_idx\n+ *  Index to aso flow meter to be free.\n+ *\n+ * @return\n+ *   0 on success.\n+ */\n+void\n+mlx5_flow_mtr_free(struct rte_eth_dev *dev, uint32_t mtr_idx)\n+{\n+\tconst struct mlx5_flow_driver_ops *fops;\n+\n+\tfops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);\n+\tfops->free_meter(dev, mtr_idx);\n+}\n+\n /**\n  * Allocate a counter.\n  *\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 11482f178f..b0a743477c 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -827,148 +827,17 @@ struct mlx5_flow {\n #define MLX5_FLOW_METER_DISABLE 0\n #define MLX5_FLOW_METER_ENABLE 1\n \n-#define MLX5_MAN_WIDTH 8\n-/* Modify this value if enum rte_mtr_color changes. */\n-#define RTE_MTR_DROPPED RTE_COLORS\n-\n-/* Meter policer statistics */\n-struct mlx5_flow_policer_stats {\n-\tuint32_t pass_cnt;\n-\t/**< Color counter for pass. */\n-\tuint32_t drop_cnt;\n-\t/**< Color counter for drop. */\n-};\n-\n-/* Meter table structure. */\n-struct mlx5_meter_domain_info {\n-\tstruct mlx5_flow_tbl_resource *tbl;\n-\t/**< Meter table. */\n-\tstruct mlx5_flow_tbl_resource *sfx_tbl;\n-\t/**< Meter suffix table. */\n-\tstruct mlx5_flow_dv_matcher *drop_matcher;\n-\t/**< Matcher for Drop. */\n-\tstruct mlx5_flow_dv_matcher *color_matcher;\n-\t/**< Matcher for Color. */\n-\tvoid *jump_actn;\n-\t/**< Meter match action. */\n-\tvoid *green_rule;\n-\t/**< Meter green rule. */\n-\tvoid *drop_rule;\n-\t/**< Meter drop rule. */\n-};\n-\n-/* Meter table set for TX RX FDB. */\n-struct mlx5_meter_domains_infos {\n-\tuint32_t ref_cnt;\n-\t/**< Table user count. */\n-\tstruct mlx5_meter_domain_info egress;\n-\t/**< TX meter table. */\n-\tstruct mlx5_meter_domain_info ingress;\n-\t/**< RX meter table. */\n-\tstruct mlx5_meter_domain_info transfer;\n-\t/**< FDB meter table. */\n-\tvoid *green_count;\n-\t/**< Counters for green rule. */\n-\tvoid *drop_count;\n-\t/**< Counters for green rule. */\n-\tuint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];\n-\t/**< Flow meter parameter. */\n-\tsize_t fmp_size;\n-\t/**< Flow meter parameter size. */\n-\tvoid *meter_action;\n-\t/**< Flow meter action. */\n-};\n+#define MLX5_ASO_CQE_RESPONSE_DELAY 10\n+#define MLX5_MTR_POLL_CQE_TIMES    100000u\n \n-/* Meter parameter structure. */\n-struct mlx5_flow_meter {\n-\tTAILQ_ENTRY(mlx5_flow_meter) next;\n+#define MLX5_MAN_WIDTH 8\n+/* Legacy Meter parameter structure. */\n+struct mlx5_legacy_flow_meter {\n+\tstruct mlx5_flow_meter_info fm;\n+\t/* Must be the first in struct. */\n+\tTAILQ_ENTRY(mlx5_legacy_flow_meter) next;\n \t/**< Pointer to the next flow meter structure. */\n \tuint32_t idx; /* Index to meter object. */\n-\tuint32_t meter_id;\n-\t/**< Meter id. */\n-\tstruct mlx5_flow_meter_profile *profile;\n-\t/**< Meter profile parameters. */\n-\n-\trte_spinlock_t sl; /**< Meter action spinlock. */\n-\n-\t/** Policer actions (per meter output color). */\n-\tenum rte_mtr_policer_action action[RTE_COLORS];\n-\n-\tuint32_t green_bytes:1;\n-\t/** Set green bytes stats to be enabled. */\n-\tuint32_t green_pkts:1;\n-\t/** Set green packets stats to be enabled. */\n-\tuint32_t red_bytes:1;\n-\t/** Set red bytes stats to be enabled. */\n-\tuint32_t red_pkts:1;\n-\t/** Set red packets stats to be enabled. */\n-\tuint32_t bytes_dropped:1;\n-\t/** Set bytes dropped stats to be enabled. */\n-\tuint32_t pkts_dropped:1;\n-\t/** Set packets dropped stats to be enabled. */\n-\n-\t/**< Rule applies to ingress traffic. */\n-\tuint32_t ingress:1;\n-\n-\t/**< Rule applies to egress traffic. */\n-\tuint32_t egress:1;\n-\t/**\n-\t * Instead of simply matching the properties of traffic as it would\n-\t * appear on a given DPDK port ID, enabling this attribute transfers\n-\t * a flow rule to the lowest possible level of any device endpoints\n-\t * found in the pattern.\n-\t *\n-\t * When supported, this effectively enables an application to\n-\t * re-route traffic not necessarily intended for it (e.g. coming\n-\t * from or addressed to different physical ports, VFs or\n-\t * applications) at the device level.\n-\t *\n-\t * It complements the behavior of some pattern items such as\n-\t * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.\n-\t *\n-\t * When transferring flow rules, ingress and egress attributes keep\n-\t * their original meaning, as if processing traffic emitted or\n-\t * received by the application.\n-\t */\n-\tuint32_t transfer:1;\n-\tstruct mlx5_meter_domains_infos *mfts;\n-\t/**< Flow table created for this meter. */\n-\tstruct mlx5_flow_policer_stats policer_stats;\n-\t/**< Meter policer statistics. */\n-\tuint32_t ref_cnt;\n-\t/**< Use count. */\n-\tuint32_t active_state:1;\n-\t/**< Meter state. */\n-\tuint32_t shared:1;\n-\t/**< Meter shared or not. */\n-\tstruct mlx5_indexed_pool *flow_ipool;\n-\t/**< Index pool for flow id. */\n-};\n-\n-/* RFC2697 parameter structure. */\n-struct mlx5_flow_meter_srtcm_rfc2697_prm {\n-\t/* green_saturation_value = cbs_mantissa * 2^cbs_exponent */\n-\tuint32_t cbs_exponent:5;\n-\tuint32_t cbs_mantissa:8;\n-\t/* cir = 8G * cir_mantissa * 1/(2^cir_exponent) Bytes/Sec */\n-\tuint32_t cir_exponent:5;\n-\tuint32_t cir_mantissa:8;\n-\t/* yellow _saturation_value = ebs_mantissa * 2^ebs_exponent */\n-\tuint32_t ebs_exponent:5;\n-\tuint32_t ebs_mantissa:8;\n-};\n-\n-/* Flow meter profile structure. */\n-struct mlx5_flow_meter_profile {\n-\tTAILQ_ENTRY(mlx5_flow_meter_profile) next;\n-\t/**< Pointer to the next flow meter structure. */\n-\tuint32_t meter_profile_id; /**< Profile id. */\n-\tstruct rte_mtr_meter_profile profile; /**< Profile detail. */\n-\tunion {\n-\t\tstruct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;\n-\t\t/**< srtcm_rfc2697 struct. */\n-\t};\n-\tuint32_t ref_cnt; /**< Use count. */\n };\n \n #define MLX5_MAX_TUNNELS 256\n@@ -1094,7 +963,7 @@ struct rte_flow {\n \t/**< Device flow handles that are part of the flow. */\n \tuint32_t drv_type:2; /**< Driver type. */\n \tuint32_t tunnel:1;\n-\tuint32_t meter:16; /**< Holds flow meter id. */\n+\tuint32_t meter:24; /**< Holds flow meter id. */\n \tuint32_t rix_mreg_copy;\n \t/**< Index to metadata register copy table resource. */\n \tuint32_t counter; /**< Holds flow counter. */\n@@ -1181,7 +1050,7 @@ struct mlx5_flow_workspace {\n \tstruct mlx5_flow_rss_desc rss_desc;\n \tuint32_t rssq_num; /* Allocated queue num in rss_desc. */\n \tuint32_t flow_idx; /* Intermediate device flow index. */\n-\tstruct mlx5_flow_meter *fm; /* Pointer to the meter in flow. */\n+\tstruct mlx5_flow_meter_info *fm; /* Pointer to the meter in flow. */\n };\n \n struct mlx5_flow_split_info {\n@@ -1227,12 +1096,16 @@ typedef int (*mlx5_flow_destroy_mtr_tbls_t)(struct rte_eth_dev *dev,\n \t\t\t\t\tstruct mlx5_meter_domains_infos *tbls);\n typedef int (*mlx5_flow_create_policer_rules_t)\n \t\t\t\t\t(struct rte_eth_dev *dev,\n-\t\t\t\t\t struct mlx5_flow_meter *fm,\n+\t\t\t\t\t struct mlx5_flow_meter_info *fm,\n \t\t\t\t\t const struct rte_flow_attr *attr);\n typedef int (*mlx5_flow_destroy_policer_rules_t)\n \t\t\t\t\t(struct rte_eth_dev *dev,\n-\t\t\t\t\t const struct mlx5_flow_meter *fm,\n+\t\t\t\t\t const struct mlx5_flow_meter_info *fm,\n \t\t\t\t\t const struct rte_flow_attr *attr);\n+typedef uint32_t (*mlx5_flow_mtr_alloc_t)\n+\t\t\t\t\t    (struct rte_eth_dev *dev);\n+typedef void (*mlx5_flow_mtr_free_t)(struct rte_eth_dev *dev,\n+\t\t\t\t\t\tuint32_t mtr_idx);\n typedef uint32_t (*mlx5_flow_counter_alloc_t)\n \t\t\t\t   (struct rte_eth_dev *dev);\n typedef void (*mlx5_flow_counter_free_t)(struct rte_eth_dev *dev,\n@@ -1287,6 +1160,8 @@ struct mlx5_flow_driver_ops {\n \tmlx5_flow_destroy_mtr_tbls_t destroy_mtr_tbls;\n \tmlx5_flow_create_policer_rules_t prepare_policer_rules;\n \tmlx5_flow_destroy_policer_rules_t destroy_policer_rules;\n+\tmlx5_flow_mtr_alloc_t create_meter;\n+\tmlx5_flow_mtr_free_t free_meter;\n \tmlx5_flow_counter_alloc_t counter_alloc;\n \tmlx5_flow_counter_free_t counter_free;\n \tmlx5_flow_counter_query_t counter_query;\n@@ -1346,6 +1221,32 @@ tunnel_use_standard_attr_group_translate\n \treturn verdict;\n }\n \n+/**\n+ * Get DV flow aso meter by index.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ * @param[in] idx\n+ *   mlx5 flow aso meter index in the container.\n+ * @param[out] ppool\n+ *   mlx5 flow aso meter pool in the container,\n+ *\n+ * @return\n+ *   Pointer to the aso meter, NULL otherwise.\n+ */\n+static inline struct mlx5_aso_mtr *\n+mlx5_aso_meter_by_idx(struct mlx5_priv *priv, uint32_t idx)\n+{\n+\tstruct mlx5_aso_mtr_pool *pool;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\n+\t/* Decrease to original index. */\n+\tidx--;\n+\tMLX5_ASSERT(idx / MLX5_ASO_MTRS_PER_POOL < mtrmng->n);\n+\tpool = mtrmng->pools[idx / MLX5_ASO_MTRS_PER_POOL];\n+\treturn &pool->mtrs[idx % MLX5_ASO_MTRS_PER_POOL];\n+}\n+\n int mlx5_flow_group_to_table(struct rte_eth_dev *dev,\n \t\t\t     const struct mlx5_flow_tunnel *tunnel,\n \t\t\t     uint32_t group, uint32_t *table,\n@@ -1489,10 +1390,10 @@ struct mlx5_meter_domains_infos *mlx5_flow_create_mtr_tbls\n int mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev,\n \t\t\t       struct mlx5_meter_domains_infos *tbl);\n int mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t\t   struct mlx5_flow_meter *fm,\n+\t\t\t\t   struct mlx5_flow_meter_info *fm,\n \t\t\t\t   const struct rte_flow_attr *attr);\n int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t\t    struct mlx5_flow_meter *fm,\n+\t\t\t\t    struct mlx5_flow_meter_info *fm,\n \t\t\t\t    const struct rte_flow_attr *attr);\n int mlx5_flow_meter_flush(struct rte_eth_dev *dev,\n \t\t\t  struct rte_mtr_error *error);\n@@ -1588,12 +1489,11 @@ struct mlx5_aso_age_action *flow_aso_age_get_by_idx(struct rte_eth_dev *dev,\n int flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev,\n \t\t\t\t\t     const struct rte_flow_item *item,\n \t\t\t\t\t     struct rte_flow_error *error);\n-\n void flow_release_workspace(void *data);\n int mlx5_flow_os_init_workspace_once(void);\n void *mlx5_flow_os_get_specific_workspace(void);\n int mlx5_flow_os_set_specific_workspace(struct mlx5_flow_workspace *data);\n void mlx5_flow_os_release_workspace(void);\n-\n-\n+uint32_t mlx5_flow_mtr_alloc(struct rte_eth_dev *dev);\n+void mlx5_flow_mtr_free(struct rte_eth_dev *dev, uint32_t mtr_idx);\n #endif /* RTE_PMD_MLX5_FLOW_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex dfd734353c..cf55ed6353 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -4866,7 +4866,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tconst struct rte_flow_action_meter *am = action->conf;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \n \tif (!am)\n \t\treturn rte_flow_error_set(error, EINVAL,\n@@ -4886,7 +4886,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"meter action not supported\");\n-\tfm = mlx5_flow_meter_find(priv, am->mtr_id);\n+\tfm = mlx5_flow_meter_find(priv, am->mtr_id, NULL);\n \tif (!fm)\n \t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n@@ -5939,6 +5939,161 @@ flow_dv_counter_free(struct rte_eth_dev *dev, uint32_t counter)\n \t}\n }\n \n+/**\n+ * Resize a meter id container.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, otherwise negative errno value and rte_errno is set.\n+ */\n+static int\n+flow_dv_mtr_container_resize(struct rte_eth_dev *dev)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tvoid *old_pools = mtrmng->pools;\n+\tuint32_t resize = mtrmng->n + MLX5_MTRS_CONTAINER_RESIZE;\n+\tuint32_t mem_size = sizeof(struct mlx5_aso_mtr_pool *) * resize;\n+\tvoid *pools = mlx5_malloc(MLX5_MEM_ZERO, mem_size, 0, SOCKET_ID_ANY);\n+\n+\tif (!pools) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn -ENOMEM;\n+\t}\n+\tif (old_pools)\n+\t\tmemcpy(pools, old_pools, mtrmng->n *\n+\t\t\t\t       sizeof(struct mlx5_aso_mtr_pool *));\n+\tmtrmng->n = resize;\n+\tmtrmng->pools = pools;\n+\tif (old_pools)\n+\t\tmlx5_free(old_pools);\n+\treturn 0;\n+}\n+\n+/**\n+ * Prepare a new meter and/or a new meter pool.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ * @param[out] mtr_free\n+ *   Where to put the pointer of a new meter.g.\n+ *\n+ * @return\n+ *   The meter pool pointer and @mtr_free is set on success,\n+ *   NULL otherwise and rte_errno is set.\n+ */\n+static struct mlx5_aso_mtr_pool *\n+flow_dv_mtr_pool_create(struct rte_eth_dev *dev,\n+\t\t\t     struct mlx5_aso_mtr **mtr_free)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tstruct mlx5_aso_mtr_pool *pool = NULL;\n+\tstruct mlx5_devx_obj *dcs = NULL;\n+\tuint32_t i;\n+\tuint32_t log_obj_size;\n+\n+\tlog_obj_size = rte_log2_u32(MLX5_ASO_MTRS_PER_POOL >> 1);\n+\tdcs = mlx5_devx_cmd_create_flow_meter_aso_obj(priv->sh->ctx,\n+\t\t\tpriv->sh->pdn, log_obj_size);\n+\tif (!dcs) {\n+\t\trte_errno = ENODATA;\n+\t\treturn NULL;\n+\t}\n+\tpool = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*pool), 0, SOCKET_ID_ANY);\n+\tif (!pool) {\n+\t\trte_errno = ENOMEM;\n+\t\tclaim_zero(mlx5_devx_cmd_destroy(dcs));\n+\t\treturn NULL;\n+\t}\n+\tpool->devx_obj = dcs;\n+\tpool->index = mtrmng->n_valid;\n+\tif (pool->index == mtrmng->n && flow_dv_mtr_container_resize(dev)) {\n+\t\tmlx5_free(pool);\n+\t\tclaim_zero(mlx5_devx_cmd_destroy(dcs));\n+\t\treturn NULL;\n+\t}\n+\tmtrmng->pools[pool->index] = pool;\n+\tmtrmng->n_valid++;\n+\tfor (i = 1; i < MLX5_ASO_MTRS_PER_POOL; ++i) {\n+\t\tpool->mtrs[i].offset = i;\n+\t\tpool->mtrs[i].fm.meter_id = UINT32_MAX;\n+\t\tLIST_INSERT_HEAD(&mtrmng->meters,\n+\t\t\t\t\t\t&pool->mtrs[i], next);\n+\t}\n+\tpool->mtrs[0].offset = 0;\n+\tpool->mtrs[0].fm.meter_id = UINT32_MAX;\n+\t*mtr_free = &pool->mtrs[0];\n+\treturn pool;\n+}\n+\n+/**\n+ * Release a flow meter into pool.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ * @param[in] mtr_idx\n+ *   Index to aso flow meter.\n+ */\n+static void\n+flow_dv_aso_mtr_release_to_pool(struct rte_eth_dev *dev, uint32_t mtr_idx)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tstruct mlx5_aso_mtr *aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);\n+\n+\tMLX5_ASSERT(aso_mtr);\n+\trte_spinlock_lock(&mtrmng->mtrsl);\n+\tmemset(&aso_mtr->fm, 0, sizeof(struct mlx5_flow_meter_info));\n+\taso_mtr->state = ASO_METER_FREE;\n+\taso_mtr->fm.meter_id = UINT32_MAX;\n+\tLIST_INSERT_HEAD(&mtrmng->meters, aso_mtr, next);\n+\trte_spinlock_unlock(&mtrmng->mtrsl);\n+}\n+\n+/**\n+ * Allocate a aso flow meter.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ *\n+ * @return\n+ *   Index to aso flow meter on success, 0 otherwise and rte_errno is set.\n+ */\n+static uint32_t\n+flow_dv_mtr_alloc(struct rte_eth_dev *dev)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\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+\tuint32_t mtr_idx = 0;\n+\n+\tif (!priv->config.devx) {\n+\t\trte_errno = ENOTSUP;\n+\t\treturn 0;\n+\t}\n+\t/* Allocate the flow meter memory. */\n+\t/* Get free meters from management. */\n+\trte_spinlock_lock(&mtrmng->mtrsl);\n+\tmtr_free = LIST_FIRST(&mtrmng->meters);\n+\tif (mtr_free)\n+\t\tLIST_REMOVE(mtr_free, next);\n+\tif (!mtr_free && !flow_dv_mtr_pool_create(dev, &mtr_free)) {\n+\t\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\t\treturn 0;\n+\t}\n+\tmtr_free->state = ASO_METER_WAIT;\n+\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\tpool = container_of(mtr_free,\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+\treturn mtr_idx;\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@@ -12569,7 +12724,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n \tstruct mlx5_flow_handle *dev_handle;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meter *fm = NULL;\n+\tstruct mlx5_flow_meter_info *fm = NULL;\n \tuint32_t srss = 0;\n \n \tif (!flow)\n@@ -12580,8 +12735,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n \t\tflow->counter = 0;\n \t}\n \tif (flow->meter) {\n-\t\tfm = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR],\n-\t\t\t\t    flow->meter);\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\tflow->meter = 0;\n@@ -13679,7 +13833,7 @@ flow_dv_destroy_domain_policer_rule(struct rte_eth_dev *dev,\n  */\n static int\n flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t      const struct mlx5_flow_meter *fm,\n+\t\t\t      const struct mlx5_flow_meter_info *fm,\n \t\t\t      const struct rte_flow_attr *attr)\n {\n \tstruct mlx5_meter_domains_infos *mtb = fm ? fm->mfts : NULL;\n@@ -13702,6 +13856,8 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,\n  *   Pointer to Ethernet device.\n  * @param[in] fm\n  *   Pointer to flow meter structure.\n+ * @param[in] mtr_idx\n+ *   meter index.\n  * @param[in] mtb\n  *   Pointer to DV meter table set.\n  * @param[out] drop_rule\n@@ -13714,7 +13870,8 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,\n  */\n static int\n flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,\n-\t\t\t\t    struct mlx5_flow_meter *fm,\n+\t\t\t\t    struct mlx5_flow_meter_info *fm,\n+\t\t\t\t    uint32_t mtr_idx,\n \t\t\t\t    struct mlx5_meter_domain_info *dtb,\n \t\t\t\t    void **drop_rule,\n \t\t\t\t    void **green_rule)\n@@ -13762,7 +13919,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,\n \t/* Create Drop flow, matching meter_id only. */\n \ti = 0;\n \tflow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c,\n-\t\t\t       (fm->idx << mtr_id_offset), UINT32_MAX);\n+\t\t\t       (mtr_idx << mtr_id_offset), UINT32_MAX);\n \tif (mtb->drop_count)\n \t\tactions[i++] = mtb->drop_count;\n \tactions[i++] = priv->sh->dr_drop_action;\n@@ -13776,7 +13933,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,\n \ti = 0;\n \tif (priv->mtr_reg_share) {\n \t\tflow_dv_match_meta_reg(matcher.buf, value.buf, color_reg_c,\n-\t\t\t\t       ((fm->idx << mtr_id_offset) |\n+\t\t\t\t       ((mtr_idx << mtr_id_offset) |\n \t\t\t\t\trte_col_2_mlx5_col(RTE_COLOR_GREEN)),\n \t\t\t\t       UINT32_MAX);\n \t} else {\n@@ -13784,7 +13941,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,\n \t\t\t\t       rte_col_2_mlx5_col(RTE_COLOR_GREEN),\n \t\t\t\t       UINT32_MAX);\n \t\tflow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c,\n-\t\t\t\t       fm->idx, UINT32_MAX);\n+\t\t\t\t       mtr_idx, UINT32_MAX);\n \t}\n \tif (mtb->green_count)\n \t\tactions[i++] = mtb->green_count;\n@@ -13817,9 +13974,10 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,\n  */\n static int\n flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n-\t\t\t      struct mlx5_flow_meter *fm,\n+\t\t\t      struct mlx5_flow_meter_info *fm,\n \t\t\t      const struct rte_flow_attr *attr)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_meter_domains_infos *mtb = fm->mfts;\n \tbool initialized = false;\n \tstruct mlx5_flow_counter *cnt;\n@@ -13829,6 +13987,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n \tvoid *ingress_green_rule = NULL;\n \tvoid *transfer_drop_rule = NULL;\n \tvoid *transfer_green_rule = NULL;\n+\tuint32_t mtr_idx;\n \tint ret;\n \n \t/* Get the statistics counters for green/drop. */\n@@ -13855,9 +14014,23 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n \t */\n \tif (mtb->egress.drop_rule)\n \t\tinitialized = true;\n+\tif (priv->sh->meter_aso_en) {\n+\t\tstruct mlx5_aso_mtr *aso_mtr = NULL;\n+\t\tstruct mlx5_aso_mtr_pool *pool;\n+\n+\t\taso_mtr = container_of(fm, struct mlx5_aso_mtr, fm);\n+\t\tpool = container_of(aso_mtr, struct mlx5_aso_mtr_pool,\n+\t\t\t\t    mtrs[aso_mtr->offset]);\n+\t\tmtr_idx = MLX5_MAKE_MTR_IDX(pool->index, aso_mtr->offset);\n+\t} else {\n+\t\tstruct mlx5_legacy_flow_meter *legacy_fm;\n+\n+\t\tlegacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm);\n+\t\tmtr_idx = legacy_fm->idx;\n+\t}\n \tif (attr->egress) {\n \t\tret = flow_dv_create_policer_forward_rule(dev,\n-\t\t\t\tfm, &mtb->egress,\n+\t\t\t\tfm, mtr_idx, &mtb->egress,\n \t\t\t\t&egress_drop_rule, &egress_green_rule);\n \t\tif (ret) {\n \t\t\tDRV_LOG(ERR, \"Failed to create egress policer.\");\n@@ -13866,7 +14039,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n \t}\n \tif (attr->ingress) {\n \t\tret = flow_dv_create_policer_forward_rule(dev,\n-\t\t\t\tfm, &mtb->ingress,\n+\t\t\t\tfm, mtr_idx, &mtb->ingress,\n \t\t\t\t&ingress_drop_rule, &ingress_green_rule);\n \t\tif (ret) {\n \t\t\tDRV_LOG(ERR, \"Failed to create ingress policer.\");\n@@ -13875,7 +14048,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n \t}\n \tif (attr->transfer) {\n \t\tret = flow_dv_create_policer_forward_rule(dev,\n-\t\t\t\tfm, &mtb->transfer,\n+\t\t\t\tfm, mtr_idx, &mtb->transfer,\n \t\t\t\t&transfer_drop_rule, &transfer_green_rule);\n \t\tif (ret) {\n \t\t\tDRV_LOG(ERR, \"Failed to create transfer policer.\");\n@@ -14215,6 +14388,8 @@ const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {\n \t.destroy_mtr_tbls = flow_dv_destroy_mtr_tbl,\n \t.prepare_policer_rules = flow_dv_prepare_policer_rules,\n \t.destroy_policer_rules = flow_dv_destroy_policer_rules,\n+\t.create_meter = flow_dv_mtr_alloc,\n+\t.free_meter = flow_dv_aso_mtr_release_to_pool,\n \t.counter_alloc = flow_dv_counter_allocate,\n \t.counter_free = flow_dv_counter_free,\n \t.counter_query = flow_dv_counter_query,\ndiff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c\nindex 2a37decaaf..956a6c33e7 100644\n--- a/drivers/net/mlx5/mlx5_flow_meter.c\n+++ b/drivers/net/mlx5/mlx5_flow_meter.c\n@@ -28,40 +28,43 @@\n  */\n static void *\n mlx5_flow_meter_action_create(struct mlx5_priv *priv,\n-\t\t\t      struct mlx5_flow_meter *fm)\n+\t\t\t      struct mlx5_flow_meter_info *fm)\n {\n #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER\n \tstruct mlx5dv_dr_flow_meter_attr mtr_init;\n-\tvoid *attr = fm->mfts->fmp;\n+\tuint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];\n \tstruct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm =\n \t\t\t\t\t\t     &fm->profile->srtcm_prm;\n+\tuint32_t cbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);\n+\tuint32_t ebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);\n+\tuint32_t val;\n \n-\tfm->mfts->fmp_size = MLX5_ST_SZ_BYTES(flow_meter_parameters);\n-\tmemset(attr, 0, fm->mfts->fmp_size);\n-\tMLX5_SET(flow_meter_parameters, attr, valid, 1);\n-\tMLX5_SET(flow_meter_parameters, attr, bucket_overflow, 1);\n-\tMLX5_SET(flow_meter_parameters, attr,\n-\t\t start_color, MLX5_FLOW_COLOR_GREEN);\n-\tMLX5_SET(flow_meter_parameters, attr, both_buckets_on_green, 0);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, cbs_exponent, srtcm->cbs_exponent);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, cbs_mantissa, srtcm->cbs_mantissa);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, cir_exponent, srtcm->cir_exponent);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, cir_mantissa, srtcm->cir_mantissa);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, ebs_exponent, srtcm->ebs_exponent);\n-\tMLX5_SET(flow_meter_parameters,\n-\t\t attr, ebs_mantissa, srtcm->ebs_mantissa);\n+\tmemset(fmp, 0, MLX5_ST_SZ_BYTES(flow_meter_parameters));\n+\tMLX5_SET(flow_meter_parameters, fmp, valid, 1);\n+\tMLX5_SET(flow_meter_parameters, fmp, bucket_overflow, 1);\n+\tMLX5_SET(flow_meter_parameters, fmp,\n+\t\tstart_color, MLX5_FLOW_COLOR_GREEN);\n+\tMLX5_SET(flow_meter_parameters, fmp, both_buckets_on_green, 0);\n+\tval = (cbs_cir >> ASO_DSEG_CBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\tMLX5_SET(flow_meter_parameters, fmp, cbs_exponent, val);\n+\tval = (cbs_cir >> ASO_DSEG_CBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;\n+\tMLX5_SET(flow_meter_parameters, fmp, cbs_mantissa, val);\n+\tval = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\tMLX5_SET(flow_meter_parameters, fmp, cir_exponent, val);\n+\tval = (cbs_cir & ASO_DSEG_MAN_MASK);\n+\tMLX5_SET(flow_meter_parameters, fmp, cir_mantissa, val);\n+\tval = (ebs_eir >> ASO_DSEG_EBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\tMLX5_SET(flow_meter_parameters, fmp, ebs_exponent, val);\n+\tval = (ebs_eir >> ASO_DSEG_EBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;\n+\tMLX5_SET(flow_meter_parameters, fmp, ebs_mantissa, val);\n \tmtr_init.next_table =\n \t\tfm->transfer ? fm->mfts->transfer.tbl->obj :\n-\t\t    fm->egress ? fm->mfts->egress.tbl->obj :\n-\t\t\t\t       fm->mfts->ingress.tbl->obj;\n+\t\t\tfm->egress ? fm->mfts->egress.tbl->obj :\n+\t\t\t\tfm->mfts->ingress.tbl->obj;\n \tmtr_init.reg_c_index = priv->mtr_color_reg - REG_C_0;\n-\tmtr_init.flow_meter_parameter = fm->mfts->fmp;\n-\tmtr_init.flow_meter_parameter_sz = fm->mfts->fmp_size;\n+\tmtr_init.flow_meter_parameter = fmp;\n+\tmtr_init.flow_meter_parameter_sz =\n+\t\tMLX5_ST_SZ_BYTES(flow_meter_parameters);\n \tmtr_init.active = fm->active_state;\n \treturn mlx5_glue->dv_create_flow_action_meter(&mtr_init);\n #else\n@@ -89,7 +92,7 @@ mlx5_flow_meter_profile_find(struct mlx5_priv *priv, uint32_t meter_profile_id)\n \tstruct mlx5_flow_meter_profile *fmp;\n \n \tTAILQ_FOREACH(fmp, fmps, next)\n-\t\tif (meter_profile_id == fmp->meter_profile_id)\n+\t\tif (meter_profile_id == fmp->id)\n \t\t\treturn fmp;\n \treturn NULL;\n }\n@@ -239,44 +242,51 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,\n {\n \tstruct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;\n \tuint8_t man, exp;\n+\tuint32_t cbs_exp, cbs_man, cir_exp, cir_man;\n+\tuint32_t ebs_exp, ebs_man;\n \n \tif (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)\n \t\treturn -rte_mtr_error_set(error, ENOTSUP,\n \t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE,\n \t\t\t\tNULL, \"Metering algorithm not supported.\");\n+\t/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */\n+\tmlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,\n+\t\t\t\t    &man, &exp);\n+\t/* Check if cir mantissa is too large. */\n+\tif (exp > ASO_DSEG_CIR_EXP_MASK)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n+\t\t\t\t\t  \"meter profile parameter cir is\"\n+\t\t\t\t\t  \" not supported.\");\n+\tcir_man = man;\n+\tcir_exp = exp;\n \t /* cbs = cbs_mantissa * 2^cbs_exponent */\n \tmlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,\n \t\t\t\t    &man, &exp);\n-\tsrtcm->cbs_mantissa = man;\n-\tsrtcm->cbs_exponent = exp;\n \t/* Check if cbs mantissa is too large. */\n-\tif (srtcm->cbs_exponent != exp)\n-\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\tif (exp > ASO_DSEG_EXP_MASK)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n-\t\t\t\t\t  \"Metering profile parameter cbs is\"\n-\t\t\t\t\t  \" invalid.\");\n-\t/* ebs = ebs_mantissa * 2^ebs_exponent */\n+\t\t\t\t\t  \"meter profile parameter cbs is\"\n+\t\t\t\t\t  \" not supported.\");\n+\tcbs_man = man;\n+\tcbs_exp = exp;\n+\tsrtcm->cbs_cir = rte_cpu_to_be_32(cbs_exp << ASO_DSEG_CBS_EXP_OFFSET |\n+\t\t\t\tcbs_man << ASO_DSEG_CBS_MAN_OFFSET |\n+\t\t\t\tcir_exp << ASO_DSEG_CIR_EXP_OFFSET |\n+\t\t\t\tcir_man);\n \tmlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.ebs,\n \t\t\t\t    &man, &exp);\n-\tsrtcm->ebs_mantissa = man;\n-\tsrtcm->ebs_exponent = exp;\n \t/* Check if ebs mantissa is too large. */\n-\tif (srtcm->ebs_exponent != exp)\n-\t\treturn -rte_mtr_error_set(error, EINVAL,\n-\t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n-\t\t\t\t\t  \"Metering profile parameter ebs is\"\n-\t\t\t\t\t  \" invalid.\");\n-\t/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */\n-\tmlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,\n-\t\t\t\t    &man, &exp);\n-\tsrtcm->cir_mantissa = man;\n-\tsrtcm->cir_exponent = exp;\n-\t/* Check if cir mantissa is too large. */\n-\tif (srtcm->cir_exponent != exp)\n-\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\tif (exp > ASO_DSEG_EXP_MASK)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n-\t\t\t\t\t  \"Metering profile parameter cir is\"\n-\t\t\t\t\t  \" invalid.\");\n+\t\t\t\t\t  \"meter profile parameter ebs is\"\n+\t\t\t\t\t  \" not supported.\");\n+\tebs_man = man;\n+\tebs_exp = exp;\n+\tsrtcm->ebs_eir = rte_cpu_to_be_32(ebs_exp << ASO_DSEG_EBS_EXP_OFFSET |\n+\t\t\t\t\tebs_man << ASO_DSEG_EBS_MAN_OFFSET);\n \treturn 0;\n }\n \n@@ -306,7 +316,11 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \tmemset(cap, 0, sizeof(*cap));\n-\tcap->n_max = 1 << qattr->log_max_flow_meter;\n+\tif (priv->sh->meter_aso_en)\n+\t    /* 2 meters per one ASO cache line. */\n+\t\tcap->n_max = 1 << (qattr->log_max_num_meter_aso + 1);\n+\telse\n+\t\tcap->n_max = 1 << qattr->log_max_flow_meter;\n \tcap->n_shared_max = cap->n_max;\n \tcap->identical = 1;\n \tcap->shared_identical = 1;\n@@ -365,7 +379,7 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,\n \t\t\t\t\t  NULL, \"Meter profile memory \"\n \t\t\t\t\t  \"alloc failed.\");\n \t/* Fill profile info. */\n-\tfmp->meter_profile_id = meter_profile_id;\n+\tfmp->id = meter_profile_id;\n \tfmp->profile = *profile;\n \t/* Fill the flow meter parameters for the PRM. */\n \tret = mlx5_flow_meter_param_fill(fmp, error);\n@@ -499,7 +513,7 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,\n \t\t\t\t NULL,\n \t\t\t\t \"Green color only supports recolor green action.\");\n \t/* Validate meter id. */\n-\tif (mlx5_flow_meter_find(priv, meter_id))\n+\tif (mlx5_flow_meter_find(priv, meter_id, NULL))\n \t\treturn -rte_mtr_error_set(error, EEXIST,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID, NULL,\n \t\t\t\t\t  \"Meter object already exists.\");\n@@ -524,7 +538,7 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,\n  */\n static int\n mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n-\t\tstruct mlx5_flow_meter *fm,\n+\t\tstruct mlx5_flow_meter_info *fm,\n \t\tconst struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm,\n \t\tuint64_t modify_bits, uint32_t active_state)\n {\n@@ -533,33 +547,37 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n \tuint32_t *attr;\n \tstruct mlx5dv_dr_flow_meter_attr mod_attr = { 0 };\n \tint ret;\n+\tuint32_t cbs_cir, ebs_eir, val;\n \n \t/* Fill command parameters. */\n \tmod_attr.reg_c_index = priv->mtr_color_reg - REG_C_0;\n \tmod_attr.flow_meter_parameter = in;\n-\tmod_attr.flow_meter_parameter_sz = fm->mfts->fmp_size;\n+\tmod_attr.flow_meter_parameter_sz =\n+\t\t\t\tMLX5_ST_SZ_BYTES(flow_meter_parameters);\n \tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)\n \t\tmod_attr.active = !!active_state;\n \telse\n \t\tmod_attr.active = 0;\n \tattr = in;\n+\tcbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);\n+\tebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);\n \tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cbs_exponent, srtcm->cbs_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cbs_mantissa, srtcm->cbs_mantissa);\n+\t\tval = (cbs_cir >> ASO_DSEG_CBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, cbs_exponent, val);\n+\t\tval = (cbs_cir >> ASO_DSEG_CBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, cbs_mantissa, val);\n \t}\n \tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cir_exponent, srtcm->cir_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cir_mantissa, srtcm->cir_mantissa);\n+\t\tval = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, cir_exponent, val);\n+\t\tval = cbs_cir & ASO_DSEG_MAN_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, cir_mantissa, val);\n \t}\n \tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, ebs_exponent, srtcm->ebs_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, ebs_mantissa, srtcm->ebs_mantissa);\n+\t\tval = (ebs_eir >> ASO_DSEG_EBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, ebs_exponent, val);\n+\t\tval = (ebs_eir >> ASO_DSEG_EBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;\n+\t\tMLX5_SET(flow_meter_parameters, attr, ebs_mantissa, val);\n \t}\n \t/* Apply modifications to meter only if it was created. */\n \tif (fm->mfts->meter_action) {\n@@ -572,26 +590,6 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n \t/* Update succeedded modify meter parameters. */\n \tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)\n \t\tfm->active_state = !!active_state;\n-\tattr = fm->mfts->fmp;\n-\tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cbs_exponent, srtcm->cbs_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cbs_mantissa, srtcm->cbs_mantissa);\n-\t}\n-\tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cir_exponent, srtcm->cir_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, cir_mantissa, srtcm->cir_mantissa);\n-\t}\n-\tif (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, ebs_exponent, srtcm->ebs_exponent);\n-\t\tMLX5_SET(flow_meter_parameters,\n-\t\t\t attr, ebs_mantissa, srtcm->ebs_mantissa);\n-\t}\n-\n \treturn 0;\n #else\n \t(void)priv;\n@@ -604,7 +602,7 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n }\n \n static void\n-mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter *fm,\n+mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter_info *fm,\n \t\t\t\tuint64_t stats_mask)\n {\n \tfm->green_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN) ? 1 : 0;\n@@ -639,9 +637,10 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\t       struct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meters *fms = &priv->flow_meters;\n+\tstruct mlx5_legacy_flow_meters *fms = &priv->flow_meters;\n \tstruct mlx5_flow_meter_profile *fmp;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_legacy_flow_meter *legacy_fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tconst struct rte_flow_attr attr = {\n \t\t\t\t.ingress = 1,\n \t\t\t\t.egress = 1,\n@@ -653,8 +652,9 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\t.need_lock = 1,\n \t\t.type = \"mlx5_flow_mtr_flow_id_pool\",\n \t};\n+\tstruct mlx5_aso_mtr *aso_mtr;\n+\tuint32_t mtr_idx;\n \tint ret;\n-\tuint32_t idx = 0;\n \tuint8_t mtr_id_bits;\n \tuint8_t mtr_reg_bits = priv->mtr_reg_share ?\n \t\t\t\tMLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS;\n@@ -674,19 +674,31 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n \t\t\t\t\t  NULL, \"Meter profile id not valid.\");\n \t/* Allocate the flow meter memory. */\n-\tfm = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_MTR], &idx);\n-\tif (fm == NULL)\n-\t\treturn -rte_mtr_error_set(error, ENOMEM,\n-\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t\t  \"Memory alloc failed for meter.\");\n-\tmtr_id_bits = MLX5_REG_BITS - __builtin_clz(idx);\n+\tif (priv->sh->meter_aso_en) {\n+\t\tmtr_idx = mlx5_flow_mtr_alloc(dev);\n+\t\tif (!mtr_idx)\n+\t\t\treturn -rte_mtr_error_set(error, ENOMEM,\n+\t\t\t\tRTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\"Memory alloc failed for meter.\");\n+\t\taso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);\n+\t\tfm = &aso_mtr->fm;\n+\t} else {\n+\t\tlegacy_fm = mlx5_ipool_zmalloc\n+\t\t\t\t(priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx);\n+\t\tif (legacy_fm == NULL)\n+\t\t\treturn -rte_mtr_error_set(error, ENOMEM,\n+\t\t\t\tRTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\"Memory alloc failed for meter.\");\n+\t\tlegacy_fm->idx = mtr_idx;\n+\t\tfm = &legacy_fm->fm;\n+\t}\n+\tmtr_id_bits = MLX5_REG_BITS - __builtin_clz(mtr_idx);\n \tif ((mtr_id_bits + priv->max_mtr_flow_bits) > mtr_reg_bits) {\n \t\tDRV_LOG(ERR, \"Meter number exceeds max limit.\");\n \t\tgoto error;\n \t}\n \tif (mtr_id_bits > priv->max_mtr_bits)\n \t\tpriv->max_mtr_bits = mtr_id_bits;\n-\tfm->idx = idx;\n \t/* Fill the flow meter parameters. */\n \tfm->meter_id = meter_id;\n \tfm->profile = fmp;\n@@ -712,10 +724,11 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \tif (ret)\n \t\tgoto error;\n \t/* Add to the flow meter list. */\n-\tTAILQ_INSERT_TAIL(fms, fm, next);\n+\tif (!priv->sh->meter_aso_en)\n+\t\tTAILQ_INSERT_TAIL(fms, legacy_fm, next);\n \tfm->active_state = 1; /* Config meter starts as active. */\n \tfm->shared = !!shared;\n-\tfm->profile->ref_cnt++;\n+\t__atomic_add_fetch(&fm->profile->ref_cnt, 1, __ATOMIC_RELAXED);\n \tfm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg);\n \tif (!fm->flow_ipool)\n \t\tgoto error;\n@@ -729,12 +742,57 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\tmlx5_counter_free(dev, fm->policer_stats.pass_cnt);\n \tif (fm->policer_stats.drop_cnt)\n \t\tmlx5_counter_free(dev, fm->policer_stats.drop_cnt);\n-\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], idx);\n+\tif (priv->sh->meter_aso_en)\n+\t\tmlx5_flow_mtr_free(dev, mtr_idx);\n+\telse\n+\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], mtr_idx);\n \treturn -rte_mtr_error_set(error, -ret,\n \t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n \t\t\t\t  NULL, \"Failed to create devx meter.\");\n }\n \n+static int\n+mlx5_flow_meter_params_flush(struct rte_eth_dev *dev,\n+\t\t\tstruct mlx5_flow_meter_info *fm,\n+\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\tuint32_t mtr_idx)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_legacy_flow_meters *fms = &priv->flow_meters;\n+\tstruct mlx5_flow_meter_profile *fmp;\n+\tstruct mlx5_legacy_flow_meter *legacy_fm = NULL;\n+\n+\t/* Meter object must not have any owner. */\n+\tMLX5_ASSERT(!fm->ref_cnt);\n+\t/* Get meter profile. */\n+\tfmp = fm->profile;\n+\tif (fmp == NULL)\n+\t\treturn -1;\n+\t/* Update dependencies. */\n+\t__atomic_sub_fetch(&fmp->ref_cnt, 1, __ATOMIC_RELAXED);\n+\t/* Remove from list. */\n+\tif (!priv->sh->meter_aso_en) {\n+\t\tlegacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm);\n+\t\tTAILQ_REMOVE(fms, legacy_fm, next);\n+\t}\n+\t/* Free policer counters. */\n+\tif (fm->policer_stats.pass_cnt)\n+\t\tmlx5_counter_free(dev, fm->policer_stats.pass_cnt);\n+\tif (fm->policer_stats.drop_cnt)\n+\t\tmlx5_counter_free(dev, fm->policer_stats.drop_cnt);\n+\t/* Free meter flow table. */\n+\tif (fm->flow_ipool)\n+\t\tmlx5_ipool_destroy(fm->flow_ipool);\n+\tmlx5_flow_destroy_policer_rules(dev, fm, attr);\n+\tmlx5_flow_destroy_mtr_tbls(dev, fm->mfts);\n+\tif (priv->sh->meter_aso_en)\n+\t\tmlx5_flow_mtr_free(dev, mtr_idx);\n+\telse\n+\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR],\n+\t\t\t\t\tlegacy_fm->idx);\n+\treturn 0;\n+}\n+\n /**\n  * Destroy meter rules.\n  *\n@@ -753,21 +811,21 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\t\tstruct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meters *fms = &priv->flow_meters;\n-\tstruct mlx5_flow_meter_profile *fmp;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tstruct mlx5_flow_meter_info *fm;\n \tconst struct rte_flow_attr attr = {\n \t\t\t\t.ingress = 1,\n \t\t\t\t.egress = 1,\n \t\t\t\t.transfer = priv->config.dv_esw_en ? 1 : 0,\n \t\t\t};\n+\tuint32_t mtr_idx = 0;\n \n \tif (!priv->mtr_en)\n \t\treturn -rte_mtr_error_set(error, ENOTSUP,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, &mtr_idx);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -777,24 +835,17 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\treturn -rte_mtr_error_set(error, EBUSY,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n \t\t\t\t\t  NULL, \"Meter object is being used.\");\n-\t/* Get the meter profile. */\n-\tfmp = fm->profile;\n-\tMLX5_ASSERT(fmp);\n-\t/* Update dependencies. */\n-\tfmp->ref_cnt--;\n-\t/* Remove from the flow meter list. */\n-\tTAILQ_REMOVE(fms, fm, next);\n-\t/* Free policer counters. */\n-\tif (fm->policer_stats.pass_cnt)\n-\t\tmlx5_counter_free(dev, fm->policer_stats.pass_cnt);\n-\tif (fm->policer_stats.drop_cnt)\n-\t\tmlx5_counter_free(dev, fm->policer_stats.drop_cnt);\n-\t/* Free meter flow table */\n-\tif (fm->flow_ipool)\n-\t\tmlx5_ipool_destroy(fm->flow_ipool);\n-\tmlx5_flow_destroy_policer_rules(dev, fm, &attr);\n-\tmlx5_flow_destroy_mtr_tbls(dev, fm->mfts);\n-\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], fm->idx);\n+\tif (priv->sh->meter_aso_en) {\n+\t\tif (mlx5_l3t_clear_entry(mtrmng->mtr_idx_tbl, meter_id))\n+\t\t\treturn -rte_mtr_error_set(error, EBUSY,\n+\t\t\t\tRTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\"Fail to delete ASO Meter in index table.\");\n+\t}\n+\t/* Destroy the meter profile. */\n+\tif (mlx5_flow_meter_params_flush(dev, fm, &attr, mtr_idx))\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n+\t\t\t\t\tNULL, \"MTR object meter profile invalid.\");\n \treturn 0;\n }\n \n@@ -815,17 +866,13 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,\n  */\n static int\n mlx5_flow_meter_modify_state(struct mlx5_priv *priv,\n-\t\t\t     struct mlx5_flow_meter *fm,\n+\t\t\t     struct mlx5_flow_meter_info *fm,\n \t\t\t     uint32_t new_state,\n \t\t\t     struct rte_mtr_error *error)\n {\n \tstatic const struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm = {\n-\t\t.cbs_exponent = 20,\n-\t\t.cbs_mantissa = 191,\n-\t\t.cir_exponent = 0,\n-\t\t.cir_mantissa = 200,\n-\t\t.ebs_exponent = 0,\n-\t\t.ebs_mantissa = 0,\n+\t\t.cbs_cir = RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL),\n+\t\t.ebs_eir = 0,\n \t};\n \tuint64_t modify_bits = MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS |\n \t\t\t       MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR;\n@@ -867,7 +914,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev,\n \t\t       struct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tint ret;\n \n \tif (!priv->mtr_en)\n@@ -875,7 +922,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, NULL);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -908,7 +955,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev,\n \t\t\tstruct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tint ret;\n \n \tif (!priv->mtr_en)\n@@ -916,7 +963,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, NULL);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -954,7 +1001,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev,\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_flow_meter_profile *fmp;\n \tstruct mlx5_flow_meter_profile *old_fmp;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tuint64_t modify_bits = MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS |\n \t\t\t       MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR;\n \tint ret;\n@@ -970,7 +1017,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n \t\t\t\t\t  NULL, \"Meter profile not found.\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, NULL);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -1020,7 +1067,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,\n \t\t\t     struct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tconst struct rte_flow_attr attr = {\n \t\t\t\t.ingress = 1,\n \t\t\t\t.egress = 1,\n@@ -1034,7 +1081,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, NULL);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -1134,7 +1181,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,\n \t\t\t   struct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_flow_meter_info *fm;\n \tstruct mlx5_flow_policer_stats *ps;\n \tuint64_t pkts;\n \tuint64_t bytes;\n@@ -1145,7 +1192,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"Meter is not supported\");\n \t/* Meter object must exist. */\n-\tfm = mlx5_flow_meter_find(priv, meter_id);\n+\tfm = mlx5_flow_meter_find(priv, meter_id, NULL);\n \tif (fm == NULL)\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n@@ -1239,18 +1286,68 @@ mlx5_flow_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)\n  * @return\n  *   Pointer to the profile found on success, NULL otherwise.\n  */\n-struct mlx5_flow_meter *\n-mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id)\n+struct mlx5_flow_meter_info *\n+mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id,\n+\t\tuint32_t *mtr_idx)\n {\n-\tstruct mlx5_flow_meters *fms = &priv->flow_meters;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_legacy_flow_meter *legacy_fm;\n+\tstruct mlx5_legacy_flow_meters *fms = &priv->flow_meters;\n+\tstruct mlx5_aso_mtr *aso_mtr;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tunion mlx5_l3t_data data;\n \n-\tTAILQ_FOREACH(fm, fms, next)\n-\t\tif (meter_id == fm->meter_id)\n-\t\t\treturn fm;\n+\tif (priv->sh->meter_aso_en) {\n+\t\trte_spinlock_lock(&mtrmng->mtrsl);\n+\t\tif (!mtrmng->n_valid) {\n+\t\t\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tif (mlx5_l3t_get_entry(mtrmng->mtr_idx_tbl, meter_id, &data) ||\n+\t\t\t!data.dword) {\n+\t\t\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tif (mtr_idx)\n+\t\t\t*mtr_idx = data.dword;\n+\t\taso_mtr = mlx5_aso_meter_by_idx(priv, data.dword);\n+\t\tmlx5_l3t_clear_entry(mtrmng->mtr_idx_tbl, meter_id);\n+\t\tif (meter_id == aso_mtr->fm.meter_id) {\n+\t\t\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\t\t\treturn &aso_mtr->fm;\n+\t\t}\n+\t\trte_spinlock_unlock(&mtrmng->mtrsl);\n+\t} else {\n+\t\tTAILQ_FOREACH(legacy_fm, fms, next)\n+\t\t\tif (meter_id == legacy_fm->fm.meter_id)\n+\t\t\t\treturn &legacy_fm->fm;\n+\t}\n \treturn NULL;\n }\n \n+/**\n+ * Find meter by index.\n+ *\n+ * @param priv\n+ *   Pointer to mlx5_priv.\n+ * @param idx\n+ *   Meter index.\n+ *\n+ * @return\n+ *   Pointer to the profile found on success, NULL otherwise.\n+ */\n+struct mlx5_flow_meter_info *\n+flow_dv_meter_find_by_idx(struct mlx5_priv *priv, uint32_t idx)\n+{\n+\tstruct mlx5_aso_mtr *aso_mtr;\n+\n+\tif (priv->sh->meter_aso_en) {\n+\t\taso_mtr = mlx5_aso_meter_by_idx(priv, idx);\n+\t\treturn &aso_mtr->fm;\n+\t} else {\n+\t\treturn mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR], idx);\n+\t}\n+}\n+\n /**\n  * Attach meter to flow.\n  * Unidirectional Meter creation can only be done\n@@ -1270,7 +1367,7 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id)\n  */\n int\n mlx5_flow_meter_attach(struct mlx5_priv *priv,\n-\t\t       struct mlx5_flow_meter *fm,\n+\t\t       struct mlx5_flow_meter_info *fm,\n \t\t       const struct rte_flow_attr *attr,\n \t\t       struct rte_flow_error *error)\n {\n@@ -1319,7 +1416,7 @@ mlx5_flow_meter_attach(struct mlx5_priv *priv,\n  *  Pointer to flow meter.\n  */\n void\n-mlx5_flow_meter_detach(struct mlx5_flow_meter *fm)\n+mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm)\n {\n #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER\n \trte_spinlock_lock(&fm->sl);\n@@ -1352,39 +1449,46 @@ int\n mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_flow_meters *fms = &priv->flow_meters;\n+\tstruct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;\n+\tstruct mlx5_legacy_flow_meters *fms = &priv->flow_meters;\n \tstruct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;\n \tstruct mlx5_flow_meter_profile *fmp;\n-\tstruct mlx5_flow_meter *fm;\n+\tstruct mlx5_legacy_flow_meter *legacy_fm;\n+\tstruct mlx5_flow_meter_info *fm;\n+\tstruct mlx5_aso_mtr_pool *mtr_pool;\n \tconst struct rte_flow_attr attr = {\n \t\t\t\t.ingress = 1,\n \t\t\t\t.egress = 1,\n \t\t\t\t.transfer = priv->config.dv_esw_en ? 1 : 0,\n \t\t\t};\n \tvoid *tmp;\n+\tuint32_t i, offset, mtr_idx;\n \n-\tTAILQ_FOREACH_SAFE(fm, fms, next, tmp) {\n-\t\t/* Meter object must not have any owner. */\n-\t\tMLX5_ASSERT(!fm->ref_cnt);\n-\t\t/* Get meter profile. */\n-\t\tfmp = fm->profile;\n-\t\tif (fmp == NULL)\n-\t\t\treturn -rte_mtr_error_set(error, EINVAL,\n-\t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n-\t\t\t\tNULL, \"MTR object meter profile invalid.\");\n-\t\t/* Update dependencies. */\n-\t\tfmp->ref_cnt--;\n-\t\t/* Remove from list. */\n-\t\tTAILQ_REMOVE(fms, fm, next);\n-\t\t/* Free policer counters. */\n-\t\tif (fm->policer_stats.pass_cnt)\n-\t\t\tmlx5_counter_free(dev, fm->policer_stats.pass_cnt);\n-\t\tif (fm->policer_stats.drop_cnt)\n-\t\t\tmlx5_counter_free(dev, fm->policer_stats.drop_cnt);\n-\t\t/* Free meter flow table. */\n-\t\tmlx5_flow_destroy_policer_rules(dev, fm, &attr);\n-\t\tmlx5_flow_destroy_mtr_tbls(dev, fm->mfts);\n-\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], fm->idx);\n+\tif (priv->sh->meter_aso_en) {\n+\t\ti = mtrmng->n_valid;\n+\t\twhile (i--) {\n+\t\t\tmtr_pool = mtrmng->pools[i];\n+\t\t\tfor (offset = 0; offset < MLX5_ASO_MTRS_PER_POOL;\n+\t\t\t\toffset++) {\n+\t\t\t\tfm = &mtr_pool->mtrs[offset].fm;\n+\t\t\t\tmtr_idx = MLX5_MAKE_MTR_IDX(i, offset);\n+\t\t\t\tif (fm->meter_id != UINT32_MAX &&\n+\t\t\t\t\tmlx5_flow_meter_params_flush(dev,\n+\t\t\t\t\t\tfm, &attr, mtr_idx))\n+\t\t\t\t\treturn -rte_mtr_error_set\n+\t\t\t\t\t(error, EINVAL,\n+\t\t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n+\t\t\t\t\tNULL, \"MTR object meter profile invalid.\");\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\tTAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) {\n+\t\t\tfm = &legacy_fm->fm;\n+\t\t\tif (mlx5_flow_meter_params_flush(dev, fm, &attr, 0))\n+\t\t\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n+\t\t\t\t\tNULL, \"MTR object meter profile invalid.\");\n+\t\t}\n \t}\n \tTAILQ_FOREACH_SAFE(fmp, fmps, next, tmp) {\n \t\t/* Check unused. */\n",
    "prefixes": [
        "v5",
        "09/14"
    ]
}