public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>
Subject: [PATCH v6 10/11] net/rtap: add extended statistics support
Date: Sat, 14 Feb 2026 15:44:19 -0800	[thread overview]
Message-ID: <20260214234726.188947-11-stephen@networkplumber.org> (raw)
In-Reply-To: <20260214234726.188947-1-stephen@networkplumber.org>

Add xstats support to rtap PMD following the virtio PMD design pattern.

Statistics provided per queue (14 Rx + 12 Tx):
- Packet size distribution (6 buckets: 64, 65-127, 128-255, 256-511,
  512-1023, 1024-1518 bytes)
- Packet type classification (broadcast, multicast, unicast)
- Rx offload stats (LRO, checksum validation, mbuf alloc failures)
- Tx offload stats (TSO, checksum offload, multi-segment packets)

Statistics follow DPDK naming convention:
  {direction}_q{queue_id}_{detail}_{unit}

Examples:
  rx_q0_size_64_packets
  rx_q0_broadcast_packets
  rx_q0_lro_packets
  tx_q0_tso_packets
  tx_q0_checksum_offload_packets

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 doc/guides/nics/features/rtap.ini |   1 +
 drivers/net/rtap/meson.build      |   1 +
 drivers/net/rtap/rtap.h           |  41 +++++
 drivers/net/rtap/rtap_ethdev.c    |   3 +
 drivers/net/rtap/rtap_rxtx.c      |   3 +
 drivers/net/rtap/rtap_xstats.c    | 293 ++++++++++++++++++++++++++++++
 6 files changed, 342 insertions(+)
 create mode 100644 drivers/net/rtap/rtap_xstats.c

diff --git a/doc/guides/nics/features/rtap.ini b/doc/guides/nics/features/rtap.ini
index 48fe3f1b33..233227e7d4 100644
--- a/doc/guides/nics/features/rtap.ini
+++ b/doc/guides/nics/features/rtap.ini
@@ -15,6 +15,7 @@ Basic stats          = Y
 Stats per queue      = Y
 TSO                  = Y
 L4 checksum offload  = Y
+Extended stats       = P
 Multiprocess aware   = Y
 Linux                = Y
 ARMv7                = Y
diff --git a/drivers/net/rtap/meson.build b/drivers/net/rtap/meson.build
index 58943e035a..835d1e557d 100644
--- a/drivers/net/rtap/meson.build
+++ b/drivers/net/rtap/meson.build
@@ -22,6 +22,7 @@ sources = files(
         'rtap_intr.c',
         'rtap_netlink.c',
         'rtap_rxtx.c',
+        'rtap_xstats.c',
 )
 
 ext_deps += liburing
diff --git a/drivers/net/rtap/rtap.h b/drivers/net/rtap/rtap.h
index 2c17117a80..ac4a616e99 100644
--- a/drivers/net/rtap/rtap.h
+++ b/drivers/net/rtap/rtap.h
@@ -35,6 +35,22 @@ extern int rtap_logtype;
 #define PMD_TX_LOG(...) do { } while (0)
 #endif
 
+/* Packet size buckets for xstats (similar to virtio PMD) */
+#define RTAP_NUM_PKT_SIZE_BUCKETS	6
+
+/* Extended statistics for Rx queues */
+struct rtap_rx_xstats {
+	uint64_t size_bins[RTAP_NUM_PKT_SIZE_BUCKETS];
+	uint64_t broadcast_packets;
+	uint64_t multicast_packets;
+	uint64_t unicast_packets;
+	uint64_t lro_packets;
+	uint64_t checksum_good;
+	uint64_t checksum_none;
+	uint64_t checksum_bad;
+	uint64_t mbuf_alloc_failed;
+};
+
 struct rtap_rx_queue {
 	struct rte_mempool *mb_pool;	/* rx buffer pool */
 	struct io_uring io_ring;	/* queue of posted read's */
@@ -45,8 +61,21 @@ struct rtap_rx_queue {
 	uint64_t rx_packets;
 	uint64_t rx_bytes;
 	uint64_t rx_errors;
+
+	struct rtap_rx_xstats xstats;	/* extended statistics */
 } __rte_cache_aligned;
 
+/* Extended statistics for Tx queues */
+struct rtap_tx_xstats {
+	uint64_t size_bins[RTAP_NUM_PKT_SIZE_BUCKETS];
+	uint64_t broadcast_packets;
+	uint64_t multicast_packets;
+	uint64_t unicast_packets;
+	uint64_t tso_packets;
+	uint64_t checksum_offload;
+	uint64_t multiseg_packets;
+};
+
 struct rtap_tx_queue {
 	struct io_uring io_ring;
 	uint16_t port_id;
@@ -56,6 +85,8 @@ struct rtap_tx_queue {
 	uint64_t tx_packets;
 	uint64_t tx_bytes;
 	uint64_t tx_errors;
+
+	struct rtap_tx_xstats xstats;	/* extended statistics */
 } __rte_cache_aligned;
 
 struct rtap_pmd {
@@ -108,4 +139,14 @@ void rtap_rx_intr_vec_uninstall(struct rte_eth_dev *dev);
 int rtap_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
 int rtap_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
 
+/* rtap_xstats.c */
+int rtap_xstats_get_names(struct rte_eth_dev *dev,
+			  struct rte_eth_xstat_name *xstats_names,
+			  unsigned int limit);
+int rtap_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+		    unsigned int n);
+int rtap_xstats_reset(struct rte_eth_dev *dev);
+void rtap_rx_xstats_update(struct rtap_rx_queue *rxq, struct rte_mbuf *mb);
+void rtap_tx_xstats_update(struct rtap_tx_queue *txq, struct rte_mbuf *mb);
+
 #endif /* _RTAP_H_ */
diff --git a/drivers/net/rtap/rtap_ethdev.c b/drivers/net/rtap/rtap_ethdev.c
index 2cbb66b675..eb581608cc 100644
--- a/drivers/net/rtap/rtap_ethdev.c
+++ b/drivers/net/rtap/rtap_ethdev.c
@@ -541,6 +541,9 @@ static const struct eth_dev_ops rtap_ops = {
 	.allmulticast_disable	= rtap_allmulticast_disable,
 	.stats_get		= rtap_stats_get,
 	.stats_reset		= rtap_stats_reset,
+	.xstats_get		= rtap_xstats_get,
+	.xstats_get_names	= rtap_xstats_get_names,
+	.xstats_reset		= rtap_xstats_reset,
 	.rx_queue_setup		= rtap_rx_queue_setup,
 	.rx_queue_release	= rtap_rx_queue_release,
 	.tx_queue_setup		= rtap_tx_queue_setup,
diff --git a/drivers/net/rtap/rtap_rxtx.c b/drivers/net/rtap/rtap_rxtx.c
index cd9b4f0bac..f0ea53b8cf 100644
--- a/drivers/net/rtap/rtap_rxtx.c
+++ b/drivers/net/rtap/rtap_rxtx.c
@@ -289,6 +289,7 @@ rtap_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 
 			PMD_RX_LOG(ERR, "Rx mbuf alloc failed");
 			dev->data->rx_mbuf_alloc_failed++;
+			rxq->xstats.mbuf_alloc_failed++;
 
 			nmb = mb;	 /* Reuse original */
 			goto resubmit;
@@ -317,6 +318,7 @@ rtap_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 		mb->port = rxq->port_id;
 
 		__rte_mbuf_sanity_check(mb, 1);
+		rtap_rx_xstats_update(rxq, mb);
 		num_bytes += mb->pkt_len;
 		bufs[num_rx++] = mb;
 
@@ -735,6 +737,7 @@ rtap_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 
 		io_uring_sqe_set_data(sqe, mb);
 		rtap_tx_offload(hdr, mb);
+		rtap_tx_xstats_update(txq, mb);
 
 		PMD_TX_LOG(DEBUG, "write m=%p segs=%u", mb, mb->nb_segs);
 
diff --git a/drivers/net/rtap/rtap_xstats.c b/drivers/net/rtap/rtap_xstats.c
new file mode 100644
index 0000000000..b5886844c5
--- /dev/null
+++ b/drivers/net/rtap/rtap_xstats.c
@@ -0,0 +1,293 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2026 Stephen Hemminger
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <ethdev_driver.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+
+#include "rtap.h"
+
+/*
+ * Xstats name/offset descriptors, following the virtio PMD pattern.
+ *
+ * Both xstats_get_names and xstats_get iterate these same tables
+ * in the same per-queue order, guaranteeing name[i] matches value[i].
+ */
+struct rtap_xstats_name_off {
+	const char *name;
+	unsigned int offset;
+};
+
+#define RTAP_RXQ_XSTAT(field) { #field, offsetof(struct rtap_rx_xstats, field) }
+#define RTAP_TXQ_XSTAT(field) { #field, offsetof(struct rtap_tx_xstats, field) }
+
+static const struct rtap_xstats_name_off rtap_rxq_xstats[] = {
+	RTAP_RXQ_XSTAT(size_bins[0]),
+	RTAP_RXQ_XSTAT(size_bins[1]),
+	RTAP_RXQ_XSTAT(size_bins[2]),
+	RTAP_RXQ_XSTAT(size_bins[3]),
+	RTAP_RXQ_XSTAT(size_bins[4]),
+	RTAP_RXQ_XSTAT(size_bins[5]),
+	RTAP_RXQ_XSTAT(broadcast_packets),
+	RTAP_RXQ_XSTAT(multicast_packets),
+	RTAP_RXQ_XSTAT(unicast_packets),
+	RTAP_RXQ_XSTAT(lro_packets),
+	RTAP_RXQ_XSTAT(checksum_good),
+	RTAP_RXQ_XSTAT(checksum_none),
+	RTAP_RXQ_XSTAT(checksum_bad),
+	RTAP_RXQ_XSTAT(mbuf_alloc_failed),
+};
+
+static const struct rtap_xstats_name_off rtap_txq_xstats[] = {
+	RTAP_TXQ_XSTAT(size_bins[0]),
+	RTAP_TXQ_XSTAT(size_bins[1]),
+	RTAP_TXQ_XSTAT(size_bins[2]),
+	RTAP_TXQ_XSTAT(size_bins[3]),
+	RTAP_TXQ_XSTAT(size_bins[4]),
+	RTAP_TXQ_XSTAT(size_bins[5]),
+	RTAP_TXQ_XSTAT(broadcast_packets),
+	RTAP_TXQ_XSTAT(multicast_packets),
+	RTAP_TXQ_XSTAT(unicast_packets),
+	RTAP_TXQ_XSTAT(tso_packets),
+	RTAP_TXQ_XSTAT(checksum_offload),
+	RTAP_TXQ_XSTAT(multiseg_packets),
+};
+
+/* Display names for size buckets (indexed by array position) */
+static const char * const rtap_size_bucket_names[] = {
+	"size_64",
+	"size_65_to_127",
+	"size_128_to_255",
+	"size_256_to_511",
+	"size_512_to_1023",
+	"size_1024_to_1518",
+};
+
+/* Size bucket upper bounds for the update helpers */
+static const uint16_t rtap_size_bucket_limits[RTAP_NUM_PKT_SIZE_BUCKETS] = {
+	64, 127, 255, 511, 1023, 1518,
+};
+
+#define RTAP_NUM_RXQ_XSTATS RTE_DIM(rtap_rxq_xstats)
+#define RTAP_NUM_TXQ_XSTATS RTE_DIM(rtap_txq_xstats)
+
+static unsigned int
+rtap_xstats_count(const struct rte_eth_dev *dev)
+{
+	return dev->data->nb_rx_queues * RTAP_NUM_RXQ_XSTATS +
+	       dev->data->nb_tx_queues * RTAP_NUM_TXQ_XSTATS;
+}
+
+/*
+ * Build a display name for a per-queue xstat.
+ *
+ * For size_bins[N] entries, use the human-readable bucket name;
+ * for everything else, use the field name directly.
+ */
+static void
+rtap_xstat_name(char *buf, size_t bufsz,
+		const char *dir, unsigned int q,
+		const struct rtap_xstats_name_off *desc)
+{
+	/* Check if this is a size_bins entry */
+	for (unsigned int i = 0; i < RTAP_NUM_PKT_SIZE_BUCKETS; i++) {
+		char binref[32];
+
+		snprintf(binref, sizeof(binref), "size_bins[%u]", i);
+		if (strcmp(desc->name, binref) == 0) {
+			snprintf(buf, bufsz, "%s_q%u_%s_packets",
+				 dir, q, rtap_size_bucket_names[i]);
+			return;
+		}
+	}
+
+	snprintf(buf, bufsz, "%s_q%u_%s", dir, q, desc->name);
+}
+
+int
+rtap_xstats_get_names(struct rte_eth_dev *dev,
+		      struct rte_eth_xstat_name *xstats_names,
+		      unsigned int limit)
+{
+	unsigned int nb_rx = dev->data->nb_rx_queues;
+	unsigned int nb_tx = dev->data->nb_tx_queues;
+	unsigned int count = rtap_xstats_count(dev);
+	unsigned int idx = 0;
+
+	if (xstats_names == NULL)
+		return count;
+
+	/* Rx queue stats: all stats for queue 0, then all for queue 1, ... */
+	for (unsigned int q = 0; q < nb_rx; q++) {
+		for (unsigned int i = 0; i < RTAP_NUM_RXQ_XSTATS; i++) {
+			if (idx >= limit)
+				goto out;
+
+			rtap_xstat_name(xstats_names[idx].name,
+					sizeof(xstats_names[idx].name),
+					"rx", q, &rtap_rxq_xstats[i]);
+			idx++;
+		}
+	}
+
+	/* Tx queue stats: all stats for queue 0, then all for queue 1, ... */
+	for (unsigned int q = 0; q < nb_tx; q++) {
+		for (unsigned int i = 0; i < RTAP_NUM_TXQ_XSTATS; i++) {
+			if (idx >= limit)
+				goto out;
+
+			rtap_xstat_name(xstats_names[idx].name,
+					sizeof(xstats_names[idx].name),
+					"tx", q, &rtap_txq_xstats[i]);
+			idx++;
+		}
+	}
+
+out:
+	return count;
+}
+
+int
+rtap_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+		unsigned int n)
+{
+	unsigned int nb_rx = dev->data->nb_rx_queues;
+	unsigned int nb_tx = dev->data->nb_tx_queues;
+	unsigned int count = rtap_xstats_count(dev);
+	unsigned int idx = 0;
+
+	if (n < count)
+		return count;
+
+	/* Collect Rx queue xstats — same per-queue order as names */
+	for (unsigned int q = 0; q < nb_rx; q++) {
+		struct rtap_rx_queue *rxq = dev->data->rx_queues[q];
+
+		for (unsigned int i = 0; i < RTAP_NUM_RXQ_XSTATS; i++) {
+			xstats[idx].id = idx;
+			if (rxq == NULL)
+				xstats[idx].value = 0;
+			else
+				xstats[idx].value =
+					*(uint64_t *)((char *)&rxq->xstats +
+						       rtap_rxq_xstats[i].offset);
+			idx++;
+		}
+	}
+
+	/* Collect Tx queue xstats — same per-queue order as names */
+	for (unsigned int q = 0; q < nb_tx; q++) {
+		struct rtap_tx_queue *txq = dev->data->tx_queues[q];
+
+		for (unsigned int i = 0; i < RTAP_NUM_TXQ_XSTATS; i++) {
+			xstats[idx].id = idx;
+			if (txq == NULL)
+				xstats[idx].value = 0;
+			else
+				xstats[idx].value =
+					*(uint64_t *)((char *)&txq->xstats +
+						       rtap_txq_xstats[i].offset);
+			idx++;
+		}
+	}
+
+	return idx;
+}
+
+int
+rtap_xstats_reset(struct rte_eth_dev *dev)
+{
+	for (unsigned int q = 0; q < dev->data->nb_rx_queues; q++) {
+		struct rtap_rx_queue *rxq = dev->data->rx_queues[q];
+		if (rxq != NULL)
+			memset(&rxq->xstats, 0, sizeof(rxq->xstats));
+	}
+
+	for (unsigned int q = 0; q < dev->data->nb_tx_queues; q++) {
+		struct rtap_tx_queue *txq = dev->data->tx_queues[q];
+		if (txq != NULL)
+			memset(&txq->xstats, 0, sizeof(txq->xstats));
+	}
+
+	return 0;
+}
+
+/* Helper to update Rx xstats — called from rx_burst */
+void
+rtap_rx_xstats_update(struct rtap_rx_queue *rxq, struct rte_mbuf *mb)
+{
+	struct rtap_rx_xstats *xs = &rxq->xstats;
+	uint16_t pkt_len = mb->pkt_len;
+	struct rte_ether_hdr *eth_hdr;
+
+	/* Update size bucket */
+	for (unsigned int i = 0; i < RTAP_NUM_PKT_SIZE_BUCKETS; i++) {
+		if (pkt_len <= rtap_size_bucket_limits[i]) {
+			xs->size_bins[i]++;
+			break;
+		}
+	}
+
+	/* Update packet type counters */
+	eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
+	if (rte_is_broadcast_ether_addr(&eth_hdr->dst_addr))
+		xs->broadcast_packets++;
+	else if (rte_is_multicast_ether_addr(&eth_hdr->dst_addr))
+		xs->multicast_packets++;
+	else
+		xs->unicast_packets++;
+
+	/* Update offload-related counters */
+	if (mb->ol_flags & RTE_MBUF_F_RX_LRO)
+		xs->lro_packets++;
+
+	if (mb->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
+		xs->checksum_good++;
+	else if (mb->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_NONE)
+		xs->checksum_none++;
+	else if (mb->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_BAD)
+		xs->checksum_bad++;
+}
+
+/* Helper to update Tx xstats — called from tx_burst */
+void
+rtap_tx_xstats_update(struct rtap_tx_queue *txq, struct rte_mbuf *mb)
+{
+	struct rtap_tx_xstats *xs = &txq->xstats;
+	uint16_t pkt_len = mb->pkt_len;
+	struct rte_ether_hdr *eth_hdr;
+
+	/* Update size bucket */
+	for (unsigned int i = 0; i < RTAP_NUM_PKT_SIZE_BUCKETS; i++) {
+		if (pkt_len <= rtap_size_bucket_limits[i]) {
+			xs->size_bins[i]++;
+			break;
+		}
+	}
+
+	/* Update packet type counters */
+	eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
+	if (rte_is_broadcast_ether_addr(&eth_hdr->dst_addr))
+		xs->broadcast_packets++;
+	else if (rte_is_multicast_ether_addr(&eth_hdr->dst_addr))
+		xs->multicast_packets++;
+	else
+		xs->unicast_packets++;
+
+	/* Update offload-related counters */
+	if (mb->ol_flags & RTE_MBUF_F_TX_TCP_SEG)
+		xs->tso_packets++;
+
+	if ((mb->ol_flags & RTE_MBUF_F_TX_L4_MASK) != 0)
+		xs->checksum_offload++;
+
+	if (mb->nb_segs > 1)
+		xs->multiseg_packets++;
+}
-- 
2.51.0


  parent reply	other threads:[~2026-02-14 23:48 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-10 21:23 [RFC 0/8] ioring: network driver Stephen Hemminger
2024-12-10 21:23 ` [RFC 1/8] net/ioring: introduce new driver Stephen Hemminger
2024-12-10 21:23 ` [RFC 2/8] net/ioring: implement link state Stephen Hemminger
2024-12-10 21:23 ` [RFC 3/8] net/ioring: implement control functions Stephen Hemminger
2024-12-10 21:23 ` [RFC 4/8] net/ioring: implement management functions Stephen Hemminger
2024-12-10 21:23 ` [RFC 5/8] net/ioring: implement primary secondary fd passing Stephen Hemminger
2024-12-10 21:23 ` [RFC 6/8] net/ioring: implement receive and transmit Stephen Hemminger
2024-12-10 21:23 ` [RFC 7/8] net/ioring: add VLAN support Stephen Hemminger
2024-12-10 21:23 ` [RFC 8/8] net/ioring: implement statistics Stephen Hemminger
2024-12-11 11:34 ` [RFC 0/8] ioring: network driver Konstantin Ananyev
2024-12-11 15:03   ` Stephen Hemminger
2024-12-12 19:06     ` Konstantin Ananyev
2024-12-19 15:40       ` Morten Brørup
2024-12-20 14:34         ` Konstantin Ananyev
2024-12-20 16:19           ` Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 " Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 1/8] net/ioring: introduce new driver Stephen Hemminger
2024-12-28 16:39     ` Morten Brørup
2024-12-11 16:28   ` [PATCH v2 2/8] net/ioring: implement link state Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 3/8] net/ioring: implement control functions Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 4/8] net/ioring: implement management functions Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 5/8] net/ioring: implement primary secondary fd passing Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 6/8] net/ioring: implement receive and transmit Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 7/8] net/ioring: add VLAN support Stephen Hemminger
2024-12-11 16:28   ` [PATCH v2 8/8] net/ioring: implement statistics Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 0/9] ioring PMD device Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 1/9] net/ioring: introduce new driver Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 2/9] net/ioring: implement link state Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 3/9] net/ioring: implement control functions Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 4/9] net/ioring: implement management functions Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 5/9] net/ioring: implement secondary process support Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 6/9] net/ioring: implement receive and transmit Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 7/9] net/ioring: add VLAN support Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 8/9] net/ioring: implement statistics Stephen Hemminger
2025-03-11 23:51   ` [PATCH v3 9/9] net/ioring: support multi-segment Rx and Tx Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 00/10] new ioring PMD Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 01/10] net/ioring: introduce new driver Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 02/10] net/ioring: implement link state Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 03/10] net/ioring: implement control functions Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 04/10] net/ioring: implement management functions Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 05/10] net/ioring: implement secondary process support Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 06/10] net/ioring: implement receive and transmit Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 07/10] net/ioring: implement statistics Stephen Hemminger
2025-03-13 21:50   ` [PATCH v4 08/10] net/ioring: support multi-segment Rx and Tx Stephen Hemminger
2025-03-13 21:51   ` [PATCH v4 09/10] net/ioring: support Tx checksum and segment offload Stephen Hemminger
2025-03-13 21:51   ` [PATCH v4 10/10] net/ioring: add support for Rx offload Stephen Hemminger
2026-02-09 18:38 ` [PATCH v5 00/10] net/rtap: add io_uring based TAP driver Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 01/10] net/rtap: add driver skeleton and documentation Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 02/10] net/rtap: add TAP device creation and queue management Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 03/10] net/rtap: add Rx/Tx with scatter/gather support Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 04/10] net/rtap: add statistics and device info Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 05/10] net/rtap: add link and device management operations Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 06/10] net/rtap: add checksum and TSO offload support Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 07/10] net/rtap: add link state change interrupt Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 08/10] net/rtap: add multi-process support Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 09/10] net/rtap: add Rx interrupt support Stephen Hemminger
2026-02-09 18:39   ` [PATCH v5 10/10] test: add unit tests for rtap PMD Stephen Hemminger
2026-02-10  9:18   ` [PATCH v5 00/10] net/rtap: add io_uring based TAP driver Morten Brørup
2026-02-14 23:44 ` [PATCH v6 00/11] " Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 01/11] net/rtap: add driver skeleton and documentation Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 02/11] net/rtap: add TAP device creation and queue management Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 03/11] net/rtap: add Rx/Tx with scatter/gather support Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 04/11] net/rtap: add statistics and device info Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 05/11] net/rtap: add link and device management operations Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 06/11] net/rtap: add checksum and TSO offload support Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 07/11] net/rtap: add multi-process support Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 08/11] net/rtap: add link state change interrupt Stephen Hemminger
2026-02-14 23:44   ` [PATCH v6 09/11] net/rtap: add Rx interrupt support Stephen Hemminger
2026-02-14 23:44   ` Stephen Hemminger [this message]
2026-02-14 23:44   ` [PATCH v6 11/11] test: add unit tests for rtap PMD Stephen Hemminger
2026-02-15  8:58   ` [PATCH v6 00/11] net/rtap: add io_uring based TAP driver Konstantin Ananyev
2026-02-15 17:08     ` Stephen Hemminger

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=20260214234726.188947-11-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --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