Commit 845d9e8d authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Fix used-RPI accounting problem.

With 255 vports created a link trasition can casue a crash.

When going through discovery after a link bounce the driver is using
rpis before the cmd FCOE_POST_HDR_TEMPLATES completes. By doing that the
next rpi bumps the rpi range out of the boundary.

The fix it to increment the next_rpi only when the
FCOE_POST_HDR_TEMPLATE succeeds.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dd6e1f71
...@@ -8667,7 +8667,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -8667,7 +8667,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_do_scr_ns_plogi(phba, vport); lpfc_do_scr_ns_plogi(phba, vport);
goto out; goto out;
fdisc_failed: fdisc_failed:
if (vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS) if (vport->fc_vport &&
(vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS))
lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_vport_set_state(vport, FC_VPORT_FAILED);
/* Cancel discovery timer */ /* Cancel discovery timer */
lpfc_can_disctmo(vport); lpfc_can_disctmo(vport);
......
...@@ -6525,7 +6525,6 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -6525,7 +6525,6 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
uint16_t rpi_limit, curr_rpi_range; uint16_t rpi_limit, curr_rpi_range;
struct lpfc_dmabuf *dmabuf; struct lpfc_dmabuf *dmabuf;
struct lpfc_rpi_hdr *rpi_hdr; struct lpfc_rpi_hdr *rpi_hdr;
uint32_t rpi_count;
/* /*
* If the SLI4 port supports extents, posting the rpi header isn't * If the SLI4 port supports extents, posting the rpi header isn't
...@@ -6538,8 +6537,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -6538,8 +6537,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
return NULL; return NULL;
/* The limit on the logical index is just the max_rpi count. */ /* The limit on the logical index is just the max_rpi count. */
rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base + rpi_limit = phba->sli4_hba.max_cfg_param.max_rpi;
phba->sli4_hba.max_cfg_param.max_rpi - 1;
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
/* /*
...@@ -6550,18 +6548,10 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -6550,18 +6548,10 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
curr_rpi_range = phba->sli4_hba.next_rpi; curr_rpi_range = phba->sli4_hba.next_rpi;
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
/* /* Reached full RPI range */
* The port has a limited number of rpis. The increment here if (curr_rpi_range == rpi_limit)
* is LPFC_RPI_HDR_COUNT - 1 to account for the starting value
* and to allow the full max_rpi range per port.
*/
if ((curr_rpi_range + (LPFC_RPI_HDR_COUNT - 1)) > rpi_limit)
rpi_count = rpi_limit - curr_rpi_range;
else
rpi_count = LPFC_RPI_HDR_COUNT;
if (!rpi_count)
return NULL; return NULL;
/* /*
* First allocate the protocol header region for the port. The * First allocate the protocol header region for the port. The
* port expects a 4KB DMA-mapped memory region that is 4K aligned. * port expects a 4KB DMA-mapped memory region that is 4K aligned.
...@@ -6595,13 +6585,9 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -6595,13 +6585,9 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
/* The rpi_hdr stores the logical index only. */ /* The rpi_hdr stores the logical index only. */
rpi_hdr->start_rpi = curr_rpi_range; rpi_hdr->start_rpi = curr_rpi_range;
rpi_hdr->next_rpi = phba->sli4_hba.next_rpi + LPFC_RPI_HDR_COUNT;
list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list); list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list);
/*
* The next_rpi stores the next logical module-64 rpi value used
* to post physical rpis in subsequent rpi postings.
*/
phba->sli4_hba.next_rpi += rpi_count;
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
return rpi_hdr; return rpi_hdr;
......
...@@ -17137,6 +17137,14 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) ...@@ -17137,6 +17137,14 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page)
"status x%x add_status x%x, mbx status x%x\n", "status x%x add_status x%x, mbx status x%x\n",
shdr_status, shdr_add_status, rc); shdr_status, shdr_add_status, rc);
rc = -ENXIO; rc = -ENXIO;
} else {
/*
* The next_rpi stores the next logical module-64 rpi value used
* to post physical rpis in subsequent rpi postings.
*/
spin_lock_irq(&phba->hbalock);
phba->sli4_hba.next_rpi = rpi_page->next_rpi;
spin_unlock_irq(&phba->hbalock);
} }
return rc; return rc;
} }
......
...@@ -698,6 +698,7 @@ struct lpfc_rpi_hdr { ...@@ -698,6 +698,7 @@ struct lpfc_rpi_hdr {
struct lpfc_dmabuf *dmabuf; struct lpfc_dmabuf *dmabuf;
uint32_t page_count; uint32_t page_count;
uint32_t start_rpi; uint32_t start_rpi;
uint16_t next_rpi;
}; };
struct lpfc_rsrc_blks { struct lpfc_rsrc_blks {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment