[dpdk-dev,3/3] null: add xstats to provide the number of rx polls
Commit Message
When using the null driver and passing in packets via
the rx ring, it is useful to know that the driver has
polled the ring. Add a count of rx polls to the xstats
to provide this information.
Signed-off-by: Paul Atkins <patkins@brocade.com>
---
drivers/net/null/rte_eth_null.c | 70 +++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
@@ -65,6 +65,15 @@ static const char *valid_arguments[] = {
struct pmd_internals;
+struct eth_null_xstats {
+ rte_atomic64_t rx_polls;
+ rte_atomic64_t tx_polls;
+};
+
+struct eth_null_hw_stats {
+ uint64_t rx_polls;
+};
+
struct null_queue {
struct pmd_internals *internals;
@@ -74,6 +83,7 @@ struct null_queue {
rte_atomic64_t rx_pkts;
rte_atomic64_t tx_pkts;
rte_atomic64_t err_pkts;
+ struct eth_null_xstats xstats;
};
struct pmd_internals {
@@ -109,6 +119,19 @@ static struct rte_eth_link pmd_link = {
.link_status = 0
};
+/* store statistics names and its offset in stats structure */
+struct eth_null_xstats_name_off {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+ unsigned offset;
+};
+
+static const struct eth_null_xstats_name_off eth_null_stats_strings[] = {
+ {"rx_polls", offsetof(struct eth_null_xstats, rx_polls)},
+};
+
+#define ETH_NULL_NB_XSTATS_PER_Q (sizeof(eth_null_stats_strings) / \
+ sizeof(eth_null_stats_strings[0]))
+
static uint16_t
eth_null_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
{
@@ -175,6 +198,7 @@ eth_null_copy_rx_from_ring(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
i = rte_ring_mc_dequeue_burst(h->internals->rx_ring, (void **)bufs,
nb_bufs);
rte_atomic64_add(&h->rx_pkts, 1);
+ rte_atomic64_add(&h->xstats.rx_polls, 1);
return i;
}
@@ -231,6 +255,7 @@ eth_null_copy_tx_to_ring(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
nb_bufs);
rte_atomic64_add(&h->tx_pkts, 1);
+ rte_atomic64_add(&h->tx_pkts, i);
return i;
}
@@ -410,6 +435,49 @@ eth_stats_reset(struct rte_eth_dev *dev)
}
}
+static int
+eth_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+ unsigned n)
+{
+ struct pmd_internals *internal;
+ unsigned count = ETH_NULL_NB_XSTATS_PER_Q * dev->data->nb_rx_queues;
+ unsigned q, i = 0;
+ uint64_t val, *stats_ptr;
+
+ if (n < count)
+ return count;
+
+ internal = dev->data->dev_private;
+
+ /* Extended stats */
+ count = 0;
+ for (q = 0; q < ETH_NULL_NB_XSTATS_PER_Q; q++) {
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ stats_ptr = RTE_PTR_ADD(
+ &internal->rx_null_queues[q].xstats,
+ eth_null_stats_strings[i].offset +
+ q * sizeof(uint64_t));
+ val = *stats_ptr;
+ snprintf(xstats[count].name, sizeof(xstats[count].name),
+ "rx_queue_%u_%s", q,
+ eth_null_stats_strings[count].name);
+ xstats[count++].value = val;
+ }
+ }
+ return count;
+}
+
+static void
+eth_xstats_reset(struct rte_eth_dev *dev)
+{
+ struct pmd_internals *internal;
+ unsigned i;
+
+ internal = dev->data->dev_private;
+ for (i = 0; i < dev->data->nb_rx_queues; i++)
+ internal->rx_null_queues[i].xstats.rx_polls.cnt = 0;
+}
+
static void
eth_queue_release(void *q)
{
@@ -523,6 +591,8 @@ static const struct eth_dev_ops ops = {
.link_update = eth_link_update,
.stats_get = eth_stats_get,
.stats_reset = eth_stats_reset,
+ .xstats_get = eth_xstats_get,
+ .xstats_reset = eth_xstats_reset,
.reta_update = eth_rss_reta_update,
.reta_query = eth_rss_reta_query,
.rss_hash_update = eth_rss_hash_update,