public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2] libsas: Check for completed commands before calling lldd_abort_task()
@ 2018-01-08 12:04 Hannes Reinecke
  2018-01-08 17:11 ` Yves-Alexis Perez
  2018-01-09  4:09 ` Jason Yan
  0 siblings, 2 replies; 8+ messages in thread
From: Hannes Reinecke @ 2018-01-08 12:04 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: Christoph Hellwig, James Bottomley, linux-scsi, Yves-Alexis Perez,
	Hannes Reinecke, Hannes Reinecke

The abort handler might be racing with command completion, so the
task might already be NULL by the time the abort handler is called.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/libsas/sas_scsi_host.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 58476b7..08203fb 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -486,18 +486,34 @@ static int sas_queue_reset(struct domain_device *dev, int reset_type,
 
 int sas_eh_abort_handler(struct scsi_cmnd *cmd)
 {
-	int res;
-	struct sas_task *task = TO_SAS_TASK(cmd);
+	int res = TMF_RESP_FUNC_COMPLETE;
+	struct sas_task *task;
 	struct Scsi_Host *host = cmd->device->host;
 	struct sas_internal *i = to_sas_internal(host->transportt);
+	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct sas_ha_struct *ha = dev->port->ha;
+	unsigned long flags;
 
 	if (!i->dft->lldd_abort_task)
 		return FAILED;
 
-	res = i->dft->lldd_abort_task(task);
+	/* Avoid sas_scsi_task_done() interfering */
+	spin_lock_irqsave(&dev->done_lock, flags);
+	task = TO_SAS_TASK(cmd);
+	if (test_bit(SAS_HA_FROZEN, &ha->state)) {
+		res = TMF_RESP_FUNC_FAILED;
+		task = NULL;
+	} else
+		ASSIGN_SAS_TASK(cmd, NULL);
+	spin_unlock_irqrestore(&dev->done_lock, flags);
+	if (task)
+		res = i->dft->lldd_abort_task(task);
 	if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
 		return SUCCESS;
 
+	spin_lock_irqsave(&dev->done_lock, flags);
+	ASSIGN_SAS_TASK(cmd, task);
+	spin_unlock_irqrestore(&dev->done_lock, flags);
 	return FAILED;
 }
 EXPORT_SYMBOL_GPL(sas_eh_abort_handler);
-- 
1.8.5.6

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

end of thread, other threads:[~2018-01-09 14:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-08 12:04 [PATCHv2] libsas: Check for completed commands before calling lldd_abort_task() Hannes Reinecke
2018-01-08 17:11 ` Yves-Alexis Perez
2018-01-09  9:30   ` Hannes Reinecke
2018-01-09 14:13     ` Yves-Alexis Perez
2018-01-09  4:09 ` Jason Yan
2018-01-09  7:34   ` Hannes Reinecke
2018-01-09  9:04     ` Jason Yan
2018-01-09  9:27       ` Hannes Reinecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox