Public bug reported:
[ Impact ]
QEMU's userspace virtio-net RX path can permanently stall in an affected
guest network device. The guest and QEMU process remain alive, and
guest-to-host traffic can still be observed after bypassing ARP with a
static neighbour entry, but host-to-guest delivery stops until the VM is
restarted.
The issue is a race in virtio_net_has_buffers(). The old code enables RX
queue notification and then re-checks available buffers, but that re-
check reused a stale shadow copy of the available index instead of re-
reading the guest's available index. With event-index notification
suppression, the guest can add buffers in the small window between
enabling notification and the re-check without sending another kick, and
because the re-check never refreshes that shadow copy it misses those
new buffers. QEMU then waits for a kick that will not arrive, leaving
the host-to-guest RX path wedged.
This affects workloads using QEMU userspace virtio-net, especially under
sustained host-to-guest traffic and configurations that make RX buffer
exhaustion more frequent.
[ Test Plan ]
The test must use QEMU userspace virtio-net. Do not use vhost-net for
this test, because vhost-net moves the data path out of the QEMU
userspace code being fixed.
How to run this plan:
- Run steps 1-6 twice: once on the affected qemu (expect step 7) and once on
the patched qemu carrying the fix (expect step 8). Concrete bridge/tap, build
and run commands used here are in the detailed sections below.
- The stall is a race, so it is not deterministic. A single clean run does
not prove the fix. On the affected qemu, repeat the run (and if needed raise -P
/ -t or lower the ring) until the stall is observed; on the patched qemu,
repeat the same condition that reliably reproduced on the affected qemu several
times and confirm it never stalls.
1. Prepare a KVM host and one Ubuntu guest connected through a host
bridge and tap device.
Host:
bridge: 10.77.0.1/24
tap: attached to the bridge
Guest:
static IP: 10.77.0.2/24
kernel command line includes: swiotlb=force
(with iommu_platform=on this forces the guest onto the bounce-buffer DMA
path, which makes RX buffer exhaustion and the notification race more frequent)
QEMU NIC:
virtio-net-pci-non-transitional
iommu_platform=on
mrg_rxbuf=on
rx_queue_size=256
2. Boot the guest with the qemu-system-x86_64 binary under test.
In the guest, reduce the virtio-net ring when the QEMU version
supports it:
sudo ethtool -G GUEST_IFACE rx 64 tx 64 || true
Record the actual ring size:
ethtool -g GUEST_IFACE
3. In the guest, start two iperf3 servers:
iperf3 -s -p 8001
iperf3 -s -p 8002
4. From the host, start simultaneous host-to-guest traffic to both
ports.
Short run used for Noble, where RX/TX could be reduced to 64:
iperf3 -c 10.77.0.2 -p 8001 -P 20 -w 256k -t 120 -i 5 -f m
iperf3 -c 10.77.0.2 -p 8002 -P 20 -w 256k -t 120 -i 5 -f m
Stronger run used for Jammy, where QEMU 6.2 only allowed RX/TX 256.
Because the ring cannot be shrunk, raise the stream count instead to
make RX buffer exhaustion frequent (P80 reproduces reliably; the earlier
P40 was intermittent):
iperf3 -c 10.77.0.2 -p 8001 -P 80 -w 256k -t 120 -i 5 -f m
iperf3 -c 10.77.0.2 -p 8002 -P 80 -w 256k -t 120 -i 5 -f m
5. After the load, verify host-to-guest connectivity:
ping -c 10 -W 1 10.77.0.2
timeout 15s iperf3 -c 10.77.0.2 -p 8001 -P 1 -t 5 -i 1 -f m
6. If host-to-guest traffic stalls, verify that the VM and guest TX path
are still alive:
- the guest serial console still accepts commands
- QMP/HMP reports the VM as running and virtio-net as not broken
- add a static neighbour entry for 10.77.0.1 inside the guest
- send one UDP packet from the guest to 10.77.0.1
- observe that UDP packet on the host with a UDP listener or tcpdump
7. Expected result on an affected qemu:
The host-to-guest RX path eventually stalls. This is observed as
either:
- an iperf3 receiver summary of 0.00 Bytes / 0.00 Mbits/sec, or
- a post-load TCP probe whose receiver side drops to 0.00 Mbits/sec.
The VM remains running. The guest serial console still works. Guest-
to-host UDP can still be observed after static ARP, showing that this is
not a full VM hang.
8. Expected result on the patched qemu:
The same workload completes without host-to-guest RX stall:
- iperf3 receiver throughput remains non-zero
- host-to-guest ping succeeds
- the post-load TCP probe succeeds
- serial-console guest-to-host ping succeeds
Validation examples from the test environment:
Noble stock qemu 1:8.2.2+ds-0ubuntu1.17:
P20 / 120s / RX 64 TX 64 reproduced the stall.
Jammy stock qemu 1:6.2+dfsg-2ubuntu6.31:
P80 / 120s / RX 256 TX 256 with a Jammy 22.04 guest reproduced the
host-to-guest RX stall in 5/5 runs.
The earlier P40 / 240s condition reproduced only intermittently (about 1
in 12). See section 13 for the rate sweep.
Patched QEMU 8.2.2 with the stable-8.2 fix:
P20 / 120s completed with non-zero receiver throughput, successful
post-load ping, successful TCP probe, and successful serial-console ping.
[ Where problems could occur ]
The change touches virtio-net RX buffer availability checking and a
virtio core notification helper. Regressions would most likely appear as
virtio-net RX performance changes, missed or extra virtqueue
notifications, or guest network connectivity problems under high
throughput.
The fix makes the notification-enable path more conservative by re-
reading the available index after enabling notification, instead of
relying on the older check that can miss a guest buffer update. The risk
is mitigated by the patch being present in newer upstream/stable QEMU
versions and by focused regression testing with sustained virtio-net
traffic.
[ Other Info ]
Upstream fix:
f937309fbdbb48c354220a3e7110c202ae4aa7fa
virtio-net: Fix network stall at the host side waiting for kick
** Affects: qemu (Ubuntu)
Importance: Undecided
Status: Fix Released
** Affects: qemu (Ubuntu Jammy)
Importance: Undecided
Assignee: Seyeong Kim (seyeongkim)
Status: In Progress
** Affects: qemu (Ubuntu Noble)
Importance: Undecided
Assignee: Seyeong Kim (seyeongkim)
Status: In Progress
** Also affects: qemu (Ubuntu Noble)
Importance: Undecided
Status: New
** Also affects: qemu (Ubuntu Jammy)
Importance: Undecided
Status: New
** Changed in: qemu (Ubuntu)
Status: New => Fix Released
** Changed in: qemu (Ubuntu Jammy)
Assignee: (unassigned) => Seyeong Kim (seyeongkim)
** Changed in: qemu (Ubuntu Noble)
Assignee: (unassigned) => Seyeong Kim (seyeongkim)
** Changed in: qemu (Ubuntu Noble)
Status: New => In Progress
** Changed in: qemu (Ubuntu Jammy)
Status: New => In Progress
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2158673
Title:
qemu: virtio-net host-to-guest RX stalls under sustained traffic
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2158673/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs