]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: lpfc: Fix used-RPI accounting problem.
authorJames Smart <james.smart@broadcom.com>
Wed, 12 Jul 2017 22:44:59 +0000 (18:44 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Fri, 14 Jul 2017 00:13:42 +0000 (17:13 -0700)
[backport of a1d3e3605028f2b4b0ff811b91df73454d9b8792]
From: rkennedy <dick.kennedy@avagotech.com>

Orabug: 26439257

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>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli4.h

index fd45a798c2aa03ab30c9a6d25b5049e90be7d95a..d9f8b8eff8779798599d99d29517a0c6d0face43 100644 (file)
@@ -8493,7 +8493,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);
index 739b80a323236c1dfc8d6e74a42ac639a25454f5..de50650dc4cac8c814a7b1f99069a6f64fef3dda 100644 (file)
@@ -6112,7 +6112,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
@@ -6125,8 +6124,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);
        /*
@@ -6137,18 +6135,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.
@@ -6182,13 +6172,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;
 
index 2eebf2eca207c73c318b935d3a67c3bdb352e400..69b6070ad6771212794404baa26c824d904072a5 100644 (file)
@@ -15884,6 +15884,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;
 }
index be83ae7deda14668e566dae59c4c2dbc3153ec25..86c1493f101a64d2e4c64653cd2b6ff578628592 100644 (file)
@@ -647,6 +647,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 {