diff mbox series

[5/5] libata: Fix command retry decision

Message ID 20180509002812.13151-6-damien.lemoal@wdc.com
State Not Applicable
Delegated to: David Miller
Headers show
Series libata fixes and improvements | expand

Commit Message

Damien Le Moal May 9, 2018, 12:28 a.m. UTC
For failed commands with valid sense data (e.g. NCQ commands),
scsi_check_sense() is used in ata_analyze_tf() to determine if the
command can be retried. In such case, rely on this decision and ignore
the command error mask based decision done in ata_worth_retry().

This fixes useless retries of commands such as unaligned writes on zoned
disks (TYPE_ZAC).

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 drivers/ata/libata-eh.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Comments

Hannes Reinecke May 9, 2018, 5:45 a.m. UTC | #1
On 05/09/2018 02:28 AM, Damien Le Moal wrote:
> For failed commands with valid sense data (e.g. NCQ commands),
> scsi_check_sense() is used in ata_analyze_tf() to determine if the
> command can be retried. In such case, rely on this decision and ignore
> the command error mask based decision done in ata_worth_retry().
> 
> This fixes useless retries of commands such as unaligned writes on zoned
> disks (TYPE_ZAC).
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
>   drivers/ata/libata-eh.c | 12 ++++++++----
>   1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
> index ccaed93985bb..816388df72a6 100644
> --- a/drivers/ata/libata-eh.c
> +++ b/drivers/ata/libata-eh.c
> @@ -2237,12 +2237,16 @@ static void ata_eh_link_autopsy(struct ata_link *link)
>   		if (qc->err_mask & ~AC_ERR_OTHER)
>   			qc->err_mask &= ~AC_ERR_OTHER;
>   
> -		/* SENSE_VALID trumps dev/unknown error and revalidation */
> +		/*
> +		 * SENSE_VALID trumps dev/unknown error and revalidation. Upper
> +		 * layers will determine whether the command is worth retrying
> +		 * based on the sense data and device class/type. Otherwise,
> +		 * determine directly if the command is worth retrying using its
> +		 * error mask and flags.
> +		 */
>   		if (qc->flags & ATA_QCFLAG_SENSE_VALID)
>   			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
> -
> -		/* determine whether the command is worth retrying */
> -		if (ata_eh_worth_retry(qc))
> +		else if (ata_eh_worth_retry(qc))
>   			qc->flags |= ATA_QCFLAG_RETRY;
>   
>   		/* accumulate error info */
> 
Ah. That was what I intended with the original ATA sense handling 
implementation, but never got around doing it properly.
Thanks for fixing it up.

Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ccaed93985bb..816388df72a6 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2237,12 +2237,16 @@  static void ata_eh_link_autopsy(struct ata_link *link)
 		if (qc->err_mask & ~AC_ERR_OTHER)
 			qc->err_mask &= ~AC_ERR_OTHER;
 
-		/* SENSE_VALID trumps dev/unknown error and revalidation */
+		/*
+		 * SENSE_VALID trumps dev/unknown error and revalidation. Upper
+		 * layers will determine whether the command is worth retrying
+		 * based on the sense data and device class/type. Otherwise,
+		 * determine directly if the command is worth retrying using its
+		 * error mask and flags.
+		 */
 		if (qc->flags & ATA_QCFLAG_SENSE_VALID)
 			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
-
-		/* determine whether the command is worth retrying */
-		if (ata_eh_worth_retry(qc))
+		else if (ata_eh_worth_retry(qc))
 			qc->flags |= ATA_QCFLAG_RETRY;
 
 		/* accumulate error info */