summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VNFs/DPPD-PROX/Makefile6
-rw-r--r--VNFs/DPPD-PROX/cmd_parser.c4
-rw-r--r--VNFs/DPPD-PROX/display.c11
-rw-r--r--VNFs/DPPD-PROX/display.h6
-rw-r--r--VNFs/DPPD-PROX/display_latency_distr.c193
-rw-r--r--VNFs/DPPD-PROX/display_latency_distr.h23
-rw-r--r--VNFs/DPPD-PROX/handle_lat.c17
-rw-r--r--VNFs/DPPD-PROX/handle_lat.h7
-rw-r--r--VNFs/DPPD-PROX/stats_latency.c24
-rw-r--r--VNFs/DPPD-PROX/stats_latency.h5
10 files changed, 278 insertions, 18 deletions
diff --git a/VNFs/DPPD-PROX/Makefile b/VNFs/DPPD-PROX/Makefile
index bc11f5d8..f8bde421 100644
--- a/VNFs/DPPD-PROX/Makefile
+++ b/VNFs/DPPD-PROX/Makefile
@@ -1,5 +1,5 @@
##
-## Copyright (c) 2010-2017 Intel Corporation
+## Copyright (c) 2010-2019 Intel Corporation
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
@@ -133,7 +133,7 @@ CFLAGS += -DPROX_PREFETCH_OFFSET=2
#CFLAGS += -DASSERT
#CFLAGS += -DENABLE_EXTRA_USER_STATISTICS
CFLAGS += -DLATENCY_PER_PACKET
-CFLAGS += -DLATENCY_DETAILS
+CFLAGS += -DLATENCY_HISTOGRAM
CFLAGS += -DGRE_TP
CFLAGS += -std=gnu99
CFLAGS += -D_GNU_SOURCE # for PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
@@ -204,7 +204,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += thread_pipeline.c
SRCS-y += prox_args.c prox_cfg.c prox_cksum.c prox_port_cfg.c
SRCS-y += cfgfile.c clock.c commands.c cqm.c msr.c defaults.c
-SRCS-y += display.c display_latency.c display_mempools.c
+SRCS-y += display.c display_latency.c display_latency_distr.c display_mempools.c
SRCS-y += display_ports.c display_rings.c display_priority.c display_pkt_len.c display_l4gen.c display_tasks.c display_irq.c
SRCS-y += log.c hash_utils.c main.c parse_utils.c file_utils.c
SRCS-y += run.c input_conn.c input_curses.c
diff --git a/VNFs/DPPD-PROX/cmd_parser.c b/VNFs/DPPD-PROX/cmd_parser.c
index a8fe3a0a..3e71c569 100644
--- a/VNFs/DPPD-PROX/cmd_parser.c
+++ b/VNFs/DPPD-PROX/cmd_parser.c
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -1910,7 +1910,7 @@ static void task_lat_show_latency_histogram(uint8_t lcore_id, uint8_t task_id, s
plog_info("Bucket [%zu]: %"PRIu64"\n", i, buckets[i]);
}
#else
- plog_info("LATENCY_DETAILS disabled\n");
+ plog_info("LATENCY_HISTOGRAM disabled\n");
#endif
}
diff --git a/VNFs/DPPD-PROX/display.c b/VNFs/DPPD-PROX/display.c
index d7421e85..e1b8d8d2 100644
--- a/VNFs/DPPD-PROX/display.c
+++ b/VNFs/DPPD-PROX/display.c
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
#include "display_ports.h"
#include "display_priority.h"
#include "display_irq.h"
+#include "display_latency_distr.h"
#include "display_rings.h"
#include "display_pkt_len.h"
#include "display_l4gen.h"
@@ -292,6 +293,9 @@ static void display_init_screens(void)
display_add_screen(display_ports());
display_add_screen(display_mempools());
display_add_screen(display_latency());
+#ifdef LATENCY_HISTOGRAM
+ display_add_screen(display_latency_distr());
+#endif
display_add_screen(display_rings());
display_add_screen(display_l4gen());
display_add_screen(display_pkt_len());
@@ -917,6 +921,11 @@ void display_refresh(void)
stats_display_layout(1);
}
+void display_renew(void)
+{
+ stats_display_layout(0);
+}
+
void display_stats(void)
{
display_lock();
diff --git a/VNFs/DPPD-PROX/display.h b/VNFs/DPPD-PROX/display.h
index 4b517546..4c9f9ba7 100644
--- a/VNFs/DPPD-PROX/display.h
+++ b/VNFs/DPPD-PROX/display.h
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
#ifndef _DISPLAY_H_
#define _DISPLAY_H_
+#define PROX_MAX_COLS 32
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
@@ -33,7 +34,7 @@ struct display_column {
};
struct display_table {
- struct display_column cols[16];
+ struct display_column cols[PROX_MAX_COLS];
char title[32];
int n_cols;
int offset;
@@ -86,6 +87,7 @@ void display_init(void);
void display_end(void);
void display_stats(void);
void display_refresh(void);
+void display_renew(void);
void display_print(const char *str);
void display_cmd(const char *cmd, int cmd_len, int cursor_pos);
void display_screen(unsigned screen_id);
diff --git a/VNFs/DPPD-PROX/display_latency_distr.c b/VNFs/DPPD-PROX/display_latency_distr.c
new file mode 100644
index 00000000..9808a702
--- /dev/null
+++ b/VNFs/DPPD-PROX/display_latency_distr.c
@@ -0,0 +1,193 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <math.h>
+#include "handle_lat.h"
+#include "display_latency_distr.h"
+#include "stats_latency.h"
+#include "display.h"
+#include "lconf.h"
+
+static struct display_page display_page_latency_distr;
+static struct display_column *stats_latency_distr[LAT_BUCKET_COUNT];
+static struct display_column *stats_max;
+static struct display_column *core_col;
+static struct display_column *name_col;
+static uint32_t global_min_bucket_id = 0, global_max_bucket_id = LAT_BUCKET_COUNT - 1;
+static const uint16_t global_nb_buckets_displayed = 15;
+static uint32_t group_size = 9; //LAT_BUCKET_COUNT / global_nb_buckets_displayed;
+
+#define UNIT_INT(i) (((i) * bucket_unit_nsec)/1000)
+#define UNIT_FRACT(i) ((((i) * bucket_unit_nsec) % 1000) / 100)
+
+static void display_latency_distr_draw_frame(struct screen_state *state)
+{
+ uint32_t n_tasks = stats_get_n_latency();
+ struct lcore_cfg *lconf = NULL;
+ struct task_args *targ;
+ char name[32];
+ char *ptr;
+
+ display_page_init(&display_page_latency_distr);
+
+ struct display_table *core_name = display_page_add_table(&display_page_latency_distr);
+
+ display_table_init(core_name, "Core/task");
+ core_col = display_table_add_col(core_name);
+ name_col = display_table_add_col(core_name);
+ display_column_init(core_col, "Nb", 4);
+ display_column_init(name_col, "Name", 5);
+
+ uint32_t bucket_size = stats_get_latency_bucket_size();
+ struct display_table *stats = display_page_add_table(&display_page_latency_distr);
+ uint32_t bucket_unit_nsec = 1000000000 / (rte_get_tsc_hz() >> bucket_size);
+ if (state->toggle == 0) {
+ display_table_init(stats, "Statistics per second");
+ } else {
+ display_table_init(stats, "Total statistics");
+ }
+ char title[64];
+ stats_max = display_table_add_col(stats);
+ snprintf(title, sizeof(title), " MAXIMUM(mic)");
+ display_column_init(stats_max, title, 11);
+ plog_info("Bucket unit is %d nsec, bucket size is %d, freq is %ld\n", bucket_unit_nsec, bucket_size, rte_get_tsc_hz());
+
+ uint32_t i = global_min_bucket_id, first = i, k = 0;
+ while ((i < LAT_BUCKET_COUNT) && (i <= global_max_bucket_id)) {
+ stats_latency_distr[k] = display_table_add_col(stats);
+ if (i < LAT_BUCKET_COUNT - group_size) {
+ snprintf(title, sizeof(title), "%d.%01d-%d.%01d", UNIT_INT(i), UNIT_FRACT(i), UNIT_INT(i + group_size), UNIT_FRACT(i + group_size));
+ } else {
+ snprintf(title, sizeof(title), "> %d.%01d", UNIT_INT(i), UNIT_FRACT(i));
+ }
+ display_column_init(stats_latency_distr[k++], title, 9);
+ i += group_size;
+ }
+ display_page_draw_frame(&display_page_latency_distr, n_tasks);
+
+ uint32_t count = 0;
+ lconf = NULL;
+ while (core_targ_next(&lconf, &targ, 0) == 0) {
+ if (strcmp(targ->task_init->mode_str, "lat") == 0) {
+ display_column_print_core_task(core_col, count, lconf, targ);
+ if (targ->id == 0)
+ display_column_print(name_col, count, "%s", lconf->name);
+ count++;
+ }
+ }
+}
+
+static void display_latency_distr_draw_stats(struct screen_state *state)
+{
+ const uint32_t n_latency = stats_get_n_latency();
+ uint64_t *bucket;
+ uint32_t bucket_id = 0, min_bucket_id = LAT_BUCKET_COUNT - 1, max_bucket_id = 0;
+ struct time_unit tu;
+
+ for (uint32_t count = 0; count < n_latency; ++count) {
+ if (state->toggle == 0)
+ tu = stats_latency_get(count)->max.time;
+ else
+ tu = stats_latency_tot_get(count)->max.time;
+ display_column_print(stats_max, count, "%9lu.%03lu", tu.sec * 1000000 + tu.nsec / 1000, tu.nsec % 1000);
+ }
+
+ // Calculate min_bucket_id: id of 1st bucket with data for any tasks
+ // Calculate max_bucket_id: id of last bucket with data for any tasks
+ for (uint i = 0; i < LAT_BUCKET_COUNT; ++i) {
+ for (uint32_t count = 0; count < n_latency; ++count) {
+ if (state->toggle == 0)
+ bucket = stats_latency_get_bucket(count);
+ else
+ bucket = stats_latency_get_tot_bucket(count);
+ if (bucket[i] != 0) {
+ min_bucket_id = i;
+ break;
+ }
+ }
+ if (min_bucket_id != LAT_BUCKET_COUNT - 1)
+ break;
+ }
+
+ for (uint i = LAT_BUCKET_COUNT; i > 0; i--) {
+ for (uint32_t count = 0; count < n_latency; ++count) {
+ if (state->toggle == 0)
+ bucket = stats_latency_get_bucket(count);
+ else
+ bucket = stats_latency_get_tot_bucket(count);
+ if (bucket[i - 1] != 0) {
+ max_bucket_id = i - 1;
+ break;
+ }
+ }
+ if (max_bucket_id)
+ break;
+ }
+
+ if (max_bucket_id - min_bucket_id + 1 < global_nb_buckets_displayed) {
+ max_bucket_id = global_nb_buckets_displayed + min_bucket_id - 1;
+ }
+
+ if ((global_min_bucket_id != min_bucket_id) || (global_max_bucket_id != max_bucket_id)) {
+ global_min_bucket_id = min_bucket_id;
+ global_max_bucket_id = max_bucket_id;
+ // Calculate how many buckets must be grouped together
+ if (max_bucket_id - min_bucket_id + 1 > global_nb_buckets_displayed)
+ group_size = ceil(1.0 * (max_bucket_id - min_bucket_id + 1) / global_nb_buckets_displayed);
+ else
+ group_size = 1;
+ display_latency_distr_draw_frame(state);
+ display_renew();
+ plog_info("min_bucket_id = %d, max_bucket_id = %d\n", min_bucket_id, max_bucket_id);
+ }
+
+ for (uint32_t count = 0; count < n_latency; ++count) {
+ if (state->toggle == 0)
+ bucket = stats_latency_get_bucket(count);
+ else
+ bucket = stats_latency_get_tot_bucket(count);
+ uint32_t i = min_bucket_id, k = 0;
+ uint64_t nb = 0;
+ while ((i < LAT_BUCKET_COUNT) && (i <= global_max_bucket_id)){
+ for (uint32_t j = 0; j <= group_size; j++)
+ if (i + j < LAT_BUCKET_COUNT)
+ nb += bucket[i+j];
+ display_column_print(stats_latency_distr[k++], count, "%9lu", nb);
+ if ((nb == 16) || (nb == 48))
+ for (uint32_t j = 0; j <= group_size; j++)
+ plog_info("id %d: %ld\n", i+j, bucket[i+j]);
+ nb = 0;
+ i += group_size;
+ }
+ }
+}
+
+static int display_latency_distr_get_height(void)
+{
+ return stats_get_n_latency();
+}
+
+static struct display_screen display_screen_latency_distr = {
+ .draw_frame = display_latency_distr_draw_frame,
+ .draw_stats = display_latency_distr_draw_stats,
+ .get_height = display_latency_distr_get_height,
+ .title = "latency_distr",
+};
+
+struct display_screen *display_latency_distr(void)
+{
+ return &display_screen_latency_distr;
+}
diff --git a/VNFs/DPPD-PROX/display_latency_distr.h b/VNFs/DPPD-PROX/display_latency_distr.h
new file mode 100644
index 00000000..d22f16a4
--- /dev/null
+++ b/VNFs/DPPD-PROX/display_latency_distr.h
@@ -0,0 +1,23 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#ifndef DISPLAY_LATENCY_DISTR_H
+#define DISPLAY_LATENCY_DISTR_H
+
+struct display_screen;
+struct display_screen *display_latency_distr(void);
+
+#endif /* DISPLAY_LATENCY_DISTR_H */
diff --git a/VNFs/DPPD-PROX/handle_lat.c b/VNFs/DPPD-PROX/handle_lat.c
index a82e74ad..ef4da319 100644
--- a/VNFs/DPPD-PROX/handle_lat.c
+++ b/VNFs/DPPD-PROX/handle_lat.c
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@
#include "prox_shared.h"
#include "prox_port_cfg.h"
-#define DEFAULT_BUCKET_SIZE 10
+#define DEFAULT_BUCKET_SIZE 11
#define ACCURACY_BUFFER_SIZE (2 * ACCURACY_WINDOW)
struct lat_info {
@@ -60,7 +60,7 @@ struct delayed_latency_entry {
uint32_t packet_id;
uint8_t generator_id;
uint64_t pkt_rx_time;
- uint64_t pkt_tx_time;
+ uint64_t pkt_tx_time; // Time written into packets by gen. Unit is TSC >> LATENCY_ACCURACY
uint64_t rx_time_err;
};
@@ -128,6 +128,11 @@ static uint32_t diff_time(uint32_t rx_time, uint32_t tx_time)
return rx_time - tx_time;
}
+uint32_t task_lat_get_latency_bucket_size(struct task_lat *task)
+{
+ return task->lat_test->bucket_size;
+}
+
struct lat_test *task_lat_get_latency_meassurement(struct task_lat *task)
{
if (task->use_lt == task->using_lt)
@@ -453,7 +458,7 @@ static void lat_test_histogram_add(struct lat_test *lat_test, uint64_t lat_tsc)
uint64_t bucket_id = (lat_tsc >> lat_test->bucket_size);
size_t bucket_count = sizeof(lat_test->buckets)/sizeof(lat_test->buckets[0]);
- bucket_id = bucket_id < bucket_count? bucket_id : bucket_count;
+ bucket_id = bucket_id < bucket_count? bucket_id : (bucket_count - 1);
lat_test->buckets[bucket_id]++;
}
@@ -776,8 +781,8 @@ static void init_task_lat(struct task_base *tbase, struct task_args *targ)
task->lt[0].min_lat = -1;
task->lt[1].min_lat = -1;
- task->lt[0].bucket_size = targ->bucket_size - LATENCY_ACCURACY;
- task->lt[1].bucket_size = targ->bucket_size - LATENCY_ACCURACY;
+ task->lt[0].bucket_size = targ->bucket_size;
+ task->lt[1].bucket_size = targ->bucket_size;
if (task->unique_id_pos) {
task_lat_init_eld(task, socket_id);
task_lat_reset_eld(task);
diff --git a/VNFs/DPPD-PROX/handle_lat.h b/VNFs/DPPD-PROX/handle_lat.h
index 46f5e7d4..da164656 100644
--- a/VNFs/DPPD-PROX/handle_lat.h
+++ b/VNFs/DPPD-PROX/handle_lat.h
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -30,6 +30,8 @@
// 8192 packets is equivalent to 550 micro-seconds at 10Gbps for 64 bytes packets
#define ACCURACY_WINDOW 8192
+#define LAT_BUCKET_COUNT 128
+
struct lat_test {
uint64_t tot_all_pkts;
uint64_t tot_pkts;
@@ -44,7 +46,7 @@ struct lat_test {
uint64_t tot_lat_error;
unsigned __int128 var_lat_error;
- uint64_t buckets[128];
+ uint64_t buckets[LAT_BUCKET_COUNT];
uint64_t bucket_size;
uint64_t lost_packets;
};
@@ -186,6 +188,7 @@ static void lat_test_copy(struct lat_test *dst, struct lat_test *src)
struct task_lat;
struct lat_test *task_lat_get_latency_meassurement(struct task_lat *task);
+uint32_t task_lat_get_latency_bucket_size(struct task_lat *task);
void task_lat_use_other_latency_meassurement(struct task_lat *task);
void task_lat_set_accuracy_limit(struct task_lat *task, uint32_t accuracy_limit_nsec);
diff --git a/VNFs/DPPD-PROX/stats_latency.c b/VNFs/DPPD-PROX/stats_latency.c
index 7db53f20..58bad6fa 100644
--- a/VNFs/DPPD-PROX/stats_latency.c
+++ b/VNFs/DPPD-PROX/stats_latency.c
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
struct stats_latency_manager_entry {
struct task_lat *task;
+ uint32_t bucket_size;
uint8_t lcore_id;
uint8_t task_id;
struct lat_test lat_test;
@@ -32,6 +33,7 @@ struct stats_latency_manager_entry {
struct stats_latency_manager {
uint16_t n_latency;
+ uint32_t bucket_size;
struct stats_latency_manager_entry entries[0]; /* copy of stats when running update stats. */
};
@@ -48,6 +50,11 @@ int stats_get_n_latency(void)
return slm->n_latency;
}
+int stats_get_latency_bucket_size(void)
+{
+ return slm->bucket_size;
+}
+
uint32_t stats_latency_get_core_id(uint32_t i)
{
return slm->entries[i].lcore_id;
@@ -63,6 +70,16 @@ struct stats_latency *stats_latency_get(uint32_t i)
return &slm->entries[i].stats;
}
+uint64_t *stats_latency_get_bucket(uint32_t i)
+{
+ return slm->entries[i].lat_test.buckets;
+}
+
+uint64_t *stats_latency_get_tot_bucket(uint32_t i)
+{
+ return slm->entries[i].tot_lat_test.buckets;
+}
+
struct stats_latency *stats_latency_tot_get(uint32_t i)
{
return &slm->entries[i].tot;
@@ -140,9 +157,14 @@ static void stats_latency_add_task(struct lcore_cfg *lconf, struct task_args *ta
struct stats_latency_manager_entry *new_entry = &slm->entries[slm->n_latency];
new_entry->task = (struct task_lat *)targ->tbase;
+ new_entry->bucket_size = task_lat_get_latency_bucket_size(new_entry->task);
new_entry->lcore_id = lconf->id;
new_entry->task_id = targ->id;
new_entry->tot_lat_test.min_lat = -1;
+ if (slm->bucket_size == 0)
+ slm->bucket_size = new_entry->bucket_size;
+ else if (slm->bucket_size != new_entry->bucket_size)
+ plog_err("Latency bucket size does not support different bucket sizes per task - using bucket size from first task (%d)\n", slm->bucket_size);
slm->n_latency++;
}
diff --git a/VNFs/DPPD-PROX/stats_latency.h b/VNFs/DPPD-PROX/stats_latency.h
index 83cd4a18..32f3ba34 100644
--- a/VNFs/DPPD-PROX/stats_latency.h
+++ b/VNFs/DPPD-PROX/stats_latency.h
@@ -1,5 +1,5 @@
/*
-// Copyright (c) 2010-2017 Intel Corporation
+// Copyright (c) 2010-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -36,6 +36,8 @@ struct stats_latency {
uint32_t stats_latency_get_core_id(uint32_t i);
uint32_t stats_latency_get_task_id(uint32_t i);
struct stats_latency *stats_latency_get(uint32_t i);
+uint64_t *stats_latency_get_bucket(uint32_t i);
+uint64_t *stats_latency_get_tot_bucket(uint32_t i);
struct stats_latency *stats_latency_find(uint32_t lcore_id, uint32_t task_id);
struct stats_latency *stats_latency_tot_get(uint32_t i);
@@ -46,6 +48,7 @@ void stats_latency_update(void);
void stats_latency_reset(void);
int stats_get_n_latency(void);
+int stats_get_latency_bucket_size(void);
#ifdef LATENCY_HISTOGRAM
void stats_core_lat_histogram(uint8_t lcore_id, uint8_t task_id, uint64_t **buckets);