Skip to content

Commit 2cabf10

Browse files
Arun Easimartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix hang on NVMe command timeouts
The abort callback gets called only when it gets posted to firmware. The refcounting is done properly in the callback. On internal errors, the callback is not invoked leading to a hung I/O. Fix this by having separate error code when command gets returned from firmware. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arun Easi <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent f6e327f commit 2cabf10

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5166,6 +5166,9 @@ struct secure_flash_update_block_pk {
51665166
#define QLA_BUSY 0x107
51675167
#define QLA_ALREADY_REGISTERED 0x109
51685168
#define QLA_OS_TIMER_EXPIRED 0x10a
5169+
#define QLA_ERR_NO_QPAIR 0x10b
5170+
#define QLA_ERR_NOT_FOUND 0x10c
5171+
#define QLA_ERR_FROM_FW 0x10d
51695172

51705173
#define NVRAM_DELAY() udelay(10)
51715174

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
157157
sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
158158
GFP_ATOMIC);
159159
if (!sp)
160-
return rval;
160+
return QLA_MEMORY_ALLOC_FAILED;
161161

162162
abt_iocb = &sp->u.iocb_cmd;
163163
sp->type = SRB_ABT_CMD;
@@ -190,7 +190,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
190190
if (wait) {
191191
wait_for_completion(&abt_iocb->u.abt.comp);
192192
rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
193-
QLA_SUCCESS : QLA_FUNCTION_FAILED;
193+
QLA_SUCCESS : QLA_ERR_FROM_FW;
194194
sp->free(sp);
195195
}
196196

@@ -1988,7 +1988,7 @@ qla24xx_async_abort_command(srb_t *sp)
19881988

19891989
if (handle == req->num_outstanding_cmds) {
19901990
/* Command not found. */
1991-
return QLA_FUNCTION_FAILED;
1991+
return QLA_ERR_NOT_FOUND;
19921992
}
19931993
if (sp->type == SRB_FXIOCB_DCMD)
19941994
return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,

drivers/scsi/qla2xxx/qla_mbx.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,7 +3245,7 @@ qla24xx_abort_command(srb_t *sp)
32453245
if (sp->qpair)
32463246
req = sp->qpair->req;
32473247
else
3248-
return QLA_FUNCTION_FAILED;
3248+
return QLA_ERR_NO_QPAIR;
32493249

32503250
if (ql2xasynctmfenable)
32513251
return qla24xx_async_abort_command(sp);
@@ -3258,7 +3258,7 @@ qla24xx_abort_command(srb_t *sp)
32583258
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
32593259
if (handle == req->num_outstanding_cmds) {
32603260
/* Command not found. */
3261-
return QLA_FUNCTION_FAILED;
3261+
return QLA_ERR_NOT_FOUND;
32623262
}
32633263

32643264
abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);

drivers/scsi/qla2xxx/qla_nvme.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ static void qla_nvme_abort_work(struct work_struct *work)
227227
srb_t *sp = priv->sp;
228228
fc_port_t *fcport = sp->fcport;
229229
struct qla_hw_data *ha = fcport->vha->hw;
230-
int rval;
230+
int rval, abts_done_called = 1;
231231

232232
ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
233-
"%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n",
234-
__func__, sp, sp->handle, fcport, fcport->deleted);
233+
"%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n",
234+
__func__, sp, sp->handle, fcport, sp->u.iocb_cmd.u.nvme.desc, fcport->deleted);
235235

236236
if (!ha->flags.fw_started || fcport->deleted == QLA_SESS_DELETED)
237237
goto out;
@@ -251,12 +251,20 @@ static void qla_nvme_abort_work(struct work_struct *work)
251251
__func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
252252
sp, sp->handle, fcport, rval);
253253

254+
/*
255+
* If async tmf is enabled, the abort callback is called only on
256+
* return codes QLA_SUCCESS and QLA_ERR_FROM_FW.
257+
*/
258+
if (ql2xasynctmfenable &&
259+
rval != QLA_SUCCESS && rval != QLA_ERR_FROM_FW)
260+
abts_done_called = 0;
261+
254262
/*
255263
* Returned before decreasing kref so that I/O requests
256264
* are waited until ABTS complete. This kref is decreased
257265
* at qla24xx_abort_sp_done function.
258266
*/
259-
if (ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp))
267+
if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp))
260268
return;
261269
out:
262270
/* kref_get was done before work was schedule. */
@@ -804,14 +812,14 @@ void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *ori
804812
case CS_PORT_LOGGED_OUT:
805813
/* BA_RJT was received for the ABTS */
806814
case CS_PORT_CONFIG_CHG:
807-
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09d,
815+
ql_dbg(ql_dbg_async, vha, 0xf09d,
808816
"Abort I/O IOCB completed with error, comp_status=%x\n",
809817
comp_status);
810818
break;
811819

812820
/* BA_RJT was received for the ABTS */
813821
case CS_REJECT_RECEIVED:
814-
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
822+
ql_dbg(ql_dbg_async, vha, 0xf09e,
815823
"BA_RJT was received for the ABTS rjt_vendorUnique = %u",
816824
abt->fw.ba_rjt_vendorUnique);
817825
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
@@ -820,18 +828,18 @@ void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *ori
820828
break;
821829

822830
case CS_COMPLETE:
823-
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09f,
831+
ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0xf09f,
824832
"IOCB request is completed successfully comp_status=%x\n",
825833
comp_status);
826834
break;
827835

828836
case CS_IOCB_ERROR:
829-
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf0a0,
837+
ql_dbg(ql_dbg_async, vha, 0xf0a0,
830838
"IOCB request is failed, comp_status=%x\n", comp_status);
831839
break;
832840

833841
default:
834-
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf0a1,
842+
ql_dbg(ql_dbg_async, vha, 0xf0a1,
835843
"Invalid Abort IO IOCB Completion Status %x\n",
836844
comp_status);
837845
break;

0 commit comments

Comments
 (0)