Commit daafc8d3 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: Fix mailbox recovery during PCIe error

For the mailbox thread that encounters a PCIe error, pause that thread
until PCIe link reset/recovery has completed to prevent the thread from
possibly unmapping any type of DMA resource that might be in progress.

Link: https://lore.kernel.org/r/20210329085229.4367-10-njavali@marvell.comTested-by: default avatarLaurence Oberman <loberman@redhat.com>
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f7a0ed47
...@@ -102,7 +102,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -102,7 +102,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
int rval, i; int rval, i;
unsigned long flags = 0; unsigned long flags = 0;
device_reg_t *reg; device_reg_t *reg;
uint8_t abort_active; uint8_t abort_active, eeh_delay;
uint8_t io_lock_on; uint8_t io_lock_on;
uint16_t command = 0; uint16_t command = 0;
uint16_t *iptr; uint16_t *iptr;
...@@ -136,7 +136,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -136,7 +136,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
"PCI error, exiting.\n"); "PCI error, exiting.\n");
return QLA_FUNCTION_TIMEOUT; return QLA_FUNCTION_TIMEOUT;
} }
eeh_delay = 0;
reg = ha->iobase; reg = ha->iobase;
io_lock_on = base_vha->flags.init_done; io_lock_on = base_vha->flags.init_done;
...@@ -159,11 +159,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -159,11 +159,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
} }
/* check if ISP abort is active and return cmd with timeout */ /* check if ISP abort is active and return cmd with timeout */
if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
ha->flags.eeh_busy) && !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) {
!is_rom_cmd(mcp->mb[0])) {
ql_log(ql_log_info, vha, 0x1005, ql_log(ql_log_info, vha, 0x1005,
"Cmd 0x%x aborted with timeout since ISP Abort is pending\n", "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
mcp->mb[0]); mcp->mb[0]);
...@@ -186,7 +185,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -186,7 +185,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
return QLA_FUNCTION_TIMEOUT; return QLA_FUNCTION_TIMEOUT;
} }
atomic_dec(&ha->num_pend_mbx_stage1); atomic_dec(&ha->num_pend_mbx_stage1);
if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||
ha->flags.eeh_busy) {
ql_log(ql_log_warn, vha, 0xd035,
"Error detected: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n",
ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]);
rval = QLA_ABORTED; rval = QLA_ABORTED;
goto premature_exit; goto premature_exit;
} }
...@@ -266,6 +269,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -266,6 +269,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
if (!wait_for_completion_timeout(&ha->mbx_intr_comp, if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
mcp->tov * HZ)) { mcp->tov * HZ)) {
if (chip_reset != ha->chip_reset) { if (chip_reset != ha->chip_reset) {
eeh_delay = ha->flags.eeh_busy ? 1 : 0;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
ha->flags.mbox_busy = 0; ha->flags.mbox_busy = 0;
spin_unlock_irqrestore(&ha->hardware_lock, spin_unlock_irqrestore(&ha->hardware_lock,
...@@ -283,6 +288,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -283,6 +288,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
} else if (ha->flags.purge_mbox || } else if (ha->flags.purge_mbox ||
chip_reset != ha->chip_reset) { chip_reset != ha->chip_reset) {
eeh_delay = ha->flags.eeh_busy ? 1 : 0;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
ha->flags.mbox_busy = 0; ha->flags.mbox_busy = 0;
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -324,6 +331,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -324,6 +331,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
while (!ha->flags.mbox_int) { while (!ha->flags.mbox_int) {
if (ha->flags.purge_mbox || if (ha->flags.purge_mbox ||
chip_reset != ha->chip_reset) { chip_reset != ha->chip_reset) {
eeh_delay = ha->flags.eeh_busy ? 1 : 0;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
ha->flags.mbox_busy = 0; ha->flags.mbox_busy = 0;
spin_unlock_irqrestore(&ha->hardware_lock, spin_unlock_irqrestore(&ha->hardware_lock,
...@@ -532,7 +541,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -532,7 +541,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
/* Allow next mbx cmd to come in. */ /* Allow next mbx cmd to come in. */
complete(&ha->mbx_cmd_comp); complete(&ha->mbx_cmd_comp);
if (ha->isp_ops->abort_isp(vha)) { if (ha->isp_ops->abort_isp(vha) &&
!ha->flags.eeh_busy) {
/* Failed. retry later. */ /* Failed. retry later. */
set_bit(ISP_ABORT_NEEDED, set_bit(ISP_ABORT_NEEDED,
&vha->dpc_flags); &vha->dpc_flags);
...@@ -585,6 +595,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -585,6 +595,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
} }
i = 500;
while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) {
/*
* The caller of this mailbox encounter pci error.
* Hold the thread until PCIE link reset complete to make
* sure caller does not unmap dma while recovery is
* in progress.
*/
msleep(1);
i--;
}
return rval; return rval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment