diff options
| author | Richard Weinberger <richard@nod.at> | 2026-07-17 11:04:04 +0200 |
|---|---|---|
| committer | Damien Le Moal <dlemoal@kernel.org> | 2026-07-21 08:55:31 +0900 |
| commit | 4a2e5409472e8a0e3e2817e149c55c1d5f803742 (patch) | |
| tree | 22b17884f01da10bf72cc48dcce18c52c4b727b8 /tools/perf/scripts/python/flamegraph.py | |
| parent | 5e8e8c42ce25782ff738a68724f8f5b93348121f (diff) | |
ata: libata-sff: don't busy-wait for PIO data-in command completion
Unlike PIO data-out, the PIO data-in protocol raises no completion
interrupt, the last interrupt announces the final data block, and once
the host has drained it from the data register the ending status must
be obtained synchronously. ata_sff_hsm_move() does this by spinning
in ata_wait_idle() for up to 10ms.
Usually this is not a big deal unless the device is slow. In my case
it's a CF card which keeps BSY asserted for multiple milliseconds(!)
after the final data block. Since the waiting happens in the
interrupt handler, under the port lock with interrupts disabled, the
CPU is hogged for milliseconds on every read command.
To improve the situation, bound the inline wait to ~100us. If the
device is still busy after that, mark the command ATA_TFLAG_POLLING,
so the interrupt handler won't race for it, and obtain the ending
status via ata_sff_pio_task(), which sleeps between status checks
instead of spinning with the lock held.
Since ata_sff_pio_task() may now finish a data-in command, it must
wait for both BSY and DRQ to clear at HSM_ST_LAST, matching what
ata_wait_idle() enforced.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Diffstat (limited to 'tools/perf/scripts/python/flamegraph.py')
0 files changed, 0 insertions, 0 deletions
