From: Longjun Tang <lange_tang@163.com>
To: mst@redhat.com, kuba@kernel.org
Cc: jasowangio@gmail.com, xuanzhuo@linux.alibaba.com,
virtualization@lists.linux.dev, netdev@vger.kernel.org,
tanglongjun@kylinos.cn
Subject: [RFC PATCH 0/3] virtio_net: introduce an RX queue watchdog for stuck detection
Date: Fri, 28 Aug 2026 15:43:23 +0800 [thread overview]
Message-ID: <20260828074326.65594-1-lange_tang@163.com> (raw)
From: Longjun Tang <tanglongjun@kylinos.cn>
The virtio_net RX path relies on backend interrupt notifications.
The backend(vhost_net/vhost-user) appends buffers to the used ring
and then notifies the guest, relying on the hypervisor(KVM) to inject
the interrupt. On receiving it, virtio_net schedules NAPI, drains the
used ring and refills descriptors.
If the hypervisor fails to inject the interrupt(e.g. a transient KVM
failure), the guest never schedules NAPI, so it neither consumes buffers
nor returns descriptors. The backend keeps appending until the ring is full,
then stops and, with no free descriptors left, also stops sending
notifications. Both sides now wait for the other, and the RX queue is
permanently stuck.
The root cause is the lost interrupt in the hypervisor, and the proper
fix belongs there. Nevertheless, I believe virtio_net needs a way to
observe and diagnose it. Today, once a queue hangs, there is no signal
to the operator that anything is wrong: the RX path has no equivalent of
the TX watchdog (ndo_tx_timeout). This series lets virtio_net detect a
stuck RX queue. It is detection only: the driver records the event and
logs a warning, leaving recovery to a follow-up if desired.
Implementation
--------------
Patch 1 exports virtqueue_get_last_used_idx(), a read-only accessor for
the last_used_idx. Together with the existing virtqueue_poll(), it lets
a driver ask whether the device has produced buffers that the driver has
not consumed yet ("backlog").
Patch 2 adds a per-device RX watchdog that scans all RX queues once per
second. A queue is considered stuck when, for rx_watchdog_timeo seconds
(default 5, 0 disables it), all of the following hold simultaneously:
- the queue has a non-zero backlog (used.idx != last_used_idx);
- the driver makes no consumption progress (last_used_idx unchanged);
- no new interrupt arrives (rq->calls unchanged).
On detection it logs a warning, rate-limited to once per timeout.
Patch 3 adds a per-queue rx_timeouts statistic, exposed via ethtool -S,
so the number of watchdog events can be observed per queue.
RFC
---
This is sent as an RFC to gather feedback on a few open points:
- Scope: this series only detects the stuck queue. Is it better to
keep detection and recovery separate, or should recovery (forcing a
NAPI poll to drain the queue) be included?
- Default: rx_watchdog_timeo defaults to 5 seconds (enabled). Should
the watchdog be enabled by default, or disabled unless explicitly
requested?
Parts of this series, including portions of this cover letter, were drafted
with AI assistance. I have carefully reviewed everything;
questions and comments are welcome.
Thanks!
Lange
Longjun Tang (3):
virtio: add virtqueue_get_last_used_idx() helper
virtio_net: introduce an RX queue watchdog for stuck detection
virtio_net: add rx_timeouts per-queue statistic
drivers/net/virtio_net.c | 103 +++++++++++++++++++++++++++++++++++
drivers/virtio/virtio_ring.c | 23 +++++++-
include/linux/virtio.h | 2 +
3 files changed, 126 insertions(+), 2 deletions(-)
base-commit: 2709dd5ae32f0828f386327c76bba9f39f63a1c6
--
2.43.0
next reply other threads:[~2026-08-28 7:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 7:43 Longjun Tang [this message]
2026-08-28 7:43 ` [RFC PATCH 1/3] virtio: add virtqueue_get_last_used_idx() helper Longjun Tang
2026-08-28 7:43 ` [RFC PATCH 2/3] virtio_net: introduce an RX queue watchdog for stuck detection Longjun Tang
2026-08-28 7:43 ` [RFC PATCH 3/3] virtio_net: add rx_timeouts per-queue statistic Longjun Tang
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=20260828074326.65594-1-lange_tang@163.com \
--to=lange_tang@163.com \
--cc=jasowangio@gmail.com \
--cc=kuba@kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=tanglongjun@kylinos.cn \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/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