app/testpmd: add stats per queue

Signed-off-by: Intel
This commit is contained in:
Intel 2012-12-20 00:00:00 +01:00 committed by Thomas Monjalon
parent 84ac1559c4
commit ed30d9b691
5 changed files with 348 additions and 12 deletions

View File

@ -100,8 +100,8 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
cmdline_printf(cl,
"Display informations:\n"
"---------------------\n"
"- show port info|stats|fdir X|all\n"
" Diplays information or stats on port X, or all\n"
"- show port info|stats|fdir|stat_qmap X|all\n"
" Diplays information or stats or stats queue mapping on port X, or all\n"
"- clear port stats X|all\n"
" Clear stats for port X, or all\n"
"- show config rxtx|cores|fwd\n"
@ -175,6 +175,9 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
" Set bit field value of a port register\n"
"- write regbit port_id reg_off bit_x value\n"
" Set bit value of a port register\n"
"- set stat_qmap tx|rx port_id queue_id qmapping\n"
" Set statistics mapping (qmapping 0..15) for tx|rx queue_id on port_id\n"
" e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2 on port 0 to mapping 5\n"
"\n");
cmdline_printf(cl,
"Control forwarding:\n"
@ -1631,6 +1634,9 @@ static void cmd_showportall_parsed(void *parsed_result,
else if (!strcmp(res->what, "fdir"))
for (i = 0; i < nb_ports; i++)
fdir_get_infos(i);
else if (!strcmp(res->what, "stat_qmap"))
for (i = 0; i < nb_ports; i++)
nic_stats_mapping_display(i);
}
cmdline_parse_token_string_t cmd_showportall_show =
@ -1640,13 +1646,13 @@ cmdline_parse_token_string_t cmd_showportall_port =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
cmdline_parse_token_string_t cmd_showportall_what =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
"info#stats#fdir");
"info#stats#fdir#stat_qmap");
cmdline_parse_token_string_t cmd_showportall_all =
TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
cmdline_parse_inst_t cmd_showportall = {
.f = cmd_showportall_parsed,
.data = NULL,
.help_str = "show|clear port info|stats|fdir all",
.help_str = "show|clear port info|stats|fdir|stat_qmap all",
.tokens = {
(void *)&cmd_showportall_show,
(void *)&cmd_showportall_port,
@ -1678,6 +1684,8 @@ static void cmd_showport_parsed(void *parsed_result,
nic_stats_display(res->portnum);
else if (!strcmp(res->what, "fdir"))
fdir_get_infos(res->portnum);
else if (!strcmp(res->what, "stat_qmap"))
nic_stats_mapping_display(res->portnum);
}
cmdline_parse_token_string_t cmd_showport_show =
@ -1687,14 +1695,14 @@ cmdline_parse_token_string_t cmd_showport_port =
TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
cmdline_parse_token_string_t cmd_showport_what =
TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
"info#stats#fdir");
"info#stats#fdir#stat_qmap");
cmdline_parse_token_num_t cmd_showport_portnum =
TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, INT32);
cmdline_parse_inst_t cmd_showport = {
.f = cmd_showport_parsed,
.data = NULL,
.help_str = "show|clear port info|stats|fdir X (X = port number)",
.help_str = "show|clear port info|stats|fdir|stat_qmap X (X = port number)",
.tokens = {
(void *)&cmd_showport_show,
(void *)&cmd_showport_port,
@ -2120,6 +2128,63 @@ cmdline_parse_inst_t cmd_mac_addr = {
};
/* *** CONFIGURE QUEUE STATS COUNTER MAPPINGS *** */
struct cmd_set_qmap_result {
cmdline_fixed_string_t set;
cmdline_fixed_string_t qmap;
cmdline_fixed_string_t what;
uint8_t port_id;
uint16_t queue_id;
uint8_t map_value;
};
static void
cmd_set_qmap_parsed(void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_set_qmap_result *res = parsed_result;
int is_rx = (strcmp(res->what, "tx") == 0) ? 0 : 1;
set_qmap(res->port_id, (uint8_t)is_rx, res->queue_id, res->map_value);
}
cmdline_parse_token_string_t cmd_setqmap_set =
TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
set, "set");
cmdline_parse_token_string_t cmd_setqmap_qmap =
TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
qmap, "stat_qmap");
cmdline_parse_token_string_t cmd_setqmap_what =
TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
what, "tx#rx");
cmdline_parse_token_num_t cmd_setqmap_portid =
TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
port_id, UINT8);
cmdline_parse_token_num_t cmd_setqmap_queueid =
TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
queue_id, UINT16);
cmdline_parse_token_num_t cmd_setqmap_mapvalue =
TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
map_value, UINT8);
cmdline_parse_inst_t cmd_set_qmap = {
.f = cmd_set_qmap_parsed,
.data = NULL,
.help_str = "Set statistics mapping value on tx|rx queue_id of port_id",
.tokens = {
(void *)&cmd_setqmap_set,
(void *)&cmd_setqmap_qmap,
(void *)&cmd_setqmap_what,
(void *)&cmd_setqmap_portid,
(void *)&cmd_setqmap_queueid,
(void *)&cmd_setqmap_mapvalue,
NULL,
},
};
/* ******************************************************************************** */
/* list of instructions */
cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_help,
@ -2161,6 +2226,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_masks_filter,
(cmdline_parse_inst_t *)&cmd_stop,
(cmdline_parse_inst_t *)&cmd_mac_addr,
(cmdline_parse_inst_t *)&cmd_set_qmap,
NULL,
};

View File

@ -83,6 +83,8 @@ void
nic_stats_display(portid_t port_id)
{
struct rte_eth_stats stats;
struct rte_port *port = &ports[port_id];
uint8_t i;
static const char *nic_stats_border = "########################";
@ -93,12 +95,23 @@ nic_stats_display(portid_t port_id)
rte_eth_stats_get(port_id, &stats);
printf("\n %s NIC statistics for port %-2d %s\n",
nic_stats_border, port_id, nic_stats_border);
printf(" RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64"RX-bytes: "
"%-"PRIu64"\n"
" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64"TX-bytes: "
"%-"PRIu64"\n",
stats.ipackets, stats.ierrors, stats.ibytes,
stats.opackets, stats.oerrors, stats.obytes);
if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
printf(" RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64"RX-bytes: "
"%-"PRIu64"\n"
" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64"TX-bytes: "
"%-"PRIu64"\n",
stats.ipackets, stats.ierrors, stats.ibytes,
stats.opackets, stats.oerrors, stats.obytes);
}
else {
printf(" RX-packets: %10"PRIu64" RX-errors: %10"PRIu64
" RX-bytes: %10"PRIu64"\n"
" TX-packets: %10"PRIu64" TX-errors: %10"PRIu64
" TX-bytes: %10"PRIu64"\n",
stats.ipackets, stats.ierrors, stats.ibytes,
stats.opackets, stats.oerrors, stats.obytes);
}
/* stats fdir */
if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
@ -106,6 +119,24 @@ nic_stats_display(portid_t port_id)
stats.fdirmiss,
stats.fdirmatch);
if (port->rx_queue_stats_mapping_enabled) {
printf("\n");
for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
printf(" Stats reg %2d RX-packets: %10"PRIu64
" RX-errors: %10"PRIu64
" RX-bytes: %10"PRIu64"\n",
i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
}
}
if (port->tx_queue_stats_mapping_enabled) {
printf("\n");
for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
printf(" Stats reg %2d TX-packets: %10"PRIu64
" TX-bytes: %10"PRIu64"\n",
i, stats.q_opackets[i], stats.q_obytes[i]);
}
}
printf(" %s############################%s\n",
nic_stats_border, nic_stats_border);
}
@ -121,6 +152,55 @@ nic_stats_clear(portid_t port_id)
printf("\n NIC statistics for port %d cleared\n", port_id);
}
void
nic_stats_mapping_display(portid_t port_id)
{
struct rte_port *port = &ports[port_id];
uint16_t i;
static const char *nic_stats_mapping_border = "########################";
if (port_id >= nb_ports) {
printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
return;
}
if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
printf("Port id %d - either does not support queue statistic mapping or"
" no queue statistic mapping set\n", port_id);
return;
}
printf("\n %s NIC statistics mapping for port %-2d %s\n",
nic_stats_mapping_border, port_id, nic_stats_mapping_border);
if (port->rx_queue_stats_mapping_enabled) {
for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
if (rx_queue_stats_mappings[i].port_id == port_id) {
printf(" RX-queue %2d mapped to Stats Reg %2d\n",
rx_queue_stats_mappings[i].queue_id,
rx_queue_stats_mappings[i].stats_counter_id);
}
}
printf("\n");
}
if (port->tx_queue_stats_mapping_enabled) {
for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
if (tx_queue_stats_mappings[i].port_id == port_id) {
printf(" TX-queue %2d mapped to Stats Reg %2d\n",
tx_queue_stats_mappings[i].queue_id,
tx_queue_stats_mappings[i].stats_counter_id);
}
}
}
printf(" %s####################################%s\n",
nic_stats_mapping_border, nic_stats_mapping_border);
}
void
port_infos_display(portid_t port_id)
{
@ -978,6 +1058,58 @@ tx_vlan_reset(portid_t port_id)
ports[port_id].tx_ol_flags &= ~PKT_TX_VLAN_PKT;
}
void
set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)
{
uint16_t i;
uint8_t existing_mapping_found = 0;
if (port_id_is_invalid(port_id))
return;
if (is_rx ? (rx_queue_id_is_invalid(queue_id)) : (tx_queue_id_is_invalid(queue_id)))
return;
if (map_value >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
printf("map_value not in required range 0..%d\n",
RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
return;
}
if (!is_rx) { /*then tx*/
for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
if ((tx_queue_stats_mappings[i].port_id == port_id) &&
(tx_queue_stats_mappings[i].queue_id == queue_id)) {
tx_queue_stats_mappings[i].stats_counter_id = map_value;
existing_mapping_found = 1;
break;
}
}
if (!existing_mapping_found) { /* A new additional mapping... */
tx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id;
tx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id;
tx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value;
nb_tx_queue_stats_mappings++;
}
}
else { /*rx*/
for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
if ((rx_queue_stats_mappings[i].port_id == port_id) &&
(rx_queue_stats_mappings[i].queue_id == queue_id)) {
rx_queue_stats_mappings[i].stats_counter_id = map_value;
existing_mapping_found = 1;
break;
}
}
if (!existing_mapping_found) { /* A new additional mapping... */
rx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id;
rx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id;
rx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value;
nb_rx_queue_stats_mappings++;
}
}
}
void
tx_cksum_set(portid_t port_id, uint8_t cksum_mask)
{

View File

@ -155,6 +155,12 @@ usage(char* progname)
" (0 <= N <= value of txd)\n");
printf(" --txrst=N set the transmit RS bit threshold of TX rings to N"
" (0 <= N <= value of txd)\n");
printf(" --tx-queue-stats-mapping (port,queue,mapping)[,(port,queue,mapping]:"
" tx queues statistics counters mapping"
" (0 <= mapping <= %d)\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
printf(" --rx-queue-stats-mapping (port,queue,mapping)[,(port,queue,mapping]:"
" rx queues statistics counters mapping"
" (0 <= mapping <= %d)\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
}
static int
@ -224,6 +230,87 @@ parse_fwd_portmask(const char *portmask)
set_fwd_ports_mask((uint64_t) pm);
}
static int
parse_queue_stats_mapping_config(const char *q_arg, int is_rx)
{
char s[256];
const char *p, *p0 = q_arg;
char *end;
enum fieldnames {
FLD_PORT = 0,
FLD_QUEUE,
FLD_STATS_COUNTER,
_NUM_FLD
};
unsigned long int_fld[_NUM_FLD];
char *str_fld[_NUM_FLD];
int i;
unsigned size;
/* reset from value set at definition */
is_rx ? (nb_rx_queue_stats_mappings = 0) : (nb_tx_queue_stats_mappings = 0);
while ((p = strchr(p0,'(')) != NULL) {
++p;
if((p0 = strchr(p,')')) == NULL)
return -1;
size = p0 - p;
if(size >= sizeof(s))
return -1;
rte_snprintf(s, sizeof(s), "%.*s", size, p);
if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
return -1;
for (i = 0; i < _NUM_FLD; i++){
errno = 0;
int_fld[i] = strtoul(str_fld[i], &end, 0);
if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
return -1;
}
/* Check mapping field is in correct range (0..RTE_ETHDEV_QUEUE_STAT_CNTRS-1) */
if (int_fld[FLD_STATS_COUNTER] >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
printf("Stats counter not in the correct range 0..%d\n",
RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
return -1;
}
if (is_rx ? (nb_rx_queue_stats_mappings >= MAX_RX_QUEUE_STATS_MAPPINGS) :
(nb_tx_queue_stats_mappings >= MAX_TX_QUEUE_STATS_MAPPINGS)) {
printf("exceeded max number of %s queue statistics mappings: %hu\n",
is_rx ? "RX" : "TX",
is_rx ? nb_rx_queue_stats_mappings : nb_tx_queue_stats_mappings);
return -1;
}
if (!is_rx) {
tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].port_id =
(uint8_t)int_fld[FLD_PORT];
tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].queue_id =
(uint8_t)int_fld[FLD_QUEUE];
tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].stats_counter_id =
(uint8_t)int_fld[FLD_STATS_COUNTER];
++nb_tx_queue_stats_mappings;
}
else {
rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].port_id =
(uint8_t)int_fld[FLD_PORT];
rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].queue_id =
(uint8_t)int_fld[FLD_QUEUE];
rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].stats_counter_id =
(uint8_t)int_fld[FLD_STATS_COUNTER];
++nb_rx_queue_stats_mappings;
}
}
/* Reassign the rx/tx_queue_stats_mappings pointer to point to this newly populated array rather */
/* than to the default array (that was set at its definition) */
is_rx ? (rx_queue_stats_mappings = rx_queue_stats_mappings_array) :
(tx_queue_stats_mappings = tx_queue_stats_mappings_array);
return 0;
}
void
launch_args_parse(int argc, char** argv)
{
@ -269,6 +356,8 @@ launch_args_parse(int argc, char** argv)
{ "rxht", 1, 0, 0 },
{ "rxwt", 1, 0, 0 },
{ "rxfreet", 1, 0, 0 },
{ "tx-queue-stats-mapping", 1, 0, 0 },
{ "rx-queue-stats-mapping", 1, 0, 0 },
{ 0, 0, 0, 0 },
};
@ -630,6 +719,18 @@ launch_args_parse(int argc, char** argv)
else
rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "tx-queue-stats-mapping")) {
if (parse_queue_stats_mapping_config(optarg, TX)) {
rte_exit(EXIT_FAILURE,
"invalid TX queue statistics mapping config entered\n");
}
}
if (!strcmp(lgopts[opt_idx].name, "rx-queue-stats-mapping")) {
if (parse_queue_stats_mapping_config(optarg, RX)) {
rte_exit(EXIT_FAILURE,
"invalid RX queue statistics mapping config entered\n");
}
}
break;
case 'h':
usage(argv[0]);

View File

@ -245,6 +245,18 @@ struct rte_fdir_conf fdir_conf = {
static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
uint16_t nb_tx_queue_stats_mappings = 0;
uint16_t nb_rx_queue_stats_mappings = 0;
/* Forward function declarations */
static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
/*
* Setup default configuration.
*/

View File

@ -131,6 +131,8 @@ struct rte_port {
void *fwd_ctx; /**< Forwarding mode context */
uint64_t rx_bad_ip_csum; /**< rx pkts with bad ip checksum */
uint64_t rx_bad_l4_csum; /**< rx pkts with bad l4 checksum */
uint8_t tx_queue_stats_mapping_enabled;
uint8_t rx_queue_stats_mapping_enabled;
};
/**
@ -197,6 +199,25 @@ struct fwd_config {
portid_t nb_fwd_ports; /**< Nb. of ports involved. */
};
#define MAX_TX_QUEUE_STATS_MAPPINGS 1024 /* MAX_PORT of 32 @ 32 tx_queues/port */
#define MAX_RX_QUEUE_STATS_MAPPINGS 4096 /* MAX_PORT of 32 @ 128 rx_queues/port */
struct queue_stats_mappings {
uint8_t port_id;
uint16_t queue_id;
uint8_t stats_counter_id;
} __rte_cache_aligned;
extern struct queue_stats_mappings tx_queue_stats_mappings_array[];
extern struct queue_stats_mappings rx_queue_stats_mappings_array[];
/* Assign both tx and rx queue stats mappings to the same default values */
extern struct queue_stats_mappings *tx_queue_stats_mappings;
extern struct queue_stats_mappings *rx_queue_stats_mappings;
extern uint16_t nb_tx_queue_stats_mappings;
extern uint16_t nb_rx_queue_stats_mappings;
/* globals used for configuration */
extern uint16_t verbose_level; /**< Drives messages being displayed, if any. */
extern uint8_t interactive;
@ -330,6 +351,7 @@ void launch_args_parse(int argc, char** argv);
void prompt(void);
void nic_stats_display(portid_t port_id);
void nic_stats_clear(portid_t port_id);
void nic_stats_mapping_display(portid_t port_id);
void port_infos_display(portid_t port_id);
void fwd_lcores_config_display(void);
void fwd_config_display(void);
@ -363,6 +385,9 @@ void rx_vlan_all_filter_set(portid_t port_id, int on);
void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
void tx_vlan_reset(portid_t port_id);
void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value);
void tx_cksum_set(portid_t port_id, uint8_t cksum_mask);
void set_verbose_level(uint16_t vb_level);