Page MenuHomeFreeBSD

vtnet: Ensure that L3 protocol headers are aligned when necessary
AcceptedPublic

Authored by markj on Jul 27 2023, 3:12 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, May 26, 1:52 AM
Unknown Object (File)
Thu, May 9, 8:28 PM
Unknown Object (File)
Apr 21 2024, 5:40 AM
Unknown Object (File)
Dec 20 2023, 7:18 AM
Unknown Object (File)
Nov 10 2023, 4:53 AM
Unknown Object (File)
Oct 9 2023, 3:49 AM
Unknown Object (File)
Sep 10 2023, 2:46 AM
Unknown Object (File)
Aug 16 2023, 5:03 AM
Subscribers

Details

Reviewers
adrian
Group Reviewers
network
Summary

This addresses alignment faults which occur when running an armv7 kernel
in QEMU: the L3 protocol implementations effectively assume that headers
are aligned.

Modify vtnet's buffer allocation routine to add a 2-byte offset to the
beginning of the data buffer. Add 2 to the interface MTU so that we
allocate sufficiently large clusters.

PR: 271288
Sponsored by: Klara, Inc.
Sponsored by: Stormshield

Diff Detail

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

Event Timeline

markj requested review of this revision.Jul 27 2023, 3:12 PM

i know this keeps happening for unaligned-unhappy platforms, but can we please at least try to "fix" this in the L3 path too? Do an explicit pull-up and counter on the input path just in case something sneaks through?

Because this may be fine for ethernet and vtnet, but other platforms (eg with various 802.11 decap paths) i was still hitting this in the MIPS tree in yesteryear - with the combination of tx/rx alignment requirements for hardware drivers, it actually meant that the ethernet alignment was slow (because of buffer copying) to make up for L3 requirements, but the L2 code (eg for bridging) was just fine with it.

This revision is now accepted and ready to land.Jul 27 2023, 3:26 PM

On a very, very quick first glance I've got concerns that this is incomplete, or could break alignment in other cases (but I have been away from this code for awhile). Depending on the features negotiated - V1, legacy with or without mergeable buffers - the header size can vary, along with what we enqueue for the Rx header desc. What features are negotiated on your QEMU testbed? We might be able to get a similar outcome by adjusting VTNET_RX_HEADER_PAD.

On a very, very quick first glance I've got concerns that this is incomplete, or could break alignment in other cases (but I have been away from this code for awhile). Depending on the features negotiated - V1, legacy with or without mergeable buffers - the header size can vary, along with what we enqueue for the Rx header desc. What features are negotiated on your QEMU testbed? We might be able to get a similar outcome by adjusting VTNET_RX_HEADER_PAD.

You're right, this is incomplete. Depending on the features negotiated, the virtio header's size can be 0 or 2 mod 4. In my setup, mergeable buffers are configured. There, the header size is a multiple of 4, which is why my hack works. VTNET_RX_HEADER_PAD is only used with legacy virtio, assuming I'm reading correctly.

i know this keeps happening for unaligned-unhappy platforms, but can we please at least try to "fix" this in the L3 path too? Do an explicit pull-up and counter on the input path just in case something sneaks through?

Because this may be fine for ethernet and vtnet, but other platforms (eg with various 802.11 decap paths) i was still hitting this in the MIPS tree in yesteryear - with the combination of tx/rx alignment requirements for hardware drivers, it actually meant that the ethernet alignment was slow (because of buffer copying) to make up for L3 requirements, but the L2 code (eg for bridging) was just fine with it.

Yes, protocol layers should be detecting this problem and handling it somehow. As you say, most NIC drivers have to perform some copying after the fact in order to fix the alignment anyway, so it ought to be ok to push that down into layers which actually require it. The trouble is figuring out which protocols require alignment, and whether we should instead annotate more protocol headers with __packed or __aligned(2) so that they don't require any special alignment to begin with.