All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ata: libata-eh: Retry non-NCQ commands when their sense data asks for it
@ 2026-10-30  9:00 Niklas Cassel
  2026-10-30 18:21 ` Igor Pylypiv
  0 siblings, 1 reply; 2+ messages in thread
From: Niklas Cassel @ 2026-10-30  9:00 UTC (permalink / raw)
  To: Damien Le Moal; +Cc: linux-ide, Niklas Cassel

When a failed command has valid sense data, ata_eh_analyze_tf() asks
scsi_check_sense() whether the command should be retried, and sets
ATA_QCFLAG_RETRY if it should. ata_eh_link_autopsy() then clears
AC_ERR_DEV and AC_ERR_OTHER from qc->err_mask, relying on that decision.

For an NCQ command, qc->err_mask still has AC_ERR_NCQ, so
ata_eh_finish() honors ATA_QCFLAG_RETRY. For a non-NCQ command, whose
sense data comes from REQUEST SENSE DATA EXT, qc->err_mask is now zero,
and ata_eh_finish() completes the command with scmd->retries set to
scmd->allowed, without looking at ATA_QCFLAG_RETRY. Such a command is
thus never retried, even when its sense data asks for a retry, e.g. a
transient error reported as ABORTED COMMAND.

Make ata_eh_finish() honor ATA_QCFLAG_RETRY for commands with valid
sense data. ata_eh_qc_retry() cannot be used for this: as qc->err_mask
is zero, it increments scmd->allowed, so every retry would allow one
more, and a persistent error would be retried forever. Instead,
complete the command without touching scmd->allowed or scmd->retries,
so that the SCSI midlayer retries it at most scmd->allowed times, like
any other failed command.

Fixes: 3852e3738266 ("libata: evaluate SCSI sense code")
Signed-off-by: Niklas Cassel <cassel@kernel.org>

---
Tested in QEMU: blkdebug fails a non-NCQ (PATA) read with EIO, and the
disk reports ABORTED COMMAND sense data. Before this patch, the read was
not retried (1 attempt); after it, a transient error is retried and the
read succeeds, and a persistent error is retried 5 times. NCQ commands,
and errors without sense data, were already retried and are unchanged.
---
 drivers/ata/libata-eh.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index b7e8545e569e..f99e422dfd9f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -4080,8 +4080,20 @@ void ata_eh_finish(struct ata_port *ap)
 				ata_eh_qc_complete(qc);
 			}
 		} else {
-			if (qc->flags & ATA_QCFLAG_SENSE_VALID ||
-			    qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) {
+			if (qc->flags & ATA_QCFLAG_SENSE_VALID &&
+			    qc->flags & ATA_QCFLAG_RETRY) {
+				/*
+				 * The sense data asks for a retry, see
+				 * ata_eh_analyze_tf(). ata_eh_link_autopsy()
+				 * cleared qc->err_mask, so ata_eh_qc_retry()
+				 * would increment scmd->allowed. Leave
+				 * scmd->allowed alone, so that upper layer
+				 * only retries the command if it has not
+				 * already been retried too many times.
+				 */
+				__ata_eh_qc_complete(qc);
+			} else if (qc->flags & ATA_QCFLAG_SENSE_VALID ||
+				   qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) {
 				ata_eh_qc_complete(qc);
 			} else {
 				/* feed zero TF to sense generation */
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] ata: libata-eh: Retry non-NCQ commands when their sense data asks for it
  2026-10-30  9:00 [PATCH] ata: libata-eh: Retry non-NCQ commands when their sense data asks for it Niklas Cassel
@ 2026-10-30 18:21 ` Igor Pylypiv
  0 siblings, 0 replies; 2+ messages in thread
From: Igor Pylypiv @ 2026-10-30 18:21 UTC (permalink / raw)
  To: Niklas Cassel; +Cc: Damien Le Moal, linux-ide

On Fri, Oct 30, 2026 at 10:00:48AM +0100, Niklas Cassel wrote:
> When a failed command has valid sense data, ata_eh_analyze_tf() asks
> scsi_check_sense() whether the command should be retried, and sets
> ATA_QCFLAG_RETRY if it should. ata_eh_link_autopsy() then clears
> AC_ERR_DEV and AC_ERR_OTHER from qc->err_mask, relying on that decision.
> 
> For an NCQ command, qc->err_mask still has AC_ERR_NCQ, so
> ata_eh_finish() honors ATA_QCFLAG_RETRY. For a non-NCQ command, whose
> sense data comes from REQUEST SENSE DATA EXT, qc->err_mask is now zero,
> and ata_eh_finish() completes the command with scmd->retries set to
> scmd->allowed, without looking at ATA_QCFLAG_RETRY. Such a command is
> thus never retried, even when its sense data asks for a retry, e.g. a
> transient error reported as ABORTED COMMAND.
> 
> Make ata_eh_finish() honor ATA_QCFLAG_RETRY for commands with valid
> sense data. ata_eh_qc_retry() cannot be used for this: as qc->err_mask
> is zero, it increments scmd->allowed, so every retry would allow one
> more, and a persistent error would be retried forever. Instead,
> complete the command without touching scmd->allowed or scmd->retries,
> so that the SCSI midlayer retries it at most scmd->allowed times, like
> any other failed command.
> 
> Fixes: 3852e3738266 ("libata: evaluate SCSI sense code")
> Signed-off-by: Niklas Cassel <cassel@kernel.org>

Reviewed-by: Igor Pylypiv <ipylypiv@google.com>

Thanks,
Igor

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-30 18:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30  9:00 [PATCH] ata: libata-eh: Retry non-NCQ commands when their sense data asks for it Niklas Cassel
2026-10-30 18:21 ` Igor Pylypiv

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.