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: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
dd6e1f71b7
commit
845d9e8df2
|
@ -8667,7 +8667,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
lpfc_do_scr_ns_plogi(phba, vport);
|
||||
goto out;
|
||||
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);
|
||||
/* Cancel discovery timer */
|
||||
lpfc_can_disctmo(vport);
|
||||
|
|
|
@ -6525,7 +6525,6 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
uint16_t rpi_limit, curr_rpi_range;
|
||||
struct lpfc_dmabuf *dmabuf;
|
||||
struct lpfc_rpi_hdr *rpi_hdr;
|
||||
uint32_t rpi_count;
|
||||
|
||||
/*
|
||||
* 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)
|
|||
return NULL;
|
||||
|
||||
/* The limit on the logical index is just the max_rpi count. */
|
||||
rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base +
|
||||
phba->sli4_hba.max_cfg_param.max_rpi - 1;
|
||||
rpi_limit = phba->sli4_hba.max_cfg_param.max_rpi;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
/*
|
||||
|
@ -6550,18 +6548,10 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
curr_rpi_range = phba->sli4_hba.next_rpi;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
/*
|
||||
* The port has a limited number of rpis. The increment here
|
||||
* 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)
|
||||
/* Reached full RPI range */
|
||||
if (curr_rpi_range == rpi_limit)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* First allocate the protocol header region for the port. The
|
||||
* 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)
|
|||
|
||||
/* The rpi_hdr stores the logical index only. */
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
return rpi_hdr;
|
||||
|
||||
|
|
|
@ -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",
|
||||
shdr_status, shdr_add_status, rc);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -698,6 +698,7 @@ struct lpfc_rpi_hdr {
|
|||
struct lpfc_dmabuf *dmabuf;
|
||||
uint32_t page_count;
|
||||
uint32_t start_rpi;
|
||||
uint16_t next_rpi;
|
||||
};
|
||||
|
||||
struct lpfc_rsrc_blks {
|
||||
|
|
Loading…
Reference in New Issue