diff options
author | Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com> | 2016-11-14 16:26:22 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-11-14 18:38:10 -0500 |
commit | c733ab3512431436a26e0381829b45794cb13fb0 (patch) | |
tree | 8a462254a2f5e092fdc3c5294378a4755bb7d31d | |
parent | 18f6084a989ba1b38702f9af37a2e4049a924be6 (diff) |
scsi: qla2xxx: do not abort all commands in the adapter during EEH recovery
The previous commit 1535aa75a3d8 ("qla2xxx: fix invalid DMA access after
command aborts in PCI device remove") introduced a regression during an
EEH recovery, since the change to the qla2x00_abort_all_cmds() function
calls qla2xxx_eh_abort(), which verifies the EEH recovery condition but
handles it heavy-handed. (commit a465537ad1a4 "qla2xxx: Disable the
adapter and skip error recovery in case of register disconnect.")
This problem warrants a more general/optimistic solution right into
qla2xxx_eh_abort() (eg in case a real command abort arrives during EEH
recovery, or if it takes long enough to trigger command aborts); but
it's still worth to add a check to ensure the code added by the previous
commit is correct and contained within its owner function.
This commit just adds a 'if (!ha->flags.eeh_busy)' check around it.
(ahem; a trivial fix for this -rc series; sorry for this oversight.)
With it applied, both PCI device remove and EEH recovery works fine.
Fixes: 1535aa75a3d8 ("scsi: qla2xxx: fix invalid DMA access after command aborts in PCI device remove")
Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
Acked-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 567fa080e261..56d6142852a5 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1456,15 +1456,20 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) | |||
1456 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { | 1456 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
1457 | sp = req->outstanding_cmds[cnt]; | 1457 | sp = req->outstanding_cmds[cnt]; |
1458 | if (sp) { | 1458 | if (sp) { |
1459 | /* Get a reference to the sp and drop the lock. | 1459 | /* Don't abort commands in adapter during EEH |
1460 | * The reference ensures this sp->done() call | 1460 | * recovery as it's not accessible/responding. |
1461 | * - and not the call in qla2xxx_eh_abort() - | ||
1462 | * ends the SCSI command (with result 'res'). | ||
1463 | */ | 1461 | */ |
1464 | sp_get(sp); | 1462 | if (!ha->flags.eeh_busy) { |
1465 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1463 | /* Get a reference to the sp and drop the lock. |
1466 | qla2xxx_eh_abort(GET_CMD_SP(sp)); | 1464 | * The reference ensures this sp->done() call |
1467 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1465 | * - and not the call in qla2xxx_eh_abort() - |
1466 | * ends the SCSI command (with result 'res'). | ||
1467 | */ | ||
1468 | sp_get(sp); | ||
1469 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1470 | qla2xxx_eh_abort(GET_CMD_SP(sp)); | ||
1471 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1472 | } | ||
1468 | req->outstanding_cmds[cnt] = NULL; | 1473 | req->outstanding_cmds[cnt] = NULL; |
1469 | sp->done(vha, sp, res); | 1474 | sp->done(vha, sp, res); |
1470 | } | 1475 | } |