Linux virtualization list
 help / color / mirror / Atom feed
* [PATCH v2] virtio_net: add rx-alloc-fail counter
@ 2026-08-20  6:09 Longjun Tang
  2026-08-24 18:20 ` Jakub Kicinski
  0 siblings, 1 reply; 3+ messages in thread
From: Longjun Tang @ 2026-08-20  6:09 UTC (permalink / raw)
  To: mst, kuba, jasowangio
  Cc: xuanzhuo, virtualization, netdev, tanglongjun, lange_tang

From: Longjun Tang <tanglongjun@kylinos.cn>

Count the cases where the driver fails to allocate a buffer or an skb,
such as when try_fill_recv() fails with ENOMEM, and report them via the
rx-alloc-fail qstat.

Plumb alloc-fail into virtnet_get_base_stats() to keep this new stat
reported consistently at both queue and device scope, matching how
packets, bytes, stop and wake are handled.

$ ./tools/net/ynl/ynltool/ynltool qstats show --json scope queue
[{"ifname":"ens3",
"ifindex":2,
"queue-type":"rx",
"queue-id":0,
"rx":{"packets":3722,"bytes":374806,"alloc-fail":0}},
{"ifname":"ens3",
"ifindex":2,
"queue-type":"tx",
"queue-id":0,
"tx":{"packets":622,"bytes":77495,"stop":0,"wake":0}}]

Signed-off-by: Longjun Tang <tanglongjun@kylinos.cn>
---
 drivers/net/virtio_net.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 3e2a5876c6c8..2eeff9c46309 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -125,6 +125,7 @@ struct virtnet_rq_stats {
 	u64_stats_t packets;
 	u64_stats_t bytes;
 	u64_stats_t drops;
+	u64_stats_t alloc_fail;
 	u64_stats_t xdp_packets;
 	u64_stats_t xdp_tx;
 	u64_stats_t xdp_redirects;
@@ -173,8 +174,9 @@ static const struct virtnet_stat_desc virtnet_sq_stats_desc_qstat[] = {
 };
 
 static const struct virtnet_stat_desc virtnet_rq_stats_desc_qstat[] = {
-	VIRTNET_RQ_STAT_QSTAT("packets", packets),
-	VIRTNET_RQ_STAT_QSTAT("bytes",   bytes),
+	VIRTNET_RQ_STAT_QSTAT("packets",    packets),
+	VIRTNET_RQ_STAT_QSTAT("bytes",      bytes),
+	VIRTNET_RQ_STAT_QSTAT("alloc_fail", alloc_fail),
 };
 
 #define VIRTNET_STATS_DESC_CQ(name) \
@@ -1917,8 +1919,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	}
 
 	skb = virtnet_build_skb(buf, buflen, xdp.data - buf, len);
-	if (unlikely(!skb))
+	if (unlikely(!skb)) {
+		u64_stats_inc(&stats->alloc_fail);
 		goto err;
+	}
 
 	if (metasize)
 		skb_metadata_set(skb, metasize);
@@ -1985,6 +1989,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		return skb;
 	}
 
+	u64_stats_inc(&stats->alloc_fail);
 err:
 	u64_stats_inc(&stats->drops);
 	page_pool_put_page(rq->page_pool, page, -1, true);
@@ -2016,8 +2021,10 @@ static struct sk_buff *receive_big(struct net_device *dev,
 
 	skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0);
 	u64_stats_add(&stats->bytes, len - vi->hdr_len);
-	if (unlikely(!skb))
+	if (unlikely(!skb)) {
+		u64_stats_inc(&stats->alloc_fail);
 		goto err;
+	}
 
 	return skb;
 
@@ -2298,8 +2305,10 @@ static struct sk_buff *receive_mergeable_xdp(struct net_device *dev,
 	switch (act) {
 	case XDP_PASS:
 		head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
-		if (unlikely(!head_skb))
+		if (unlikely(!head_skb)) {
+			u64_stats_inc(&stats->alloc_fail);
 			break;
+		}
 
 		skb_mark_for_recycle(head_skb);
 		return head_skb;
@@ -2414,8 +2423,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	head_skb = page_to_skb(vi, rq, page, offset, len, truesize, headroom);
 	curr_skb = head_skb;
 
-	if (unlikely(!curr_skb))
+	if (unlikely(!curr_skb)) {
+		u64_stats_inc(&stats->alloc_fail);
 		goto err_skb;
+	}
 
 	skb_mark_for_recycle(head_skb);
 	while (--num_buf) {
@@ -2444,8 +2455,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		truesize = mergeable_ctx_to_truesize(ctx);
 		curr_skb  = virtnet_skb_append_frag(rq, head_skb, curr_skb, page,
 						    buf, len, truesize);
-		if (!curr_skb)
+		if (!curr_skb) {
+			u64_stats_inc(&stats->alloc_fail);
 			goto err_skb;
+		}
 	}
 
 	ewma_pkt_len_add(&rq->mrg_avg_pkt_len, head_skb->len);
@@ -2928,12 +2941,14 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
 
 	u64_stats_set(&stats.packets, packets);
 	if (rq->vq->num_free > min((unsigned int)budget, virtqueue_get_vring_size(rq->vq)) / 2) {
-		if (!try_fill_recv(vi, rq, GFP_ATOMIC))
+		if (!try_fill_recv(vi, rq, GFP_ATOMIC)) {
 			/* We need to retry refilling in the next NAPI poll so
 			 * we must return budget to make sure the NAPI is
 			 * repolled.
 			 */
 			packets = budget;
+			u64_stats_inc(&stats.alloc_fail);
+		}
 	}
 
 	u64_stats_update_begin(&rq->stats.syncp);
@@ -2948,6 +2963,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
 
 	u64_stats_add(&rq->stats.packets, u64_stats_read(&stats.packets));
 	u64_stats_add(&rq->stats.bytes, u64_stats_read(&stats.bytes));
+	u64_stats_add(&rq->stats.alloc_fail, u64_stats_read(&stats.alloc_fail));
 
 	u64_stats_update_end(&rq->stats.syncp);
 
@@ -5652,6 +5668,7 @@ static void virtnet_get_base_stats(struct net_device *dev,
 	 */
 	rx->bytes = 0;
 	rx->packets = 0;
+	rx->alloc_fail = 0;
 
 	if (vi->device_stats_cap & VIRTIO_NET_STATS_TYPE_RX_BASIC) {
 		rx->hw_drops = 0;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] virtio_net: add rx-alloc-fail counter
  2026-08-20  6:09 [PATCH v2] virtio_net: add rx-alloc-fail counter Longjun Tang
@ 2026-08-24 18:20 ` Jakub Kicinski
  2026-08-25  8:13   ` Lange Tang
  0 siblings, 1 reply; 3+ messages in thread
From: Jakub Kicinski @ 2026-08-24 18:20 UTC (permalink / raw)
  To: Longjun Tang
  Cc: mst, jasowangio, xuanzhuo, virtualization, netdev, tanglongjun

On Thu, 20 Aug 2026 14:09:29 +0800 Longjun Tang wrote:
> Count the cases where the driver fails to allocate a buffer or an skb,
> such as when try_fill_recv() fails with ENOMEM, and report them via the
> rx-alloc-fail qstat.
> 
> Plumb alloc-fail into virtnet_get_base_stats() to keep this new stat
> reported consistently at both queue and device scope, matching how
> packets, bytes, stop and wake are handled.

The stats handling in virtio_net is super convoluted but AFAICT
your patch is good. Unfortunately, net-next is closed right now
(merge window) to you will have to repost next week.

Maybe you can try to cover more allocation failures per:
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260820060929.69576-1-lange_tang@163.com
Or add a sentence or two to the commit message that we do not intend
to cover 100% of cases where packet is dropped.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re:Re: [PATCH v2] virtio_net: add rx-alloc-fail counter
  2026-08-24 18:20 ` Jakub Kicinski
@ 2026-08-25  8:13   ` Lange Tang
  0 siblings, 0 replies; 3+ messages in thread
From: Lange Tang @ 2026-08-25  8:13 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst@redhat.com, jasowangio@gmail.com, xuanzhuo@linux.alibaba.com,
	virtualization@lists.linux.dev, netdev@vger.kernel.org,
	Tang Longjun

At 2026-08-25 02:20:50, "Jakub Kicinski" <kuba@kernel.org> wrote:
>On Thu, 20 Aug 2026 14:09:29 +0800 Longjun Tang wrote:
>> Count the cases where the driver fails to allocate a buffer or an skb,
>> such as when try_fill_recv() fails with ENOMEM, and report them via the
>> rx-alloc-fail qstat.
>> 
>> Plumb alloc-fail into virtnet_get_base_stats() to keep this new stat
>> reported consistently at both queue and device scope, matching how
>> packets, bytes, stop and wake are handled.
>
>The stats handling in virtio_net is super convoluted but AFAICT
>your patch is good. Unfortunately, net-next is closed right now
>(merge window) to you will have to repost next week.
>
>Maybe you can try to cover more allocation failures per:
>https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260820060929.69576-1-lange_tang@163.com
>Or add a sentence or two to the commit message that we do not intend
>to cover 100% of cases where packet is dropped.

Thank you for your review and reply.
I will repost v3 next week and add some description to the commit message:
This counter does not cover every allocation failure in all RX paths.
It is intentionally limited to the common skb and RX buffer allocation
paths to keep its meaning clear.

thanks.
Longjun Tang

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-25  8:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20  6:09 [PATCH v2] virtio_net: add rx-alloc-fail counter Longjun Tang
2026-08-24 18:20 ` Jakub Kicinski
2026-08-25  8:13   ` Lange Tang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox