Skip to content

Commit

Permalink
Datapath overhaul: zero-copy metadata with ingot, 'Compiled' UFTs (#585)
Browse files Browse the repository at this point in the history
This PR rewrites the core of OPTE's packet model to use zero-copy packet
parsing/modification via the
[`ingot`](oxidecomputer/ingot#1) library. This
enables a few changes which get us just shy of the 3Gbps mark.

* **[2.36 -> 2.7]** The use of ingot for modifying packets in both the
slowpath (UFT miss) and existing fastpath (UFT hit).
* Parsing is faster -- we no longer copy out all packet header bytes
onto the stack, and we do not allocate a vector to decompose an `mblk_t`
into individual links.
* Packet field modifications are applied directly to the `mblk_t` as
they happen, and field reads are made from the same source.
  * Non-encap layers are not copied back out.
* **[2.7 -> 2.75]** Packet L4 hashes are cached as part of the UFT,
speeding up multipath route selection over the underlay.
* **[2.75 -> 2.8]** Incremental Internet checksum recalculation is only
performed when applicable fields change on inner flow headers (e.g.,
NAT'd packets).
  * VM-to-VM / intra-VPC traffic is the main use case here.
* **[2.8 -> 3.05]** `NetworkParser`s now have the concept of inbound &
outbound `LightweightMeta` formats. These support the key operations
needed to execute all our UFT flows today (`FlowId` lookup, inner
headers modification, encap push/pop, cksum update).
* This also allows us to pre-serialize any bytes to be pushed in front
of a packet, speeding up `EmitSpec`.
* This is crucial for outbound traffic in particular, which has far
smaller (in `struct`-size) metadata.
* UFT misses or incompatible flows fallback to using the full metadata.
* **[3.05 -> 2.95]** TCP state tracking uses a separate per-flow lock
and does not require any lookup from a UFT.
* I do not have numbers on how large the performance loss would be if we
held the `Port` lock for the whole time.
* (Not measured) Packet/UFT L4 Hashes are used as the Geneve source
port, spreading inbound packets over NIC Rx queues based on the inner
flow.
* This is now possible because of #504 -- software classification would
have limited us to the default inbound queue/group.
* I feel bad for removing one more FF7 reference, but that is the way of
these things. RIP port `7777`.
* Previously, Rx queue affinity was derived solely from `(Src Sled, Dst
Sled)`.

There are several other changes here made to how OPTE functions which
are needed to support the zero-copy model.

* Each collected set of header transforms are `Arc<>`'d, such that we
can apply them outside of the `Port` lock.
* `FlowTable<S>`s now store `Arc<FlowEntry<S>>`, rather than
`FlowEntry<S>`.
* This enables the UFT entry for any flow to store its matched TCP flow,
update its hit count and timestamp, and then update the TCP state
without reacquring the `Port` lock.
* This also drastically simplifies TCP state handling in fast path cases
to not rely on post-transformation packets for lookup.
* `Opte::process` returns an `EmitSpec` which is needed to finalise a
packet before it can be used.
* I'm not too happy about the ergonomics, but we have this problem
because otherwise we'd need `Packet` to have some self-referential
fields when supporting other key parts of XDE (e.g., parse -> use fields
-> select port -> process).

Closes #571, closes #481, closes #460.

Slightly alleviates #435.
  • Loading branch information
FelixMcFelix authored Nov 19, 2024
1 parent f3002b3 commit 2e4d475
Show file tree
Hide file tree
Showing 88 changed files with 9,936 additions and 11,164 deletions.
4 changes: 2 additions & 2 deletions .github/buildomat/jobs/opte-api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opte-api"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = []
#:

Expand All @@ -24,7 +24,7 @@ header "check API_VERSION"
./check-api-version.sh

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -- --check
ptime -m cargo +nightly-2024-11-18 fmt -- --check

header "analyze std"
ptime -m cargo clippy --all-targets
Expand Down
4 changes: 2 additions & 2 deletions .github/buildomat/jobs/opte-ioctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opte-ioctl"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = []
#:

Expand All @@ -21,7 +21,7 @@ rustc --version
cd lib/opte-ioctl

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -- --check
ptime -m cargo +nightly-2024-11-18 fmt -- --check

header "analyze"
ptime -m cargo clippy --all-targets
8 changes: 4 additions & 4 deletions .github/buildomat/jobs/opte.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opte"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = []
#:

Expand All @@ -21,7 +21,7 @@ rustc --version
cd lib/opte

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -- --check
ptime -m cargo +nightly-2024-11-18 fmt -- --check

header "check docs"
#
Expand All @@ -30,13 +30,13 @@ header "check docs"
#
# Use nightly which is needed for the `kernel` feature.
RUSTDOCFLAGS="-D warnings" ptime -m \
cargo +nightly-2024-05-12 doc --no-default-features --features=api,std,engine,kernel
cargo +nightly-2024-11-18 doc --no-default-features --features=api,std,engine,kernel

header "analyze std + api"
ptime -m cargo clippy --all-targets

header "analyze no_std + engine + kernel"
ptime -m cargo +nightly-2024-05-12 clippy --no-default-features --features engine,kernel
ptime -m cargo +nightly-2024-11-18 clippy --no-default-features --features engine,kernel

header "test"
ptime -m cargo test
4 changes: 2 additions & 2 deletions .github/buildomat/jobs/opteadm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opteadm"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = [
#: "=/work/debug/opteadm",
#: "=/work/debug/opteadm.debug.sha256",
Expand All @@ -30,7 +30,7 @@ rustc --version
pushd bin/opteadm

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -- --check
ptime -m cargo +nightly-2024-11-18 fmt -- --check

header "analyze"
ptime -m cargo clippy --all-targets
Expand Down
8 changes: 4 additions & 4 deletions .github/buildomat/jobs/oxide-vpc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "oxide-vpc"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = []
#:

Expand All @@ -21,7 +21,7 @@ rustc --version
cd lib/oxide-vpc

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -- --check
ptime -m cargo +nightly-2024-11-18 fmt -- --check

header "check docs"
#
Expand All @@ -30,13 +30,13 @@ header "check docs"
#
# Use nightly which is needed for the `kernel` feature.
RUSTDOCFLAGS="-D warnings" ptime -m \
cargo +nightly-2024-05-12 doc --no-default-features --features=api,std,engine,kernel
cargo +nightly-2024-11-18 doc --no-default-features --features=api,std,engine,kernel

header "analyze std + api + usdt"
ptime -m cargo clippy --features usdt --all-targets

header "analyze no_std + engine + kernel"
ptime -m cargo +nightly-2024-05-12 clippy --no-default-features --features engine,kernel
ptime -m cargo +nightly-2024-11-18 clippy --no-default-features --features engine,kernel

header "test"
ptime -m cargo test
2 changes: 1 addition & 1 deletion .github/buildomat/jobs/p5p.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opte-p5p"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = [
#: "=/out/opte.p5p",
#: "=/out/opte.p5p.sha256",
Expand Down
6 changes: 3 additions & 3 deletions .github/buildomat/jobs/xde.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#: name = "opte-xde"
#: variety = "basic"
#: target = "helios-2.0"
#: rust_toolchain = "nightly-2024-05-12"
#: rust_toolchain = "nightly-2024-11-18"
#: output_rules = [
#: "=/work/debug/xde.dbg",
#: "=/work/debug/xde.dbg.sha256",
Expand Down Expand Up @@ -75,7 +75,7 @@ pushd xde
cp xde.conf /work/xde.conf

header "check style"
ptime -m cargo +nightly-2024-05-12 fmt -p xde -p xde-link -- --check
ptime -m cargo +nightly-2024-11-18 fmt -p xde -p xde-link -- --check

header "analyze"
ptime -m cargo clippy -- \
Expand Down Expand Up @@ -123,7 +123,7 @@ sha256sum $REL_TGT/xde_link.so > $REL_TGT/xde_link.so.sha256

header "build xde integration tests"
pushd xde-tests
cargo +nightly-2024-05-12 fmt -- --check
cargo +nightly-2024-11-18 fmt -- --check
cargo clippy --all-targets
cargo build --test loopback
loopback_test=$(
Expand Down
Loading

0 comments on commit 2e4d475

Please sign in to comment.