lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250506154117.10651-1-alex-shalimov@yandex-team.ru>
Date: Tue,  6 May 2025 18:41:17 +0300
From: Alexander Shalimov <alex-shalimov@...dex-team.ru>
To: netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: willemdebruijn.kernel@...il.com,
	jasowang@...hat.com,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	Alexander Shalimov <alex-shalimov@...dex-team.ru>
Subject: [PATCH] net/tun: expose queue utilization stats via ethtool

TUN/TAP devices are heavily used in network virtualization scenarios
such as QEMU/KVM with "-netdev tap" and are commonly paired with virtio-net
or vhost-net backends. Under high network load, queues of the tuntap device
may become saturated, resulting in TX drops.

Existing aggregated drop counters alone are often insufficient during
complex debugging and performance tuning, especially in high-throughput
environments. Visibility of real-time queue utilization is critical for
understanding why guest VMs might be unable to dequeue packets in time.

This patch exposes per-queue utilization statistics via ethtool -S,
allowing on-demand inspection of queue fill levels. Utilization metrics are
captured at the time of the ethtool invocation, providing a snapshot useful
for correlation with guest and host behavior.

Signed-off-by: Alexander Shalimov <alex-shalimov@...dex-team.ru>
---
 drivers/net/tun.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 7babd1e9a378..122327e591a5 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -3537,6 +3537,57 @@ static void tun_get_channels(struct net_device *dev,
 	channels->max_combined = tun->flags & IFF_MULTI_QUEUE ? MAX_TAP_QUEUES : 1;
 }
 
+static void tun_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+	char *p = (char *)buf;
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < dev->real_num_tx_queues; i++) {
+			snprintf(p, ETH_GSTRING_LEN, "tx_queue_usage_%u", i);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+static int tun_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return dev->real_num_tx_queues;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void tun_get_ethtool_stats(struct net_device *dev,
+				  struct ethtool_stats *stats, u64 *data)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	struct tun_file *tfile;
+	int i;
+	int producer, consumer, size, usage;
+
+	rcu_read_lock();
+	for (i = 0; i < dev->real_num_tx_queues; i++) {
+		tfile = rcu_dereference(tun->tfiles[i]);
+
+		producer = READ_ONCE(tfile->tx_ring.producer);
+		consumer = READ_ONCE(tfile->tx_ring.consumer_head);
+		size = READ_ONCE(tfile->tx_ring.size);
+
+		if (producer >= consumer)
+			usage = producer - consumer;
+		else
+			usage = size - (consumer - producer);
+
+		data[i] = usage;
+	}
+	rcu_read_unlock();
+}
+
 static const struct ethtool_ops tun_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_RX_MAX_FRAMES,
 	.get_drvinfo	= tun_get_drvinfo,
@@ -3549,6 +3600,9 @@ static const struct ethtool_ops tun_ethtool_ops = {
 	.set_coalesce   = tun_set_coalesce,
 	.get_link_ksettings = tun_get_link_ksettings,
 	.set_link_ksettings = tun_set_link_ksettings,
+	.get_strings	    = tun_get_strings,
+	.get_sset_count	    = tun_get_sset_count,
+	.get_ethtool_stats  = tun_get_ethtool_stats,
 };
 
 static int tun_queue_resize(struct tun_struct *tun)
-- 
2.39.5 (Apple Git-154)


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ