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);
|
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
"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 {
|
|||||||
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user