From: Sasha Levin Date: Fri, 16 Apr 2021 17:46:21 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v5.4.114~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=06e196f659407c124009e32aab48f8598b002940;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/scsi-qla2xxx-fix-fabric-scan-hang.patch b/queue-5.4/scsi-qla2xxx-fix-fabric-scan-hang.patch new file mode 100644 index 00000000000..18e20046e41 --- /dev/null +++ b/queue-5.4/scsi-qla2xxx-fix-fabric-scan-hang.patch @@ -0,0 +1,191 @@ +From adbcb609276f743b3f347ee24ee1c02b782f2748 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2019 14:06:05 -0800 +Subject: scsi: qla2xxx: Fix fabric scan hang + +From: Quinn Tran + +[ Upstream commit f57a0107359605b29f4ea9afb8ee2e03473b1448 ] + +On timeout, SRB pointer was cleared from outstanding command array and +dropped. It was not allowed to go through the done process and cleanup. +This patch will abort the SRB where FW will return it with an error status +and resume the normal cleanup. + +Link: https://lore.kernel.org/r/20191217220617.28084-3-hmadhani@marvell.com +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_gbl.h | 1 + + drivers/scsi/qla2xxx/qla_init.c | 34 +++++++++++++++------------ + drivers/scsi/qla2xxx/qla_iocb.c | 41 ++++++++++++++++++++++++++------- + 3 files changed, 53 insertions(+), 23 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index 5a3c47eed645..7aa233771ec8 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -256,6 +256,7 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); + + extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); + extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); ++extern int qla24xx_async_abort_cmd(srb_t *, bool); + + extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); + +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index b4f0c2c8414e..643b8ae36cbe 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -50,16 +50,9 @@ qla2x00_sp_timeout(struct timer_list *t) + { + srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer); + struct srb_iocb *iocb; +- struct req_que *req; +- unsigned long flags; +- struct qla_hw_data *ha = sp->vha->hw; + +- WARN_ON_ONCE(irqs_disabled()); +- spin_lock_irqsave(&ha->hardware_lock, flags); +- req = sp->qpair->req; +- req->outstanding_cmds[sp->handle] = NULL; ++ WARN_ON(irqs_disabled()); + iocb = &sp->u.iocb_cmd; +- spin_unlock_irqrestore(&ha->hardware_lock, flags); + iocb->timeout(sp); + } + +@@ -153,7 +146,7 @@ static void qla24xx_abort_sp_done(srb_t *sp, int res) + sp->free(sp); + } + +-static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) ++int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) + { + scsi_qla_host_t *vha = cmd_sp->vha; + struct srb_iocb *abt_iocb; +@@ -253,6 +246,7 @@ qla2x00_async_iocb_timeout(void *data) + case SRB_NACK_PRLI: + case SRB_NACK_LOGO: + case SRB_CTRL_VP: ++ default: + rc = qla24xx_async_abort_cmd(sp, false); + if (rc) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); +@@ -269,10 +263,6 @@ qla2x00_async_iocb_timeout(void *data) + sp->done(sp, QLA_FUNCTION_TIMEOUT); + } + break; +- default: +- WARN_ON_ONCE(true); +- sp->done(sp, QLA_FUNCTION_TIMEOUT); +- break; + } + } + +@@ -1794,9 +1784,23 @@ qla2x00_tmf_iocb_timeout(void *data) + { + srb_t *sp = data; + struct srb_iocb *tmf = &sp->u.iocb_cmd; ++ int rc, h; ++ unsigned long flags; + +- tmf->u.tmf.comp_status = CS_TIMEOUT; +- complete(&tmf->u.tmf.comp); ++ rc = qla24xx_async_abort_cmd(sp, false); ++ if (rc) { ++ spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); ++ for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { ++ if (sp->qpair->req->outstanding_cmds[h] == sp) { ++ sp->qpair->req->outstanding_cmds[h] = NULL; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); ++ tmf->u.tmf.comp_status = CS_TIMEOUT; ++ tmf->u.tmf.data = QLA_FUNCTION_FAILED; ++ complete(&tmf->u.tmf.comp); ++ } + } + + static void qla2x00_tmf_sp_done(srb_t *sp, int res) +diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c +index 3f43410fab9d..936103604d02 100644 +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2537,13 +2537,32 @@ qla2x00_els_dcmd_iocb_timeout(void *data) + fc_port_t *fcport = sp->fcport; + struct scsi_qla_host *vha = sp->vha; + struct srb_iocb *lio = &sp->u.iocb_cmd; ++ unsigned long flags = 0; ++ int res, h; + + ql_dbg(ql_dbg_io, vha, 0x3069, + "%s Timeout, hdl=%x, portid=%02x%02x%02x\n", + sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa); + +- complete(&lio->u.els_logo.comp); ++ /* Abort the exchange */ ++ res = qla24xx_async_abort_cmd(sp, false); ++ if (res) { ++ ql_dbg(ql_dbg_io, vha, 0x3070, ++ "mbx abort_command failed.\n"); ++ spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); ++ for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { ++ if (sp->qpair->req->outstanding_cmds[h] == sp) { ++ sp->qpair->req->outstanding_cmds[h] = NULL; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); ++ complete(&lio->u.els_logo.comp); ++ } else { ++ ql_dbg(ql_dbg_io, vha, 0x3071, ++ "mbx abort_command success.\n"); ++ } + } + + static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res) +@@ -2708,23 +2727,29 @@ qla2x00_els_dcmd2_iocb_timeout(void *data) + srb_t *sp = data; + fc_port_t *fcport = sp->fcport; + struct scsi_qla_host *vha = sp->vha; +- struct qla_hw_data *ha = vha->hw; + unsigned long flags = 0; +- int res; ++ int res, h; + + ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069, + "%s hdl=%x ELS Timeout, %8phC portid=%06x\n", + sp->name, sp->handle, fcport->port_name, fcport->d_id.b24); + + /* Abort the exchange */ +- spin_lock_irqsave(&ha->hardware_lock, flags); +- res = ha->isp_ops->abort_command(sp); ++ res = qla24xx_async_abort_cmd(sp, false); + ql_dbg(ql_dbg_io, vha, 0x3070, + "mbx abort_command %s\n", + (res == QLA_SUCCESS) ? "successful" : "failed"); +- spin_unlock_irqrestore(&ha->hardware_lock, flags); +- +- sp->done(sp, QLA_FUNCTION_TIMEOUT); ++ if (res) { ++ spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); ++ for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { ++ if (sp->qpair->req->outstanding_cmds[h] == sp) { ++ sp->qpair->req->outstanding_cmds[h] = NULL; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); ++ sp->done(sp, QLA_FUNCTION_TIMEOUT); ++ } + } + + void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi) +-- +2.30.2 + diff --git a/queue-5.4/series b/queue-5.4/series index 4449311b012..82b598feb5a 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -5,3 +5,4 @@ scsi-qla2xxx-fix-device-connect-issues-in-p2p-config.patch scsi-qla2xxx-retry-plogi-on-fc-nvme-prli-failure.patch scsi-qla2xxx-add-a-shadow-variable-to-hold-disc_stat.patch scsi-qla2xxx-fix-stuck-login-session-using-prli_pend.patch +scsi-qla2xxx-fix-fabric-scan-hang.patch