Skip to content

dd: ignore a failed cache drop while copying - #14748

Open
ChihweiLHBird wants to merge 1 commit into
uutils:mainfrom
ChihweiLHBird:zhiwei/fix-dd-nocache-on-a-pipe
Open

ChihweiLHBird wants to merge 1 commit into
uutils:mainfrom
ChihweiLHBird:zhiwei/fix-dd-nocache-on-a-pipe

Conversation

@ChihweiLHBird

Copy link
Copy Markdown
Contributor

Summary

iflag=nocache and oflag=nocache diagnosed every failed cache drop, so copying from or to a pipe printed failed to discard cache for: 'standard input': Illegal seek once per read and exited 1 even though the copy succeeded. GNU ignores those failures while copying and diagnoses them only with count=0, where dropping the cache is the whole job: "when count=0, failure to discard the cache is diagnosed and reflected in the exit status" (manual, dd invocation; the invalidate_cache callers in dd.c).

Input::discard_cache and Output::discard_cache now return the error instead of printing it, and the two callers decide: dd_copy ignores it, flush_caches_full_length (the count=0 path) reports it and sets the exit status.

Part of #14705 (tests/dd/nocache.sh).

Example

dd if=/dev/zero bs=1M count=1 status=none | dd iflag=nocache bs=1M of=/dev/null

Before (exit 1):

dd: failed to discard cache for: 'standard input': Illegal seek
dd: failed to discard cache for: 'standard input': Illegal seek
...
0+16 records in
0+16 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied

After, the same as GNU 9.12 (exit 0):

0+16 records in
0+16 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied

count=0 is unchanged and still diagnoses the failure, as GNU does:

$ dd count=0 status=none | dd iflag=nocache count=0 status=none; echo $?
dd: failed to discard cache for: 'standard input': Illegal seek
1

@ChihweiLHBird
ChihweiLHBird marked this pull request as ready for review September 20, 2026 08:44
@codspeed

codspeed Bot commented Sep 20, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 3.43%

❌ 5 regressed benchmarks
✅ 13 untouched benchmarks
⏩ 414 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation dd_copy_default 32.2 ms 33.5 ms -3.97%
Simulation dd_copy_4k_blocks 2.6 ms 2.6 ms -3.51%
Simulation dd_copy_with_seek 4.8 ms 5 ms -3.39%
Simulation dd_copy_with_skip 4.7 ms 4.9 ms -3.24%
Simulation dd_copy_8k_blocks 1.8 ms 1.9 ms -3.05%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing ChihweiLHBird:zhiwei/fix-dd-nocache-on-a-pipe (5da8c11) with main (5eb255f)

Open in CodSpeed

Footnotes

  1. 414 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.

@github-actions

github-actions Bot commented Sep 20, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Congrats! The gnu test tests/dd/nocache is no longer failing!

@ChihweiLHBird
ChihweiLHBird force-pushed the zhiwei/fix-dd-nocache-on-a-pipe branch from 5b69be5 to ae1248c Compare September 20, 2026 16:54
@ChihweiLHBird

Copy link
Copy Markdown
Contributor Author

I looked into the CodSpeed report. The regression is real but small, and it comes from compiler register allocation rather than from any added work.

benchmark executed instructions vs main
dd_copy_default (512 B blocks) +0.68%
dd_copy_8k_blocks +0.04%
dd_copy_with_skip +0.11%
dd_copy_with_seek +0.11%

Cause. None of these benchmarks pass nocache to dd, so the changed code never runs in them. As a diagnostic I built the PR with the three nocache blocks deleted from the copy loop; that build matches main's instruction count exactly, so all of the extra instructions come from how the compiler lays out the loop around those blocks. The PR changes what the call inside them does (return the error instead of printing it), which changes the compiler's register plan for the whole loop: the same work is done with about ten more register-to-stack moves per block. The default benchmark copies 65,536 blocks, which is where 0.68% comes from.

I couldn't find a variant of this fix reaches zero instructions increase. Another variant, adding a bunch of quietly_discard_cache functions, would lower +0.68% to +0.52%, but the code structure can look, in my opinion, less readable, that way. Let me know if the performance if prioritized though, and I would be happy to adopt that design.

@ChihweiLHBird
ChihweiLHBird force-pushed the zhiwei/fix-dd-nocache-on-a-pipe branch 2 times, most recently from 0c61751 to 82c41b3 Compare September 21, 2026 08:17
Signed-off-by: Zhiwei Liang <zhiwei.liang@zliang.me>
@ChihweiLHBird
ChihweiLHBird force-pushed the zhiwei/fix-dd-nocache-on-a-pipe branch from 82c41b3 to 5da8c11 Compare September 21, 2026 15:48

This branch has not been deployed

No deployments
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.

1 participant