Thread (39 messages) 39 messages, 5 authors, 2021-07-08
STALE1838d
Revisions (2)
  1. v1 current
  2. v3 [diff vs current]

[PATCH 02/21] libsas: Only abort commands from inside the error handler

From: Bart Van Assche <bvanassche@acm.org>
Date: 2021-07-01 21:12:40
Subsystem: scsi libsas subsystem, scsi subsystem, the rest · Maintainers: "James E.J. Bottomley", "Martin K. Petersen", Linus Torvalds

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@suse.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <redacted>
Cc: John Garry <redacted>
Cc: Yves-Alexis Perez <redacted>
Fixes: c9f926000fe3 ("scsi: libsas: Disable asynchronous aborts for SATA devices")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 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;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help