Skip to content

Commit 68ad831

Browse files
Arun Easimartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix crash when I/O abort times out
While performing CPU hotplug, a crash with the following stack was seen: Call Trace: qla24xx_process_response_queue+0x42a/0x970 [qla2xxx] qla2x00_start_nvme_mq+0x3a2/0x4b0 [qla2xxx] qla_nvme_post_cmd+0x166/0x240 [qla2xxx] nvme_fc_start_fcp_op.part.0+0x119/0x2e0 [nvme_fc] blk_mq_dispatch_rq_list+0x17b/0x610 __blk_mq_sched_dispatch_requests+0xb0/0x140 blk_mq_sched_dispatch_requests+0x30/0x60 __blk_mq_run_hw_queue+0x35/0x90 __blk_mq_delay_run_hw_queue+0x161/0x180 blk_execute_rq+0xbe/0x160 __nvme_submit_sync_cmd+0x16f/0x220 [nvme_core] nvmf_connect_admin_queue+0x11a/0x170 [nvme_fabrics] nvme_fc_create_association.cold+0x50/0x3dc [nvme_fc] nvme_fc_connect_ctrl_work+0x19/0x30 [nvme_fc] process_one_work+0x1e8/0x3c0 On abort timeout, completion was called without checking if the I/O was already completed. Verify that I/O and abort request are indeed outstanding before attempting completion. Fixes: 71c80b7 ("scsi: qla2xxx: Do command completion on abort timeout") Reported-by: Marco Patalano <[email protected]> Tested-by: Marco Patalano <[email protected]> Cc: [email protected] Signed-off-by: Arun Easi <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 7fb4278 commit 68ad831

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void qla24xx_abort_iocb_timeout(void *data)
110110
struct qla_qpair *qpair = sp->qpair;
111111
u32 handle;
112112
unsigned long flags;
113+
int sp_found = 0, cmdsp_found = 0;
113114

114115
if (sp->cmd_sp)
115116
ql_dbg(ql_dbg_async, sp->vha, 0x507c,
@@ -124,27 +125,32 @@ static void qla24xx_abort_iocb_timeout(void *data)
124125
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
125126
for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
126127
if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
127-
sp->cmd_sp))
128+
sp->cmd_sp)) {
128129
qpair->req->outstanding_cmds[handle] = NULL;
130+
cmdsp_found = 1;
131+
}
129132

130133
/* removing the abort */
131134
if (qpair->req->outstanding_cmds[handle] == sp) {
132135
qpair->req->outstanding_cmds[handle] = NULL;
136+
sp_found = 1;
133137
break;
134138
}
135139
}
136140
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
137141

138-
if (sp->cmd_sp) {
142+
if (cmdsp_found && sp->cmd_sp) {
139143
/*
140144
* This done function should take care of
141145
* original command ref: INIT
142146
*/
143147
sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
144148
}
145149

146-
abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
147-
sp->done(sp, QLA_OS_TIMER_EXPIRED);
150+
if (sp_found) {
151+
abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
152+
sp->done(sp, QLA_OS_TIMER_EXPIRED);
153+
}
148154
}
149155

150156
static void qla24xx_abort_sp_done(srb_t *sp, int res)

0 commit comments

Comments
 (0)