]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: ipr: Fix missed EH wakeup
authorBrian King <brking@linux.vnet.ibm.com>
Wed, 15 Mar 2017 21:58:36 +0000 (16:58 -0500)
committerSasha Levin <alexander.levin@microsoft.com>
Wed, 23 May 2018 01:33:43 +0000 (21:33 -0400)
[ Upstream commit 66a0d59cdd12546ddf01d229de28b07ccf6d637f ]

Following a command abort or device reset, ipr's EH handlers wait for
the commands getting aborted to get sent back from the adapter prior to
returning from the EH handler. This fixes up some cases where the
completion handler was not getting called, which would have resulted in
the EH thread waiting until it timed out, greatly extending EH time.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Reviewed-by: Wendy Xiong <wenxiong@linux.vnet.ibm.com>
Tested-by: Wendy Xiong <wenxiong@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
drivers/scsi/ipr.c

index cd52c070701b8e622cdd4c9df4e85831ea9990c7..3a9648d7f441e373166d035ed0d0c1a17b5e7d29 100644 (file)
@@ -835,8 +835,10 @@ static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd)
 
        qc->err_mask |= AC_ERR_OTHER;
        sata_port->ioasa.status |= ATA_BUSY;
-       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
        ata_qc_complete(qc);
+       if (ipr_cmd->eh_comp)
+               complete(ipr_cmd->eh_comp);
+       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -5859,8 +5861,10 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
                res->in_erp = 0;
        }
        scsi_dma_unmap(ipr_cmd->scsi_cmd);
-       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
        scsi_cmd->scsi_done(scsi_cmd);
+       if (ipr_cmd->eh_comp)
+               complete(ipr_cmd->eh_comp);
+       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -6250,8 +6254,10 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
        }
 
        scsi_dma_unmap(ipr_cmd->scsi_cmd);
-       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
        scsi_cmd->scsi_done(scsi_cmd);
+       if (ipr_cmd->eh_comp)
+               complete(ipr_cmd->eh_comp);
+       list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
 }
 
 /**
@@ -6277,8 +6283,10 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
                scsi_dma_unmap(scsi_cmd);
 
                spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags);
-               list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
                scsi_cmd->scsi_done(scsi_cmd);
+               if (ipr_cmd->eh_comp)
+                       complete(ipr_cmd->eh_comp);
+               list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
                spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags);
        } else {
                spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);