get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 50549,
    "url": "https://patches.dpdk.org/api/patches/50549/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1551287944-27314-1-git-send-email-wan.junjie@foxmail.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": "<1551287944-27314-1-git-send-email-wan.junjie@foxmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1551287944-27314-1-git-send-email-wan.junjie@foxmail.com",
    "date": "2019-02-27T17:19:04",
    "name": "[v5] lib/metrics: add unregister api for metrics",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "6c2752b05ae9e958c4279c0423468f19d0c6d52c",
    "submitter": {
        "id": 1224,
        "url": "https://patches.dpdk.org/api/people/1224/?format=api",
        "name": "=?ISO-8859-1?B?V2FuIEp1bmppZQ==?=",
        "email": "wan.junjie@foxmail.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1551287944-27314-1-git-send-email-wan.junjie@foxmail.com/mbox/",
    "series": [
        {
            "id": 3564,
            "url": "https://patches.dpdk.org/api/series/3564/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=3564",
            "date": "2019-02-27T17:19:04",
            "name": "[v5] lib/metrics: add unregister api for metrics",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/3564/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/50549/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/50549/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 6F4865F20;\n\tWed, 27 Feb 2019 18:19:37 +0100 (CET)",
            "from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142])\n\tby dpdk.org (Postfix) with ESMTP id 39E115F1D\n\tfor <dev@dpdk.org>; Wed, 27 Feb 2019 18:19:35 +0100 (CET)",
            "from promote.cache-dns.local (unknown [112.4.40.171])\n\tby esmtp4.qq.com (ESMTP) with \n\tid ; Thu, 28 Feb 2019 01:19:28 +0800 (CST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=foxmail.com;\n\ts=s201512; t=1551287972;\n\tbh=ck/28t6Ynll7P9zWlhzxJKCGGrQOU9dMOWGxxr7N9uc=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References;\n\tb=KtYnHXt9F1V0OPkirW5uug8GfOt9JJryl9RFNA95JxtgxE5YN5wpXgfSF8SohX1L/\n\tvEidtnbyeTMi1ejiOLjPfErqzQ1Q4lvtgLhrr1cnfEmOPIANmVPvKwxX7pcj+qAlX/\n\tXSgcT+2oWbg/2NKoQQjjxgiQyfEbN+Cwg5sVaT3g=",
        "X-QQ-mid": "esmtp7t1551287970tlp8hzspq",
        "X-QQ-SSF": "B1000000000000F0F6100700000000K",
        "X-QQ-FEAT": "Tp2hW+Mew+fiYqaslvr+vUdbE/liY4tkMK6l0CjvOW4rzuXwkkWBd7I9Zpfgk\n\tCok+KmNO6/m0yy3Xrro02WqBS0yzCinxQNXHQHdnBX6cgUH+fj/g+91ekFE99YDaIFxocFm\n\t/aLHXGoywJNuVZWrGew82SfxGI3iUdB4VQvOyeOM4AA8b1fjol0NdJnnAar3ItMrfgLROS9\n\t4XnWYxnP3OTCWmce7iv7z8weYePL2ChyoZOPcFeFCtmPBfVrP7pcR/tmPwCC189l9D4mwvX\n\tLol/sHs1nbKrXj5Am7+3DO9SCsGJTYi8NVtWbPRbyNQk1n",
        "X-QQ-GoodBg": "0",
        "From": "Junjie Wan <wan.junjie@foxmail.com>",
        "To": "remy.horton@intel.com",
        "Cc": "dev@dpdk.org,\n\tjunka <wan.junjie@foxmail.com>",
        "Date": "Thu, 28 Feb 2019 01:19:04 +0800",
        "Message-Id": "<1551287944-27314-1-git-send-email-wan.junjie@foxmail.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1550849955-15101-1-git-send-email-wan.junjie@foxmail.com>",
        "References": "<1550849955-15101-1-git-send-email-wan.junjie@foxmail.com>",
        "X-QQ-SENDSIZE": "520",
        "Feedback-ID": "esmtp:foxmail.com:bgforeign:bgforeign2",
        "X-QQ-Bgrelay": "1",
        "Subject": "[dpdk-dev] [PATCH v5] lib/metrics: add unregister api for metrics",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: junka <wan.junjie@foxmail.com>\n\nThe bitmap will help maintain the metrics. We can dynamically\nadd and remove metrics data. For example, after uninit latency lib,\nit could remove itself from the metrics. This could make the result\nfrom rte_metrics_get_names much more simple to display the wanted\nmetrics data only.\n\nSigned-off-by: Junjie Wan <wan.junjie@foxmail.com>\n---\nv5:\n* Fix test case and coding style issues\n\n lib/librte_metrics/rte_metrics.c | 221 ++++++++++++++++++++++++++-------------\n lib/librte_metrics/rte_metrics.h |  21 ++++\n 2 files changed, 170 insertions(+), 72 deletions(-)",
    "diff": "diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c\nindex 99a96b6..d3bbdd5 100644\n--- a/lib/librte_metrics/rte_metrics.c\n+++ b/lib/librte_metrics/rte_metrics.c\n@@ -12,6 +12,7 @@\n #include <rte_lcore.h>\n #include <rte_memzone.h>\n #include <rte_spinlock.h>\n+#include <rte_bitmap.h>\n \n #define RTE_METRICS_MAX_METRICS 256\n #define RTE_METRICS_MEMZONE_NAME \"RTE_METRICS\"\n@@ -28,10 +29,7 @@ struct rte_metrics_meta_s {\n \tuint64_t value[RTE_MAX_ETHPORTS];\n \t/** Used for global metrics */\n \tuint64_t global_value;\n-\t/** Index of next root element (zero for none) */\n-\tuint16_t idx_next_set;\n-\t/** Index of next metric in set (zero for none) */\n-\tuint16_t idx_next_stat;\n+\n };\n \n /**\n@@ -43,14 +41,12 @@ struct rte_metrics_meta_s {\n  * processes is not guaranteed.\n  */\n struct rte_metrics_data_s {\n-\t/**   Index of last metadata entry with valid data.\n-\t * This value is not valid if cnt_stats is zero.\n-\t */\n-\tuint16_t idx_last_set;\n \t/**   Number of metrics. */\n \tuint16_t cnt_stats;\n \t/** Metric data memory block. */\n \tstruct rte_metrics_meta_s metadata[RTE_METRICS_MAX_METRICS];\n+\t/** Metric data bitmap in use */\n+\tstruct rte_bitmap *bits;\n \t/** Metric data access lock */\n \trte_spinlock_t lock;\n };\n@@ -60,6 +56,8 @@ struct rte_metrics_data_s {\n {\n \tstruct rte_metrics_data_s *stats;\n \tconst struct rte_memzone *memzone;\n+\tuint32_t bmp_size;\n+\tvoid *bmp_mem;\n \n \tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n \t\treturn;\n@@ -73,6 +71,21 @@ struct rte_metrics_data_s {\n \t\trte_exit(EXIT_FAILURE, \"Unable to allocate stats memzone\\n\");\n \tstats = memzone->addr;\n \tmemset(stats, 0, sizeof(struct rte_metrics_data_s));\n+\n+\tbmp_size =\n+\t\trte_bitmap_get_memory_footprint(RTE_METRICS_MAX_METRICS);\n+\tbmp_mem = rte_malloc(\"metrics_bits\", bmp_size,\n+\t\t\t\t\t\tRTE_CACHE_LINE_SIZE);\n+\tif (bmp_mem == NULL)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to allocate metrics bitmap\\n\");\n+\n+\tstats->bits = rte_bitmap_init(RTE_METRICS_MAX_METRICS,\n+\t\t\tbmp_mem, bmp_size);\n+\tif (stats->bits == NULL) {\n+\t\trte_exit(EXIT_FAILURE, \"Failed to init metrics bitmap\\n\");\n+\t\trte_free(bmp_mem);\n+\t}\n+\n \trte_spinlock_init(&stats->lock);\n }\n \n@@ -90,8 +103,8 @@ struct rte_metrics_data_s {\n \tstruct rte_metrics_meta_s *entry = NULL;\n \tstruct rte_metrics_data_s *stats;\n \tconst struct rte_memzone *memzone;\n-\tuint16_t idx_name;\n-\tuint16_t idx_base;\n+\tuint16_t idx_name, idx;\n+\tuint16_t idx_base = RTE_METRICS_MAX_METRICS;\n \n \t/* Some sanity checks */\n \tif (cnt_names < 1 || names == NULL)\n@@ -110,19 +123,33 @@ struct rte_metrics_data_s {\n \n \trte_spinlock_lock(&stats->lock);\n \n-\t/* Overwritten later if this is actually first set.. */\n-\tstats->metadata[stats->idx_last_set].idx_next_set = stats->cnt_stats;\n-\n-\tstats->idx_last_set = idx_base = stats->cnt_stats;\n+\t/* search for a continuous array, fail if not enough*/\n+\tfor (idx_name = 0; idx_name < RTE_METRICS_MAX_METRICS; idx_name++) {\n+\t\tif (!rte_bitmap_get(stats->bits, idx_name)) {\n+\t\t\tidx_base = idx_name;\n+\t\t\tif (idx_base + cnt_names > RTE_METRICS_MAX_METRICS)\n+\t\t\t\treturn -ENOMEM;\n+\t\t\tfor (idx = idx_base;\n+\t\t\t\tidx < idx_base + cnt_names; idx++) {\n+\t\t\t\tif (rte_bitmap_get(stats->bits, idx))\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (idx == idx_base + cnt_names)\n+\t\t\t\tbreak;\n+\t\t\tidx_name = idx;\n+\t\t}\n+\t}\n+\tif (idx_base == RTE_METRICS_MAX_METRICS)\n+\t\treturn -ENOMEM;\n \n-\tfor (idx_name = 0; idx_name < cnt_names; idx_name++) {\n-\t\tentry = &stats->metadata[idx_name + stats->cnt_stats];\n-\t\tstrlcpy(entry->name, names[idx_name], RTE_METRICS_MAX_NAME_LEN);\n+\tfor (idx = idx_base; idx < idx_base + cnt_names; idx++) {\n+\t\trte_bitmap_set(stats->bits, idx);\n+\t\tentry = &stats->metadata[idx];\n+\t\tstrlcpy(entry->name, names[idx-idx_base],\n+\t\t\tRTE_METRICS_MAX_NAME_LEN);\n \t\tmemset(entry->value, 0, sizeof(entry->value));\n-\t\tentry->idx_next_stat = idx_name + stats->cnt_stats + 1;\n+\t\tentry->global_value = 0;\n \t}\n-\tentry->idx_next_stat = 0;\n-\tentry->idx_next_set = 0;\n \tstats->cnt_stats += cnt_names;\n \n \trte_spinlock_unlock(&stats->lock);\n@@ -142,7 +169,6 @@ struct rte_metrics_data_s {\n \tconst uint64_t *values,\n \tuint32_t count)\n {\n-\tstruct rte_metrics_meta_s *entry;\n \tstruct rte_metrics_data_s *stats;\n \tconst struct rte_memzone *memzone;\n \tuint16_t idx_metric;\n@@ -163,18 +189,69 @@ struct rte_metrics_data_s {\n \n \trte_spinlock_lock(&stats->lock);\n \n-\tif (key >= stats->cnt_stats) {\n+\tidx_metric = key;\n+\tcnt_setsize = 0;\n+\twhile (idx_metric < RTE_METRICS_MAX_METRICS) {\n+\t\tif (rte_bitmap_get(stats->bits, idx_metric)) {\n+\t\t\tcnt_setsize++;\n+\t\t\tidx_metric++;\n+\t\t} else\n+\t\t\tbreak;\n+\t}\n+\t/* Check update does not cross set border */\n+\tif (cnt_setsize == 0 || count > cnt_setsize) {\n \t\trte_spinlock_unlock(&stats->lock);\n \t\treturn -EINVAL;\n \t}\n+\n+\tfor (idx_value = 0; idx_value < count; idx_value++) {\n+\t\tidx_metric = key + idx_value;\n+\t\tif (port_id == RTE_METRICS_GLOBAL)\n+\t\t\tstats->metadata[idx_metric].global_value =\n+\t\t\t\tvalues[idx_value];\n+\t\telse\n+\t\t\tstats->metadata[idx_metric].value[port_id] =\n+\t\t\t\tvalues[idx_value];\n+\t}\n+\n+\trte_spinlock_unlock(&stats->lock);\n+\treturn 0;\n+}\n+\n+int\n+rte_metrics_unreg_values(uint16_t key, uint16_t count)\n+{\n+\tstruct rte_metrics_data_s *stats;\n+\tconst struct rte_memzone *memzone;\n+\tuint16_t idx_metric;\n+\tuint16_t idx_value;\n+\tuint16_t cnt_setsize;\n+\n+\t/* Some sanity checks */\n+\tif (count < 1)\n+\t\treturn -EINVAL;\n+\n+\tmemzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);\n+\tif (memzone == NULL)\n+\t\treturn -EIO;\n+\n+\tstats = memzone->addr;\n+\tif (stats->cnt_stats < count)\n+\t\treturn -EINVAL;\n+\n+\tif (key >= RTE_METRICS_MAX_METRICS)\n+\t\treturn -EINVAL;\n+\n+\trte_spinlock_lock(&stats->lock);\n+\n \tidx_metric = key;\n \tcnt_setsize = 1;\n-\twhile (idx_metric < stats->cnt_stats) {\n-\t\tentry = &stats->metadata[idx_metric];\n-\t\tif (entry->idx_next_stat == 0)\n+\twhile (idx_metric < RTE_METRICS_MAX_METRICS) {\n+\t\tif (rte_bitmap_get(stats->bits, idx_metric)) {\n+\t\t\tcnt_setsize++;\n+\t\t\tidx_metric++;\n+\t\t} else\n \t\t\tbreak;\n-\t\tcnt_setsize++;\n-\t\tidx_metric++;\n \t}\n \t/* Check update does not cross set border */\n \tif (count > cnt_setsize) {\n@@ -182,29 +259,26 @@ struct rte_metrics_data_s {\n \t\treturn -ERANGE;\n \t}\n \n-\tif (port_id == RTE_METRICS_GLOBAL)\n-\t\tfor (idx_value = 0; idx_value < count; idx_value++) {\n-\t\t\tidx_metric = key + idx_value;\n-\t\t\tstats->metadata[idx_metric].global_value =\n-\t\t\t\tvalues[idx_value];\n-\t\t}\n-\telse\n-\t\tfor (idx_value = 0; idx_value < count; idx_value++) {\n-\t\t\tidx_metric = key + idx_value;\n-\t\t\tstats->metadata[idx_metric].value[port_id] =\n-\t\t\t\tvalues[idx_value];\n-\t\t}\n+\tfor (idx_value = 0; idx_value < count; idx_value++) {\n+\t\tidx_metric = key + idx_value;\n+\t\tmemset(stats->metadata[idx_metric].name, 0,\n+\t\t\tRTE_METRICS_MAX_NAME_LEN);\n+\t\trte_bitmap_clear(stats->bits, idx_metric);\n+\t}\n+\tstats->cnt_stats -= count;\n \trte_spinlock_unlock(&stats->lock);\n+\n \treturn 0;\n }\n \n+\n int\n rte_metrics_get_names(struct rte_metric_name *names,\n \tuint16_t capacity)\n {\n \tstruct rte_metrics_data_s *stats;\n \tconst struct rte_memzone *memzone;\n-\tuint16_t idx_name;\n+\tuint16_t idx_name, idx = 0;\n \tint return_value;\n \n \tmemzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);\n@@ -213,18 +287,23 @@ struct rte_metrics_data_s {\n \n \tstats = memzone->addr;\n \trte_spinlock_lock(&stats->lock);\n-\tif (names != NULL) {\n-\t\tif (capacity < stats->cnt_stats) {\n-\t\t\treturn_value = stats->cnt_stats;\n-\t\t\trte_spinlock_unlock(&stats->lock);\n-\t\t\treturn return_value;\n-\t\t}\n-\t\tfor (idx_name = 0; idx_name < stats->cnt_stats; idx_name++)\n-\t\t\tstrlcpy(names[idx_name].name,\n+\n+\treturn_value = stats->cnt_stats;\n+\tif (names == NULL || capacity < stats->cnt_stats) {\n+\t\trte_spinlock_unlock(&stats->lock);\n+\t\treturn return_value;\n+\t}\n+\n+\tfor (idx_name = 0; idx < stats->cnt_stats &&\n+\t\tidx_name < RTE_METRICS_MAX_METRICS; idx_name++) {\n+\t\tif (rte_bitmap_get(stats->bits, idx_name)) {\n+\t\t\tstrlcpy(names[idx].name,\n \t\t\t\tstats->metadata[idx_name].name,\n \t\t\t\tRTE_METRICS_MAX_NAME_LEN);\n+\t\t\tidx++;\n+\t\t}\n \t}\n-\treturn_value = stats->cnt_stats;\n+\n \trte_spinlock_unlock(&stats->lock);\n \treturn return_value;\n }\n@@ -237,7 +316,7 @@ struct rte_metrics_data_s {\n \tstruct rte_metrics_meta_s *entry;\n \tstruct rte_metrics_data_s *stats;\n \tconst struct rte_memzone *memzone;\n-\tuint16_t idx_name;\n+\tuint16_t idx_name, idx = 0;\n \tint return_value;\n \n \tif (port_id != RTE_METRICS_GLOBAL &&\n@@ -251,30 +330,28 @@ struct rte_metrics_data_s {\n \tstats = memzone->addr;\n \trte_spinlock_lock(&stats->lock);\n \n-\tif (values != NULL) {\n-\t\tif (capacity < stats->cnt_stats) {\n-\t\t\treturn_value = stats->cnt_stats;\n-\t\t\trte_spinlock_unlock(&stats->lock);\n-\t\t\treturn return_value;\n+\treturn_value = stats->cnt_stats;\n+\n+\tif (values == NULL || capacity < stats->cnt_stats) {\n+\t\trte_spinlock_unlock(&stats->lock);\n+\t\treturn return_value;\n+\t}\n+\n+\tfor (idx_name = 0; idx < stats->cnt_stats &&\n+\t\t\tidx_name < RTE_METRICS_MAX_METRICS;\n+\t\t\tidx_name++) {\n+\t\tif (rte_bitmap_get(stats->bits, idx_name)) {\n+\t\t\tentry = &stats->metadata[idx_name];\n+\t\t\tvalues[idx].key = idx_name;\n+\t\t\tif (port_id == RTE_METRICS_GLOBAL)\n+\t\t\t\tvalues[idx].value = entry->global_value;\n+\t\t\telse\n+\t\t\t\tvalues[idx].value = entry->value[port_id];\n+\t\t\tidx++;\n \t\t}\n-\t\tif (port_id == RTE_METRICS_GLOBAL)\n-\t\t\tfor (idx_name = 0;\n-\t\t\t\t\tidx_name < stats->cnt_stats;\n-\t\t\t\t\tidx_name++) {\n-\t\t\t\tentry = &stats->metadata[idx_name];\n-\t\t\t\tvalues[idx_name].key = idx_name;\n-\t\t\t\tvalues[idx_name].value = entry->global_value;\n-\t\t\t}\n-\t\telse\n-\t\t\tfor (idx_name = 0;\n-\t\t\t\t\tidx_name < stats->cnt_stats;\n-\t\t\t\t\tidx_name++) {\n-\t\t\t\tentry = &stats->metadata[idx_name];\n-\t\t\t\tvalues[idx_name].key = idx_name;\n-\t\t\t\tvalues[idx_name].value = entry->value[port_id];\n-\t\t\t}\n \t}\n-\treturn_value = stats->cnt_stats;\n+\n \trte_spinlock_unlock(&stats->lock);\n+\n \treturn return_value;\n }\ndiff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h\nindex 67a60fa..afde1c0 100644\n--- a/lib/librte_metrics/rte_metrics.h\n+++ b/lib/librte_metrics/rte_metrics.h\n@@ -123,6 +123,27 @@ struct rte_metric_value {\n int rte_metrics_reg_names(const char * const *names, uint16_t cnt_names);\n \n /**\n+ * Unregister set of metrics.\n+ *\n+ * Remove the metrics previously registered\n+ *\n+ * @param key\n+ *   Id of metrics to remove\n+ *\n+ * @param count\n+ *   Number of metrics\n+ *\n+ * @return\n+ *  - Zero: Success\n+ *  - -EIO: Error, unable to access metrics shared memory\n+ *    (rte_metrics_init() not called)\n+ *  - -EINVAL: Error, invalid parameters\n+ *  - -ERANGE: Error, oversized\n+ */\n+int\n+rte_metrics_unreg_values(uint16_t key, uint16_t count);\n+\n+/**\n  * Get metric name-key lookup table.\n  *\n  * @param names\n",
    "prefixes": [
        "v5"
    ]
}