Added command lat all stats 75/69475/3
authorXavier Simonart <xavier.simonart@intel.com>
Mon, 30 Dec 2019 22:49:52 +0000 (23:49 +0100)
committerXavier Simonart <xavier.simonart@intel.com>
Wed, 29 Jan 2020 11:31:40 +0000 (12:31 +0100)
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>
VNFs/DPPD-PROX/cmd_parser.c
VNFs/DPPD-PROX/display_latency_distr.c
VNFs/DPPD-PROX/handle_lat.h

index 3e71c56..0dd173f 100644 (file)
@@ -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},
index 9808a70..3e1cc38 100644 (file)
@@ -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;
                }
index da16465..a80afc9 100644 (file)
@@ -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