From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Bruce Richardson <bruce.richardson@intel.com>
Subject: [PATCH v3 16/16] test/pmd_ring: test per-queue xstats
Date: Thu, 13 Aug 2026 10:55:15 -0700 [thread overview]
Message-ID: <20260813180402.622784-17-stephen@networkplumber.org> (raw)
In-Reply-To: <20260813180402.622784-1-stephen@networkplumber.org>
Add a test that per-queue xstats are reported for every configured
queue, and only for those. Uses different Rx and Tx queue counts so
that each direction is checked independently.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_pmd_ring.c | 145 +++++++++++++++++++++++++++++++++++++++
1 file changed, 145 insertions(+)
diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index cb08dcf1d9..e7682906df 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -4,7 +4,10 @@
#include "test.h"
#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <rte_eth_ring.h>
#include <rte_ethdev.h>
@@ -557,6 +560,147 @@ test_ethdev_configure_ports(void)
return TEST_SUCCESS;
}
+/*
+ * Per-queue xstats are added by ethdev for all configured queues.
+ * Use a port with different Rx and Tx queue counts to check that each
+ * direction is reported independently.
+ */
+#define QSTATS_NB_RXQ 3
+#define QSTATS_NB_TXQ 5
+#define QSTATS_NB_RINGS RTE_MAX(QSTATS_NB_RXQ, QSTATS_NB_TXQ)
+
+static int
+test_queue_xstats(void)
+{
+ struct rte_ring *qrings[QSTATS_NB_RINGS] = { };
+ struct rte_eth_xstat_name *names = NULL;
+ struct rte_eth_xstat *xstats = NULL;
+ struct rte_eth_conf null_conf;
+ unsigned int i, nb_names, found;
+ char expected[RTE_ETH_XSTATS_NAME_SIZE];
+ int port = -1, nb_xstats, ret = -1;
+ uint16_t q;
+
+ for (q = 0; q < QSTATS_NB_RINGS; q++) {
+ char name[RTE_RING_NAMESIZE];
+
+ snprintf(name, sizeof(name), "RQ%u", q);
+ qrings[q] = rte_ring_create(name, RING_SIZE, SOCKET0,
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+ if (qrings[q] == NULL) {
+ printf("rte_ring_create %s failed\n", name);
+ goto out;
+ }
+ }
+
+ port = rte_eth_from_rings("net_ringq", qrings, QSTATS_NB_RXQ,
+ qrings, QSTATS_NB_TXQ, SOCKET0);
+ if (port < 0) {
+ printf("failed to create port\n");
+ goto out;
+ }
+
+ memset(&null_conf, 0, sizeof(null_conf));
+ if (rte_eth_dev_configure(port, QSTATS_NB_RXQ, QSTATS_NB_TXQ,
+ &null_conf) < 0) {
+ printf("configure failed\n");
+ goto out;
+ }
+
+ for (q = 0; q < QSTATS_NB_RXQ; q++) {
+ if (rte_eth_rx_queue_setup(port, q, RING_SIZE, SOCKET0,
+ NULL, mp) < 0) {
+ printf("Rx queue %u setup failed\n", q);
+ goto out;
+ }
+ }
+ for (q = 0; q < QSTATS_NB_TXQ; q++) {
+ if (rte_eth_tx_queue_setup(port, q, RING_SIZE, SOCKET0,
+ NULL) < 0) {
+ printf("Tx queue %u setup failed\n", q);
+ goto out;
+ }
+ }
+
+ nb_xstats = rte_eth_xstats_get_names(port, NULL, 0);
+ if (nb_xstats <= 0) {
+ printf("no xstats reported\n");
+ goto out;
+ }
+
+ names = calloc(nb_xstats, sizeof(*names));
+ xstats = calloc(nb_xstats, sizeof(*xstats));
+ if (names == NULL || xstats == NULL) {
+ printf("out of memory\n");
+ goto out;
+ }
+
+ nb_names = rte_eth_xstats_get_names(port, names, nb_xstats);
+ if (nb_names != (unsigned int)nb_xstats) {
+ printf("got %u names, expected %d\n", nb_names, nb_xstats);
+ goto out;
+ }
+
+ if (rte_eth_xstats_get(port, xstats, nb_xstats) != nb_xstats) {
+ printf("xstats count does not match names count\n");
+ goto out;
+ }
+
+ /* No traffic has passed, so every counter must still be zero. */
+ for (i = 0; i < (unsigned int)nb_xstats; i++) {
+ if (xstats[i].value != 0) {
+ printf("xstat '%s' is %"PRIu64", expected 0\n",
+ names[xstats[i].id].name, xstats[i].value);
+ goto out;
+ }
+ }
+
+ /* Every configured queue must have its counters, in both directions. */
+ for (q = 0; q < QSTATS_NB_RXQ + QSTATS_NB_TXQ; q++) {
+ bool rx = q < QSTATS_NB_RXQ;
+
+ snprintf(expected, sizeof(expected), "%s_q%u_packets",
+ rx ? "rx" : "tx", rx ? q : q - QSTATS_NB_RXQ);
+
+ for (i = 0, found = 0; i < nb_names; i++)
+ if (strcmp(names[i].name, expected) == 0)
+ found++;
+
+ if (found != 1) {
+ printf("expected one '%s', got %u\n", expected, found);
+ goto out;
+ }
+ }
+
+ /* Queues beyond the configured count must not be reported. */
+ snprintf(expected, sizeof(expected), "rx_q%u_packets", QSTATS_NB_RXQ);
+ for (i = 0; i < nb_names; i++) {
+ if (strcmp(names[i].name, expected) == 0) {
+ printf("unexpected stat '%s'\n", expected);
+ goto out;
+ }
+ }
+
+ snprintf(expected, sizeof(expected), "tx_q%u_packets", QSTATS_NB_TXQ);
+ for (i = 0; i < nb_names; i++) {
+ if (strcmp(names[i].name, expected) == 0) {
+ printf("unexpected stat '%s'\n", expected);
+ goto out;
+ }
+ }
+
+ ret = TEST_SUCCESS;
+out:
+ free(names);
+ free(xstats);
+ if (port >= 0)
+ rte_eth_dev_close(port);
+ for (q = 0; q < QSTATS_NB_RINGS; q++)
+ rte_ring_free(qrings[q]);
+
+ return ret;
+}
+
static int
test_get_stats_for_port(void)
{
@@ -581,6 +725,7 @@ unit_test_suite test_pmd_ring_suite = {
TEST_CASE(test_send_basic_packets),
TEST_CASE(test_get_stats_for_port),
TEST_CASE(test_stats_reset_for_port),
+ TEST_CASE(test_queue_xstats),
TEST_CASE(test_pmd_ring_pair_create_attach),
TEST_CASE(test_command_line_ring_port),
TEST_CASES_END()
--
2.53.0
prev parent reply other threads:[~2026-08-13 18:05 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
2026-05-30 16:09 ` [RFC 1/7] net/virtio: remove unused " Stephen Hemminger
2026-05-30 16:09 ` [RFC 2/7] net/enic: remove queue_stats_mapping ethdev_op Stephen Hemminger
2026-05-30 16:09 ` [RFC 3/7] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-05-30 16:09 ` [RFC 4/7] net/e1000: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 5/7] net/ixgbe: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 6/7] net/txgbe: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
2026-06-01 1:56 ` fengchengwen
2026-06-01 8:45 ` Andrew Rybchenko
2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 1/9] net/virtio: remove unused " Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 2/9] app/testpmd: remove unused function prototype Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 3/9] net/enic: remove unneeded ops initialization Stephen Hemminger
2026-07-24 1:52 ` Hyong Youb Kim (hyonkim)
2026-07-23 20:28 ` [PATCH v2 4/9] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-07-24 7:26 ` David Marchand
2026-07-24 15:20 ` Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 5/9] net/e1000: " Stephen Hemminger
2026-07-24 7:31 ` David Marchand
2026-08-13 12:26 ` Bruce Richardson
2026-07-23 20:28 ` [PATCH v2 6/9] net/ixgbe: " Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 7/9] net/txgbe: " Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 8/9] net/sxe2: " Stephen Hemminger
2026-07-23 20:28 ` [PATCH v2 9/9] ethdev: remove support for " Stephen Hemminger
2026-07-24 7:39 ` [PATCH v2 0/9] Complete removal of " David Marchand
2026-07-24 7:42 ` David Marchand
2026-07-24 15:28 ` Stephen Hemminger
2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 01/16] net/virtio: remove unused queue stats mapping Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 02/16] app/testpmd: remove leftover set qmap Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 03/16] net/enic: remove unneeded ops initialization Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 04/16] net/cnxk: fix Tx drops added to Rx queue errors Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 05/16] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 06/16] net/e1000: " Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 07/16] net/ixgbe: " Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 08/16] net/txgbe: " Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 09/16] net/sxe2: fix null dereference in stats get Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 10/16] net/sxe2: remove queue stats mapping Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 11/16] ethdev: remove support for " Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 12/16] net/mvpp2: fix out of range Tx queue stats write Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 13/16] net/ntnic: fix Tx errors reported as Rx queue errors Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 14/16] net/xsc: fix Tx errors added to " Stephen Hemminger
2026-08-13 17:55 ` [PATCH v3 15/16] ethdev: remove queue stats counter limit Stephen Hemminger
2026-08-13 17:55 ` Stephen Hemminger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260813180402.622784-17-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.