+static int
+alloc_xstats_display_info(portid_t pi)
+{
+ uint64_t **ids_supp = &ports[pi].xstats_info.ids_supp;
+ uint64_t **prev_values = &ports[pi].xstats_info.prev_values;
+ uint64_t **curr_values = &ports[pi].xstats_info.curr_values;
+
+ if (xstats_display_num == 0)
+ return 0;
+
+ *ids_supp = calloc(xstats_display_num, sizeof(**ids_supp));
+ if (*ids_supp == NULL)
+ goto fail_ids_supp;
+
+ *prev_values = calloc(xstats_display_num,
+ sizeof(**prev_values));
+ if (*prev_values == NULL)
+ goto fail_prev_values;
+
+ *curr_values = calloc(xstats_display_num,
+ sizeof(**curr_values));
+ if (*curr_values == NULL)
+ goto fail_curr_values;
+
+ ports[pi].xstats_info.allocated = true;
+
+ return 0;
+
+fail_curr_values:
+ free(*prev_values);
+fail_prev_values:
+ free(*ids_supp);
+fail_ids_supp:
+ return -ENOMEM;
+}
+
+static void
+free_xstats_display_info(portid_t pi)
+{
+ if (!ports[pi].xstats_info.allocated)
+ return;
+ free(ports[pi].xstats_info.ids_supp);
+ free(ports[pi].xstats_info.prev_values);
+ free(ports[pi].xstats_info.curr_values);
+ ports[pi].xstats_info.allocated = false;
+}
+
+/** Fill helper structures for specified port to show extended statistics. */
+static void
+fill_xstats_display_info_for_port(portid_t pi)
+{
+ unsigned int stat, stat_supp;
+ const char *xstat_name;
+ struct rte_port *port;
+ uint64_t *ids_supp;
+ int rc;
+
+ if (xstats_display_num == 0)
+ return;
+
+ if (pi == (portid_t)RTE_PORT_ALL) {
+ fill_xstats_display_info();
+ return;
+ }
+
+ port = &ports[pi];
+ if (port->port_status != RTE_PORT_STARTED)
+ return;
+
+ if (!port->xstats_info.allocated && alloc_xstats_display_info(pi) != 0)
+ rte_exit(EXIT_FAILURE,
+ "Failed to allocate xstats display memory\n");
+
+ ids_supp = port->xstats_info.ids_supp;
+ for (stat = stat_supp = 0; stat < xstats_display_num; stat++) {
+ xstat_name = xstats_display[stat].name;
+ rc = rte_eth_xstats_get_id_by_name(pi, xstat_name,
+ ids_supp + stat_supp);
+ if (rc != 0) {
+ fprintf(stderr, "No xstat '%s' on port %u - skip it %u\n",
+ xstat_name, pi, stat);
+ continue;
+ }
+ stat_supp++;
+ }
+
+ port->xstats_info.ids_supp_sz = stat_supp;
+}
+
+/** Fill helper structures for all ports to show extended statistics. */
+static void
+fill_xstats_display_info(void)
+{
+ portid_t pi;
+
+ if (xstats_display_num == 0)
+ return;
+
+ RTE_ETH_FOREACH_DEV(pi)
+ fill_xstats_display_info_for_port(pi);
+}
+