mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
scsi: qla2xxx: Fix crash due to stale SRB access around I/O timeouts
Ensure SRB is returned during I/O timeout error escalation. If that is not
possible fail the escalation path.
Following crash stack was seen:
BUG: unable to handle kernel paging request at 0000002f56aa90f8
IP: qla_chk_edif_rx_sa_delete_pending+0x14/0x30 [qla2xxx]
Call Trace:
? qla2x00_status_entry+0x19f/0x1c50 [qla2xxx]
? qla2x00_start_sp+0x116/0x1170 [qla2xxx]
? dma_pool_alloc+0x1d6/0x210
? mempool_alloc+0x54/0x130
? qla24xx_process_response_queue+0x548/0x12b0 [qla2xxx]
? qla_do_work+0x2d/0x40 [qla2xxx]
? process_one_work+0x14c/0x390
Link: https://lore.kernel.org/r/20220616053508.27186-6-njavali@marvell.com
Fixes: d74595278f
("scsi: qla2xxx: Add multiple queue pair functionality.")
Cc: stable@vger.kernel.org
Signed-off-by: Arun Easi <aeasi@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
5304673bdb
commit
c39587bc0a
1 changed files with 31 additions and 12 deletions
|
@ -1342,21 +1342,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
||||||
/*
|
/*
|
||||||
* Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED.
|
* Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
|
__qla2x00_eh_wait_for_pending_commands(struct qla_qpair *qpair, unsigned int t,
|
||||||
uint64_t l, enum nexus_wait_type type)
|
uint64_t l, enum nexus_wait_type type)
|
||||||
{
|
{
|
||||||
int cnt, match, status;
|
int cnt, match, status;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
scsi_qla_host_t *vha = qpair->vha;
|
||||||
struct req_que *req;
|
struct req_que *req = qpair->req;
|
||||||
srb_t *sp;
|
srb_t *sp;
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
|
|
||||||
status = QLA_SUCCESS;
|
status = QLA_SUCCESS;
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||||
req = vha->req;
|
|
||||||
for (cnt = 1; status == QLA_SUCCESS &&
|
for (cnt = 1; status == QLA_SUCCESS &&
|
||||||
cnt < req->num_outstanding_cmds; cnt++) {
|
cnt < req->num_outstanding_cmds; cnt++) {
|
||||||
sp = req->outstanding_cmds[cnt];
|
sp = req->outstanding_cmds[cnt];
|
||||||
|
@ -1383,15 +1382,35 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
|
||||||
if (!match)
|
if (!match)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||||
status = qla2x00_eh_wait_on_command(cmd);
|
status = qla2x00_eh_wait_on_command(cmd);
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
|
||||||
|
uint64_t l, enum nexus_wait_type type)
|
||||||
|
{
|
||||||
|
struct qla_qpair *qpair;
|
||||||
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
int i, status = QLA_SUCCESS;
|
||||||
|
|
||||||
|
status = __qla2x00_eh_wait_for_pending_commands(ha->base_qpair, t, l,
|
||||||
|
type);
|
||||||
|
for (i = 0; status == QLA_SUCCESS && i < ha->max_qpairs; i++) {
|
||||||
|
qpair = ha->queue_pair_map[i];
|
||||||
|
if (!qpair)
|
||||||
|
continue;
|
||||||
|
status = __qla2x00_eh_wait_for_pending_commands(qpair, t, l,
|
||||||
|
type);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static char *reset_errors[] = {
|
static char *reset_errors[] = {
|
||||||
"HBA not online",
|
"HBA not online",
|
||||||
"HBA not ready",
|
"HBA not ready",
|
||||||
|
@ -1425,7 +1444,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (fcport->deleted)
|
if (fcport->deleted)
|
||||||
return SUCCESS;
|
return FAILED;
|
||||||
|
|
||||||
ql_log(ql_log_info, vha, 0x8009,
|
ql_log(ql_log_info, vha, 0x8009,
|
||||||
"DEVICE RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", vha->host_no,
|
"DEVICE RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", vha->host_no,
|
||||||
|
@ -1493,7 +1512,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (fcport->deleted)
|
if (fcport->deleted)
|
||||||
return SUCCESS;
|
return FAILED;
|
||||||
|
|
||||||
ql_log(ql_log_info, vha, 0x8009,
|
ql_log(ql_log_info, vha, 0x8009,
|
||||||
"TARGET RESET ISSUED nexus=%ld:%d cmd=%p.\n", vha->host_no,
|
"TARGET RESET ISSUED nexus=%ld:%d cmd=%p.\n", vha->host_no,
|
||||||
|
|
Loading…
Reference in a new issue