提交 9d3d340d 编写于 作者: J James Smart 提交者: Christoph Hellwig

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: NDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: NJames Smart <james.smart@broadcom.com>
Reviewed-by: NJohannes Thumshirn <jthumshirn@suse.de>
上级 2b7824d0
...@@ -2486,6 +2486,10 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi) ...@@ -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 *); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册