aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2015-04-07 15:07:22 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-10 10:49:39 -0400
commitbe6bb94100dc6803a530e20aad05360e6267f56b (patch)
treeea5df54e557e2c8428d4b830d3410430187d8946 /drivers/scsi
parent34154e05bc135f16804584d81a8c810611a4abe9 (diff)
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')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c60
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c24
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c49
5 files changed, 127 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 665c88cf6404..dd01ea86361d 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -284,6 +284,7 @@ void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
284 struct lpfc_sli_ring *, uint32_t); 284 struct lpfc_sli_ring *, uint32_t);
285void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *); 285void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *);
286void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); 286void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
287void lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *, LPFC_MBOXQ_t *);
287int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t, 288int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
288 struct lpfc_iocbq *, uint32_t); 289 struct lpfc_iocbq *, uint32_t);
289void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t); 290void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index f73d58c8fec3..ba5da266a128 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -3700,6 +3700,11 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3700 kfree(mp); 3700 kfree(mp);
3701 mempool_free(pmb, phba->mbox_mem_pool); 3701 mempool_free(pmb, phba->mbox_mem_pool);
3702 if (ndlp) { 3702 if (ndlp) {
3703 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
3704 "0006 rpi%x DID:%x flg:%x %d map:%x %p\n",
3705 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
3706 atomic_read(&ndlp->kref.refcount),
3707 ndlp->nlp_usg_map, ndlp);
3703 if (NLP_CHK_NODE_ACT(ndlp)) { 3708 if (NLP_CHK_NODE_ACT(ndlp)) {
3704 lpfc_nlp_put(ndlp); 3709 lpfc_nlp_put(ndlp);
3705 /* This is the end of the default RPI cleanup logic for 3710 /* This is the end of the default RPI cleanup logic for
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 9d06d4592c3a..2a51df7bdb0c 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3439,6 +3439,11 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3439 pmb->context1 = NULL; 3439 pmb->context1 = NULL;
3440 pmb->context2 = NULL; 3440 pmb->context2 = NULL;
3441 3441
3442 lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
3443 "0002 rpi:%x DID:%x flg:%x %d map:%x %p\n",
3444 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
3445 atomic_read(&ndlp->kref.refcount),
3446 ndlp->nlp_usg_map, ndlp);
3442 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) 3447 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
3443 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; 3448 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
3444 3449
@@ -3855,6 +3860,11 @@ out:
3855 ndlp->nlp_flag |= NLP_RPI_REGISTERED; 3860 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
3856 ndlp->nlp_type |= NLP_FABRIC; 3861 ndlp->nlp_type |= NLP_FABRIC;
3857 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 3862 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
3863 lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
3864 "0003 rpi:%x DID:%x flg:%x %d map%x %p\n",
3865 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
3866 atomic_read(&ndlp->kref.refcount),
3867 ndlp->nlp_usg_map, ndlp);
3858 3868
3859 if (vport->port_state < LPFC_VPORT_READY) { 3869 if (vport->port_state < LPFC_VPORT_READY) {
3860 /* Link up discovery requires Fabric registration. */ 3870 /* Link up discovery requires Fabric registration. */
@@ -4250,8 +4260,15 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
4250 ndlp->active_rrqs_xri_bitmap = active_rrqs_xri_bitmap; 4260 ndlp->active_rrqs_xri_bitmap = active_rrqs_xri_bitmap;
4251 4261
4252 spin_unlock_irqrestore(&phba->ndlp_lock, flags); 4262 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
4253 if (vport->phba->sli_rev == LPFC_SLI_REV4) 4263 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
4254 ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba); 4264 ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
4265 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
4266 "0008 rpi:%x DID:%x flg:%x refcnt:%d "
4267 "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
4268 ndlp->nlp_flag,
4269 atomic_read(&ndlp->kref.refcount),
4270 ndlp->nlp_usg_map, ndlp);
4271 }
4255 4272
4256 4273
4257 if (state != NLP_STE_UNUSED_NODE) 4274 if (state != NLP_STE_UNUSED_NODE)
@@ -4276,9 +4293,12 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
4276 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 4293 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
4277 return; 4294 return;
4278 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 4295 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
4279 if (vport->phba->sli_rev == LPFC_SLI_REV4) 4296 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
4280 lpfc_cleanup_vports_rrqs(vport, ndlp); 4297 lpfc_cleanup_vports_rrqs(vport, ndlp);
4281 lpfc_nlp_put(ndlp); 4298 lpfc_unreg_rpi(vport, ndlp);
4299 } else {
4300 lpfc_nlp_put(ndlp);
4301 }
4282 return; 4302 return;
4283} 4303}
4284 4304
@@ -4515,7 +4535,17 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
4515 mbox->context1 = ndlp; 4535 mbox->context1 = ndlp;
4516 mbox->mbox_cmpl = lpfc_nlp_logo_unreg; 4536 mbox->mbox_cmpl = lpfc_nlp_logo_unreg;
4517 } else { 4537 } else {
4518 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 4538 if (phba->sli_rev == LPFC_SLI_REV4 &&
4539 (!(vport->load_flag & FC_UNLOADING)) &&
4540 (bf_get(lpfc_sli_intf_if_type,
4541 &phba->sli4_hba.sli_intf) ==
4542 LPFC_SLI_INTF_IF_TYPE_2)) {
4543 mbox->context1 = lpfc_nlp_get(ndlp);
4544 mbox->mbox_cmpl =
4545 lpfc_sli4_unreg_rpi_cmpl_clr;
4546 } else
4547 mbox->mbox_cmpl =
4548 lpfc_sli_def_mbox_cmpl;
4519 } 4549 }
4520 4550
4521 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); 4551 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
@@ -4741,6 +4771,11 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
4741 /* For this case we need to cleanup the default rpi 4771 /* For this case we need to cleanup the default rpi
4742 * allocated by the firmware. 4772 * allocated by the firmware.
4743 */ 4773 */
4774 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
4775 "0005 rpi:%x DID:%x flg:%x %d map:%x %p\n",
4776 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
4777 atomic_read(&ndlp->kref.refcount),
4778 ndlp->nlp_usg_map, ndlp);
4744 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) 4779 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
4745 != NULL) { 4780 != NULL) {
4746 rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID, 4781 rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID,
@@ -5482,7 +5517,11 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5482 ndlp->nlp_flag |= NLP_RPI_REGISTERED; 5517 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
5483 ndlp->nlp_type |= NLP_FABRIC; 5518 ndlp->nlp_type |= NLP_FABRIC;
5484 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 5519 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
5485 5520 lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
5521 "0004 rpi:%x DID:%x flg:%x %d map:%x %p\n",
5522 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
5523 atomic_read(&ndlp->kref.refcount),
5524 ndlp->nlp_usg_map, ndlp);
5486 /* 5525 /*
5487 * Start issuing Fabric-Device Management Interface (FDMI) command to 5526 * Start issuing Fabric-Device Management Interface (FDMI) command to
5488 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if 5527 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if
@@ -5648,6 +5687,13 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
5648 INIT_LIST_HEAD(&ndlp->nlp_listp); 5687 INIT_LIST_HEAD(&ndlp->nlp_listp);
5649 if (vport->phba->sli_rev == LPFC_SLI_REV4) { 5688 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
5650 ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba); 5689 ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
5690 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
5691 "0007 rpi:%x DID:%x flg:%x refcnt:%d "
5692 "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID,
5693 ndlp->nlp_flag,
5694 atomic_read(&ndlp->kref.refcount),
5695 ndlp->nlp_usg_map, ndlp);
5696
5651 ndlp->active_rrqs_xri_bitmap = 5697 ndlp->active_rrqs_xri_bitmap =
5652 mempool_alloc(vport->phba->active_rrq_pool, 5698 mempool_alloc(vport->phba->active_rrq_pool,
5653 GFP_KERNEL); 5699 GFP_KERNEL);
@@ -5682,9 +5728,9 @@ lpfc_nlp_release(struct kref *kref)
5682 5728
5683 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, 5729 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
5684 "0279 lpfc_nlp_release: ndlp:x%p did %x " 5730 "0279 lpfc_nlp_release: ndlp:x%p did %x "
5685 "usgmap:x%x refcnt:%d\n", 5731 "usgmap:x%x refcnt:%d rpi:%x\n",
5686 (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, 5732 (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map,
5687 atomic_read(&ndlp->kref.refcount)); 5733 atomic_read(&ndlp->kref.refcount), ndlp->nlp_rpi);
5688 5734
5689 /* remove ndlp from action. */ 5735 /* remove ndlp from action. */
5690 lpfc_nlp_remove(ndlp->vport, ndlp); 5736 lpfc_nlp_remove(ndlp->vport, ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 4947cc4abc0d..166b2c76cb20 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2775,9 +2775,19 @@ lpfc_sli4_node_prep(struct lpfc_hba *phba)
2775 list_for_each_entry_safe(ndlp, next_ndlp, 2775 list_for_each_entry_safe(ndlp, next_ndlp,
2776 &vports[i]->fc_nodes, 2776 &vports[i]->fc_nodes,
2777 nlp_listp) { 2777 nlp_listp) {
2778 if (NLP_CHK_NODE_ACT(ndlp)) 2778 if (NLP_CHK_NODE_ACT(ndlp)) {
2779 ndlp->nlp_rpi = 2779 ndlp->nlp_rpi =
2780 lpfc_sli4_alloc_rpi(phba); 2780 lpfc_sli4_alloc_rpi(phba);
2781 lpfc_printf_vlog(ndlp->vport, KERN_INFO,
2782 LOG_NODE,
2783 "0009 rpi:%x DID:%x "
2784 "flg:%x map:%x %p\n",
2785 ndlp->nlp_rpi,
2786 ndlp->nlp_DID,
2787 ndlp->nlp_flag,
2788 ndlp->nlp_usg_map,
2789 ndlp);
2790 }
2781 } 2791 }
2782 } 2792 }
2783 } 2793 }
@@ -2941,8 +2951,18 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action)
2941 * RPI. Get a new RPI when the adapter port 2951 * RPI. Get a new RPI when the adapter port
2942 * comes back online. 2952 * comes back online.
2943 */ 2953 */
2944 if (phba->sli_rev == LPFC_SLI_REV4) 2954 if (phba->sli_rev == LPFC_SLI_REV4) {
2955 lpfc_printf_vlog(ndlp->vport,
2956 KERN_INFO, LOG_NODE,
2957 "0011 lpfc_offline: "
2958 "ndlp:x%p did %x "
2959 "usgmap:x%x rpi:%x\n",
2960 ndlp, ndlp->nlp_DID,
2961 ndlp->nlp_usg_map,
2962 ndlp->nlp_rpi);
2963
2945 lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); 2964 lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
2965 }
2946 lpfc_unreg_rpi(vports[i], ndlp); 2966 lpfc_unreg_rpi(vports[i], ndlp);
2947 } 2967 }
2948 } 2968 }
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)
2213 else 2213 else
2214 mempool_free(pmb, phba->mbox_mem_pool); 2214 mempool_free(pmb, phba->mbox_mem_pool);
2215} 2215}
2216 /**
2217 * lpfc_sli4_unreg_rpi_cmpl_clr - mailbox completion handler
2218 * @phba: Pointer to HBA context object.
2219 * @pmb: Pointer to mailbox object.
2220 *
2221 * This function is the unreg rpi mailbox completion handler. It
2222 * frees the memory resources associated with the completed mailbox
2223 * command. An additional refrenece is put on the ndlp to prevent
2224 * lpfc_nlp_release from freeing the rpi bit in the bitmask before
2225 * the unreg mailbox command completes, this routine puts the
2226 * reference back.
2227 *
2228 **/
2229void
2230lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2231{
2232 struct lpfc_vport *vport = pmb->vport;
2233 struct lpfc_nodelist *ndlp;
2234
2235 ndlp = pmb->context1;
2236 if (pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) {
2237 if (phba->sli_rev == LPFC_SLI_REV4 &&
2238 (bf_get(lpfc_sli_intf_if_type,
2239 &phba->sli4_hba.sli_intf) ==
2240 LPFC_SLI_INTF_IF_TYPE_2)) {
2241 if (ndlp) {
2242 lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
2243 "0010 UNREG_LOGIN vpi:%x "
2244 "rpi:%x DID:%x map:%x %p\n",
2245 vport->vpi, ndlp->nlp_rpi,
2246 ndlp->nlp_DID,
2247 ndlp->nlp_usg_map, ndlp);
2248
2249 lpfc_nlp_put(ndlp);
2250 }
2251 }
2252 }
2253
2254 mempool_free(pmb, phba->mbox_mem_pool);
2255}
2216 2256
2217/** 2257/**
2218 * lpfc_sli_handle_mb_event - Handle mailbox completions from firmware 2258 * lpfc_sli_handle_mb_event - Handle mailbox completions from firmware
@@ -15659,14 +15699,14 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba)
15659 struct lpfc_rpi_hdr *rpi_hdr; 15699 struct lpfc_rpi_hdr *rpi_hdr;
15660 unsigned long iflag; 15700 unsigned long iflag;
15661 15701
15662 max_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
15663 rpi_limit = phba->sli4_hba.next_rpi;
15664
15665 /* 15702 /*
15666 * Fetch the next logical rpi. Because this index is logical, 15703 * Fetch the next logical rpi. Because this index is logical,
15667 * the driver starts at 0 each time. 15704 * the driver starts at 0 each time.
15668 */ 15705 */
15669 spin_lock_irqsave(&phba->hbalock, iflag); 15706 spin_lock_irqsave(&phba->hbalock, iflag);
15707 max_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
15708 rpi_limit = phba->sli4_hba.next_rpi;
15709
15670 rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, 0); 15710 rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, 0);
15671 if (rpi >= rpi_limit) 15711 if (rpi >= rpi_limit)
15672 rpi = LPFC_RPI_ALLOC_ERROR; 15712 rpi = LPFC_RPI_ALLOC_ERROR;
@@ -15675,6 +15715,9 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba)
15675 phba->sli4_hba.max_cfg_param.rpi_used++; 15715 phba->sli4_hba.max_cfg_param.rpi_used++;
15676 phba->sli4_hba.rpi_count++; 15716 phba->sli4_hba.rpi_count++;
15677 } 15717 }
15718 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
15719 "0001 rpi:%x max:%x lim:%x\n",
15720 (int) rpi, max_rpi, rpi_limit);
15678 15721
15679 /* 15722 /*
15680 * Don't try to allocate more rpi header regions if the device limit 15723 * Don't try to allocate more rpi header regions if the device limit