DPDK patches and discussions
 help / color / mirror / Atom feed
From: =?gb18030?B?zfK/ob3c?= <wan.junjie@foxmail.com>
To: =?gb18030?B?ZGV2?= <dev@dpdk.org>
Subject: [dpdk-dev] [PATCH] lib/metrics: add unregister api for metrics
Date: Fri, 22 Feb 2019 14:16:50 +0800	[thread overview]
Message-ID: <tencent_D09839CC57548580FB70E0A72744D61D3608@qq.com> (raw)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb18030", Size: 10102 bytes --]

Use the bitmap lib to help maintain the metrics. we can dynamically
 add and remove metrics data. After uninit latency, it can
 remove itself from the metrics to make the result from rte_metrics_get_names more simple.

Signed-off-by: junka <wan.junjie@foxmail.com>
---
 lib/librte_latencystats/rte_latencystats.c |   4 +-
 lib/librte_metrics/rte_metrics.c           | 189 +++++++++++++++++++++--------
 lib/librte_metrics/rte_metrics.h           |  21 ++++
 3 files changed, 161 insertions(+), 53 deletions(-)

diff --git a/lib/librte_latencystats/rte_latencystats.c b/lib/librte_latencystats/rte_latencystats.c
index 5715549..b18c3ea 100644
--- a/lib/librte_latencystats/rte_latencystats.c
+++ b/lib/librte_latencystats/rte_latencystats.c
@@ -291,7 +291,9 @@ struct latency_stats_nameoff {
 "qid=%d\n", pid, qid);
 }
 }
-
+
+rte_metrics_unreg_values(latency_stats_index, NUM_LATENCY_STATS);
+
 /* free up the memzone */
 mz = rte_memzone_lookup(MZ_RTE_LATENCY_STATS);
 if (mz)
diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c
index 99a96b6..704e5ae 100644
--- a/lib/librte_metrics/rte_metrics.c
+++ b/lib/librte_metrics/rte_metrics.c
@@ -12,6 +12,7 @@
 #include <rte_lcore.h>
 #include <rte_memzone.h>
 #include <rte_spinlock.h>
+#include <rte_bitmap.h>
 
 #define RTE_METRICS_MAX_METRICS 256
 #define RTE_METRICS_MEMZONE_NAME "RTE_METRICS"
@@ -28,10 +29,7 @@ struct rte_metrics_meta_s {
 uint64_t value[RTE_MAX_ETHPORTS];
 /** Used for global metrics */
 uint64_t global_value;
-/** Index of next root element (zero for none) */
-uint16_t idx_next_set;
-/** Index of next metric in set (zero for none) */
-uint16_t idx_next_stat;
+
 };
 
 /**
@@ -43,14 +41,12 @@ struct rte_metrics_meta_s {
  * processes is not guaranteed.
  */
 struct rte_metrics_data_s {
-/**   Index of last metadata entry with valid data.
- * This value is not valid if cnt_stats is zero.
- */
-uint16_t idx_last_set;
 /**   Number of metrics. */
 uint16_t cnt_stats;
 /** Metric data memory block. */
 struct rte_metrics_meta_s metadata[RTE_METRICS_MAX_METRICS];
+/** Metric data bitmap in use */
+struct rte_bitmap *bits;
 /** Metric data access lock */
 rte_spinlock_t lock;
 };
@@ -60,6 +56,7 @@ struct rte_metrics_data_s {
 {
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
+uint32_t bmp_size;
 
 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 return;
@@ -73,6 +70,24 @@ struct rte_metrics_data_s {
 rte_exit(EXIT_FAILURE, "Unable to allocate stats memzone\n");
 stats = memzone->addr;
 memset(stats, 0, sizeof(struct rte_metrics_data_s));
+
+bmp_size =
+rte_bitmap_get_memory_footprint(RTE_METRICS_MAX_METRICS);
+void *bmpmem = rte_malloc("metrics_bits", bmp_size,
+RTE_CACHE_LINE_SIZE);
+if (bmpmem == NULL) {
+rte_exit(EXIT_FAILURE, 
+"Failed to allocate vlan bitmap for device\n");
+}
+
+stats->bits = rte_bitmap_init(RTE_METRICS_MAX_METRICS,
+bmpmem, bmp_size);
+if (stats->bits == NULL) {
+rte_exit(EXIT_FAILURE, 
+"Failed to init vlan bitmap for bonded device \n");
+rte_free(bmpmem);
+}
+    
 rte_spinlock_init(&stats->lock);
 }
 
@@ -90,7 +105,7 @@ struct rte_metrics_data_s {
 struct rte_metrics_meta_s *entry = NULL;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name,idx;
 uint16_t idx_base;
 
 /* Some sanity checks */
@@ -110,19 +125,36 @@ struct rte_metrics_data_s {
 
 rte_spinlock_lock(&stats->lock);
 
-/* Overwritten later if this is actually first set.. */
-stats->metadata[stats->idx_last_set].idx_next_set = stats->cnt_stats;
-
-stats->idx_last_set = idx_base = stats->cnt_stats;
-
-for (idx_name = 0; idx_name < cnt_names; idx_name++) {
-entry = &stats->metadata[idx_name + stats->cnt_stats];
-strlcpy(entry->name, names[idx_name], RTE_METRICS_MAX_NAME_LEN);
-memset(entry->value, 0, sizeof(entry->value));
-entry->idx_next_stat = idx_name + stats->cnt_stats + 1;
+    //search for a continuous array, fail if not enough
+for (idx_name = 0; idx_name < RTE_METRICS_MAX_METRICS; idx_name++)
+{
+if(!rte_bitmap_get(stats->bits,idx_name))
+{
+idx_base = idx_name;
+if(idx_base + cnt_names > RTE_METRICS_MAX_METRICS)
+return -ENOMEM;
+for(idx = idx_base; idx < idx_base+cnt_names; idx++)
+{
+if(rte_bitmap_get(stats->bits, idx))
+{
+break;
+}
+}
+if(idx == idx_base+cnt_names)
+{
+break;
+}
+idx_name = idx;
+}
 }
-entry->idx_next_stat = 0;
-entry->idx_next_set = 0;
+for(idx = idx_base; idx < idx_base+cnt_names; idx++)
+{
+rte_bitmap_set(stats->bits, idx);
+entry = &stats->metadata[idx];
+strlcpy(entry->name, names[idx-idx_base], RTE_METRICS_MAX_NAME_LEN);
+memset(entry->value, 0, sizeof(entry->value));
+entry->global_value = 0;
+    }
 stats->cnt_stats += cnt_names;
 
 rte_spinlock_unlock(&stats->lock);
@@ -142,7 +174,6 @@ struct rte_metrics_data_s {
 const uint64_t *values,
 uint32_t count)
 {
-struct rte_metrics_meta_s *entry;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
 uint16_t idx_metric;
@@ -163,18 +194,14 @@ struct rte_metrics_data_s {
 
 rte_spinlock_lock(&stats->lock);
 
-if (key >= stats->cnt_stats) {
-rte_spinlock_unlock(&stats->lock);
-return -EINVAL;
-}
 idx_metric = key;
 cnt_setsize = 1;
-while (idx_metric < stats->cnt_stats) {
-entry = &stats->metadata[idx_metric];
-if (entry->idx_next_stat == 0)
-break;
-cnt_setsize++;
-idx_metric++;
+while (idx_metric < RTE_METRICS_MAX_METRICS) {
+if(rte_bitmap_get(stats->bits, idx_metric)){
+    cnt_setsize++;
+    idx_metric++;
+        }else
+            break;
 }
 /* Check update does not cross set border */
 if (count > cnt_setsize) {
@@ -199,12 +226,67 @@ struct rte_metrics_data_s {
 }
 
 int
+rte_metrics_unreg_values(uint16_t key, uint16_t count)
+{
+    struct rte_metrics_data_s *stats;
+    const struct rte_memzone *memzone;
+    uint16_t idx_metric;
+    uint16_t idx_value;
+uint16_t cnt_setsize;
+
+    /* Some sanity checks */
+    if (count < 1 )
+        return -EINVAL;
+
+    memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+    if (memzone == NULL)
+        return -EIO;
+    stats = memzone->addr;
+
+    if (stats->cnt_stats < count)
+        return -EINVAL;
+
+    if (key >= RTE_METRICS_MAX_METRICS) {
+return -EINVAL;
+}
+    
+    rte_spinlock_lock(&stats->lock);
+    
+idx_metric = key;
+cnt_setsize = 1;
+while (idx_metric < RTE_METRICS_MAX_METRICS) {
+if(rte_bitmap_get(stats->bits,idx_metric)){
+    cnt_setsize++;
+    idx_metric++;
+        }else
+            break;
+}
+/* Check update does not cross set border */
+if (count > cnt_setsize) {
+rte_spinlock_unlock(&stats->lock);
+return -ERANGE;
+}
+
+
+for (idx_value = 0; idx_value < count; idx_value++) {
+idx_metric = key + idx_value;
+memset(stats->metadata[idx_metric].name, 0, RTE_METRICS_MAX_NAME_LEN) ;
+        rte_bitmap_clear(stats->bits, idx_metric);
+    }
+    stats->cnt_stats -= count;
+    rte_spinlock_unlock(&stats->lock);
+
+    return 0;
+}
+
+
+int
 rte_metrics_get_names(struct rte_metric_name *names,
 uint16_t capacity)
 {
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name, idx=0;
 int return_value;
 
 memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
@@ -219,10 +301,14 @@ struct rte_metrics_data_s {
 rte_spinlock_unlock(&stats->lock);
 return return_value;
 }
-for (idx_name = 0; idx_name < stats->cnt_stats; idx_name++)
-strlcpy(names[idx_name].name,
-stats->metadata[idx_name].name,
-RTE_METRICS_MAX_NAME_LEN);
+for (idx_name = 0;idx< stats->cnt_stats && idx_name < RTE_METRICS_MAX_METRICS; idx_name++)
+if(rte_bitmap_get(stats->bits,idx_name))
+{
+strlcpy(names[idx].name,
+stats->metadata[idx_name].name,
+RTE_METRICS_MAX_NAME_LEN);
+idx ++;
+}
 }
 return_value = stats->cnt_stats;
 rte_spinlock_unlock(&stats->lock);
@@ -237,7 +323,7 @@ struct rte_metrics_data_s {
 struct rte_metrics_meta_s *entry;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name, idx=0;
 int return_value;
 
 if (port_id != RTE_METRICS_GLOBAL &&
@@ -257,22 +343,21 @@ struct rte_metrics_data_s {
 rte_spinlock_unlock(&stats->lock);
 return return_value;
 }
-if (port_id == RTE_METRICS_GLOBAL)
-for (idx_name = 0;
-idx_name < stats->cnt_stats;
-idx_name++) {
-entry = &stats->metadata[idx_name];
-values[idx_name].key = idx_name;
-values[idx_name].value = entry->global_value;
-}
-else
-for (idx_name = 0;
-idx_name < stats->cnt_stats;
-idx_name++) {
+
+for (idx_name = 0;idx< stats->cnt_stats &&
+idx_name < RTE_METRICS_MAX_METRICS;
+idx_name++) {
+if(rte_bitmap_get(stats->bits,idx_name))
+{
 entry = &stats->metadata[idx_name];
-values[idx_name].key = idx_name;
-values[idx_name].value = entry->value[port_id];
+values[idx].key = idx_name;
+if (port_id == RTE_METRICS_GLOBAL)
+values[idx].value = entry->global_value;
+else
+values[idx].value = entry->value[port_id];
+idx++;
 }
+}
 }
 return_value = stats->cnt_stats;
 rte_spinlock_unlock(&stats->lock);
diff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h
index 67a60fa..fb1859b 100644
--- a/lib/librte_metrics/rte_metrics.h
+++ b/lib/librte_metrics/rte_metrics.h
@@ -123,6 +123,27 @@ struct rte_metric_value {
 int rte_metrics_reg_names(const char * const *names, uint16_t cnt_names);
 
 /**
+ * Un-register set of metrics.
+ *
+ * Remove the metrics previously registerd
+ *
+ * @param key
+ *   Id of metrics to remove
+ *
+ * @param count
+ *   Number of metrics
+ *
+ * @return
+ *  - Zero: Success
+ *  - -EIO: Error, unable to access metrics shared memory
+ *    (rte_metrics_init() not called)
+ *  - -EINVAL: Error, invalid parameters
+ *  - -ERANGE: Error, oversized
+ */
+int
+rte_metrics_unreg_values(uint16_t key, uint16_t count);
+
+/**
  * Get metric name-key lookup table.
  *
  * @param names
-- 
1.8.3.1

             reply	other threads:[~2019-02-22  6:16 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22  6:16  =?gb18030?B?zfK/ob3c?= [this message]
2019-02-22 13:56 ` [dpdk-dev] [PATCH v2] " wanjunjie
2019-02-22 15:03   ` [dpdk-dev] [PATCH v3] " wanjunjie
2019-02-22 15:39     ` [dpdk-dev] [PATCH v4] " wanjunjie
2019-02-26 16:10       ` Remy Horton
2019-02-27 17:19       ` [dpdk-dev] [PATCH v5] " Junjie Wan
2019-02-28 11:53         ` Remy Horton
2019-02-28 13:28           ` Wan Junjie
2019-02-28 13:55             ` Remy Horton
2019-04-02  0:27         ` Thomas Monjalon
2019-04-02  0:27           ` Thomas Monjalon
2019-04-02  0:30           ` Thomas Monjalon
2019-04-02  0:30             ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_D09839CC57548580FB70E0A72744D61D3608@qq.com \
    --to=wan.junjie@foxmail.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).