/*
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static void
nic_xstats_display(uint8_t port_id)
{
- struct rte_eth_xstats *xstats;
+ struct rte_eth_xstat_name *xstats_names;
+ struct rte_eth_xstat *xstats;
int len, ret, i;
+ int idx_name;
static const char *nic_stats_border = "########################";
- len = rte_eth_xstats_get(port_id, NULL, 0);
+ len = rte_eth_xstats_get_names(port_id, NULL, 0);
if (len < 0) {
printf("Cannot get xstats count\n");
return;
return;
}
+ xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
+ if (xstats_names == NULL) {
+ printf("Cannot allocate memory for xstat names\n");
+ free(xstats);
+ return;
+ }
+ if (len != rte_eth_xstats_get_names(
+ port_id, xstats_names, len)) {
+ printf("Cannot get xstat names\n");
+ return;
+ }
+
printf("###### NIC extended statistics for port %-2d #########\n",
port_id);
printf("%s############################\n",
}
for (i = 0; i < len; i++)
- printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
+ for (idx_name = 0; idx_name < len; idx_name++)
+ if (xstats_names[idx_name].id == xstats[i].id) {
+ printf("%s: %"PRIu64"\n",
+ xstats_names[idx_name].name,
+ xstats[i].value);
+ break;
+ }
printf("%s############################\n",
nic_stats_border);
free(xstats);
+ free(xstats_names);
}
static void
void
nic_xstats_display(portid_t port_id)
{
- struct rte_eth_xstats *xstats;
- int len, ret, i;
+ struct rte_eth_xstat *xstats;
+ int cnt_xstats, idx_xstat, idx_name;
+ struct rte_eth_xstat_name *xstats_names;
printf("###### NIC extended statistics for port %-2d\n", port_id);
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ printf("Error: Invalid port number %i\n", port_id);
+ return;
+ }
+
+ /* Get count */
+ cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0);
+ if (cnt_xstats < 0) {
+ printf("Error: Cannot get count of xstats\n");
+ return;
+ }
- len = rte_eth_xstats_get(port_id, NULL, 0);
- if (len < 0) {
- printf("Cannot get xstats count\n");
+ /* Get id-name lookup table */
+ xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
+ if (xstats_names == NULL) {
+ printf("Cannot allocate memory for xstats lookup\n");
return;
}
- xstats = malloc(sizeof(xstats[0]) * len);
+ if (cnt_xstats != rte_eth_xstats_get_names(
+ port_id, xstats_names, cnt_xstats)) {
+ printf("Error: Cannot get xstats lookup\n");
+ return;
+ }
+
+ /* Get stats themselves */
+ xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
if (xstats == NULL) {
printf("Cannot allocate memory for xstats\n");
+ free(xstats_names);
return;
}
- ret = rte_eth_xstats_get(port_id, xstats, len);
- if (ret < 0 || ret > len) {
- printf("Cannot get xstats\n");
- free(xstats);
+ if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) {
+ printf("Error: Unable to get xstats\n");
return;
}
- for (i = 0; i < len; i++)
- printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
+
+ /* Display xstats */
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++)
+ for (idx_name = 0; idx_name < cnt_xstats; idx_name++)
+ if (xstats_names[idx_name].id == xstats[idx_xstat].id) {
+ printf("%s: %"PRIu64"\n",
+ xstats_names[idx_name].name,
+ xstats[idx_xstat].value);
+ break;
+ }
+ free(xstats_names);
free(xstats);
}
do not need to care about the kind of devices that are being used, making it
easier to add new buses later.
-* The xstats API and rte_eth_xstats struct will be changed to allow retrieval
- of values without any string copies or parsing.
- No backwards compatibility is planned, as it would require code duplication
- in every PMD that supports xstats.
-
* ABI changes are planned for adding four new flow types. This impacts
RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
but release 2.3 will. [postponed]
ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff.
+* The extended statistics are fetched by ids with ``rte_eth_xstats_get``
+ after a lookup by name ``rte_eth_xstats_get_names``.
+
ABI Changes
-----------
static void eth_igb_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *rte_stats);
static int eth_igb_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
static void eth_igbvf_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *rte_stats);
static int eth_igbvf_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int eth_igbvf_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
}
static int
-eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* Extended stats */
for (i = 0; i < IGB_NB_XSTATS; i++) {
- xstats[i].name[0] = '\0';
xstats[i].id = i;
xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
rte_igb_stats_strings[i].offset);
}
static int
-eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
return 0;
for (i = 0; i < IGBVF_NB_XSTATS; i++) {
- xstats[i].name[0] = '\0';
xstats[i].id = i;
xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
rte_igbvf_stats_strings[i].offset);
}
static int
-fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct fm10k_hw_stats *hw_stats =
/* Global stats */
for (i = 0; i < FM10K_NB_HW_XSTATS; i++) {
- xstats[count].name[0] = '\0';
xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
fm10k_hw_stats_strings[count].offset);
count++;
/* PF queue stats */
for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) {
for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) {
- xstats[count].name[0] = '\0';
xstats[count].value =
*(uint64_t *)(((char *)&hw_stats->q[q]) +
fm10k_hw_stats_rx_q_strings[i].offset);
count++;
}
for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) {
- xstats[count].name[0] = '\0';
xstats[count].value =
*(uint64_t *)(((char *)&hw_stats->q[q]) +
fm10k_hw_stats_tx_q_strings[i].offset);
static void i40e_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
}
static int
-i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
/* Get stats from i40e_eth_stats struct */
for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
rte_i40e_stats_strings[i].offset);
/* Get individiual stats from i40e_hw_port struct */
for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
rte_i40e_hw_port_strings[i].offset);
for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) {
for (prio = 0; prio < 8; prio++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value =
*(uint64_t *)(((char *)hw_stats) +
for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) {
for (prio = 0; prio < 8; prio++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value =
*(uint64_t *)(((char *)hw_stats) +
static void i40evf_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int i40evf_dev_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
}
static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n)
+ struct rte_eth_xstat *xstats, unsigned n)
{
int ret;
unsigned i;
/* loop over xstats array and values from pstats */
for (i = 0; i < I40EVF_NB_XSTATS; i++) {
- xstats[i].name[0] = '\0';
xstats[i].id = i;
xstats[i].value = *(uint64_t *)(((char *)pstats) +
rte_i40evf_stats_strings[i].offset);
static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
}
static int
-ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct ixgbe_hw *hw =
count = 0;
for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
xstats[count].id = count;
- xstats[count].name[0] = '\0';
xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
rte_ixgbe_stats_strings[i].offset);
count++;
for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
xstats[count].id = count;
- xstats[count].name[0] = '\0';
xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
rte_ixgbe_rxq_strings[stat].offset +
(sizeof(uint64_t) * i));
for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) {
for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) {
xstats[count].id = count;
- xstats[count].name[0] = '\0';
xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
rte_ixgbe_txq_strings[stat].offset +
(sizeof(uint64_t) * i));
}
static int
-ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
static void virtio_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static int virtio_dev_xstats_get(struct rte_eth_dev *dev,
- struct rte_eth_xstats *xstats, unsigned n);
+ struct rte_eth_xstat *xstats, unsigned n);
static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
}
static int
-virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned n)
{
unsigned i;
unsigned t;
for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)rxvq) +
rte_virtio_q_stat_strings[t].offset);
unsigned t;
for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
- xstats[count].name[0] = '\0';
xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)txvq) +
rte_virtio_q_stat_strings[t].offset);
/* retrieve ethdev extended statistics */
int
-rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
+rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
unsigned n)
{
struct rte_eth_stats eth_stats;
stats_ptr = RTE_PTR_ADD(ð_stats,
rte_stats_strings[i].offset);
val = *stats_ptr;
- xstats[count].name[0] = '\0';
xstats[count].id = count + xcount;
xstats[count++].value = val;
}
rte_rxq_stats_strings[i].offset +
q * sizeof(uint64_t));
val = *stats_ptr;
- xstats[count].name[0] = '\0';
xstats[count].id = count + xcount;
xstats[count++].value = val;
}
rte_txq_stats_strings[i].offset +
q * sizeof(uint64_t));
val = *stats_ptr;
- xstats[count].name[0] = '\0';
xstats[count].id = count + xcount;
xstats[count++].value = val;
}
* statistics that are not provided in the generic rte_eth_stats
* structure.
*/
-struct rte_eth_xstats {
- char name[RTE_ETH_XSTATS_NAME_SIZE];
+struct rte_eth_xstat {
uint64_t id;
uint64_t value;
};
/**< @internal Reset global I/O statistics of an Ethernet device to 0. */
typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev,
- struct rte_eth_xstats *stats, unsigned n);
+ struct rte_eth_xstat *stats, unsigned n);
/**< @internal Get extended stats of an Ethernet device. */
typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev);
* shall not be used by the caller.
* - negative value on error (invalid port id)
*/
-int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
+int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
unsigned n);
/**