Fix crash after issuing lip reset
When RPI is not available, driver sends WQE with invalid RPI value and rejected by HBA. lpfc 0000:82:00.3: 1:3154 BLS ABORT RSP failed, data: x3/xa0320008 and lpfc :2753 PLOGI failure DID:FFFFFA Status:x3/xa0240008 In this case, driver accesses rpi_ids array out of bounds. Fix: Check return value of lpfc_sli4_alloc_rpi(). Do not allocate lpfc_nodelist entry if RPI is not available. When RPI is not available, we will get discovery timeouts and command drops for some of the vports as seen below. lpfc :0273 Unexpected discovery timeout, vport State x0 lpfc :0230 Unexpected timeout, hba link state x5 lpfc :0111 Dropping received ELS cmd Data: x0 xc90c55 x0 Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
This commit is contained in:
committed by
Christoph Hellwig
parent
2b7824d00d
commit
9d3d340d19
@@ -2486,6 +2486,10 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi)
|
|||||||
mbox, *rpi);
|
mbox, *rpi);
|
||||||
else {
|
else {
|
||||||
*rpi = lpfc_sli4_alloc_rpi(phba);
|
*rpi = lpfc_sli4_alloc_rpi(phba);
|
||||||
|
if (*rpi == LPFC_RPI_ALLOC_ERROR) {
|
||||||
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
status = lpfc_reg_rpi(phba, phba->pport->vpi,
|
status = lpfc_reg_rpi(phba, phba->pport->vpi,
|
||||||
phba->pport->fc_myDID,
|
phba->pport->fc_myDID,
|
||||||
(uint8_t *)&phba->pport->fc_sparam,
|
(uint8_t *)&phba->pport->fc_sparam,
|
||||||
|
@@ -99,7 +99,7 @@ void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *);
|
|||||||
|
|
||||||
int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
|
int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||||
struct lpfc_iocbq *, struct lpfc_nodelist *);
|
struct lpfc_iocbq *, struct lpfc_nodelist *);
|
||||||
void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t);
|
struct lpfc_nodelist *lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did);
|
||||||
struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *);
|
struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *);
|
||||||
int lpfc_nlp_put(struct lpfc_nodelist *);
|
int lpfc_nlp_put(struct lpfc_nodelist *);
|
||||||
int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp);
|
int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp);
|
||||||
|
@@ -895,10 +895,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
* Cannot find existing Fabric ndlp, so allocate a
|
* Cannot find existing Fabric ndlp, so allocate a
|
||||||
* new one
|
* new one
|
||||||
*/
|
*/
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, PT2PT_RemoteID);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
goto fail;
|
goto fail;
|
||||||
lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
|
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
ndlp = lpfc_enable_node(vport, ndlp,
|
ndlp = lpfc_enable_node(vport, ndlp,
|
||||||
NLP_STE_UNUSED_NODE);
|
NLP_STE_UNUSED_NODE);
|
||||||
@@ -1364,7 +1363,6 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
|
|||||||
int
|
int
|
||||||
lpfc_initial_flogi(struct lpfc_vport *vport)
|
lpfc_initial_flogi(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = vport->phba;
|
|
||||||
struct lpfc_nodelist *ndlp;
|
struct lpfc_nodelist *ndlp;
|
||||||
|
|
||||||
vport->port_state = LPFC_FLOGI;
|
vport->port_state = LPFC_FLOGI;
|
||||||
@@ -1374,10 +1372,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
|
|||||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, Fabric_DID);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return 0;
|
return 0;
|
||||||
lpfc_nlp_init(vport, ndlp, Fabric_DID);
|
|
||||||
/* Set the node type */
|
/* Set the node type */
|
||||||
ndlp->nlp_type |= NLP_FABRIC;
|
ndlp->nlp_type |= NLP_FABRIC;
|
||||||
/* Put ndlp onto node list */
|
/* Put ndlp onto node list */
|
||||||
@@ -1418,17 +1415,15 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
|
|||||||
int
|
int
|
||||||
lpfc_initial_fdisc(struct lpfc_vport *vport)
|
lpfc_initial_fdisc(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = vport->phba;
|
|
||||||
struct lpfc_nodelist *ndlp;
|
struct lpfc_nodelist *ndlp;
|
||||||
|
|
||||||
/* First look for the Fabric ndlp */
|
/* First look for the Fabric ndlp */
|
||||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, Fabric_DID);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return 0;
|
return 0;
|
||||||
lpfc_nlp_init(vport, ndlp, Fabric_DID);
|
|
||||||
/* Put ndlp onto node list */
|
/* Put ndlp onto node list */
|
||||||
lpfc_enqueue_node(vport, ndlp);
|
lpfc_enqueue_node(vport, ndlp);
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
@@ -1564,14 +1559,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|||||||
phba->active_rrq_pool);
|
phba->active_rrq_pool);
|
||||||
return ndlp;
|
return ndlp;
|
||||||
}
|
}
|
||||||
new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
|
new_ndlp = lpfc_nlp_init(vport, ndlp->nlp_DID);
|
||||||
if (!new_ndlp) {
|
if (!new_ndlp) {
|
||||||
if (active_rrqs_xri_bitmap)
|
if (active_rrqs_xri_bitmap)
|
||||||
mempool_free(active_rrqs_xri_bitmap,
|
mempool_free(active_rrqs_xri_bitmap,
|
||||||
phba->active_rrq_pool);
|
phba->active_rrq_pool);
|
||||||
return ndlp;
|
return ndlp;
|
||||||
}
|
}
|
||||||
lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
|
|
||||||
} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
|
||||||
rc = memcmp(&ndlp->nlp_portname, name,
|
rc = memcmp(&ndlp->nlp_portname, name,
|
||||||
sizeof(struct lpfc_name));
|
sizeof(struct lpfc_name));
|
||||||
@@ -2845,10 +2839,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
|||||||
|
|
||||||
ndlp = lpfc_findnode_did(vport, nportid);
|
ndlp = lpfc_findnode_did(vport, nportid);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, nportid);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return 1;
|
return 1;
|
||||||
lpfc_nlp_init(vport, ndlp, nportid);
|
|
||||||
lpfc_enqueue_node(vport, ndlp);
|
lpfc_enqueue_node(vport, ndlp);
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
||||||
@@ -2938,10 +2931,9 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
|||||||
|
|
||||||
ndlp = lpfc_findnode_did(vport, nportid);
|
ndlp = lpfc_findnode_did(vport, nportid);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, nportid);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return 1;
|
return 1;
|
||||||
lpfc_nlp_init(vport, ndlp, nportid);
|
|
||||||
lpfc_enqueue_node(vport, ndlp);
|
lpfc_enqueue_node(vport, ndlp);
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
||||||
@@ -6133,7 +6125,6 @@ int
|
|||||||
lpfc_els_handle_rscn(struct lpfc_vport *vport)
|
lpfc_els_handle_rscn(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
struct lpfc_nodelist *ndlp;
|
struct lpfc_nodelist *ndlp;
|
||||||
struct lpfc_hba *phba = vport->phba;
|
|
||||||
|
|
||||||
/* Ignore RSCN if the port is being torn down. */
|
/* Ignore RSCN if the port is being torn down. */
|
||||||
if (vport->load_flag & FC_UNLOADING) {
|
if (vport->load_flag & FC_UNLOADING) {
|
||||||
@@ -6182,12 +6173,11 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
|
|||||||
}
|
}
|
||||||
ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
|
ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
|
||||||
} else {
|
} else {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, NameServer_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
lpfc_els_flush_rscn(vport);
|
lpfc_els_flush_rscn(vport);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
lpfc_nlp_init(vport, ndlp, NameServer_DID);
|
|
||||||
ndlp->nlp_prev_state = ndlp->nlp_state;
|
ndlp->nlp_prev_state = ndlp->nlp_state;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
||||||
}
|
}
|
||||||
@@ -7746,11 +7736,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||||||
ndlp = lpfc_findnode_did(vport, did);
|
ndlp = lpfc_findnode_did(vport, did);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, did);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
goto dropit;
|
goto dropit;
|
||||||
|
|
||||||
lpfc_nlp_init(vport, ndlp, did);
|
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||||
newnode = 1;
|
newnode = 1;
|
||||||
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
|
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
|
||||||
@@ -8192,7 +8180,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||||||
static void
|
static void
|
||||||
lpfc_start_fdmi(struct lpfc_vport *vport)
|
lpfc_start_fdmi(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = vport->phba;
|
|
||||||
struct lpfc_nodelist *ndlp;
|
struct lpfc_nodelist *ndlp;
|
||||||
|
|
||||||
/* If this is the first time, allocate an ndlp and initialize
|
/* If this is the first time, allocate an ndlp and initialize
|
||||||
@@ -8201,9 +8188,8 @@ lpfc_start_fdmi(struct lpfc_vport *vport)
|
|||||||
*/
|
*/
|
||||||
ndlp = lpfc_findnode_did(vport, FDMI_DID);
|
ndlp = lpfc_findnode_did(vport, FDMI_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, FDMI_DID);
|
||||||
if (ndlp) {
|
if (ndlp) {
|
||||||
lpfc_nlp_init(vport, ndlp, FDMI_DID);
|
|
||||||
ndlp->nlp_type |= NLP_FABRIC;
|
ndlp->nlp_type |= NLP_FABRIC;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
@@ -8256,7 +8242,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
|
|||||||
|
|
||||||
ndlp = lpfc_findnode_did(vport, NameServer_DID);
|
ndlp = lpfc_findnode_did(vport, NameServer_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, NameServer_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
||||||
lpfc_disc_start(vport);
|
lpfc_disc_start(vport);
|
||||||
@@ -8267,7 +8253,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
|
|||||||
"0251 NameServer login: no memory\n");
|
"0251 NameServer login: no memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lpfc_nlp_init(vport, ndlp, NameServer_DID);
|
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
|
@@ -4368,10 +4368,17 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
uint32_t did;
|
uint32_t did;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long *active_rrqs_xri_bitmap = NULL;
|
unsigned long *active_rrqs_xri_bitmap = NULL;
|
||||||
|
int rpi = LPFC_RPI_ALLOC_ERROR;
|
||||||
|
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||||
|
rpi = lpfc_sli4_alloc_rpi(vport->phba);
|
||||||
|
if (rpi == LPFC_RPI_ALLOC_ERROR)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->ndlp_lock, flags);
|
spin_lock_irqsave(&phba->ndlp_lock, flags);
|
||||||
/* The ndlp should not be in memory free mode */
|
/* The ndlp should not be in memory free mode */
|
||||||
if (NLP_CHK_FREE_REQ(ndlp)) {
|
if (NLP_CHK_FREE_REQ(ndlp)) {
|
||||||
@@ -4381,7 +4388,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
"usgmap:x%x refcnt:%d\n",
|
"usgmap:x%x refcnt:%d\n",
|
||||||
(void *)ndlp, ndlp->nlp_usg_map,
|
(void *)ndlp, ndlp->nlp_usg_map,
|
||||||
kref_read(&ndlp->kref));
|
kref_read(&ndlp->kref));
|
||||||
return NULL;
|
goto free_rpi;
|
||||||
}
|
}
|
||||||
/* The ndlp should not already be in active mode */
|
/* The ndlp should not already be in active mode */
|
||||||
if (NLP_CHK_NODE_ACT(ndlp)) {
|
if (NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
@@ -4391,7 +4398,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
"usgmap:x%x refcnt:%d\n",
|
"usgmap:x%x refcnt:%d\n",
|
||||||
(void *)ndlp, ndlp->nlp_usg_map,
|
(void *)ndlp, ndlp->nlp_usg_map,
|
||||||
kref_read(&ndlp->kref));
|
kref_read(&ndlp->kref));
|
||||||
return NULL;
|
goto free_rpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep the original DID */
|
/* Keep the original DID */
|
||||||
@@ -4409,7 +4416,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
|
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
|
||||||
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
||||||
ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
|
ndlp->nlp_rpi = rpi;
|
||||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
||||||
"0008 rpi:%x DID:%x flg:%x refcnt:%d "
|
"0008 rpi:%x DID:%x flg:%x refcnt:%d "
|
||||||
"map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
|
"map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
|
||||||
@@ -4426,6 +4433,11 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
"node enable: did:x%x",
|
"node enable: did:x%x",
|
||||||
ndlp->nlp_DID, 0, 0);
|
ndlp->nlp_DID, 0, 0);
|
||||||
return ndlp;
|
return ndlp;
|
||||||
|
|
||||||
|
free_rpi:
|
||||||
|
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||||
|
lpfc_sli4_free_rpi(vport->phba, rpi);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -5107,11 +5119,9 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
|
|||||||
if ((vport->fc_flag & FC_RSCN_MODE) != 0 &&
|
if ((vport->fc_flag & FC_RSCN_MODE) != 0 &&
|
||||||
lpfc_rscn_payload_check(vport, did) == 0)
|
lpfc_rscn_payload_check(vport, did) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
ndlp = (struct lpfc_nodelist *)
|
ndlp = lpfc_nlp_init(vport, did);
|
||||||
mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL);
|
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return NULL;
|
return NULL;
|
||||||
lpfc_nlp_init(vport, ndlp, did);
|
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||||
if (vport->phba->nvmet_support)
|
if (vport->phba->nvmet_support)
|
||||||
return ndlp;
|
return ndlp;
|
||||||
@@ -5887,16 +5897,31 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
struct lpfc_nodelist *
|
||||||
lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did)
|
||||||
uint32_t did)
|
|
||||||
{
|
{
|
||||||
|
struct lpfc_nodelist *ndlp;
|
||||||
|
int rpi = LPFC_RPI_ALLOC_ERROR;
|
||||||
|
|
||||||
|
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
||||||
|
rpi = lpfc_sli4_alloc_rpi(vport->phba);
|
||||||
|
if (rpi == LPFC_RPI_ALLOC_ERROR)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndlp = mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL);
|
||||||
|
if (!ndlp) {
|
||||||
|
if (vport->phba->sli_rev == LPFC_SLI_REV4)
|
||||||
|
lpfc_sli4_free_rpi(vport->phba, rpi);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(ndlp, 0, sizeof (struct lpfc_nodelist));
|
memset(ndlp, 0, sizeof (struct lpfc_nodelist));
|
||||||
|
|
||||||
lpfc_initialize_node(vport, ndlp, did);
|
lpfc_initialize_node(vport, ndlp, did);
|
||||||
INIT_LIST_HEAD(&ndlp->nlp_listp);
|
INIT_LIST_HEAD(&ndlp->nlp_listp);
|
||||||
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
||||||
ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
|
ndlp->nlp_rpi = rpi;
|
||||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
||||||
"0007 rpi:%x DID:%x flg:%x refcnt:%d "
|
"0007 rpi:%x DID:%x flg:%x refcnt:%d "
|
||||||
"map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
|
"map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
|
||||||
@@ -5918,7 +5943,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||||||
"node init: did:x%x",
|
"node init: did:x%x",
|
||||||
ndlp->nlp_DID, 0, 0);
|
ndlp->nlp_DID, 0, 0);
|
||||||
|
|
||||||
return;
|
return ndlp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This routine releases all resources associated with a specifc NPort's ndlp
|
/* This routine releases all resources associated with a specifc NPort's ndlp
|
||||||
|
@@ -2874,34 +2874,38 @@ lpfc_sli4_node_prep(struct lpfc_hba *phba)
|
|||||||
{
|
{
|
||||||
struct lpfc_nodelist *ndlp, *next_ndlp;
|
struct lpfc_nodelist *ndlp, *next_ndlp;
|
||||||
struct lpfc_vport **vports;
|
struct lpfc_vport **vports;
|
||||||
int i;
|
int i, rpi;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (phba->sli_rev != LPFC_SLI_REV4)
|
if (phba->sli_rev != LPFC_SLI_REV4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vports = lpfc_create_vport_work_array(phba);
|
vports = lpfc_create_vport_work_array(phba);
|
||||||
if (vports != NULL) {
|
if (vports == NULL)
|
||||||
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
|
return;
|
||||||
if (vports[i]->load_flag & FC_UNLOADING)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(ndlp, next_ndlp,
|
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
|
||||||
&vports[i]->fc_nodes,
|
if (vports[i]->load_flag & FC_UNLOADING)
|
||||||
nlp_listp) {
|
continue;
|
||||||
if (NLP_CHK_NODE_ACT(ndlp)) {
|
|
||||||
ndlp->nlp_rpi =
|
list_for_each_entry_safe(ndlp, next_ndlp,
|
||||||
lpfc_sli4_alloc_rpi(phba);
|
&vports[i]->fc_nodes,
|
||||||
lpfc_printf_vlog(ndlp->vport, KERN_INFO,
|
nlp_listp) {
|
||||||
LOG_NODE,
|
if (!NLP_CHK_NODE_ACT(ndlp))
|
||||||
"0009 rpi:%x DID:%x "
|
continue;
|
||||||
"flg:%x map:%x %p\n",
|
rpi = lpfc_sli4_alloc_rpi(phba);
|
||||||
ndlp->nlp_rpi,
|
if (rpi == LPFC_RPI_ALLOC_ERROR) {
|
||||||
ndlp->nlp_DID,
|
spin_lock_irqsave(&phba->ndlp_lock, flags);
|
||||||
ndlp->nlp_flag,
|
NLP_CLR_NODE_ACT(ndlp);
|
||||||
ndlp->nlp_usg_map,
|
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
|
||||||
ndlp);
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ndlp->nlp_rpi = rpi;
|
||||||
|
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
|
||||||
|
"0009 rpi:%x DID:%x "
|
||||||
|
"flg:%x map:%x %p\n", ndlp->nlp_rpi,
|
||||||
|
ndlp->nlp_DID, ndlp->nlp_flag,
|
||||||
|
ndlp->nlp_usg_map, ndlp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lpfc_destroy_vport_work_array(phba, vports);
|
lpfc_destroy_vport_work_array(phba, vports);
|
||||||
@@ -4722,10 +4726,9 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
|
|||||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, Fabric_DID);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
return 0;
|
return 0;
|
||||||
lpfc_nlp_init(vport, ndlp, Fabric_DID);
|
|
||||||
/* Set the node type */
|
/* Set the node type */
|
||||||
ndlp->nlp_type |= NLP_FABRIC;
|
ndlp->nlp_type |= NLP_FABRIC;
|
||||||
/* Put ndlp onto node list */
|
/* Put ndlp onto node list */
|
||||||
|
@@ -16542,14 +16542,13 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_vport *vport,
|
|||||||
|
|
||||||
ndlp = lpfc_findnode_did(vport, sid);
|
ndlp = lpfc_findnode_did(vport, sid);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, sid);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
|
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
|
||||||
"1268 Failed to allocate ndlp for "
|
"1268 Failed to allocate ndlp for "
|
||||||
"oxid:x%x SID:x%x\n", oxid, sid);
|
"oxid:x%x SID:x%x\n", oxid, sid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lpfc_nlp_init(vport, ndlp, sid);
|
|
||||||
/* Put ndlp onto pport node list */
|
/* Put ndlp onto pport node list */
|
||||||
lpfc_enqueue_node(vport, ndlp);
|
lpfc_enqueue_node(vport, ndlp);
|
||||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
|
@@ -738,10 +738,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
|||||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||||
if (!ndlp) {
|
if (!ndlp) {
|
||||||
/* Cannot find existing Fabric ndlp, allocate one */
|
/* Cannot find existing Fabric ndlp, allocate one */
|
||||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
ndlp = lpfc_nlp_init(vport, Fabric_DID);
|
||||||
if (!ndlp)
|
if (!ndlp)
|
||||||
goto skip_logo;
|
goto skip_logo;
|
||||||
lpfc_nlp_init(vport, ndlp, Fabric_DID);
|
|
||||||
/* Indicate free memory when release */
|
/* Indicate free memory when release */
|
||||||
NLP_SET_FREE_REQ(ndlp);
|
NLP_SET_FREE_REQ(ndlp);
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user