]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: lpfc: Fix oops of nvme host during driver unload.
authorDick Kennedy <dick.kennedy@broadcom.com>
Sat, 30 Sep 2017 00:34:45 +0000 (17:34 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 3 Oct 2017 02:46:41 +0000 (22:46 -0400)
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>
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_nvmet.c

index 60f2ae6826d3a87a78435529b27bae8f3ca1c91c..d06ce19843e6844c6703c45cb1ed6799bc99ab8a 100644 (file)
@@ -416,6 +416,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
        lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
        vport = lport->vport;
 
+       if (vport->load_flag & FC_UNLOADING)
+               return -ENODEV;
+
        ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
                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;
        phba = vport->phba;
 
+       if (vport->load_flag & FC_UNLOADING) {
+               ret = -ENODEV;
+               goto out_fail;
+       }
+
        /* Validate pointers. */
        if (!pnvme_lport || !pnvme_rport || !freqpriv) {
                lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR | LOG_NODE,
index 55badeace5912579894319fc15c0816935cb2dab..84cf1b9079f78849fe2c6101df88245d90c28cb1 100644 (file)
@@ -632,6 +632,9 @@ lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,
        struct ulp_bde64 bpl;
        int rc;
 
+       if (phba->pport->load_flag & FC_UNLOADING)
+               return -ENODEV;
+
        lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
                        "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;
        int rc;
 
+       if (phba->pport->load_flag & FC_UNLOADING) {
+               rc = -ENODEV;
+               goto aerr;
+       }
+
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
        if (ctxp->ts_cmd_nvme) {
                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;
        unsigned long flags;
 
+       if (phba->pport->load_flag & FC_UNLOADING)
+               return;
+
        lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
                        "6103 NVMET Abort op: oxri x%x flg x%x ste %d\n",
                        ctxp->oxid, ctxp->flag, ctxp->state);