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

Commit 9e210178 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Synchronize access to remoteport via rport



The driver currently uses the ndlp to get the local rport which is then used
to get the nvme transport remoteport pointer. There can be cases where a stale
remoteport pointer is obtained as synchronization isn't done through the
different dereferences.

Correct by using locks to synchronize the dereferences.

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 d87161be
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		goto buffer_done;

	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		nrport = NULL;
		spin_lock(&vport->phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (!rport)
			continue;

		/* local short-hand pointer. */
		if (rport)
			nrport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		if (!nrport)
			continue;

@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
	struct lpfc_nodelist  *ndlp;
#if (IS_ENABLED(CONFIG_NVME_FC))
	struct lpfc_nvme_rport *rport;
	struct nvme_fc_remote_port *remoteport = NULL;
#endif

	shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
		if (ndlp->rport)
			ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
#if (IS_ENABLED(CONFIG_NVME_FC))
		spin_lock(&vport->phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (rport)
			remoteport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		if (remoteport)
			nvme_fc_set_remoteport_devloss(rport->remoteport,
						       vport->cfg_devloss_tmo);
#endif
+5 −5
Original line number Diff line number Diff line
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
	unsigned char *statep;
	struct nvme_fc_local_port *localport;
	struct lpfc_nvmet_tgtport *tgtp;
	struct nvme_fc_remote_port *nrport;
	struct nvme_fc_remote_port *nrport = NULL;
	struct lpfc_nvme_rport *rport;

	cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
	len += snprintf(buf + len, size - len, "\tRport List:\n");
	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		/* local short-hand pointer. */
		spin_lock(&phba->hbalock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (!rport)
			continue;

		if (rport)
			nrport = rport->remoteport;
		spin_unlock(&phba->hbalock);
		if (!nrport)
			continue;

+8 −3
Original line number Diff line number Diff line
@@ -2725,7 +2725,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
	rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);

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

@@ -2840,7 +2842,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	struct nvme_fc_local_port *localport;
	struct lpfc_nvme_lport *lport;
	struct lpfc_nvme_rport *rport;
	struct nvme_fc_remote_port *remoteport;
	struct nvme_fc_remote_port *remoteport = NULL;

	localport = vport->localport;

@@ -2854,11 +2856,14 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	if (!lport)
		goto input_err;

	spin_lock_irq(&vport->phba->hbalock);
	rport = lpfc_ndlp_get_nrport(ndlp);
	if (!rport)
	if (rport)
		remoteport = rport->remoteport;
	spin_unlock_irq(&vport->phba->hbalock);
	if (!remoteport)
		goto input_err;

	remoteport = rport->remoteport;
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
			 "6033 Unreg nvme remoteport %p, portname x%llx, "
			 "port_id x%06x, portstate x%x port type x%x\n",