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

scsi: lpfc: Rework remote port lock handling

Currently the discovery layers within the driver use the SCSI midlayer
host_lock to access node-specific structures. This can contend with the I/O
path and is too coarse of a lock.

Rework the driver so that it uses a lock specific to the remote port node
structure when accessing the structure contents. A few of the changes
brought out spots were some slightly reorganized routines worked better.

Link: https://lore.kernel.org/r/20201115192646.12977-6-james.smart@broadcom.com


Co-developed-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e9b11083
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -1131,8 +1131,6 @@ struct lpfc_hba {
	uint8_t hb_outstanding;
	struct timer_list rrq_tmr;
	enum hba_temp_state over_temp_state;
	/* ndlp reference management */
	spinlock_t ndlp_lock;
	/*
	 * Following bit will be set for all buffer tags which are not
	 * associated with any HBQ.
+4 −4
Original line number Diff line number Diff line
@@ -368,11 +368,11 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,

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

@@ -3637,11 +3637,11 @@ 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);
		spin_lock(&ndlp->lock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (rport)
			remoteport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		spin_unlock(&ndlp->lock);
		if (rport && remoteport)
			nvme_fc_set_remoteport_devloss(remoteport,
						       vport->cfg_devloss_tmo);
+4 −6
Original line number Diff line number Diff line
@@ -825,7 +825,6 @@ lpfc_ns_rsp_audit_did(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
{
	struct lpfc_hba *phba = vport->phba;
	struct lpfc_nodelist *ndlp = NULL;
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	char *str;

	if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_FT)
@@ -854,12 +853,12 @@ lpfc_ns_rsp_audit_did(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
			if (ndlp->nlp_type != NLP_NVME_INITIATOR ||
			    ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
				continue;
			spin_lock_irq(shost->host_lock);
			spin_lock_irq(&ndlp->lock);
			if (ndlp->nlp_DID == Did)
				ndlp->nlp_flag &= ~NLP_NVMET_RECOV;
			else
				ndlp->nlp_flag |= NLP_NVMET_RECOV;
			spin_unlock_irq(shost->host_lock);
			spin_unlock_irq(&ndlp->lock);
		}
	}
}
@@ -875,7 +874,6 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
	uint32_t Did, CTentry;
	int Cnt;
	struct list_head head;
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_nodelist *ndlp = NULL;

	lpfc_set_disctmo(vport);
@@ -921,9 +919,9 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
				continue;
			lpfc_disc_state_machine(vport, ndlp, NULL,
						NLP_EVT_DEVICE_RECOVERY);
			spin_lock_irq(shost->host_lock);
			spin_lock_irq(&ndlp->lock);
			ndlp->nlp_flag &= ~NLP_NVMET_RECOV;
			spin_unlock_irq(shost->host_lock);
			spin_unlock_irq(&ndlp->lock);
		}
	}

+2 −2
Original line number Diff line number Diff line
@@ -955,13 +955,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
	len += scnprintf(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);
		spin_lock(&ndlp->lock);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (rport)
			nrport = rport->remoteport;
		else
			nrport = NULL;
		spin_unlock(&phba->hbalock);
		spin_unlock(&ndlp->lock);
		if (!nrport)
			continue;

+3 −0
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@ struct lpfc_nodelist {
	struct list_head nlp_listp;
	struct lpfc_name nlp_portname;
	struct lpfc_name nlp_nodename;

	spinlock_t	lock;			/* Node management lock */

	uint32_t         nlp_flag;		/* entry flags */
	uint32_t         nlp_DID;		/* FC D_ID of entry */
	uint32_t         nlp_last_elscmd;	/* Last ELS cmd sent */
Loading