summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorDick Kennedy <dick.kennedy@broadcom.com>2017-09-29 17:34:29 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2017-10-02 22:46:33 -0400
commit1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e (patch)
tree443eb288638e1b2981fe88ff83ff47ed613b37c4 /drivers/scsi/lpfc/lpfc_els.c
parent401bb4169da655f3e5d28d0b208182e1ab60bf2a (diff)
scsi: lpfc: Fix crash receiving ELS while detaching driver
The driver crashes when attempting to use a freed ndpl pointer. The pci_remove_one handler runs on a separate kernel thread. The order of the removal is starting by freeing all of the ndlps and then disabling interrupts. In between these two events the driver can still receive an ELS and process it. When it tries to use the ndlp pointer will be NULL Change the order of the pci_remove_one vs disable interrupts so that interrupts are disabled before the ndlp's are freed. Cc: <stable@vger.kernel.org> # 4.12+ 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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 468a66371de9..3ebf6ccba6e6 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -7430,6 +7430,8 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
timeout = (uint32_t)(phba->fc_ratov << 1);
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return;
if ((phba->pport->load_flag & FC_UNLOADING))
return;
@@ -9310,6 +9312,9 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return;
+
spin_lock_irq(&phba->hbalock);
list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
list) {
@@ -9416,7 +9421,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
rxid, 1);
/* Check if TXQ queue needs to be serviced */
- if (!(list_empty(&pring->txq)))
+ if (pring && !list_empty(&pring->txq))
lpfc_worker_wake_up(phba);
return;
}