app/testpmd: add option to display extended statistics
[dpdk.git] / app / test-pmd / parameters.c
index b69897e..2e67723 100644 (file)
@@ -61,6 +61,10 @@ usage(char* progname)
               "(only if interactive is disabled).\n");
        printf("  --stats-period=PERIOD: statistics will be shown "
               "every PERIOD seconds (only if interactive is disabled).\n");
+       printf("  --display-xstats xstat_name1[,...]: comma-separated list of "
+              "extended statistics to show. Used with --stats-period "
+              "specified or interactive commands that show Rx/Tx statistics "
+              "(i.e. 'show port stats').\n");
        printf("  --nb-cores=N: set the number of forwarding cores "
               "(1 <= N <= %d).\n", nb_lcores);
        printf("  --nb-ports=N: set the number of forwarding ports "
@@ -473,6 +477,72 @@ parse_event_printing_config(const char *optarg, int enable)
        return 0;
 }
 
+static int
+parse_xstats_list(const char *in_str, struct rte_eth_xstat_name **xstats,
+                 unsigned int *xstats_num)
+{
+       int max_names_nb, names_nb, nonempty_names_nb;
+       int name, nonempty_name;
+       int stringlen;
+       char **names;
+       char *str;
+       int ret;
+       int i;
+
+       names = NULL;
+       str = strdup(in_str);
+       if (str == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       stringlen = strlen(str);
+
+       for (i = 0, max_names_nb = 1; str[i] != '\0'; i++) {
+               if (str[i] == ',')
+                       max_names_nb++;
+       }
+
+       names = calloc(max_names_nb, sizeof(*names));
+       if (names == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       names_nb = rte_strsplit(str, stringlen, names, max_names_nb, ',');
+       if (names_nb < 0) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       nonempty_names_nb = 0;
+       for (i = 0; i < names_nb; i++) {
+               if (names[i][0] == '\0')
+                       continue;
+               nonempty_names_nb++;
+       }
+       *xstats = calloc(nonempty_names_nb, sizeof(**xstats));
+       if (*xstats == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       for (name = nonempty_name = 0; name < names_nb; name++) {
+               if (names[name][0] == '\0')
+                       continue;
+               rte_strscpy((*xstats)[nonempty_name].name, names[name],
+                           sizeof((*xstats)[nonempty_name].name));
+               nonempty_name++;
+       }
+
+       *xstats_num = nonempty_names_nb;
+       ret = 0;
+
+out:
+       free(names);
+       free(str);
+       return ret;
+}
+
 static int
 parse_link_speed(int n)
 {
@@ -539,6 +609,7 @@ launch_args_parse(int argc, char** argv)
 #endif
                { "tx-first",                   0, 0, 0 },
                { "stats-period",               1, 0, 0 },
+               { "display-xstats",             1, 0, 0 },
                { "nb-cores",                   1, 0, 0 },
                { "nb-ports",                   1, 0, 0 },
                { "coremask",                   1, 0, 0 },
@@ -699,6 +770,16 @@ launch_args_parse(int argc, char** argv)
                                stats_period = n;
                                break;
                        }
+                       if (!strcmp(lgopts[opt_idx].name, "display-xstats")) {
+                               char rc;
+
+                               rc = parse_xstats_list(optarg, &xstats_display,
+                                                      &xstats_display_num);
+                               if (rc != 0)
+                                       rte_exit(EXIT_FAILURE,
+                                                "Failed to parse display-xstats argument: %d\n",
+                                                rc);
+                       }
                        if (!strcmp(lgopts[opt_idx].name,
                                    "eth-peers-configfile")) {
                                if (init_peer_eth_addrs(optarg) != 0)