forked from Minki/linux
scsi: qla2xxx: Fix deadlock between ATIO and HW lock
Move ATIO queue processing out of hardware_lock to prevent deadlock.
Fixes: 3bb67df5b5
("qla2xxx: Check for online flag instead of active reset when transmitting responses")
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
b6faaaf796
commit
1073daa470
@ -4859,19 +4859,10 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
||||
*/
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha)) {
|
||||
if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock,
|
||||
flags);
|
||||
qlt_24xx_process_atio_queue(vha, 0);
|
||||
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);
|
||||
}
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags);
|
||||
qlt_24xx_process_atio_queue(vha, 0);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3121,6 +3121,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
uint16_t mb[8];
|
||||
struct rsp_que *rsp;
|
||||
unsigned long flags;
|
||||
bool process_atio = false;
|
||||
|
||||
rsp = (struct rsp_que *) dev_id;
|
||||
if (!rsp) {
|
||||
@ -3181,22 +3182,13 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE_27XX:
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
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);
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
break;
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
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);
|
||||
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x504f,
|
||||
"Unrecognized interrupt type (%d).\n", stat * 0xff);
|
||||
@ -3210,6 +3202,12 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
qla2x00_handle_mbx_completion(ha, status);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -3256,6 +3254,7 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
uint32_t hccr;
|
||||
uint16_t mb[8];
|
||||
unsigned long flags;
|
||||
bool process_atio = false;
|
||||
|
||||
rsp = (struct rsp_que *) dev_id;
|
||||
if (!rsp) {
|
||||
@ -3312,22 +3311,13 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE_27XX:
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
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);
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
break;
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
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);
|
||||
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x5051,
|
||||
"Unrecognized interrupt type (%d).\n", stat & 0xff);
|
||||
@ -3338,6 +3328,12 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
qla2x00_handle_mbx_completion(ha, status);
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user