dd: page-align the read buffer for iflag=direct#13373
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
ff5279f to
d57f06a
Compare
|
Updated the description to properly credit #12143, which I had missed when opening this (my issue search didn't match its title). See the "Relation to existing PRs" section. |
Merging this PR will not alter performance
Comparing Footnotes
|
|
GNU testsuite comparison: |
|
Thanks for the report — breakdown of the two kinds of deltas: Memory (all six: exactly +4.0 KB): this is the intentional over-allocation by one page that provides the alignment guarantee ( Simulation (−4…−5%): per-iteration bookkeeping of the new buffer wrapper (capacity check + slice re-borrow), which adds up at
Worth keeping in mind when weighing the remaining instruction-count delta: these benchmarks don't use direct I/O, and CodSpeed doesn't measure syscall cost — while the bug this PR fixes currently makes every full-block (The Android job failure is unrelated — it died in "Create and cache emulator image".) |
|
Verified the fast path against the gate's own metric (instruction counts, single-pass analysis-mode bench binaries under
Down from the reported 4–5% to well under 1.5% (≈8 instructions per copied block, from the remaining slice re-borrows). The constant +4 KiB in the memory-mode numbers is the page over-allocation that provides the alignment guarantee itself. |
|
Round 3, following up on the flame graphs from the last run: Rather than keep shaving at wrapper overhead, b859333 removes it structurally by consolidating with the read path from #12143 (credit to @chrboe — this is essentially his slice-based design on top of the safe runtime-page-size allocation):
The diff is net −75 lines. This run's CodSpeed result reflects it: no simulation benchmark is flagged anymore (previously
That leaves the headline number (−16.32%), which is now purely the seven Memory entries averaged: peak memory is up by exactly one page (+4,096 B, constant, not proportional to the buffer size) because the buffer over-allocates one alignment unit to place the data page-aligned. That is the fix itself — the same trade GNU dd makes via Re-verified after the refactor: The other two failing checks look unrelated to this diff: the macOS job failed on a |
b859333 to
5868242
Compare
|
Round 4: the seven Memory flags are gone as well — 5868242 removes the one-page over-allocation instead of asking for it to be acknowledged.
Being explicit about the trade-off, since the PR previously advertised "no unsafe": this adds three small unsafe blocks ( Side effect on the hot loop:
Re-verified after the change: 91 unit + 123 integration tests pass, outputs byte-identical to main across the 18-configuration sweep, and on a |
|
Hardened the buffer internals a bit further ahead of review: One correction to my earlier phrasing for precision: the unsafe surface is four |
804cb6f to
79bc8d5
Compare
|
i stopped reviewing it because i became tired ;) A few comments:
I will stop there too but maybe i should start providing an AGENTS.md and skills to help contributors |
|
Thanks, understood. Before reworking this: should I keep #13373 to the minimal alignment fix and move the probe/strace tests to a follow-up? |
8624f83 to
42f8ea2
Compare
42f8ea2 to
95d9fe9
Compare
|
Reworked this around a safe, |
Fixes #12085.
Problem
dd iflag=directcan fail withEINVALbecauseVec<u8>does not guarantee the alignment required byO_DIRECT.Fix
Use a safe
Vec-backed buffer that exposes a page-aligned fixed-size slice. Read helpers return the valid prefix instead of resizing the buffer, and the initial buffer size respectscountwhen less data is requested. This adds no dependency orunsafecode.Validation
cargo test -p uu_dd