Support multiple tasks in "dp core stats" command 52/67952/3
authorXavier Simonart <xavier.simonart@intel.com>
Wed, 15 May 2019 10:36:21 +0000 (12:36 +0200)
committerPatrice Buriez <patrice.buriez@intel.com>
Fri, 14 Jun 2019 17:23:40 +0000 (19:23 +0200)
The "dp core stats" command supported, as other commands, multiple cores
but not multiple tasks. It now supports both (e.g. dp core stats 1-2 0-1).
This is necessary so that users can collect all statistics from PROX in one
command line.

It will return similar information on the screen or through the socket:
- if the syntax is wrong (e.g. missing task, too many cores or tasks, ...)
  => an error message is printed on the screen, and the single error line
     "error: invalid syntax" is returned through the socket
- if the syntax is correct
  => one line is printed or returned for each core/task pair
     => if the core/task pair is invalid, the line reports an error
     => otherwise, the line provides dataplane statistics for the core/task pair,
        with the core_id and task_id added, either at the end of the line returned
        through the socket, or at the beginning of the line printed on the screen.

This means a change in behaviour when using the socket: before, when an error
happened (e.g. bad task), then nothing was returned which made it difficult for
the script to catch the syntax error.

Similar behaviour could/should be implemented for other commands.
However, care must be taken as some scripts like NSB might count the number
of lines within the output, or the number of items within the line.
This should not be an issue for dp core stats as NSB does not use it, and other
PROX scripts do not count the number of items and will be adjusted to count the
number of lines.

Change-Id: I582a671ae3d2f6493f791e80fc28e70f8e3a38d1
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
Signed-off-by: Patrice Buriez <patrice.buriez@intel.com>
VNFs/DPPD-PROX/cmd_parser.c
VNFs/DPPD-PROX/parse_utils.c

index 46cb1eb..8d0ce50 100644 (file)
@@ -1670,14 +1670,35 @@ static int parse_cmd_core_stats(const char *str, struct input *input)
 
 static int parse_cmd_dp_core_stats(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))
+       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
+       if (parse_cores_tasks(str, lcores, tasks, &nb_cores, &nb_tasks)) {
+               if (input->reply) {
+                       char buf[128];
+                       snprintf(buf, sizeof(buf), "error: invalid syntax\n");
+                       input->reply(input, buf, strlen(buf));
+               }
                return -1;
+       }
 
-       if (cores_task_are_valid(lcores, task_id, nb_cores)) {
-               for (unsigned int i = 0; i < nb_cores; i++) {
+       // 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];
+                       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;
+                       }
                        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);
@@ -1689,13 +1710,13 @@ static int parse_cmd_dp_core_stats(const char *str, struct input *input)
                        if (input->reply) {
                                char buf[128];
                                snprintf(buf, sizeof(buf),
-                                       "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64"\n",
-                                       tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail, last_tsc, rte_get_tsc_hz());
+                                       "%"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("RX: %"PRIu64", TX: %"PRIu64", RX_NON_DP: %"PRIu64", TX_NON_DP: %"PRIu64", DROP: %"PRIu64", TX_FAIL: %"PRIu64"\n",
-                                       tot_rx, tot_tx, tot_rx_non_dp, tot_tx_non_dp, tot_drop, tot_tx_fail);
+                               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);
                        }
                }
        }
index 32db5de..6653ca6 100644 (file)
@@ -897,7 +897,7 @@ int parse_list_set(uint32_t *list, const char *str2, uint32_t max_list)
                                effective_core = cur_core;
 
                        if (list_count >= max_list) {
-                               set_errf("Too many elements in list\n");
+                               set_errf("Too many elements in list");
                                return -1;
                        }
                        list[list_count++] = effective_core;