On 10/31/24 15:07, Niklas Cassel wrote:
libata is responsible to ensure that NCQ and non-NCQ commands are not mixed in the command list for the same device. This is handled using the .qc_defer callback (ata_std_qc_defer()), which will defer a non-NCQ command as long as there are NCQ commands in flight. The problem is that if an application is continuously submitting NCQ commands (e.g. fio with a queue depth greater than 1), this can completely starve out another application that is sending a non-NCQ command (because the non-NCQ command will be deferred forever). Solve this by triggering EH if there are NCQ commands in flight when a non-NCQ is submitted. If EH is scheduled, no new commands will be accepted, and EH will wake up when there are no commands in flight. We will then submit the non-NCQ command from EH context, and synchronously wait for the completion. When EH is finished, libata will continue to accept new commands like normal. Reported-by: Xingui Yang <yangxingui@xxxxxxxxxx> Closes: https://lore.kernel.org/linux-block/eef1e927-c9b2-c61d-7f48-92e65d8b0418@xxxxxxxxxx/ Suggested-by: Hannes Reinecke <hare@xxxxxxx> Signed-off-by: Niklas Cassel <cassel@xxxxxxxxxx> --- drivers/ata/libata-core.c | 169 +++++++++++++++++++++++++++++++++++--- drivers/ata/libata-eh.c | 60 +++++++++++++- drivers/ata/libata-scsi.c | 16 +++- drivers/ata/libata.h | 1 + include/linux/libata.h | 7 +- 5 files changed, 237 insertions(+), 16 deletions(-)
Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@xxxxxxx +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich