Skip to content

Commit 46a9d97

Browse files
damien-lemoalfloatious
authored andcommitted
ata: libata-eh: avoid unnecessary calls to ata_scsi_port_error_handler()
When handling SCSI command timeouts, if we had no actual command timeouts (either because the command was a deferred qc or the completion path won the race with ata_scsi_cmd_error_handler()), we do not need to go through a port error handling, as there was in fact no errors at all. Modify ata_scsi_cmd_error_handler() to return the number of commands that timed out and use this return value in ata_scsi_error() to call ata_scsi_port_error_handler() only if we had command timeouts, or if the port EH has already been scheduled due to failed commands. Otherwise, simply call scsi_eh_flush_done_q() to finish the completed commands without running the full port error handling. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org>
1 parent db1d3cf commit 46a9d97

2 files changed

Lines changed: 21 additions & 10 deletions

File tree

drivers/ata/libata-eh.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -560,21 +560,27 @@ void ata_scsi_error(struct Scsi_Host *host)
560560
{
561561
struct ata_port *ap = ata_shost_to_port(host);
562562
unsigned long flags;
563+
int nr_timedout;
563564
LIST_HEAD(eh_work_q);
564565

565566
spin_lock_irqsave(host->host_lock, flags);
566567
list_splice_init(&host->eh_cmd_q, &eh_work_q);
567568
spin_unlock_irqrestore(host->host_lock, flags);
568569

569-
ata_scsi_cmd_error_handler(host, ap, &eh_work_q);
570-
571-
/* If we timed raced normal completion and there is nothing to
572-
recover nr_timedout == 0 why exactly are we doing error recovery ? */
573-
ata_scsi_port_error_handler(host, ap);
570+
/*
571+
* First check what errors we got with ata_scsi_cmd_error_handler().
572+
* If we had no command timeouts and EH is not scheduled for this port,
573+
* meaning that we do not have any failed command, then there is no
574+
* need to go through the full port error handling. We only need to
575+
* flush the completed commands we have.
576+
*/
577+
nr_timedout = ata_scsi_cmd_error_handler(host, ap, &eh_work_q);
578+
if (nr_timedout || ata_port_eh_scheduled(ap))
579+
ata_scsi_port_error_handler(host, ap);
580+
else
581+
scsi_eh_flush_done_q(&ap->eh_done_q);
574582

575-
/* finish or retry handled scmd's and clean up */
576583
WARN_ON(!list_empty(&eh_work_q));
577-
578584
}
579585

580586
/**
@@ -586,9 +592,11 @@ void ata_scsi_error(struct Scsi_Host *host)
586592
* process the given list of commands and return those finished to the
587593
* ap->eh_done_q. This function is the first part of the libata error
588594
* handler which processes a given list of failed commands.
595+
*
596+
* Return the number of commands that timed out.
589597
*/
590-
void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
591-
struct list_head *eh_work_q)
598+
int ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
599+
struct list_head *eh_work_q)
592600
{
593601
int i;
594602
unsigned long flags;
@@ -678,6 +686,8 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
678686
ap->eh_tries = ATA_EH_MAX_TRIES;
679687

680688
spin_unlock_irqrestore(ap->lock, flags);
689+
690+
return nr_timedout;
681691
}
682692
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
683693

include/linux/libata.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,8 @@ extern int ata_ncq_prio_enable(struct ata_port *ap, struct scsi_device *sdev,
12251225
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
12261226
int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
12271227
extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
1228-
extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q);
1228+
int ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
1229+
struct list_head *eh_q);
12291230

12301231
/*
12311232
* SATA specific code - drivers/ata/libata-sata.c

0 commit comments

Comments
 (0)