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 */
|
/* spinlock for eth device callbacks */
|
||||||
static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
|
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.
|
* The user application callback description.
|
||||||
*
|
*
|
||||||
@ -1201,6 +1243,101 @@ rte_eth_stats_reset(uint8_t port_id)
|
|||||||
(*dev->dev_ops->stats_reset)(dev);
|
(*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
|
static int
|
||||||
set_queue_stats_mapping(uint8_t port_id, uint16_t queue_id, uint8_t stat_idx,
|
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. */
|
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;
|
||||||
|
|
||||||
struct rte_eth_dev_callback;
|
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);
|
typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev);
|
||||||
/**< @internal Reset global I/O statistics of an Ethernet device to 0. */
|
/**< @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,
|
typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
|
||||||
uint16_t queue_id,
|
uint16_t queue_id,
|
||||||
uint8_t stat_idx,
|
uint8_t stat_idx,
|
||||||
@ -1376,8 +1398,10 @@ struct eth_dev_ops {
|
|||||||
eth_allmulticast_enable_t allmulticast_enable;/**< RX multicast ON. */
|
eth_allmulticast_enable_t allmulticast_enable;/**< RX multicast ON. */
|
||||||
eth_allmulticast_disable_t allmulticast_disable;/**< RX multicast OF. */
|
eth_allmulticast_disable_t allmulticast_disable;/**< RX multicast OF. */
|
||||||
eth_link_update_t link_update; /**< Get device link state. */
|
eth_link_update_t link_update; /**< Get device link state. */
|
||||||
eth_stats_get_t stats_get; /**< Get device statistics. */
|
eth_stats_get_t stats_get; /**< Get generic device statistics. */
|
||||||
eth_stats_reset_t stats_reset; /**< Reset 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;
|
eth_queue_stats_mapping_set_t queue_stats_mapping_set;
|
||||||
/**< Configure per queue stat counter mapping. */
|
/**< Configure per queue stat counter mapping. */
|
||||||
eth_dev_infos_get_t dev_infos_get; /**< Get device info. */
|
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);
|
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
|
* Set a mapping for the specified transmit queue to the specified per-queue
|
||||||
* statistics counter.
|
* statistics counter.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user