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

Commit 12838e74 authored by James Smart's avatar James Smart Committed by Christoph Hellwig
Browse files

lpfc: fix race between LOGO/PLOGI handling causing NULL pointer



Fix race between LOGO/PLOGI handling causing NULL pointer

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarDick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 2f6fa2c9
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ struct lpfc_nodelist {
	struct lpfc_name nlp_portname;
	struct lpfc_name nlp_nodename;
	uint32_t         nlp_flag;		/* entry flags */
	uint32_t         nlp_add_flag;		/* additional flags */
	uint32_t         nlp_DID;		/* FC D_ID of entry */
	uint32_t         nlp_last_elscmd;	/* Last ELS cmd sent */
	uint16_t         nlp_type;
@@ -157,6 +158,9 @@ struct lpfc_node_rrq {
#define NLP_FIRSTBURST     0x40000000	/* Target supports FirstBurst */
#define NLP_RPI_REGISTERED 0x80000000	/* nlp_rpi is valid */

/* Defines for nlp_add_flag (uint32) */
#define NLP_IN_DEV_LOSS  0x00000001	/* Dev Loss processing in progress */

/* ndlp usage management macros */
#define NLP_CHK_NODE_ACT(ndlp)		(((ndlp)->nlp_usg_map \
						& NLP_USG_NODE_ACT_BIT) \
+7 −0
Original line number Diff line number Diff line
@@ -6693,6 +6693,13 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,

	phba->fc_stat.elsRcvFrame++;

	/*
	 * Do not process any unsolicited ELS commands
	 * if the ndlp is in DEV_LOSS
	 */
	if (ndlp->nlp_add_flag & NLP_IN_DEV_LOSS)
		goto dropit;

	elsiocb->context1 = lpfc_nlp_get(ndlp);
	elsiocb->vport = vport;

+18 −1
Original line number Diff line number Diff line
@@ -153,6 +153,16 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
			put_device(&rport->dev);
			return;
		}

		put_node = rdata->pnode != NULL;
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
			put_device(&rport->dev);
		return;
	}

	evtp = &ndlp->dev_loss_evt;
@@ -161,6 +171,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
		return;

	evtp->evt_arg1  = lpfc_nlp_get(ndlp);
	ndlp->nlp_add_flag |= NLP_IN_DEV_LOSS;

	spin_lock_irq(&phba->hbalock);
	/* We need to hold the node by incrementing the reference
@@ -201,8 +212,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)

	rport = ndlp->rport;

	if (!rport)
	if (!rport) {
		ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
		return fcf_inuse;
	}

	rdata = rport->dd_data;
	name = (uint8_t *) &ndlp->nlp_portname;
@@ -235,6 +248,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
@@ -250,6 +264,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
				 *name, *(name+1), *(name+2), *(name+3),
				 *(name+4), *(name+5), *(name+6), *(name+7),
				 ndlp->nlp_DID);
		ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
		return fcf_inuse;
	}

@@ -259,6 +274,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
@@ -297,6 +313,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
	put_rport = ndlp->rport != NULL;
	rdata->pnode = NULL;
	ndlp->rport = NULL;
	ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
	if (put_node)
		lpfc_nlp_put(ndlp);
	if (put_rport)