Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61184f17 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Fix Oops in nvme_register with target logout/login



lpfc_nvme_register_port hit a null prev_ndlp pointer in a test with lots of
target ports swapping addresses. The oldport value was stale, thus it's
ndlp (prev_ndlp set to it) was used.

Fix by moving oldrport pointer checks, and if used prev_ndlp pointer
assignment, to be done while the lock is held.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 08180db2
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -2317,9 +2317,13 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)

	spin_lock_irq(&vport->phba->hbalock);
	oldrport = lpfc_ndlp_get_nrport(ndlp);
	if (oldrport) {
		prev_ndlp = oldrport->ndlp;
		spin_unlock_irq(&vport->phba->hbalock);
	} else {
		spin_unlock_irq(&vport->phba->hbalock);
	if (!oldrport)
		lpfc_nlp_get(ndlp);
	}

	ret = nvme_fc_register_remoteport(localport, &rpinfo, &remote_port);
	if (!ret) {
@@ -2338,7 +2342,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
			/* New remoteport record does not guarantee valid
			 * host private memory area.
			 */
			prev_ndlp = oldrport->ndlp;
			if (oldrport == remote_port->private) {
				/* Same remoteport - ndlp should match.
				 * Just reuse.
@@ -2352,7 +2355,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
						 remote_port->port_name,
						 remote_port->port_id,
						 remote_port->port_role,
						 prev_ndlp,
						 oldrport->ndlp,
						 ndlp,
						 ndlp->nlp_type,
						 ndlp->nlp_DID);