Show a patch.

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

{
    "id": 74607,
    "url": "https://patches.dpdk.org/api/patches/74607/",
    "web_url": "https://patches.dpdk.org/patch/74607/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "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"
    },
    "msgid": "<1595404727-164521-3-git-send-email-suanmingm@mellanox.com>",
    "date": "2020-07-22T07:58:47",
    "name": "[v2,3/3] net/mlx5: fix invalid counter query",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "3366342089e7ed584d3639599a957112db5221de",
    "submitter": {
        "id": 1358,
        "url": "https://patches.dpdk.org/api/people/1358/",
        "name": "Suanming Mou",
        "email": "suanmingm@mellanox.com"
    },
    "delegate": {
        "id": 3268,
        "url": "https://patches.dpdk.org/api/users/3268/",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@mellanox.com"
    },
    "mbox": "https://patches.dpdk.org/patch/74607/mbox/",
    "series": [
        {
            "id": 11229,
            "url": "https://patches.dpdk.org/api/series/11229/",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=11229",
            "date": "2020-07-22T07:58:45",
            "name": "[v2,1/3] net/mlx5: separate aging counter pool range",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/11229/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/74607/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/74607/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "References": "<1594903224-20442-1-git-send-email-suanmingm@mellanox.com>\n <1595404727-164521-1-git-send-email-suanmingm@mellanox.com>",
        "X-BeenThere": "dev@dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH v2 3/3] net/mlx5: fix invalid counter query",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "From": "Suanming Mou <suanmingm@mellanox.com>",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BED14A0526;\n\tWed, 22 Jul 2020 09:59:09 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 046C31BFEF;\n\tWed, 22 Jul 2020 09:59:02 +0200 (CEST)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id 6C9591BFFB;\n Wed, 22 Jul 2020 09:58:55 +0200 (CEST)"
        ],
        "To": "viacheslavo@mellanox.com,\n\tmatan@mellanox.com",
        "X-Mailer": "git-send-email 1.8.3.1",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Wed, 22 Jul 2020 15:58:47 +0800",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "In-Reply-To": "<1595404727-164521-1-git-send-email-suanmingm@mellanox.com>",
        "Cc": "rasland@mellanox.com,\n\tdev@dpdk.org,\n\tstable@dpdk.org",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Message-Id": "<1595404727-164521-3-git-send-email-suanmingm@mellanox.com>",
        "Return-Path": "<dev-bounces@dpdk.org>"
    },
    "content": "Currently, the counter query requires the counter ID should start\nwith 4 aligned. In none-batch mode, the counter pool might have the\nchance to get the counter ID not 4 aligned. In this case, the counter\nshould be skipped, or the query will be failed.\n\nSkip the counter with ID not 4 aligned as the first counter in the\nnone-batch count pool to avoid invalid counter query. Once having\nnew min_dcs ID in the poll less than the skipped counters, the\nskipped counters will be returned to the pool free list to use.\n\nFixes: 5382d28c2110 (\"net/mlx5: accelerate DV flow counter transactions\")\nCc: stable@dpdk.org\n\nSigned-off-by: Suanming Mou <suanmingm@mellanox.com>\nAcked-by: Matan Azrad <matan@mellanox.com>\n---\n drivers/net/mlx5/mlx5.h         |  6 ++-\n drivers/net/mlx5/mlx5_flow.c    |  6 +++\n drivers/net/mlx5/mlx5_flow_dv.c | 94 ++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 103 insertions(+), 3 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 5d7d609..0ecfc76 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -366,8 +366,9 @@ struct mlx5_flow_counter {\n struct mlx5_flow_counter_ext {\n \tuint32_t shared:1; /**< Share counter ID with other flow rules. */\n \tuint32_t batch: 1;\n+\tuint32_t skipped:1; /* This counter is skipped or not. */\n \t/**< Whether the counter was allocated by batch command. */\n-\tuint32_t ref_cnt:30; /**< Reference counter. */\n+\tuint32_t ref_cnt:29; /**< Reference counter. */\n \tuint32_t id; /**< User counter ID. */\n \tunion {  /**< Holds the counters for the rule. */\n #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42)\n@@ -390,8 +391,9 @@ struct mlx5_flow_counter_pool {\n \t\trte_atomic64_t a64_dcs;\n \t};\n \t/* The devx object of the minimum counter ID. */\n-\tuint32_t index:29; /* Pool index in container. */\n+\tuint32_t index:28; /* Pool index in container. */\n \tuint32_t type:2; /* Memory type behind the counter array. */\n+\tuint32_t skip_cnt:1; /* Pool contains skipped counter. */\n \tvolatile uint32_t query_gen:1; /* Query round. */\n \trte_spinlock_t sl; /* The pool lock. */\n \tstruct mlx5_counter_stats_raw *raw;\ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex b56bee4..40a8575 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -5974,6 +5974,11 @@ struct mlx5_meter_domains_infos *\n \t\tgoto set_alarm;\n \tdcs = (struct mlx5_devx_obj *)(uintptr_t)rte_atomic64_read\n \t\t\t\t\t\t\t      (&pool->a64_dcs);\n+\tif (dcs->id & (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1)) {\n+\t\t/* Pool without valid counter. */\n+\t\tpool->raw_hw = NULL;\n+\t\tgoto next_pool;\n+\t}\n \toffset = batch ? 0 : dcs->id % MLX5_COUNTERS_PER_POOL;\n \t/*\n \t * Identify the counters released between query trigger and query\n@@ -5998,6 +6003,7 @@ struct mlx5_meter_domains_infos *\n \tpool->raw_hw->min_dcs_id = dcs->id;\n \tLIST_REMOVE(pool->raw_hw, next);\n \tsh->cmng.pending_queries++;\n+next_pool:\n \tpool_index++;\n \tif (pool_index >= rte_atomic16_read(&cont->n_valid)) {\n \t\tbatch ^= 0x1;\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex 2fc4457..a2b7329 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -4408,6 +4408,66 @@ struct field_modify_info modify_tcp[] = {\n }\n \n /**\n+ * Restore skipped counters in the pool.\n+ *\n+ * As counter pool query requires the first counter dcs\n+ * ID start with 4 alinged, if the pool counters with\n+ * min_dcs ID are not aligned with 4, the counters will\n+ * be skipped.\n+ * Once other min_dcs ID less than these skipped counter\n+ * dcs ID appears, the skipped counters will be safe to\n+ * use.\n+ * Should be called when min_dcs is updated.\n+ *\n+ * @param[in] pool\n+ *   Current counter pool.\n+ * @param[in] last_min_dcs\n+ *   Last min_dcs.\n+ */\n+static void\n+flow_dv_counter_restore(struct mlx5_flow_counter_pool *pool,\n+\t\t\tstruct mlx5_devx_obj *last_min_dcs)\n+{\n+\tstruct mlx5_flow_counter_ext *cnt_ext;\n+\tuint32_t offset, new_offset;\n+\tuint32_t skip_cnt = 0;\n+\tuint32_t i;\n+\n+\tif (!pool->skip_cnt)\n+\t\treturn;\n+\t/*\n+\t * If last min_dcs is not valid. The skipped counter may even after\n+\t * last min_dcs, set the offset to the whole pool.\n+\t */\n+\tif (last_min_dcs->id & (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1))\n+\t\toffset = MLX5_COUNTERS_PER_POOL;\n+\telse\n+\t\toffset = last_min_dcs->id % MLX5_COUNTERS_PER_POOL;\n+\tnew_offset = pool->min_dcs->id % MLX5_COUNTERS_PER_POOL;\n+\t/*\n+\t * Check the counters from 1 to the last_min_dcs range. Counters\n+\t * before new min_dcs indicates pool still has skipped counters.\n+\t * Counters be skipped after new min_dcs will be ready to use.\n+\t * Offset 0 counter must be empty or min_dcs, start from 1.\n+\t */\n+\tfor (i = 1; i < offset; i++) {\n+\t\tcnt_ext = MLX5_GET_POOL_CNT_EXT(pool, i);\n+\t\tif (cnt_ext->skipped) {\n+\t\t\tif (i > new_offset) {\n+\t\t\t\tcnt_ext->skipped = 0;\n+\t\t\t\tTAILQ_INSERT_TAIL\n+\t\t\t\t\t(&pool->counters[pool->query_gen],\n+\t\t\t\t\t MLX5_POOL_GET_CNT(pool, i), next);\n+\t\t\t} else {\n+\t\t\t\tskip_cnt++;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tif (!skip_cnt)\n+\t\tpool->skip_cnt = 0;\n+}\n+\n+/**\n  * Prepare a new counter and/or a new counter pool.\n  *\n  * @param[in] dev\n@@ -4432,6 +4492,7 @@ struct field_modify_info modify_tcp[] = {\n \tstruct mlx5_pools_container *cont;\n \tstruct mlx5_flow_counter_pool *pool;\n \tstruct mlx5_counters tmp_tq;\n+\tstruct mlx5_devx_obj *last_min_dcs;\n \tstruct mlx5_devx_obj *dcs = NULL;\n \tstruct mlx5_flow_counter *cnt;\n \tuint32_t add2other;\n@@ -4466,13 +4527,44 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t}\n \t\t\t}\n \t\t}\n-\t\tif (dcs->id < pool->min_dcs->id)\n+\t\tif ((dcs->id < pool->min_dcs->id ||\n+\t\t    pool->min_dcs->id &\n+\t\t    (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1)) &&\n+\t\t    !(dcs->id & (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1))) {\n+\t\t\t/*\n+\t\t\t * Update the pool min_dcs only if current dcs is\n+\t\t\t * valid and exist min_dcs is not valid or greater\n+\t\t\t * than new dcs.\n+\t\t\t */\n+\t\t\tlast_min_dcs = pool->min_dcs;\n \t\t\trte_atomic64_set(&pool->a64_dcs,\n \t\t\t\t\t (int64_t)(uintptr_t)dcs);\n+\t\t\t/*\n+\t\t\t * Restore any skipped counters if the new min_dcs\n+\t\t\t * ID is smaller or min_dcs is not valid.\n+\t\t\t */\n+\t\t\tif (dcs->id < last_min_dcs->id ||\n+\t\t\t    last_min_dcs->id &\n+\t\t\t    (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1))\n+\t\t\t\tflow_dv_counter_restore(pool, last_min_dcs);\n+\t\t}\n \t\ti = dcs->id % MLX5_COUNTERS_PER_POOL;\n \t\tcnt = MLX5_POOL_GET_CNT(pool, i);\n \t\tcnt->pool = pool;\n \t\tMLX5_GET_POOL_CNT_EXT(pool, i)->dcs = dcs;\n+\t\t/*\n+\t\t * If min_dcs is not valid, it means the new allocated dcs\n+\t\t * also fail to become the valid min_dcs, just skip it.\n+\t\t * Or if min_dcs is valid, and new dcs ID is smaller than\n+\t\t * min_dcs, but not become the min_dcs, also skip it.\n+\t\t */\n+\t\tif (pool->min_dcs->id &\n+\t\t    (MLX5_CNT_BATCH_QUERY_ID_ALIGNMENT - 1) ||\n+\t\t    dcs->id < pool->min_dcs->id) {\n+\t\t\tMLX5_GET_POOL_CNT_EXT(pool, i)->skipped = 1;\n+\t\t\tpool->skip_cnt = 1;\n+\t\t\tgoto retry;\n+\t\t}\n \t\tif (add2other) {\n \t\t\tTAILQ_INSERT_TAIL(&pool->counters[pool->query_gen],\n \t\t\t\t\t  cnt, next);\n",
    "prefixes": [
        "v2",
        "3/3"
    ]
}