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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox