virtio_net/consomme: add USO support #3114
Conversation
|
This PR modifies files containing For more on why we check whole files, instead of just diffs, check out the Rustonomicon |
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end UDP Segmentation Offload (USO) support to the virtio-net TX path by carrying USO metadata through net_backend, advertising/negotiating VIRTIO_NET_F_HOST_USO (bank 1) in virtio_net, and configuring the consomme UDP send path to use OS-supported UDP GSO mechanisms.
Changes:
- Extend
net_backendTX offload capabilities/metadata to represent USO (new support bit, TX flag, and per-packet segment size). - Update
virtio_netto advertiseHOST_USOin bank 1 and parseVirtioNetHeaderGsoProtocol::UDP_L4into the new TX metadata; add/extend tests for USO and feature negotiation. - Update
consommeUDP TX path to apply UDP GSO/segmentation using platform-specific helpers (Linux/macOS/Windows).
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| vm/devices/virtio/virtio_net/src/tests.rs | Adds USO-focused TX offload parsing tests and extends feature negotiation tests to validate HOST_USO in bank 1. |
| vm/devices/virtio/virtio_net/src/lib.rs | Advertises bank-1 HOST_USO and parses UDP_L4 GSO into backend TX metadata/flags. |
| vm/devices/net/net_consomme/src/lib.rs | Plumbs backend USO metadata into consomme::ChecksumState as gso. |
| vm/devices/net/net_consomme/consomme/src/windows.rs | Implements Windows UDP GSO socket option configuration and a platform send_to wrapper. |
| vm/devices/net/net_consomme/consomme/src/unix.rs | Implements Linux UDP_SEGMENT socket configuration and macOS sendmsg_x()-based batching send path. |
| vm/devices/net/net_consomme/consomme/src/udp.rs | Tracks per-connection GSO size and applies platform UDP GSO configuration before sending. |
| vm/devices/net/net_consomme/consomme/src/lib.rs | Extends send-path validation to tolerate IP length fields being inconsistent for TSO/USO super-packets. |
| vm/devices/net/net_backend/src/null.rs | Marks the null endpoint as supporting USO. |
| vm/devices/net/net_backend/src/lib.rs | Adds TxOffloadSupport::uso, TxFlags::offload_udp_segmentation, and TxMetadata::max_udp_segment_size. |
| vm/devices/net/gdma/src/bnic.rs | Initializes the new TxMetadata::max_udp_segment_size field for GDMA TX metadata. |
vm/devices/net/net_tap/src/lib.rs
Outdated
| tcp: true, | ||
| udp: true, | ||
| tso: true, | ||
| uso: false, |
There was a problem hiding this comment.
There’s trailing whitespace after uso: false, here. Please run formatting (or remove the extra space) to keep diffs clean and avoid lint/format noise.
| uso: false, | |
| uso: false, |
Implements VIRTIO_NET_F_HOST_USO support, allowing the guest to send large UDP super-packets that the host splits into individual datagrams using host OS provided APIs
Background:
USO (UDP Segmentation Offload) is the UDP analogue of TSO. Instead of the guest sending many individual datagrams, it sends one large buffer with a gso_size hint in the virtio header. The host then splits it at the transport layer, producing independent UDP datagrams.
Changes:
net_backend: Adds TxOffloadSupport::uso, TxFlags::offload_udp_segmentation, and TxMetadata::max_udp_segment_size to carry USO metadata through the TX pipeline.
virtio_net: Advertises HOST_USO to the guest. Handles VirtioNetHeaderGsoProtocol::UDP_L4 in parse_tx_offloads, extracting gso_size and setting the new offload flags. IPv4 USO packets also set offload_ip_header_checksum for the same reason as TSO. The IP header length validation in consomme is extended to skip total_len checks for USO super-packets, mirroring the existing TSO handling.
consomme UDP send path: Adds gso: Option to ChecksumState. Each UdpConnection tracks the currently configured GSO segment size and calls platform::set_udp_gso_size only when it changes, avoiding redundant syscalls. The subsequent send is a plain send_to on Linux and Windows since the socket is pre-configured.
Platform implementations:
Running the following benchmark:
Yielded the following results:
35930 sends in 10.0s = 1.87 Gbps (from main branch)
107842 datagrams sent in 10.0s = 5.61Gbps (with these changes)