get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 91585,
    "url": "https://patches.dpdk.org/api/patches/91585/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210415151135.2098674-5-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-5-lizh@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210415151135.2098674-5-lizh@nvidia.com",
    "date": "2021-04-15T15:11:24",
    "name": "[v5,04/14] net/mlx5: optimize meter statistics",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c3c7eb0bed671e0095d78a5003668003d763013c",
    "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-5-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/91585/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/91585/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 688C5A0C3F;\n\tThu, 15 Apr 2021 17:12:37 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BD074162303;\n\tThu, 15 Apr 2021 17:12:00 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 48DE41622FE\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:46 +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 13FFBjPJ032677;\n Thu, 15 Apr 2021 18:11:46 +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:24 +0300",
        "Message-Id": "<20210415151135.2098674-5-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 04/14] net/mlx5: optimize meter statistics",
        "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": "Meter statistics are each policer action each counter.\nTotally 4 counters per each meter.\nIt causes cache missed\nand lead to data forwarding performance low.\n\nTo optimize it, support pass counter for green\nand drop counter for red.\nTotally two counters per each meter.\nAlso use the global drop statistics for\nall meter drop action.\n\nlimitations as below:\n1. It does not support yellow counter and return 0.\n2. All the meter colors with drop action will be\n   counted only by the global drop statistics.\n3. Red color must be with drop action.\n\nSigned-off-by: Li Zhang <lizh@nvidia.com>\nAcked-by: Matan Azrad <matan@nvidia.com>\n---\n doc/guides/nics/mlx5.rst           |   6 +\n drivers/net/mlx5/mlx5_flow.h       |  24 ++--\n drivers/net/mlx5/mlx5_flow_dv.c    |   8 +-\n drivers/net/mlx5/mlx5_flow_meter.c | 217 +++++++++++++++++++----------\n 4 files changed, 173 insertions(+), 82 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst\nindex 7ff92b0491..98817e93cd 100644\n--- a/doc/guides/nics/mlx5.rst\n+++ b/doc/guides/nics/mlx5.rst\n@@ -399,6 +399,12 @@ Limitations\n   - Hairpin between two ports could only manual binding and explicit Tx flow mode. For single port hairpin, all the combinations of auto/manual binding and explicit/implicit Tx flow mode could be supported.\n   - Hairpin in switchdev SR-IOV mode is not supported till now.\n \n+- Meter:\n+  - All the meter colors with drop action will be counted only by the global drop statistics.\n+  - Green color is not supported with drop action.\n+  - Yellow detection is not supported.\n+  - Red color must be with drop action.\n+\n Statistics\n ----------\n \ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 4482a456f0..d862a1daf8 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -831,10 +831,10 @@ struct mlx5_flow {\n \n /* Meter policer statistics */\n struct mlx5_flow_policer_stats {\n-\tuint32_t cnt[RTE_COLORS + 1];\n-\t/**< Color counter, extra for drop. */\n-\tuint64_t stats_mask;\n-\t/**< Statistics mask for the colors. */\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@@ -892,10 +892,18 @@ struct mlx5_flow_meter {\n \t/** Policer actions (per meter output color). */\n \tenum rte_mtr_policer_action action[RTE_COLORS];\n \n-\t/** Set of stats counters to be enabled.\n-\t * @see enum rte_mtr_stats_type\n-\t */\n-\tuint64_t stats_mask;\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;\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex feac8bca34..70b076d400 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -13830,17 +13830,17 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,\n \tint ret;\n \n \t/* Get the statistics counters for green/drop. */\n-\tif (fm->policer_stats.cnt[RTE_COLOR_GREEN]) {\n+\tif (fm->policer_stats.pass_cnt) {\n \t\tcnt = flow_dv_counter_get_by_idx(dev,\n-\t\t\t\t\tfm->policer_stats.cnt[RTE_COLOR_GREEN],\n+\t\t\t\t\tfm->policer_stats.pass_cnt,\n \t\t\t\t\tNULL);\n \t\tmtb->green_count = cnt->action;\n \t} else {\n \t\tmtb->green_count = NULL;\n \t}\n-\tif (fm->policer_stats.cnt[RTE_MTR_DROPPED]) {\n+\tif (fm->policer_stats.drop_cnt) {\n \t\tcnt = flow_dv_counter_get_by_idx(dev,\n-\t\t\t\t\tfm->policer_stats.cnt[RTE_MTR_DROPPED],\n+\t\t\t\t\tfm->policer_stats.drop_cnt,\n \t\t\t\t\tNULL);\n \t\tmtb->drop_count = cnt->action;\n \t} else {\ndiff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c\nindex 7f7693b698..2a37decaaf 100644\n--- a/drivers/net/mlx5/mlx5_flow_meter.c\n+++ b/drivers/net/mlx5/mlx5_flow_meter.c\n@@ -467,13 +467,6 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,\n \t\t\t struct rte_mtr_params *params,\n \t\t\t struct rte_mtr_error *error)\n {\n-\tstatic enum rte_mtr_policer_action\n-\t\t\t\tvalid_recol_action[RTE_COLORS] = {\n-\t\t\t\t\t       MTR_POLICER_ACTION_COLOR_GREEN,\n-\t\t\t\t\t       MTR_POLICER_ACTION_COLOR_YELLOW,\n-\t\t\t\t\t       MTR_POLICER_ACTION_COLOR_RED };\n-\tint i;\n-\n \t/* Meter must use global drop action. */\n \tif (!priv->sh->dr_drop_action)\n \t\treturn -rte_mtr_error_set(error, ENOTSUP,\n@@ -493,13 +486,18 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,\n \t\t\t\t\t  \"Previous meter color \"\n \t\t\t\t\t  \"not supported.\");\n \t/* Validate policer settings. */\n-\tfor (i = 0; i < RTE_COLORS; i++)\n-\t\tif (params->action[i] != valid_recol_action[i] &&\n-\t\t    params->action[i] != MTR_POLICER_ACTION_DROP)\n-\t\t\treturn -rte_mtr_error_set\n-\t\t\t\t\t(error, ENOTSUP,\n-\t\t\t\t\t action2error(params->action[i]), NULL,\n-\t\t\t\t\t \"Recolor action not supported.\");\n+\tif (params->action[RTE_COLOR_RED] != MTR_POLICER_ACTION_DROP)\n+\t\treturn -rte_mtr_error_set\n+\t\t\t\t(error, ENOTSUP,\n+\t\t\t\t action2error(params->action[RTE_COLOR_RED]),\n+\t\t\t\t NULL,\n+\t\t\t\t \"Red color only supports drop action.\");\n+\tif (params->action[RTE_COLOR_GREEN] != MTR_POLICER_ACTION_COLOR_GREEN)\n+\t\treturn -rte_mtr_error_set\n+\t\t\t\t(error, ENOTSUP,\n+\t\t\t\t action2error(params->action[RTE_COLOR_GREEN]),\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 \t\treturn -rte_mtr_error_set(error, EEXIST,\n@@ -605,6 +603,19 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,\n #endif\n }\n \n+static void\n+mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter *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+\tfm->green_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_GREEN) ? 1 : 0;\n+\tfm->red_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_RED) ? 1 : 0;\n+\tfm->red_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_RED) ? 1 : 0;\n+\tfm->bytes_dropped =\n+\t\t(stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED) ? 1 : 0;\n+\tfm->pkts_dropped = (stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED) ? 1 : 0;\n+}\n+\n /**\n  * Create meter rules.\n  *\n@@ -643,7 +654,6 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \t\t.type = \"mlx5_flow_mtr_flow_id_pool\",\n \t};\n \tint ret;\n-\tunsigned int i;\n \tuint32_t idx = 0;\n \tuint8_t mtr_id_bits;\n \tuint8_t mtr_reg_bits = priv->mtr_reg_share ?\n@@ -681,12 +691,18 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \tfm->meter_id = meter_id;\n \tfm->profile = fmp;\n \tmemcpy(fm->action, params->action, sizeof(params->action));\n-\tfm->stats_mask = params->stats_mask;\n+\tmlx5_flow_meter_stats_enable_update(fm, params->stats_mask);\n \n \t/* Alloc policer counters. */\n-\tfor (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++) {\n-\t\tfm->policer_stats.cnt[i] = mlx5_counter_alloc(dev);\n-\t\tif (!fm->policer_stats.cnt[i])\n+\tif (fm->green_bytes || fm->green_pkts) {\n+\t\tfm->policer_stats.pass_cnt = mlx5_counter_alloc(dev);\n+\t\tif (!fm->policer_stats.pass_cnt)\n+\t\t\tgoto error;\n+\t}\n+\tif (fm->red_bytes || fm->red_pkts ||\n+\t    fm->bytes_dropped || fm->pkts_dropped) {\n+\t\tfm->policer_stats.drop_cnt = mlx5_counter_alloc(dev);\n+\t\tif (!fm->policer_stats.drop_cnt)\n \t\t\tgoto error;\n \t}\n \tfm->mfts = mlx5_flow_create_mtr_tbls(dev);\n@@ -699,7 +715,6 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \tTAILQ_INSERT_TAIL(fms, fm, next);\n \tfm->active_state = 1; /* Config meter starts as active. */\n \tfm->shared = !!shared;\n-\tfm->policer_stats.stats_mask = params->stats_mask;\n \tfm->profile->ref_cnt++;\n \tfm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg);\n \tif (!fm->flow_ipool)\n@@ -710,9 +725,10 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,\n \tmlx5_flow_destroy_policer_rules(dev, fm, &attr);\n \tmlx5_flow_destroy_mtr_tbls(dev, fm->mfts);\n \t/* Free policer counters. */\n-\tfor (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++)\n-\t\tif (fm->policer_stats.cnt[i])\n-\t\t\tmlx5_counter_free(dev, fm->policer_stats.cnt[i]);\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 \tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], idx);\n \treturn -rte_mtr_error_set(error, -ret,\n \t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n@@ -745,7 +761,6 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,\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-\tunsigned int i;\n \n \tif (!priv->mtr_en)\n \t\treturn -rte_mtr_error_set(error, ENOTSUP,\n@@ -770,9 +785,10 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,\n \t/* Remove from the flow meter list. */\n \tTAILQ_REMOVE(fms, fm, next);\n \t/* Free policer counters. */\n-\tfor (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++)\n-\t\tif (fm->policer_stats.cnt[i])\n-\t\t\tmlx5_counter_free(dev, fm->policer_stats.cnt[i]);\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@@ -1005,6 +1021,13 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_flow_meter *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+\tbool need_updated = false;\n+\tstruct mlx5_flow_policer_stats old_policer_stats;\n \n \tif (!priv->mtr_en)\n \t\treturn -rte_mtr_error_set(error, ENOTSUP,\n@@ -1016,7 +1039,70 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,\n \t\treturn -rte_mtr_error_set(error, ENOENT,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n \t\t\t\t\t  NULL, \"Meter object id not valid.\");\n-\tfm->policer_stats.stats_mask = stats_mask;\n+\told_policer_stats.pass_cnt = 0;\n+\told_policer_stats.drop_cnt = 0;\n+\tif (!!((RTE_MTR_STATS_N_PKTS_GREEN |\n+\t\t\t\tRTE_MTR_STATS_N_BYTES_GREEN) & stats_mask) !=\n+\t\t!!fm->policer_stats.pass_cnt) {\n+\t\tneed_updated = true;\n+\t\tif (fm->policer_stats.pass_cnt) {\n+\t\t\told_policer_stats.pass_cnt = fm->policer_stats.pass_cnt;\n+\t\t\tfm->policer_stats.pass_cnt = 0;\n+\t\t} else {\n+\t\t\tfm->policer_stats.pass_cnt =\n+\t\t\t\tmlx5_counter_alloc(dev);\n+\t\t\tif (!fm->policer_stats.pass_cnt)\n+\t\t\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  \"Counter alloc failed for meter.\");\n+\t\t}\n+\t}\n+\tif (!!((RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_BYTES_RED |\n+\t\tRTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED) &\n+\t\tstats_mask) !=\n+\t\t!!fm->policer_stats.drop_cnt) {\n+\t\tneed_updated = true;\n+\t\tif (fm->policer_stats.drop_cnt) {\n+\t\t\told_policer_stats.drop_cnt = fm->policer_stats.drop_cnt;\n+\t\t\tfm->policer_stats.drop_cnt = 0;\n+\t\t} else {\n+\t\t\tfm->policer_stats.drop_cnt =\n+\t\t\t\tmlx5_counter_alloc(dev);\n+\t\t\tif (!fm->policer_stats.drop_cnt)\n+\t\t\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  \"Counter alloc failed for meter.\");\n+\t\t}\n+\t}\n+\tif (need_updated) {\n+\t\tif (mlx5_flow_prepare_policer_rules(dev, fm, &attr)) {\n+\t\t\tif (fm->policer_stats.pass_cnt &&\n+\t\t\t\tfm->policer_stats.pass_cnt !=\n+\t\t\t\told_policer_stats.pass_cnt)\n+\t\t\t\tmlx5_counter_free(dev,\n+\t\t\t\t\tfm->policer_stats.pass_cnt);\n+\t\t\tfm->policer_stats.pass_cnt =\n+\t\t\t\t\told_policer_stats.pass_cnt;\n+\t\t\tif (fm->policer_stats.drop_cnt &&\n+\t\t\t\tfm->policer_stats.drop_cnt !=\n+\t\t\t\told_policer_stats.drop_cnt)\n+\t\t\t\tmlx5_counter_free(dev,\n+\t\t\t\t\tfm->policer_stats.drop_cnt);\n+\t\t\tfm->policer_stats.pass_cnt =\n+\t\t\t\t\told_policer_stats.pass_cnt;\n+\t\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Failed to create meter policer rules.\");\n+\t\t}\n+\t\t/* Free old policer counters. */\n+\t\tif (old_policer_stats.pass_cnt)\n+\t\t\tmlx5_counter_free(dev,\n+\t\t\t\told_policer_stats.pass_cnt);\n+\t\tif (old_policer_stats.drop_cnt)\n+\t\t\tmlx5_counter_free(dev,\n+\t\t\t\told_policer_stats.drop_cnt);\n+\t}\n+\tmlx5_flow_meter_stats_enable_update(fm, stats_mask);\n \treturn 0;\n }\n \n@@ -1047,20 +1133,11 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,\n \t\t\t   int clear,\n \t\t\t   struct rte_mtr_error *error)\n {\n-\tstatic uint64_t meter2mask[RTE_MTR_DROPPED + 1] = {\n-\t\tRTE_MTR_STATS_N_PKTS_GREEN | RTE_MTR_STATS_N_BYTES_GREEN,\n-\t\tRTE_MTR_STATS_N_PKTS_YELLOW | RTE_MTR_STATS_N_BYTES_YELLOW,\n-\t\tRTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_BYTES_RED,\n-\t\tRTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED\n-\t};\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_flow_meter *fm;\n \tstruct mlx5_flow_policer_stats *ps;\n-\tuint64_t pkts_dropped = 0;\n-\tuint64_t bytes_dropped = 0;\n \tuint64_t pkts;\n \tuint64_t bytes;\n-\tint i;\n \tint ret = 0;\n \n \tif (!priv->mtr_en)\n@@ -1074,41 +1151,42 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_ID,\n \t\t\t\t\t  NULL, \"Meter object id not valid.\");\n \tps = &fm->policer_stats;\n-\t*stats_mask = ps->stats_mask;\n-\tfor (i = 0; i < RTE_MTR_DROPPED; i++) {\n-\t\tif (*stats_mask & meter2mask[i]) {\n-\t\t\tret = mlx5_counter_query(dev, ps->cnt[i], clear, &pkts,\n+\t*stats_mask = 0;\n+\tif (fm->green_bytes)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_BYTES_GREEN;\n+\tif (fm->green_pkts)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_PKTS_GREEN;\n+\tif (fm->red_bytes)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_BYTES_RED;\n+\tif (fm->red_pkts)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_PKTS_RED;\n+\tif (fm->bytes_dropped)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_BYTES_DROPPED;\n+\tif (fm->pkts_dropped)\n+\t\t*stats_mask |= RTE_MTR_STATS_N_PKTS_DROPPED;\n+\tmemset(stats, 0, sizeof(*stats));\n+\tif (ps->pass_cnt) {\n+\t\tret = mlx5_counter_query(dev, ps->pass_cnt, clear, &pkts,\n \t\t\t\t\t\t &bytes);\n-\t\t\tif (ret)\n-\t\t\t\tgoto error;\n-\t\t\tif (fm->action[i] == MTR_POLICER_ACTION_DROP) {\n-\t\t\t\tpkts_dropped += pkts;\n-\t\t\t\tbytes_dropped += bytes;\n-\t\t\t}\n-\t\t\t/* If need to read the packets, set it. */\n-\t\t\tif ((1 << i) & (*stats_mask & meter2mask[i]))\n-\t\t\t\tstats->n_pkts[i] = pkts;\n-\t\t\t/* If need to read the bytes, set it. */\n-\t\t\tif ((1 << (RTE_MTR_DROPPED + 1 + i)) &\n-\t\t\t   (*stats_mask & meter2mask[i]))\n-\t\t\t\tstats->n_bytes[i] = bytes;\n-\t\t}\n+\t\tif (ret)\n+\t\t\tgoto error;\n+\t\t/* If need to read the packets, set it. */\n+\t\tif (fm->green_pkts)\n+\t\t\tstats->n_pkts[RTE_COLOR_GREEN] = pkts;\n+\t\t/* If need to read the bytes, set it. */\n+\t\tif (fm->green_bytes)\n+\t\t\tstats->n_bytes[RTE_COLOR_GREEN] = bytes;\n \t}\n-\t/* Dropped packets/bytes are treated differently. */\n-\tif (*stats_mask & meter2mask[i]) {\n-\t\tret = mlx5_counter_query(dev, ps->cnt[i], clear, &pkts,\n-\t\t\t\t\t &bytes);\n+\tif (ps->drop_cnt) {\n+\t\tret = mlx5_counter_query(dev, ps->drop_cnt, clear, &pkts,\n+\t\t\t\t\t\t &bytes);\n \t\tif (ret)\n \t\t\tgoto error;\n-\t\tpkts += pkts_dropped;\n-\t\tbytes += bytes_dropped;\n \t\t/* If need to read the packets, set it. */\n-\t\tif ((*stats_mask & meter2mask[i]) &\n-\t\t   RTE_MTR_STATS_N_PKTS_DROPPED)\n+\t\tif (fm->pkts_dropped)\n \t\t\tstats->n_pkts_dropped = pkts;\n \t\t/* If need to read the bytes, set it. */\n-\t\tif ((*stats_mask & meter2mask[i]) &\n-\t\t   RTE_MTR_STATS_N_BYTES_DROPPED)\n+\t\tif (fm->bytes_dropped)\n \t\t\tstats->n_bytes_dropped = bytes;\n \t}\n \treturn 0;\n@@ -1284,7 +1362,6 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)\n \t\t\t\t.transfer = priv->config.dv_esw_en ? 1 : 0,\n \t\t\t};\n \tvoid *tmp;\n-\tuint32_t i;\n \n \tTAILQ_FOREACH_SAFE(fm, fms, next, tmp) {\n \t\t/* Meter object must not have any owner. */\n@@ -1300,10 +1377,10 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)\n \t\t/* Remove from list. */\n \t\tTAILQ_REMOVE(fms, fm, next);\n \t\t/* Free policer counters. */\n-\t\tfor (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++)\n-\t\t\tif (fm->policer_stats.cnt[i])\n-\t\t\t\tmlx5_counter_free(dev,\n-\t\t\t\t\t\t  fm->policer_stats.cnt[i]);\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",
    "prefixes": [
        "v5",
        "04/14"
    ]
}