summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2019-12-30 23:49:52 +0100
committerXavier Simonart <xavier.simonart@intel.com>2020-01-29 12:31:40 +0100
commit2cd03b79c4415b5b300bc9f3dde7057e2d31b2a2 (patch)
tree4b8323595efc21ac5945efd70e7f4ba86e544de2
parent7ef348cff20a6d35fe36bb551e5b1aaa69eded1a (diff)
Added command lat all stats
lat all stats <core_id> <task_id> combines "lat stats" and "lat packets" within one command. This command returns: - One line in case the core_task parser fails. In that case the line will start with: "error: invalid syntax" - One set of lines for each core task: - if core/task is invalid, or not running lat mode, the line will contain (start with) "error...". this will be the only line for that core/task. - Otherwise the set of lines will be: - One line as returned by "lat stats". This line will be - One line starting with "error" in case of error, or - One line containing lat_min_usec, lat_max_usec, lat_avg_usec, tot_lat_min_usec, tot_lat_max_usec, last_tsc, rte_get_tsc_hz(), lcore_id, task_id - The return from lat packets i.e. - One line starting with "error" in case of error, or - 128 lines - one for each bucket - as returned by "lat packets" command This command is more useful then lat packets, as it contains the tsc - needed to see whether the sample is new or not. Change-Id: I04231aa7c5bd2d352ed6f94d40e88d3b411ce744 Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
-rw-r--r--VNFs/DPPD-PROX/cmd_parser.c307
-rw-r--r--VNFs/DPPD-PROX/display_latency_distr.c5
-rw-r--r--VNFs/DPPD-PROX/handle_lat.h3
3 files changed, 161 insertions, 154 deletions
diff --git a/VNFs/DPPD-PROX/cmd_parser.c b/VNFs/DPPD-PROX/cmd_parser.c
index 3e71c569..0dd173f3 100644
--- a/VNFs/DPPD-PROX/cmd_parser.c
+++ b/VNFs/DPPD-PROX/cmd_parser.c
@@ -1693,11 +1693,15 @@ static int parse_cmd_core_stats(const char *str, struct input *input)
return 0;
}
-static int parse_cmd_dp_core_stats(const char *str, struct input *input)
+typedef void (*parser_handler)(unsigned, unsigned, struct input *);
+static int handle_cores_tasks(const char *str, struct input *input, const char *mode_str, const char *mode_name, parser_handler f)
{
- unsigned lcores[RTE_MAX_LCORE], tasks[MAX_TASKS_PER_CORE], lcore_id, task_id, nb_cores, nb_tasks;
-
// This function either outputs a single line, in case of syntax error on the lists of cores and/or tasks
+ // or outputs (nb_cores * nb_tasks) lines, one line for each core/task pair:
+ // - if the core/task pair is invalid, the output line reports an error
+ // - otherwise, the output line provides the latency statistics for the core/task pair
+
+ unsigned lcores[RTE_MAX_LCORE], tasks[MAX_TASKS_PER_CORE], lcore_id, task_id, nb_cores, nb_tasks;
if (parse_cores_tasks(str, lcores, tasks, &nb_cores, &nb_tasks)) {
if (input->reply) {
char buf[128];
@@ -1707,9 +1711,6 @@ static int parse_cmd_dp_core_stats(const char *str, struct input *input)
return -1;
}
- // or outputs (nb_cores * nb_tasks) lines, one line for each core/task pair:
- // - if the core/task pair is invalid, the output line reports an error
- // - otherwise, the output line provides the dataplane statistics for the core/task pair
for (unsigned int i = 0; i < nb_cores; i++) {
for (unsigned int j = 0; j < nb_tasks; j++) {
lcore_id = lcores[i];
@@ -1724,122 +1725,174 @@ static int parse_cmd_dp_core_stats(const char *str, struct input *input)
}
continue;
}
- uint64_t tot_rx = stats_core_task_tot_rx(lcore_id, task_id);
- uint64_t tot_tx = stats_core_task_tot_tx(lcore_id, task_id);
- uint64_t tot_tx_fail = stats_core_task_tot_tx_fail(lcore_id, task_id);
- uint64_t tot_rx_non_dp = stats_core_task_tot_rx_non_dp(lcore_id, task_id);
- uint64_t tot_tx_non_dp = stats_core_task_tot_tx_non_dp(lcore_id, task_id);
- uint64_t tot_drop = stats_core_task_tot_drop(lcore_id, task_id);
- uint64_t last_tsc = stats_core_task_last_tsc(lcore_id, task_id);
-
- if (input->reply) {
- char buf[128];
- snprintf(buf, sizeof(buf),
- "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%u,%u\n",
- tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail, last_tsc, rte_get_tsc_hz(), lcore_id, task_id);
- input->reply(input, buf, strlen(buf));
- }
- else {
- plog_info("core: %u, task: %u, RX: %"PRIu64", TX: %"PRIu64", RX_NON_DP: %"PRIu64", TX_NON_DP: %"PRIu64", DROP: %"PRIu64", TX_FAIL: %"PRIu64"\n",
- lcore_id, task_id, tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail);
+ if ((mode_str) && (!task_is_mode(lcore_id, task_id, mode_str))) {
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf), "error: core %u task %u is not measuring %s\n", lcore_id, task_id, mode_name);
+ input->reply(input, buf, strlen(buf));
+ } else {
+ plog_info("error: core %u task %u is not measuring %s\n", lcore_id, task_id, mode_name);
+ }
+ continue;
}
+ f(lcore_id, task_id, input);
}
}
return 0;
}
-static int parse_cmd_lat_stats(const char *str, struct input *input)
+static void handle_dp_core_stats(unsigned lcore_id, unsigned task_id, struct input *input)
{
- unsigned lcores[RTE_MAX_LCORE], tasks[MAX_TASKS_PER_CORE], lcore_id, task_id, nb_cores, nb_tasks;
+ uint64_t tot_rx = stats_core_task_tot_rx(lcore_id, task_id);
+ uint64_t tot_tx = stats_core_task_tot_tx(lcore_id, task_id);
+ uint64_t tot_tx_fail = stats_core_task_tot_tx_fail(lcore_id, task_id);
+ uint64_t tot_rx_non_dp = stats_core_task_tot_rx_non_dp(lcore_id, task_id);
+ uint64_t tot_tx_non_dp = stats_core_task_tot_tx_non_dp(lcore_id, task_id);
+ uint64_t tot_drop = stats_core_task_tot_drop(lcore_id, task_id);
+ uint64_t last_tsc = stats_core_task_last_tsc(lcore_id, task_id);
- // This function either outputs a single line, in case of syntax error on the lists of cores and/or tasks
- if (parse_cores_tasks(str, lcores, tasks, &nb_cores, &nb_tasks)) {
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf),
+ "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%u,%u\n",
+ tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail, last_tsc, rte_get_tsc_hz(), lcore_id, task_id);
+ input->reply(input, buf, strlen(buf));
+ }
+ else {
+ plog_info("core: %u, task: %u, RX: %"PRIu64", TX: %"PRIu64", RX_NON_DP: %"PRIu64", TX_NON_DP: %"PRIu64", DROP: %"PRIu64", TX_FAIL: %"PRIu64"\n",
+ lcore_id, task_id, tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail);
+ }
+}
+
+static void handle_lat_stats(unsigned lcore_id, unsigned task_id, struct input *input)
+{
+ struct stats_latency *stats = stats_latency_find(lcore_id, task_id);
+ struct stats_latency *tot = stats_latency_tot_find(lcore_id, task_id);
+ if (!stats || !tot) {
if (input->reply) {
char buf[128];
- snprintf(buf, sizeof(buf), "error: invalid syntax\n");
+ snprintf(buf, sizeof(buf),
+ "error: core %u task %u stats = %p tot = %p\n",
+ lcore_id, task_id, stats, tot);
input->reply(input, buf, strlen(buf));
+ } else {
+ plog_info("error: core %u task %u stats = %p tot = %p\n",
+ lcore_id, task_id, stats, tot);
}
- return -1;
+ return;
}
- // or outputs (nb_cores * nb_tasks) lines, one line for each core/task pair:
- // - if the core/task pair is invalid, the output line reports an error
- // - otherwise, the output line provides the latency statistics for the core/task pair
- for (unsigned int i = 0; i < nb_cores; i++) {
- for (unsigned int j = 0; j < nb_tasks; j++) {
- lcore_id = lcores[i];
- task_id = tasks[j];
- if (core_task_is_valid(lcore_id, task_id) == 0) {
- if (input->reply) {
- char buf[128];
- snprintf(buf, sizeof(buf), "error: invalid core %u, task %u\n", lcore_id, task_id);
- input->reply(input, buf, strlen(buf));
- } else {
- plog_info("error: invalid core %u, task %u\n", lcore_id, task_id);
- }
- continue;
- }
- if (!task_is_mode(lcore_id, task_id, "lat")) {
- if (input->reply) {
- char buf[128];
- snprintf(buf, sizeof(buf), "error: core %u task %u is not measuring latency\n", lcore_id, task_id);
- input->reply(input, buf, strlen(buf));
- } else {
- plog_info("error: core %u task %u is not measuring latency\n", lcore_id, task_id);
- }
- continue;
- }
+ uint64_t last_tsc = stats_core_task_last_tsc(lcore_id, task_id);
+ uint64_t lat_min_usec = time_unit_to_usec(&stats->min.time);
+ uint64_t lat_max_usec = time_unit_to_usec(&stats->max.time);
+ uint64_t tot_lat_min_usec = time_unit_to_usec(&tot->min.time);
+ uint64_t tot_lat_max_usec = time_unit_to_usec(&tot->max.time);
+ uint64_t lat_avg_usec = time_unit_to_usec(&stats->avg.time);
- struct stats_latency *stats = stats_latency_find(lcore_id, task_id);
- struct stats_latency *tot = stats_latency_tot_find(lcore_id, task_id);
- if (!stats || !tot) {
- if (input->reply) {
- char buf[128];
- snprintf(buf, sizeof(buf),
- "error: core %u task %u stats = %p tot = %p\n",
- lcore_id, task_id, stats, tot);
- input->reply(input, buf, strlen(buf));
- } else {
- plog_info("error: core %u task %u stats = %p tot = %p\n",
- lcore_id, task_id, stats, tot);
- }
- continue;
- }
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf),
+ "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%u,%u\n",
+ lat_min_usec,
+ lat_max_usec,
+ lat_avg_usec,
+ tot_lat_min_usec,
+ tot_lat_max_usec,
+ last_tsc,
+ rte_get_tsc_hz(),
+ lcore_id,
+ task_id);
+ input->reply(input, buf, strlen(buf));
+ }
+ else {
+ plog_info("core: %u, task: %u, min: %"PRIu64", max: %"PRIu64", avg: %"PRIu64", min since reset: %"PRIu64", max since reset: %"PRIu64"\n",
+ lcore_id,
+ task_id,
+ lat_min_usec,
+ lat_max_usec,
+ lat_avg_usec,
+ tot_lat_min_usec,
+ tot_lat_max_usec);
+ }
+}
- uint64_t last_tsc = stats_core_task_last_tsc(lcore_id, task_id);
- uint64_t lat_min_usec = time_unit_to_usec(&stats->min.time);
- uint64_t lat_max_usec = time_unit_to_usec(&stats->max.time);
- uint64_t tot_lat_min_usec = time_unit_to_usec(&tot->min.time);
- uint64_t tot_lat_max_usec = time_unit_to_usec(&tot->max.time);
- uint64_t lat_avg_usec = time_unit_to_usec(&stats->avg.time);
+#ifdef LATENCY_HISTOGRAM
+static void handle_latency_histogram(unsigned lcore_id, unsigned task_id, struct input *input)
+{
+ uint64_t *buckets;
- if (input->reply) {
- char buf[128];
- snprintf(buf, sizeof(buf),
- "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%u,%u\n",
- lat_min_usec,
- lat_max_usec,
- lat_avg_usec,
- tot_lat_min_usec,
- tot_lat_max_usec,
- last_tsc,
- rte_get_tsc_hz(),
- lcore_id,
- task_id);
- input->reply(input, buf, strlen(buf));
- }
- else {
- plog_info("core: %u, task: %u, min: %"PRIu64", max: %"PRIu64", avg: %"PRIu64", min since reset: %"PRIu64", max since reset: %"PRIu64"\n",
- lcore_id,
- task_id,
- lat_min_usec,
- lat_max_usec,
- lat_avg_usec,
- tot_lat_min_usec,
- tot_lat_max_usec);
- }
+ stats_core_lat_histogram(lcore_id, task_id, &buckets);
+
+ if (buckets == NULL) {
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf), "error: unexpected NULL bucket\n");
+ input->reply(input, buf, strlen(buf));
}
+ return;
+ }
+
+ if (input->reply) {
+ char buf[4096] = {0};
+ for (size_t i = 0; i < LAT_BUCKET_COUNT; i++)
+ sprintf(buf+strlen(buf), "Bucket [%zu]: %"PRIu64"\n", i, buckets[i]);
+ input->reply(input, buf, strlen(buf));
+ }
+ else {
+ for (size_t i = 0; i < LAT_BUCKET_COUNT; i++)
+ if (buckets[i])
+ plog_info("Bucket [%zu]: %"PRIu64"\n", i, buckets[i]);
+ }
+}
+
+static void handle_stats_and_packets(unsigned lcore_id, unsigned task_id, struct input *input)
+{
+ handle_lat_stats(lcore_id, task_id, input);
+ handle_latency_histogram(lcore_id, task_id, input);
+}
+#endif
+
+static int parse_cmd_dp_core_stats(const char *str, struct input *input)
+{
+ handle_cores_tasks(str, input, NULL, NULL, handle_dp_core_stats);
+ return 0;
+}
+
+static int parse_cmd_lat_stats(const char *str, struct input *input)
+{
+ handle_cores_tasks(str, input, "lat", "latency", handle_lat_stats);
+ return 0;
+}
+
+static int parse_cmd_lat_packets(const char *str, struct input *input)
+{
+#ifdef LATENCY_HISTOGRAM
+ handle_cores_tasks(str, input, "lat", "latency", handle_latency_histogram);
+#else
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf), "error: invalid syntax (LATENCY_HISTOGRAM disabled)\n");
+ input->reply(input, buf, strlen(buf));
+ } else {
+ plog_info("LATENCY_HISTOGRAMS disabled\n");
}
+#endif
+ return 0;
+}
+
+static int parse_cmd_lat_stats_and_packets(const char *str, struct input *input)
+{
+#ifdef LATENCY_HISTOGRAM
+ handle_cores_tasks(str, input, "lat", "latency", handle_stats_and_packets);
+#else
+ if (input->reply) {
+ char buf[128];
+ snprintf(buf, sizeof(buf), "error: invalid syntax (LATENCY_HISTOGRAMS disabled)\n");
+ input->reply(input, buf, strlen(buf));
+ } else {
+ plog_info("LATENCY_HISTOGRAMS disabled\n");
+ }
+#endif
return 0;
}
@@ -1888,53 +1941,6 @@ static int parse_cmd_irq(const char *str, struct input *input)
return 0;
}
-static void task_lat_show_latency_histogram(uint8_t lcore_id, uint8_t task_id, struct input *input)
-{
-#ifdef LATENCY_HISTOGRAM
- uint64_t *buckets;
-
- stats_core_lat_histogram(lcore_id, task_id, &buckets);
-
- if (buckets == NULL)
- return;
-
- if (input->reply) {
- char buf[4096] = {0};
- for (size_t i = 0; i < 128; i++)
- sprintf(buf+strlen(buf), "Bucket [%zu]: %"PRIu64"\n", i, buckets[i]);
- input->reply(input, buf, strlen(buf));
- }
- else {
- for (size_t i = 0; i < 128; i++)
- if (buckets[i])
- plog_info("Bucket [%zu]: %"PRIu64"\n", i, buckets[i]);
- }
-#else
- plog_info("LATENCY_HISTOGRAM disabled\n");
-#endif
-}
-
-static int parse_cmd_lat_packets(const char *str, struct input *input)
-{
- unsigned lcores[RTE_MAX_LCORE], lcore_id, task_id, nb_cores;
-
- if (parse_cores_task(str, lcores, &task_id, &nb_cores))
- return -1;
-
- if (cores_task_are_valid(lcores, task_id, nb_cores)) {
- for (unsigned int i = 0; i < nb_cores; i++) {
- lcore_id = lcores[i];
- if (!task_is_mode(lcore_id, task_id, "lat")) {
- plog_err("Core %u task %u is not measuring latency\n", lcore_id, task_id);
- }
- else {
- task_lat_show_latency_histogram(lcore_id, task_id, input);
- }
- }
- }
- return 0;
-}
-
static int parse_cmd_cgnat_public_hash(const char *str, struct input *input)
{
unsigned lcores[RTE_MAX_LCORE], lcore_id, task_id, nb_cores;
@@ -2161,6 +2167,7 @@ static struct cmd_str cmd_strings[] = {
{"irq stats", "<core id> <task id>", "Print irq related infos", parse_cmd_irq},
{"show irq buckets", "<core id> <task id>", "Print irq buckets", parse_cmd_show_irq_buckets},
{"lat packets", "<core id> <task id>", "Print the latency for each of the last set of packets", parse_cmd_lat_packets},
+ {"lat all stats", "<core id> <task id>", "Print the latency for each of the last set of packets as well as latency distribution", parse_cmd_lat_stats_and_packets},
{"accuracy limit", "<core id> <task id> <nsec>", "Only consider latency of packets that were measured with an error no more than <nsec>", parse_cmd_accuracy},
{"core stats", "<core id> <task id>", "Print rx/tx/drop for task <task id> running on core <core id>", parse_cmd_core_stats},
{"dp core stats", "<core id> <task id>", "Print rx/tx/non_dp_rx/non_dp_tx/drop for task <task id> running on core <core id>", parse_cmd_dp_core_stats},
diff --git a/VNFs/DPPD-PROX/display_latency_distr.c b/VNFs/DPPD-PROX/display_latency_distr.c
index 9808a702..3e1cc38a 100644
--- a/VNFs/DPPD-PROX/display_latency_distr.c
+++ b/VNFs/DPPD-PROX/display_latency_distr.c
@@ -35,7 +35,7 @@ static uint32_t group_size = 9; //LAT_BUCKET_COUNT / global_nb_buckets_displayed
static void display_latency_distr_draw_frame(struct screen_state *state)
{
- uint32_t n_tasks = stats_get_n_latency();
+ uint32_t n_tasks = stats_get_n_latency();
struct lcore_cfg *lconf = NULL;
struct task_args *targ;
char name[32];
@@ -166,9 +166,6 @@ static void display_latency_distr_draw_stats(struct screen_state *state)
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;
}
diff --git a/VNFs/DPPD-PROX/handle_lat.h b/VNFs/DPPD-PROX/handle_lat.h
index da164656..a80afc90 100644
--- a/VNFs/DPPD-PROX/handle_lat.h
+++ b/VNFs/DPPD-PROX/handle_lat.h
@@ -29,6 +29,9 @@
// packet N is received (re-ordering) resulting in accuracy being unused
// 8192 packets is equivalent to 550 micro-seconds at 10Gbps for 64 bytes packets
#define ACCURACY_WINDOW 8192
+#define LAT_BUCKET_COUNT 128
+
+#define LAT_BUCKET_COUNT 128
#define LAT_BUCKET_COUNT 128