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

scsi: qla2xxx: Fix deadlock between ATIO and HW lock

Move ATIO queue processing out of hardware_lock to prevent deadlock.

Fixes: 3bb67df5 ("qla2xxx: Check for online flag instead of active reset when transmitting responses")
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b6faaaf7
...@@ -4859,19 +4859,10 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) ...@@ -4859,19 +4859,10 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
*/ */
if (qla_tgt_mode_enabled(vha) || if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha)) { qla_dual_mode_enabled(vha)) {
if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) { spin_lock_irqsave(&ha->tgt.atio_lock, flags);
spin_lock_irqsave(&ha->tgt.atio_lock, qlt_24xx_process_atio_queue(vha, 0);
flags); spin_unlock_irqrestore(&ha->tgt.atio_lock,
qlt_24xx_process_atio_queue(vha, 0); flags);
spin_unlock_irqrestore(
&ha->tgt.atio_lock, flags);
} else {
spin_lock_irqsave(&ha->hardware_lock,
flags);
qlt_24xx_process_atio_queue(vha, 1);
spin_unlock_irqrestore(
&ha->hardware_lock, flags);
}
} }
} }
} }
......
...@@ -3121,6 +3121,7 @@ qla24xx_intr_handler(int irq, void *dev_id) ...@@ -3121,6 +3121,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
uint16_t mb[8]; uint16_t mb[8];
struct rsp_que *rsp; struct rsp_que *rsp;
unsigned long flags; unsigned long flags;
bool process_atio = false;
rsp = (struct rsp_que *) dev_id; rsp = (struct rsp_que *) dev_id;
if (!rsp) { if (!rsp) {
...@@ -3181,22 +3182,13 @@ qla24xx_intr_handler(int irq, void *dev_id) ...@@ -3181,22 +3182,13 @@ qla24xx_intr_handler(int irq, void *dev_id)
qla24xx_process_response_queue(vha, rsp); qla24xx_process_response_queue(vha, rsp);
break; break;
case INTR_ATIO_QUE_UPDATE_27XX: case INTR_ATIO_QUE_UPDATE_27XX:
case INTR_ATIO_QUE_UPDATE:{ case INTR_ATIO_QUE_UPDATE:
unsigned long flags2; process_atio = true;
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
qlt_24xx_process_atio_queue(vha, 1);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
break; break;
} case INTR_ATIO_RSP_QUE_UPDATE:
case INTR_ATIO_RSP_QUE_UPDATE: { process_atio = true;
unsigned long flags2;
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
qlt_24xx_process_atio_queue(vha, 1);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
qla24xx_process_response_queue(vha, rsp); qla24xx_process_response_queue(vha, rsp);
break; break;
}
default: default:
ql_dbg(ql_dbg_async, vha, 0x504f, ql_dbg(ql_dbg_async, vha, 0x504f,
"Unrecognized interrupt type (%d).\n", stat * 0xff); "Unrecognized interrupt type (%d).\n", stat * 0xff);
...@@ -3210,6 +3202,12 @@ qla24xx_intr_handler(int irq, void *dev_id) ...@@ -3210,6 +3202,12 @@ qla24xx_intr_handler(int irq, void *dev_id)
qla2x00_handle_mbx_completion(ha, status); qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (process_atio) {
spin_lock_irqsave(&ha->tgt.atio_lock, flags);
qlt_24xx_process_atio_queue(vha, 0);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -3256,6 +3254,7 @@ qla24xx_msix_default(int irq, void *dev_id) ...@@ -3256,6 +3254,7 @@ qla24xx_msix_default(int irq, void *dev_id)
uint32_t hccr; uint32_t hccr;
uint16_t mb[8]; uint16_t mb[8];
unsigned long flags; unsigned long flags;
bool process_atio = false;
rsp = (struct rsp_que *) dev_id; rsp = (struct rsp_que *) dev_id;
if (!rsp) { if (!rsp) {
...@@ -3312,22 +3311,13 @@ qla24xx_msix_default(int irq, void *dev_id) ...@@ -3312,22 +3311,13 @@ qla24xx_msix_default(int irq, void *dev_id)
qla24xx_process_response_queue(vha, rsp); qla24xx_process_response_queue(vha, rsp);
break; break;
case INTR_ATIO_QUE_UPDATE_27XX: case INTR_ATIO_QUE_UPDATE_27XX:
case INTR_ATIO_QUE_UPDATE:{ case INTR_ATIO_QUE_UPDATE:
unsigned long flags2; process_atio = true;
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
qlt_24xx_process_atio_queue(vha, 1);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
break; break;
} case INTR_ATIO_RSP_QUE_UPDATE:
case INTR_ATIO_RSP_QUE_UPDATE: { process_atio = true;
unsigned long flags2;
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
qlt_24xx_process_atio_queue(vha, 1);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
qla24xx_process_response_queue(vha, rsp); qla24xx_process_response_queue(vha, rsp);
break; break;
}
default: default:
ql_dbg(ql_dbg_async, vha, 0x5051, ql_dbg(ql_dbg_async, vha, 0x5051,
"Unrecognized interrupt type (%d).\n", stat & 0xff); "Unrecognized interrupt type (%d).\n", stat & 0xff);
...@@ -3338,6 +3328,12 @@ qla24xx_msix_default(int irq, void *dev_id) ...@@ -3338,6 +3328,12 @@ qla24xx_msix_default(int irq, void *dev_id)
qla2x00_handle_mbx_completion(ha, status); qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (process_atio) {
spin_lock_irqsave(&ha->tgt.atio_lock, flags);
qlt_24xx_process_atio_queue(vha, 0);
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
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