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

scsi: qla2xxx: Chip reset uses wrong lock during IO flush.

As part of chip reset, all commands from all QPairs are
flushed. This patch fixes code to use Q Pair lock for flush
instead of using old hardware_lock.
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 d1e3635a
...@@ -1704,93 +1704,103 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) ...@@ -1704,93 +1704,103 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
return QLA_SUCCESS; return QLA_SUCCESS;
} }
void static void
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
{ {
int que, cnt, status; int cnt, status;
unsigned long flags; unsigned long flags;
srb_t *sp; srb_t *sp;
scsi_qla_host_t *vha = qp->vha;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req; struct req_que *req;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
struct qla_tgt_cmd *cmd; struct qla_tgt_cmd *cmd;
uint8_t trace = 0; uint8_t trace = 0;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(qp->qp_lock_ptr, flags);
for (que = 0; que < ha->max_req_queues; que++) { req = qp->req;
req = ha->req_q_map[que]; for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
if (!req) sp = req->outstanding_cmds[cnt];
continue; if (sp) {
if (!req->outstanding_cmds) req->outstanding_cmds[cnt] = NULL;
continue; if (sp->cmd_type == TYPE_SRB) {
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { if (sp->type == SRB_NVME_CMD ||
sp = req->outstanding_cmds[cnt]; sp->type == SRB_NVME_LS) {
if (sp) { sp_get(sp);
req->outstanding_cmds[cnt] = NULL; spin_unlock_irqrestore(qp->qp_lock_ptr,
if (sp->cmd_type == TYPE_SRB) { flags);
if (sp->type == SRB_NVME_CMD || qla_nvme_abort(ha, sp);
sp->type == SRB_NVME_LS) { spin_lock_irqsave(qp->qp_lock_ptr,
sp_get(sp); flags);
spin_unlock_irqrestore( } else if (GET_CMD_SP(sp) &&
&ha->hardware_lock, flags); !ha->flags.eeh_busy &&
qla_nvme_abort(ha, sp); (!test_bit(ABORT_ISP_ACTIVE,
spin_lock_irqsave( &vha->dpc_flags)) &&
&ha->hardware_lock, flags); (sp->type == SRB_SCSI_CMD)) {
} else if (GET_CMD_SP(sp) && /*
!ha->flags.eeh_busy && * Don't abort commands in
(!test_bit(ABORT_ISP_ACTIVE, * adapter during EEH
&vha->dpc_flags)) && * recovery as it's not
(sp->type == SRB_SCSI_CMD)) { * accessible/responding.
/* *
* Don't abort commands in * Get a reference to the sp
* adapter during EEH * and drop the lock. The
* recovery as it's not * reference ensures this
* accessible/responding. * sp->done() call and not the
* * call in qla2xxx_eh_abort()
* Get a reference to the sp * ends the SCSI command (with
* and drop the lock. The * result 'res').
* reference ensures this */
* sp->done() call and not the sp_get(sp);
* call in qla2xxx_eh_abort() spin_unlock_irqrestore(qp->qp_lock_ptr,
* ends the SCSI command (with flags);
* result 'res'). status = qla2xxx_eh_abort(
*/ GET_CMD_SP(sp));
sp_get(sp); spin_lock_irqsave(qp->qp_lock_ptr,
spin_unlock_irqrestore( flags);
&ha->hardware_lock, flags); /*
status = qla2xxx_eh_abort( * Get rid of extra reference
GET_CMD_SP(sp)); * if immediate exit from
spin_lock_irqsave( * ql2xxx_eh_abort
&ha->hardware_lock, flags); */
/* if (status == FAILED &&
* Get rid of extra reference (qla2x00_isp_reg_stat(ha)))
* if immediate exit from atomic_dec(
* ql2xxx_eh_abort &sp->ref_count);
*/ }
if (status == FAILED && sp->done(sp, res);
(qla2x00_isp_reg_stat(ha))) } else {
atomic_dec( if (!vha->hw->tgt.tgt_ops || !tgt ||
&sp->ref_count); qla_ini_mode_enabled(vha)) {
} if (!trace)
sp->done(sp, res); ql_dbg(ql_dbg_tgt_mgt,
} else { vha, 0xf003,
if (!vha->hw->tgt.tgt_ops || !tgt || "HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n",
qla_ini_mode_enabled(vha)) { vha->dpc_flags);
if (!trace) continue;
ql_dbg(ql_dbg_tgt_mgt,
vha, 0xf003,
"HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n",
vha->dpc_flags);
continue;
}
cmd = (struct qla_tgt_cmd *)sp;
qlt_abort_cmd_on_host_reset(cmd->vha,
cmd);
} }
cmd = (struct qla_tgt_cmd *)sp;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
} }
} }
} }
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
}
void
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
{
int que;
struct qla_hw_data *ha = vha->hw;
__qla2x00_abort_all_cmds(ha->base_qpair, res);
for (que = 0; que < ha->max_qpairs; que++) {
if (!ha->queue_pair_map[que])
continue;
__qla2x00_abort_all_cmds(ha->queue_pair_map[que], res);
}
} }
static int static int
......
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