Page MenuHomeFreeBSD

bhyve: skip empty packets in the netmap backend's receive ring
Needs ReviewPublic

Authored by wanpengqian_gmail.com on Fri, Oct 2, 3:37 AM.

Details

Reviewers
vmaffione
Group Reviewers
bhyve
Summary

A VALE switch fills slots that it has leased in a destination ring and
then not used with packets of length 0 (nm_vale_flush(), when the
sender does not hold the last lease). netmap_peek_recvlen() returned 0
for such a slot, which the frontends take for "nothing to receive", and
left it at the head of the ring. From then on the virtual NIC received
nothing, and the mevent thread spun on the ring's kevent with 100% CPU.

Skip empty packets at the head of the ring.

Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev

Test Plan

Builds on main at f958aa7e7 (2026-10-02) (usr.sbin/bhyve, amd64).

Run-tested with 14.5-RELEASE's bhyve plus this change (keelOS, a FreeBSD 14.5 based system); netmap_peek_recvlen() is identical in main. Two bhyve guests (Debian 13, virtio-net) on one VALE switch, iperf3 between them with 1 and 4 streams.

Before: one guest stops receiving (no ARP replies, ssh to it times out) and its bhyve process has a mevent thread at 100% CPU. I hit this within seconds of a 4-stream run on a VALE switch with local changes in nm_vale_flush() (VLAN support) that left unused leases often; the stock code leaves them when a destination ring is nearly full or a GSO packet is cut into fewer frames than reserved, which is rarer but ends the same way.

After: 20-second runs repeat at 24-27 Gbit/s; 20 minutes of mixed load (guest to guest and guest to LAN through a NIC attached to the switch) end with both guests reachable.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77594
Build 74477: arc lint + arc unit