According to the information I found in patch commit descriptions, for SATA devices commands must be aborted from inside the libsas error handler. Check host->ehandler to determine whether or not running inside the error handler since host->host_eh_scheduled != 0 indicates that the SCSI error handler has been scheduled but does not mean that is already running. This patch restores code that was removed by commit 909657615d9b ("scsi: libsas: allow async aborts"). Cc: Hannes Reinecke <hare@xxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Ming Lei <ming.lei@xxxxxxxxxx> Cc: John Garry <john.garry@xxxxxxxxxx> Cc: Yves-Alexis Perez <corsac@xxxxxxxxxx> Fixes: c9f926000fe3 ("scsi: libsas: Disable asynchronous aborts for SATA devices") Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/libsas/sas_scsi_host.c | 5 ++++- include/scsi/libsas.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index ee44a0d7730b..95e4d58ab9d4 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -462,6 +462,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd) int res = TMF_RESP_FUNC_FAILED; struct sas_task *task = TO_SAS_TASK(cmd); struct Scsi_Host *host = cmd->device->host; + struct sas_ha_struct *ha = SHOST_TO_SAS_HA(host); struct domain_device *dev = cmd_to_domain_dev(cmd); struct sas_internal *i = to_sas_internal(host->transportt); unsigned long flags; @@ -471,7 +472,7 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd) spin_lock_irqsave(host->host_lock, flags); /* We cannot do async aborts for SATA devices */ - if (dev_is_sata(dev) && !host->host_eh_scheduled) { + if (dev_is_sata(dev) && !ha->eh_running) { spin_unlock_irqrestore(host->host_lock, flags); return FAILED; } @@ -731,6 +732,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) tries++; retry = true; spin_lock_irq(shost->host_lock); + ha->eh_running = true; list_splice_init(&shost->eh_cmd_q, &eh_work_q); spin_unlock_irq(shost->host_lock); @@ -767,6 +769,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) /* check if any new eh work was scheduled during the last run */ spin_lock_irq(&ha->lock); + ha->eh_running = false; if (ha->eh_active == 0) { shost->host_eh_scheduled = 0; retry = false; diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 6fe125a71b60..4a8fb324140e 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -364,6 +364,7 @@ struct sas_ha_struct { struct mutex drain_mutex; unsigned long state; spinlock_t lock; + bool eh_running; int eh_active; wait_queue_head_t eh_wait_q; struct list_head eh_dev_q;