@@ -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)
@@ -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);
@@ -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