Skip to content

feat: Remove bindgen dependency for MTU crate#3337

Open
larseggert wants to merge 12 commits intomozilla:mainfrom
larseggert:feat-mtu-no-bindgen
Open

feat: Remove bindgen dependency for MTU crate#3337
larseggert wants to merge 12 commits intomozilla:mainfrom
larseggert:feat-mtu-no-bindgen

Conversation

@larseggert
Copy link
Collaborator

@codecov
Copy link

codecov bot commented Jan 21, 2026

Codecov Report

❌ Patch coverage is 0% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.06%. Comparing base (96e9859) to head (da05690).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3337      +/-   ##
==========================================
- Coverage   94.24%   94.06%   -0.19%     
==========================================
  Files         125      131       +6     
  Lines       37973    38333     +360     
  Branches    37973    38333     +360     
==========================================
+ Hits        35787    36057     +270     
- Misses       1349     1429      +80     
- Partials      837      847      +10     
Flag Coverage Δ
freebsd 93.10% <0.00%> (-0.17%) ⬇️
linux 94.24% <ø> (-0.01%) ⬇️
macos 94.12% <ø> (+<0.01%) ⬆️
windows 94.23% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 98.49% <ø> (ø)
neqo-crypto 86.90% <ø> (ø)
neqo-http3 93.88% <ø> (ø)
neqo-qpack 94.79% <ø> (ø)
neqo-transport 95.18% <100.00%> (ø)
neqo-udp 82.47% <ø> (-0.43%) ⬇️
mtu 84.61% <0.00%> (-2.00%) ⬇️

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 21, 2026

Merging this PR will degrade performance by 6.94%

❌ 2 regressed benchmarks
✅ 36 untouched benchmarks
⏩ 8 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime 1-conn/1-100mb-req (aka. Upload) 564.3 ms 587.6 ms -3.97%
Memory walltime/1000-streams/each-1-bytes 705.3 KB 757.9 KB -6.94%

Comparing larseggert:feat-mtu-no-bindgen (da05690) with main (1c30ced)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Member

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I'm following the CI parts, but don't you want CI to (mostly) just check that what is generated matches what is in the tree? But then you might also have CI propose a PR to update what is in-tree on the affected branch.

@larseggert
Copy link
Collaborator Author

larseggert commented Jan 21, 2026

But then you might also have CI propose a PR to update what is in-tree on the affected branch.

That is probably overkill. I don't really expect these bindings to ever change, since OSs have ABI promises.

Edit: But Rust version changes may cause bindgen to generate slightly different bindings. Let me look into the PR thing.

@larseggert larseggert marked this pull request as ready for review January 21, 2026 09:21
Copilot AI review requested due to automatic review settings January 21, 2026 09:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the bindgen build dependency from the MTU crate by replacing runtime binding generation with pre-generated platform-specific binding files. Instead of using bindgen during the build process, the PR checks in generated binding files for each supported platform (Linux, macOS, FreeBSD, NetBSD, OpenBSD, Solaris) and uses conditional compilation to select the appropriate bindings for the target platform.

Changes:

  • Removed bindgen from build dependencies and simplified the build script
  • Added pre-generated binding files for all supported platforms
  • Added CI workflow steps to regenerate bindings and verify they remain up-to-date
  • Updated lint attributes to use #[expect] instead of #[allow] where appropriate

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
mtu/Cargo.toml Removed bindgen dependency and updated cargo-machete ignore list
mtu/build.rs Removed bindgen-related code, keeping only platform alias configuration
mtu/src/linux.rs Updated lint attributes and changed to use static binding module path
mtu/src/bsd.rs Updated lint attributes and changed to use static binding module paths per platform
mtu/src/bindings/*.rs Added pre-generated binding files for all supported platforms
mtu/src/bindings/*.h Added header files used as input for binding generation
.github/workflows/check-mtu.yml Added CI jobs to generate bindings and verify they match committed versions
.github/actions/check-vm/action.yml Added bindgen installation and binding generation steps to VM-based tests

@larseggert larseggert force-pushed the feat-mtu-no-bindgen branch 2 times, most recently from 401f12e to da05690 Compare February 12, 2026 13:18
@github-actions
Copy link
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to main at 1c30ced.

neqo-pr as clientneqo-pr as server
neqo-pr vs. aioquic: A
neqo-pr vs. go-x-net: A BP BA
neqo-pr vs. haproxy: 🚀M A BP BA
neqo-pr vs. kwik: BP BA
neqo-pr vs. linuxquic: A ⚠️L1
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: A L1 C1
neqo-pr vs. mvfst: A L1 C1 BA
neqo-pr vs. neqo: Z
neqo-pr vs. nginx: A L1 C1 BP BA
neqo-pr vs. ngtcp2: A 🚀L1 CM
neqo-pr vs. picoquic: A ⚠️C1
neqo-pr vs. quic-go: A ⚠️L1 C1
neqo-pr vs. quiche: A 🚀L1 C1 BP BA
neqo-pr vs. quinn: A 🚀L1 C1
neqo-pr vs. s2n-quic: A ⚠️L1 C1 BA CM
neqo-pr vs. tquic: S A L1 BP BA
neqo-pr vs. xquic: A
aioquic vs. neqo-pr: Z CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: Z BP BA CM
linuxquic vs. neqo-pr: ⚠️BA
lsquic vs. neqo-pr: Z
msquic vs. neqo-pr: Z ⚠️BA CM
mvfst vs. neqo-pr: Z A L1 C1 CM
neqo vs. neqo-pr: Z
openssl vs. neqo-pr: LR M A CM
picoquic vs. neqo-pr: Z
quic-go vs. neqo-pr: 🚀Z CM
quiche vs. neqo-pr: Z CM
quinn vs. neqo-pr: Z V2 CM
s2n-quic vs. neqo-pr: CM
tquic vs. neqo-pr: Z CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions
Copy link
Contributor

Client/server transfer results

Performance differences relative to 1c30ced.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
neqo-neqo-newreno 97.1 ± 4.6 88.5 107.9 329.7 ± 7.0 💚 -1.4 -1.4%
neqo-neqo-newreno-nopacing 94.7 ± 3.5 89.1 104.4 338.0 ± 9.1 💔 1.4 1.5%
quiche-neqo-cubic 150.6 ± 6.3 136.7 176.5 212.5 ± 5.1 💚 -2.8 -1.9%
s2n-neqo-cubic 173.2 ± 5.1 162.3 191.9 184.8 ± 6.3 💚 -2.0 -1.2%

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
google-google-nopacing 462.2 ± 3.3 456.9 472.7 69.2 ± 9.7
google-neqo-cubic 273.7 ± 4.2 263.7 281.8 116.9 ± 7.6 0.9 0.3%
msquic-msquic-nopacing 180.7 ± 59.6 134.7 433.1 177.1 ± 0.5
msquic-neqo-cubic 201.0 ± 60.3 148.3 568.6 159.2 ± 0.5 2.1 1.1%
neqo-google-cubic 770.8 ± 4.1 763.6 783.2 41.5 ± 7.8 -0.5 -0.1%
neqo-msquic-cubic 159.9 ± 4.3 152.7 168.5 200.2 ± 7.4 0.4 0.2%
neqo-neqo-cubic 97.9 ± 4.0 87.9 105.4 327.0 ± 8.0 0.9 1.0%
neqo-neqo-cubic-nopacing 96.6 ± 4.6 89.6 105.1 331.4 ± 7.0 0.6 0.6%
neqo-neqo-newreno 97.1 ± 4.6 88.5 107.9 329.7 ± 7.0 💚 -1.4 -1.4%
neqo-neqo-newreno-nopacing 94.7 ± 3.5 89.1 104.4 338.0 ± 9.1 💔 1.4 1.5%
neqo-quiche-cubic 191.1 ± 4.1 185.6 204.4 167.5 ± 7.8 -0.9 -0.5%
neqo-s2n-cubic 219.2 ± 4.3 211.0 233.5 146.0 ± 7.4 -0.7 -0.3%
quiche-neqo-cubic 150.6 ± 6.3 136.7 176.5 212.5 ± 5.1 💚 -2.8 -1.9%
quiche-quiche-nopacing 142.4 ± 5.0 134.7 153.8 224.7 ± 6.4
s2n-neqo-cubic 173.2 ± 5.1 162.3 191.9 184.8 ± 6.3 💚 -2.0 -1.2%
s2n-s2n-nopacing 255.2 ± 30.8 231.8 354.5 125.4 ± 1.0

Download data for profiler.firefox.com or download performance comparison data.

@github-actions
Copy link
Contributor

Benchmark results

Significant performance differences relative to 1c30ced.

streams/walltime/1000-streams/each-1000-bytes: 💔 Performance has regressed by +1.8734%.
       time:   [45.332 ms 45.380 ms 45.428 ms]
       change: [+1.7216% +1.8734% +2.0384] (p = 0.00 < 0.05)
       Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high severe
All results
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504: No change in performance detected.
       time:   [204.46 ms 204.99 ms 205.59 ms]
       thrpt:  [486.40 MiB/s 487.83 MiB/s 489.09 MiB/s]
change:
       time:   [-0.5114% -0.1366% +0.2359] (p = 0.50 > 0.05)
       thrpt:  [-0.2353% +0.1368% +0.5140]
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: Change within noise threshold.
       time:   [278.73 ms 280.55 ms 282.40 ms]
       thrpt:  [35.411 Kelem/s 35.644 Kelem/s 35.877 Kelem/s]
change:
       time:   [-2.4411% -1.4888% -0.5781] (p = 0.00 < 0.05)
       thrpt:  [+0.5815% +1.5113% +2.5022]
       Change within noise threshold.
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504: No change in performance detected.
       time:   [38.627 ms 38.829 ms 39.047 ms]
       thrpt:  [25.610   B/s 25.754   B/s 25.889   B/s]
change:
       time:   [-0.0432% +0.5956% +1.2627] (p = 0.08 > 0.05)
       thrpt:  [-1.2469% -0.5921% +0.0432]
       No change in performance detected.
Found 11 outliers among 100 measurements (11.00%)
11 (11.00%) high severe
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504: No change in performance detected.
       time:   [204.58 ms 204.89 ms 205.24 ms]
       thrpt:  [487.23 MiB/s 488.07 MiB/s 488.80 MiB/s]
change:
       time:   [-0.4566% -0.2244% +0.0096] (p = 0.06 > 0.05)
       thrpt:  [-0.0096% +0.2249% +0.4587]
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
4 (4.00%) high mild
1 (1.00%) high severe
decode 4096 bytes, mask ff: No change in performance detected.
       time:   [4.5114 µs 4.5185 µs 4.5258 µs]
       change: [-0.3146% +0.0595% +0.5256] (p = 0.79 > 0.05)
       No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
4 (4.00%) high mild
2 (2.00%) high severe
decode 1048576 bytes, mask ff: No change in performance detected.
       time:   [1.1584 ms 1.1610 ms 1.1642 ms]
       change: [-0.3558% +0.0713% +0.4750] (p = 0.74 > 0.05)
       No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
10 (10.00%) low severe
1 (1.00%) high mild
3 (3.00%) high severe
decode 4096 bytes, mask 7f: No change in performance detected.
       time:   [5.7922 µs 5.8010 µs 5.8100 µs]
       change: [-0.4218% -0.0316% +0.2878] (p = 0.87 > 0.05)
       No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severe
decode 1048576 bytes, mask 7f: No change in performance detected.
       time:   [1.4866 ms 1.4913 ms 1.4985 ms]
       change: [+0.0268% +0.3755% +0.8629] (p = 0.08 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
decode 4096 bytes, mask 3f: No change in performance detected.
       time:   [5.5388 µs 5.5472 µs 5.5558 µs]
       change: [-1.0034% -0.4087% +0.0474] (p = 0.14 > 0.05)
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
4 (4.00%) high mild
1 (1.00%) high severe
decode 1048576 bytes, mask 3f: No change in performance detected.
       time:   [1.4145 ms 1.4166 ms 1.4189 ms]
       change: [-0.2244% -0.0082% +0.2064] (p = 0.94 > 0.05)
       No change in performance detected.
streams/simulated/1-streams/each-1000-bytes: No change in performance detected.
       time:   [129.68 ms 129.68 ms 129.68 ms]
       thrpt:  [7.5303 KiB/s 7.5305 KiB/s 7.5307 KiB/s]
change:
       time:   [-0.0035% +0.0005% +0.0045] (p = 0.80 > 0.05)
       thrpt:  [-0.0045% -0.0005% +0.0035]
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams/simulated/1000-streams/each-1-bytes: No change in performance detected.
       time:   [2.5361 s 2.5365 s 2.5368 s]
       thrpt:  [394.20   B/s 394.25   B/s 394.30   B/s]
change:
       time:   [-0.0336% -0.0154% +0.0022] (p = 0.10 > 0.05)
       thrpt:  [-0.0022% +0.0154% +0.0336]
       No change in performance detected.
streams/simulated/1000-streams/each-1000-bytes: No change in performance detected.
       time:   [6.5899 s 6.6002 s 6.6118 s]
       thrpt:  [147.70 KiB/s 147.96 KiB/s 148.19 KiB/s]
change:
       time:   [-0.3071% -0.0480% +0.2138] (p = 0.72 > 0.05)
       thrpt:  [-0.2134% +0.0480% +0.3080]
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
8 (8.00%) high severe
streams/walltime/1-streams/each-1000-bytes: No change in performance detected.
       time:   [584.86 µs 586.45 µs 588.39 µs]
       change: [-0.5264% -0.0507% +0.4188] (p = 0.84 > 0.05)
       No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
1 (1.00%) high mild
5 (5.00%) high severe
streams/walltime/1000-streams/each-1-bytes: No change in performance detected.
       time:   [12.316 ms 12.336 ms 12.357 ms]
       change: [-0.4690% -0.2267% -0.0168] (p = 0.06 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams/walltime/1000-streams/each-1000-bytes: 💔 Performance has regressed by +1.8734%.
       time:   [45.332 ms 45.380 ms 45.428 ms]
       change: [+1.7216% +1.8734% +2.0384] (p = 0.00 < 0.05)
       Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high severe
coalesce_acked_from_zero 1+1 entries: No change in performance detected.
       time:   [92.360 ns 92.731 ns 93.091 ns]
       change: [-0.1141% +0.3472% +0.8275] (p = 0.16 > 0.05)
       No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
6 (6.00%) high mild
1 (1.00%) high severe
coalesce_acked_from_zero 3+1 entries: No change in performance detected.
       time:   [110.25 ns 110.66 ns 111.08 ns]
       change: [-0.4703% -0.0699% +0.3302] (p = 0.73 > 0.05)
       No change in performance detected.
Found 12 outliers among 100 measurements (12.00%)
1 (1.00%) high mild
11 (11.00%) high severe
coalesce_acked_from_zero 10+1 entries: No change in performance detected.
       time:   [109.68 ns 110.21 ns 110.85 ns]
       change: [-0.7854% +0.1676% +0.9839] (p = 0.73 > 0.05)
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
1 (1.00%) high mild
7 (7.00%) high severe
coalesce_acked_from_zero 1000+1 entries: No change in performance detected.
       time:   [94.770 ns 94.908 ns 95.058 ns]
       change: [-0.1813% +0.3313% +0.8233] (p = 0.21 > 0.05)
       No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
5 (5.00%) high mild
5 (5.00%) high severe
RxStreamOrderer::inbound_frame(): Change within noise threshold.
       time:   [108.62 ms 108.69 ms 108.78 ms]
       change: [+0.2898% +0.5192% +0.6981] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 31 outliers among 100 measurements (31.00%)
7 (7.00%) low severe
14 (14.00%) low mild
8 (8.00%) high mild
2 (2.00%) high severe
sent::Packets::take_ranges: No change in performance detected.
       time:   [4.4956 µs 4.5989 µs 4.6931 µs]
       change: [-2.9725% +0.5994% +4.2755] (p = 0.74 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/simulated/pacing-false/varying-seeds: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/varying-seeds: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-false/same-seed: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/same-seed: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/walltime/pacing-false/varying-seeds: Change within noise threshold.
       time:   [23.349 ms 23.367 ms 23.386 ms]
       change: [+0.2746% +0.5000% +0.6609] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) low mild
1 (1.00%) high mild
transfer/walltime/pacing-true/varying-seeds: Change within noise threshold.
       time:   [24.034 ms 24.067 ms 24.120 ms]
       change: [+1.7732% +1.9882% +2.2252] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-false/same-seed: Change within noise threshold.
       time:   [23.869 ms 23.897 ms 23.937 ms]
       change: [+1.4332% +1.5825% +1.7591] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/same-seed: Change within noise threshold.
       time:   [23.771 ms 23.804 ms 23.853 ms]
       change: [-0.5619% -0.4041% -0.1989] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
4 (4.00%) high mild
1 (1.00%) high severe

Download data for profiler.firefox.com or download performance comparison data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants