ethdev: new method to retrieve extended statistics
This method can be implemented by a poll mode driver to provide non-standard statistics (which are not part of the generic statistics structure). Each statistic is returned in a generic form: "name" and "value" and can be used to dump PMD-specific statistics in the same way than ethtool in linux kernel. If the PMD does not provide the xstats_get and xstats_set functions, the ethdev API will return the generic statistics in the xstats format (name, value). This commit opens the door for a clean-up of the generic statistics structure, only keeping statistics that are really common to all PMDs and moving specific ones into the xstats API. Signed-off-by: Olivier Matz <olivier.matz@6wind.com> Reviewed-by: David Marchand <david.marchand@6wind.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com> [Thomas: fix some comments] Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
This commit is contained in:
parent
fbe37a7385
commit
ce757f5c9a
@ -114,6 +114,48 @@ static uint8_t nb_ports = 0;
|
||||
/* spinlock for eth device callbacks */
|
||||
static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
|
||||
|
||||
/* store statistics names and its offset in stats structure */
|
||||
struct rte_eth_xstats_name_off {
|
||||
char name[RTE_ETH_XSTATS_NAME_SIZE];
|
||||
unsigned offset;
|
||||
};
|
||||
|
||||
static struct rte_eth_xstats_name_off rte_stats_strings[] = {
|
||||
{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
|
||||
{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
|
||||
{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
|
||||
{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
|
||||
{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
|
||||
{"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
|
||||
{"rx_crc_errors", offsetof(struct rte_eth_stats, ibadcrc)},
|
||||
{"rx_bad_length_errors", offsetof(struct rte_eth_stats, ibadlen)},
|
||||
{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
|
||||
{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
|
||||
{"fdir_match", offsetof(struct rte_eth_stats, fdirmatch)},
|
||||
{"fdir_miss", offsetof(struct rte_eth_stats, fdirmiss)},
|
||||
{"tx_flow_control_xon", offsetof(struct rte_eth_stats, tx_pause_xon)},
|
||||
{"rx_flow_control_xon", offsetof(struct rte_eth_stats, rx_pause_xon)},
|
||||
{"tx_flow_control_xoff", offsetof(struct rte_eth_stats, tx_pause_xoff)},
|
||||
{"rx_flow_control_xoff", offsetof(struct rte_eth_stats, rx_pause_xoff)},
|
||||
};
|
||||
#define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
|
||||
|
||||
static struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
|
||||
{"rx_packets", offsetof(struct rte_eth_stats, q_ipackets)},
|
||||
{"rx_bytes", offsetof(struct rte_eth_stats, q_ibytes)},
|
||||
};
|
||||
#define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) / \
|
||||
sizeof(rte_rxq_stats_strings[0]))
|
||||
|
||||
static struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
|
||||
{"tx_packets", offsetof(struct rte_eth_stats, q_opackets)},
|
||||
{"tx_bytes", offsetof(struct rte_eth_stats, q_obytes)},
|
||||
{"tx_errors", offsetof(struct rte_eth_stats, q_errors)},
|
||||
};
|
||||
#define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \
|
||||
sizeof(rte_txq_stats_strings[0]))
|
||||
|
||||
|
||||
/**
|
||||
* The user application callback description.
|
||||
*
|
||||
@ -1201,6 +1243,101 @@ rte_eth_stats_reset(uint8_t port_id)
|
||||
(*dev->dev_ops->stats_reset)(dev);
|
||||
}
|
||||
|
||||
/* retrieve ethdev extended statistics */
|
||||
int
|
||||
rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
|
||||
unsigned n)
|
||||
{
|
||||
struct rte_eth_stats eth_stats;
|
||||
struct rte_eth_dev *dev;
|
||||
unsigned count, i, q;
|
||||
uint64_t val;
|
||||
char *stats_ptr;
|
||||
|
||||
if (port_id >= nb_ports) {
|
||||
PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
|
||||
return -1;
|
||||
}
|
||||
dev = &rte_eth_devices[port_id];
|
||||
|
||||
/* implemented by the driver */
|
||||
if (dev->dev_ops->xstats_get != NULL)
|
||||
return (*dev->dev_ops->xstats_get)(dev, xstats, n);
|
||||
|
||||
/* else, return generic statistics */
|
||||
count = RTE_NB_STATS;
|
||||
count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
|
||||
count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
|
||||
if (n < count)
|
||||
return count;
|
||||
|
||||
/* now fill the xstats structure */
|
||||
|
||||
count = 0;
|
||||
memset(ð_stats, 0, sizeof(eth_stats));
|
||||
rte_eth_stats_get(port_id, ð_stats);
|
||||
|
||||
/* global stats */
|
||||
for (i = 0; i < RTE_NB_STATS; i++) {
|
||||
stats_ptr = (char *)ð_stats + rte_stats_strings[i].offset;
|
||||
val = *(uint64_t *)stats_ptr;
|
||||
snprintf(xstats[count].name, sizeof(xstats[count].name),
|
||||
"%s", rte_stats_strings[i].name);
|
||||
xstats[count++].value = val;
|
||||
}
|
||||
|
||||
/* per-rxq stats */
|
||||
for (q = 0; q < dev->data->nb_rx_queues; q++) {
|
||||
for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
|
||||
stats_ptr = (char *)ð_stats;
|
||||
stats_ptr += rte_rxq_stats_strings[i].offset;
|
||||
stats_ptr += q * sizeof(uint64_t);
|
||||
val = *(uint64_t *)stats_ptr;
|
||||
snprintf(xstats[count].name, sizeof(xstats[count].name),
|
||||
"rx_queue_%u_%s", q,
|
||||
rte_rxq_stats_strings[i].name);
|
||||
xstats[count++].value = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* per-txq stats */
|
||||
for (q = 0; q < dev->data->nb_tx_queues; q++) {
|
||||
for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
|
||||
stats_ptr = (char *)ð_stats;
|
||||
stats_ptr += rte_txq_stats_strings[i].offset;
|
||||
stats_ptr += q * sizeof(uint64_t);
|
||||
val = *(uint64_t *)stats_ptr;
|
||||
snprintf(xstats[count].name, sizeof(xstats[count].name),
|
||||
"tx_queue_%u_%s", q,
|
||||
rte_txq_stats_strings[i].name);
|
||||
xstats[count++].value = val;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* reset ethdev extended statistics */
|
||||
void
|
||||
rte_eth_xstats_reset(uint8_t port_id)
|
||||
{
|
||||
struct rte_eth_dev *dev;
|
||||
|
||||
if (port_id >= nb_ports) {
|
||||
PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
|
||||
return;
|
||||
}
|
||||
dev = &rte_eth_devices[port_id];
|
||||
|
||||
/* implemented by the driver */
|
||||
if (dev->dev_ops->xstats_reset != NULL) {
|
||||
(*dev->dev_ops->xstats_reset)(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
/* fallback to default */
|
||||
rte_eth_stats_reset(port_id);
|
||||
}
|
||||
|
||||
static int
|
||||
set_queue_stats_mapping(uint8_t port_id, uint16_t queue_id, uint8_t stat_idx,
|
||||
|
@ -908,6 +908,21 @@ struct rte_eth_dev_info {
|
||||
uint32_t tx_offload_capa; /**< Device TX offload capabilities. */
|
||||
};
|
||||
|
||||
/** Maximum name length for extended statistics counters */
|
||||
#define RTE_ETH_XSTATS_NAME_SIZE 64
|
||||
|
||||
/**
|
||||
* An Ethernet device extended statistic structure
|
||||
*
|
||||
* This structure is used by ethdev->eth_xstats_get() to provide
|
||||
* statistics that are not provided in the generic rte_eth_stats
|
||||
* structure.
|
||||
*/
|
||||
struct rte_eth_xstats {
|
||||
char name[RTE_ETH_XSTATS_NAME_SIZE];
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
struct rte_eth_dev;
|
||||
|
||||
struct rte_eth_dev_callback;
|
||||
@ -1028,6 +1043,13 @@ typedef void (*eth_stats_get_t)(struct rte_eth_dev *dev,
|
||||
typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev);
|
||||
/**< @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);
|
||||
/**< @internal Get extended stats of an Ethernet device. */
|
||||
|
||||
typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev);
|
||||
/**< @internal Reset extended stats of an Ethernet device. */
|
||||
|
||||
typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
|
||||
uint16_t queue_id,
|
||||
uint8_t stat_idx,
|
||||
@ -1376,8 +1398,10 @@ struct eth_dev_ops {
|
||||
eth_allmulticast_enable_t allmulticast_enable;/**< RX multicast ON. */
|
||||
eth_allmulticast_disable_t allmulticast_disable;/**< RX multicast OF. */
|
||||
eth_link_update_t link_update; /**< Get device link state. */
|
||||
eth_stats_get_t stats_get; /**< Get device statistics. */
|
||||
eth_stats_reset_t stats_reset; /**< Reset device statistics. */
|
||||
eth_stats_get_t stats_get; /**< Get generic device statistics. */
|
||||
eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */
|
||||
eth_xstats_get_t xstats_get; /**< Get extended device statistics. */
|
||||
eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */
|
||||
eth_queue_stats_mapping_set_t queue_stats_mapping_set;
|
||||
/**< Configure per queue stat counter mapping. */
|
||||
eth_dev_infos_get_t dev_infos_get; /**< Get device info. */
|
||||
@ -2004,6 +2028,38 @@ extern void rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats);
|
||||
*/
|
||||
extern void rte_eth_stats_reset(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Retrieve extended statistics of an Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param xstats
|
||||
* A pointer to a table of structure of type *rte_eth_xstats*
|
||||
* to be filled with device statistics names and values.
|
||||
* This parameter can be set to NULL if n is 0.
|
||||
* @param n
|
||||
* The size of the stats table, which should be large enough to store
|
||||
* all the statistics of the device.
|
||||
* @return
|
||||
* - positive value lower or equal to n: success. The return value
|
||||
* is the number of entries filled in the stats table.
|
||||
* - positive value higher than n: error, the given statistics table
|
||||
* is too small. The return value corresponds to the size that should
|
||||
* be given to succeed. The entries in the table are not valid and
|
||||
* shall not be used by the caller.
|
||||
* - negative value on error (invalid port id)
|
||||
*/
|
||||
extern int rte_eth_xstats_get(uint8_t port_id,
|
||||
struct rte_eth_xstats *xstats, unsigned n);
|
||||
|
||||
/**
|
||||
* Reset extended statistics of an Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
*/
|
||||
extern void rte_eth_xstats_reset(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Set a mapping for the specified transmit queue to the specified per-queue
|
||||
* statistics counter.
|
||||
|
Loading…
x
Reference in New Issue
Block a user