Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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);
+5 −19
Original line number Original line Diff line number Diff line
@@ -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;


+8 −0
Original line number Original line Diff line number Diff line
@@ -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;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 {