diff options
author | James Smart <james.smart@emulex.com> | 2015-04-07 15:07:22 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-10 07:49:39 -0700 |
commit | be6bb94100dc6803a530e20aad05360e6267f56b (patch) | |
tree | ea5df54e557e2c8428d4b830d3410430187d8946 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 34154e05bc135f16804584d81a8c810611a4abe9 (diff) | |
download | linux-be6bb94100dc6803a530e20aad05360e6267f56b.tar.gz linux-be6bb94100dc6803a530e20aad05360e6267f56b.tar.bz2 linux-be6bb94100dc6803a530e20aad05360e6267f56b.zip |
lpfc: Fix premature release of rpi bit in bitmask
Currently, the driver plays off the fact that older sli4 adapters have a
different rpi access pattern that allowed for the rpi reference to be
released earlier in the teardown sequence, allowing the driver to recycle
the rpi value sooner. Newer sli4 adapters have a different access pattern that
requires us to wait for a later mailbox completion. This changes the put
call location on the newer sli4 adapters.
Symptoms of the error are "0110 ELS" and the "0372 iotag" errors.
Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 303b231b5ef7..c76c2a1e41e4 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2213,6 +2213,46 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else mempool_free(pmb, phba->mbox_mem_pool); } + /** + * lpfc_sli4_unreg_rpi_cmpl_clr - mailbox completion handler + * @phba: Pointer to HBA context object. + * @pmb: Pointer to mailbox object. + * + * This function is the unreg rpi mailbox completion handler. It + * frees the memory resources associated with the completed mailbox + * command. An additional refrenece is put on the ndlp to prevent + * lpfc_nlp_release from freeing the rpi bit in the bitmask before + * the unreg mailbox command completes, this routine puts the + * reference back. + * + **/ +void +lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +{ + struct lpfc_vport *vport = pmb->vport; + struct lpfc_nodelist *ndlp; + + ndlp = pmb->context1; + if (pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) { + if (phba->sli_rev == LPFC_SLI_REV4 && + (bf_get(lpfc_sli_intf_if_type, + &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_IF_TYPE_2)) { + if (ndlp) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, + "0010 UNREG_LOGIN vpi:%x " + "rpi:%x DID:%x map:%x %p\n", + vport->vpi, ndlp->nlp_rpi, + ndlp->nlp_DID, + ndlp->nlp_usg_map, ndlp); + + lpfc_nlp_put(ndlp); + } + } + } + + mempool_free(pmb, phba->mbox_mem_pool); +} /** * lpfc_sli_handle_mb_event - Handle mailbox completions from firmware @@ -15659,14 +15699,14 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) struct lpfc_rpi_hdr *rpi_hdr; unsigned long iflag; - max_rpi = phba->sli4_hba.max_cfg_param.max_rpi; - rpi_limit = phba->sli4_hba.next_rpi; - /* * Fetch the next logical rpi. Because this index is logical, * the driver starts at 0 each time. */ spin_lock_irqsave(&phba->hbalock, iflag); + max_rpi = phba->sli4_hba.max_cfg_param.max_rpi; + rpi_limit = phba->sli4_hba.next_rpi; + rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, 0); if (rpi >= rpi_limit) rpi = LPFC_RPI_ALLOC_ERROR; @@ -15675,6 +15715,9 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) phba->sli4_hba.max_cfg_param.rpi_used++; phba->sli4_hba.rpi_count++; } + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "0001 rpi:%x max:%x lim:%x\n", + (int) rpi, max_rpi, rpi_limit); /* * Don't try to allocate more rpi header regions if the device limit |