Sick Pigs <[email protected]> writes:

> I believe I have found a reproducible bug in GNU dd where the reported
> elapsed time
> (and therefore throughput) is incorrect, even though the actual data is
> written correctly. This leads to physically impossible speed reporting
> (e.g. 7.9 GB/s to a SATA SSD).
>
> System Information:
>
> OS:
> Linux nobara-pc 7.0.9-200.nobara.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC
>
> dd version:
> dd (coreutils) 9.7
>
> Device:
> /dev/sda (SATA SSD, EDILOCA ES580E 240GB)
>
> Commands Run:
>
> 1) Write ISO to disk:
> sudo dd if=image.iso of=/dev/sda bs=4M conv=fsync status=progress
>
> 627+1 records in
> 627+1 records out
> 2630580224 bytes copied, 0.33473 s, 7.9 GB/s
>
> 2) Independent timing verification:
> time sudo dd if=image.iso of=/dev/sda bs=4M conv=fsync status=none
>
> real 0m5.782s
> user 0m0.004s
> sys 0m0.012s
>
> 3) Verification of correctness:
> cmp image.iso /dev/sda
> (no output, exit status 0)
>
> 4) Additional test:
> Using oflag=direct produces the same incorrect timing behavior.
>
> Kernel confirms write and partition table update:
> GPT warnings appear for /dev/sda after write, confirming device was
> modified.
>
> Expected Behaviour:
> The elapsed time reported by dd should match wall-clock time, or at least
> be consistent with external timing tools like `time`. Throughput should be
> consistent with actual device performance (~400–550 MB/s for consumer SATA
> SSD).
>
> Actual Behaviour:
> dd reports elapsed time of ~0.33s, implying ~7.9 GB/s throughput, which is
> physically impossible for the hardware. However, external timing (`time`)
> shows the operation actually took ~5.8s, and the written data is correct.
>
> Additiuonal Notes:
>
> The issue appears to be purely in dd's internal timing/statistics
> reporting, not in the actual write operation itself, which completes
> correctly.
> I can reproduce this consistently with:
> - status=progress
> - conv=fsync
> - coreutils 9.7
> - Linux kernel 7.0.9 (Nobara)

It sounds like fsync took ~5.5s on your system. Can you check that? You
can check with the following command:

    $ strace -tt -T dd if=image.iso of=/dev/sda bs=4M conv=fsync \
        status=progress

Note that the output can get quite long. If you share it on list you can
just remove all of the lines aside from the fysnc and a few lines before
and after. E.g., using:

    $ strace -tt -T dd if=image.iso of=/dev/sda bs=4M conv=fsync \
        status=progress 2>&1 > /dev/null | tail -n 20

I believe the behavior is expected, at least after the following commit:

    $ git log c4f9554ee923c27529cdb76b6f75051183f59c1a -n 1
    commit c4f9554ee923c27529cdb76b6f75051183f59c1a
    Author:     Paul Eggert <[email protected]>
    AuthorDate: Thu Jan 27 18:34:09 2022 -0800
    Commit:     Paul Eggert <[email protected]>
    CommitDate: Thu Jan 27 18:35:02 2022 -0800
    
        dd: output final progress before syncing
        
        Problem reported by Sworddragon (Bug#51482).
        * src/dd.c (reported_w_bytes): New var.
        (print_xfer_stats): Set it.
        (dd_copy): Print a final progress report if useful before
        synchronizing output data.

Before that change, if there was a final progress indication that had to
be printed it would occur after fdatasync/fsync. Since those system
calls can, and often do, take a long time you would see a tiny
throughput [1] [2].

I guess the current behavior is confusing as well, but I feel like it is
slightly less confusing then the behavior before that change.

Collin

[1] https://bugs.gnu.org/51345
[2] https://bugs.gnu.org/51482



Reply via email to