scsi: lpfc: Fix oops of nvme host during driver unload.

When running NVME io as a NVME host, if the driver is unloaded there
would be oops in lpfc_sli4_issue_wqe.

When unloading, controllers are torn down and the transport initiates
set_property commands to reset the controller and issues aborts to
terminate existing io.  The drivers nvme abort and fcp io submit
routines needed to recognize the driver is unloading and fail the new
requests. It didn't, resulting in the oops.

Revise the ls and fcp io submit routines to detect the unloading state
and properly handle their cleanup.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Dick Kennedy 2017-09-29 17:34:45 -07:00 committed by Martin K. Petersen
parent 6ad8c07a2f
commit 1abcb3718b
2 changed files with 19 additions and 0 deletions

View File

@ -416,6 +416,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
lport = (struct lpfc_nvme_lport *)pnvme_lport->private; lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
vport = lport->vport; vport = lport->vport;
if (vport->load_flag & FC_UNLOADING)
return -ENODEV;
ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id); ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
@ -1252,6 +1255,11 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
vport = lport->vport; vport = lport->vport;
phba = vport->phba; phba = vport->phba;
if (vport->load_flag & FC_UNLOADING) {
ret = -ENODEV;
goto out_fail;
}
/* Validate pointers. */ /* Validate pointers. */
if (!pnvme_lport || !pnvme_rport || !freqpriv) { if (!pnvme_lport || !pnvme_rport || !freqpriv) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR | LOG_NODE, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR | LOG_NODE,

View File

@ -632,6 +632,9 @@ lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,
struct ulp_bde64 bpl; struct ulp_bde64 bpl;
int rc; int rc;
if (phba->pport->load_flag & FC_UNLOADING)
return -ENODEV;
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC, lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
"6023 NVMET LS rsp oxid x%x\n", ctxp->oxid); "6023 NVMET LS rsp oxid x%x\n", ctxp->oxid);
@ -713,6 +716,11 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
struct lpfc_iocbq *nvmewqeq; struct lpfc_iocbq *nvmewqeq;
int rc; int rc;
if (phba->pport->load_flag & FC_UNLOADING) {
rc = -ENODEV;
goto aerr;
}
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
if (ctxp->ts_cmd_nvme) { if (ctxp->ts_cmd_nvme) {
if (rsp->op == NVMET_FCOP_RSP) if (rsp->op == NVMET_FCOP_RSP)
@ -812,6 +820,9 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport,
struct lpfc_hba *phba = ctxp->phba; struct lpfc_hba *phba = ctxp->phba;
unsigned long flags; unsigned long flags;
if (phba->pport->load_flag & FC_UNLOADING)
return;
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
"6103 NVMET Abort op: oxri x%x flg x%x ste %d\n", "6103 NVMET Abort op: oxri x%x flg x%x ste %d\n",
ctxp->oxid, ctxp->flag, ctxp->state); ctxp->oxid, ctxp->flag, ctxp->state);