mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-26 04:35:01 +00:00
lpfc: fix race between LOGO/PLOGI handling causing NULL pointer
Fix race between LOGO/PLOGI handling causing NULL pointer Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
2f6fa2c911
commit
12838e74f5
@ -78,7 +78,8 @@ struct lpfc_nodelist {
|
||||
struct list_head nlp_listp;
|
||||
struct lpfc_name nlp_portname;
|
||||
struct lpfc_name nlp_nodename;
|
||||
uint32_t nlp_flag; /* entry flags */
|
||||
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) \
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user