From dafe8ceaa89577062c2364139997f04a32f77502 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 3 Sep 2014 12:56:40 -0400 Subject: lpfc: fix discovery timeout during nameserver login Fix discovery timeout during nameserver login Signed-off-by: James Smart Signed-off-by: Dick Kennedy Signed-off-by: Christoph Hellwig --- drivers/scsi/lpfc/lpfc_els.c | 5 +++++ drivers/scsi/lpfc/lpfc_init.c | 15 +++++++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 10 +++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/lpfc') diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 7a5d81a65be8..30ec80f32d1a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -8187,9 +8187,11 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, list_del(&sglq_entry->list); ndlp = sglq_entry->ndlp; sglq_entry->ndlp = NULL; + spin_lock(&pring->ring_lock); list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); sglq_entry->state = SGL_FREED; + spin_unlock(&pring->ring_lock); spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); lpfc_set_rrq_active(phba, ndlp, @@ -8208,12 +8210,15 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, spin_unlock_irqrestore(&phba->hbalock, iflag); return; } + spin_lock(&pring->ring_lock); sglq_entry = __lpfc_get_active_sglq(phba, lxri); if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { + spin_unlock(&pring->ring_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); return; } sglq_entry->state = SGL_XRI_ABORTED; + spin_unlock(&pring->ring_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 1953b3bbd60a..7f54916c4f62 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -988,9 +988,12 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) LIST_HEAD(aborts); unsigned long iflag = 0; struct lpfc_sglq *sglq_entry = NULL; + struct lpfc_sli *psli = &phba->sli; + struct lpfc_sli_ring *pring; lpfc_hba_free_post_buf(phba); lpfc_hba_clean_txcmplq(phba); + pring = &psli->ring[LPFC_ELS_RING]; /* At this point in time the HBA is either reset or DOA. Either * way, nothing should be on lpfc_abts_els_sgl_list, it needs to be @@ -1008,8 +1011,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) &phba->sli4_hba.lpfc_abts_els_sgl_list, list) sglq_entry->state = SGL_FREED; + spin_lock(&pring->ring_lock); list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); /* abts_scsi_buf_list_lock required because worker thread uses this * list. @@ -3047,6 +3052,7 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) LIST_HEAD(els_sgl_list); LIST_HEAD(scsi_sgl_list); int rc; + struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; /* * update on pci function's els xri-sgl list @@ -3087,7 +3093,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) list_add_tail(&sglq_entry->list, &els_sgl_list); } spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); } else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) { /* els xri-sgl shrinked */ @@ -3097,7 +3105,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) "%d to %d\n", phba->sli4_hba.els_xri_cnt, els_xri_cnt); spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &els_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); /* release extra els sgls from list */ for (i = 0; i < xri_cnt; i++) { @@ -3110,7 +3120,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) } } spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); } else lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -5680,10 +5692,13 @@ static void lpfc_free_els_sgl_list(struct lpfc_hba *phba) { LIST_HEAD(sglq_list); + struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; /* Retrieve all els sgls from driver list */ spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &sglq_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); /* Now free the sgl list */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 27221cb21bb8..8f3be2a5dc3f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -937,7 +937,7 @@ out: * @phba: Pointer to HBA context object. * @piocb: Pointer to the iocbq. * - * This function is called with hbalock held. This function + * This function is called with the ring lock held. This function * gets a new driver sglq object from the sglq list. If the * list is not empty then it is successful, it returns pointer to the newly * allocated sglq object else it returns NULL. @@ -1053,10 +1053,12 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) spin_unlock_irqrestore( &phba->sli4_hba.abts_sgl_list_lock, iflag); } else { + spin_lock_irqsave(&pring->ring_lock, iflag); sglq->state = SGL_FREED; sglq->ndlp = NULL; list_add_tail(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); + spin_unlock_irqrestore(&pring->ring_lock, iflag); /* Check if TXQ queue needs to be serviced */ if (!list_empty(&pring->txq)) @@ -6098,14 +6100,18 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) struct lpfc_sglq *sglq_entry_first = NULL; int status, total_cnt, post_cnt = 0, num_posted = 0, block_cnt = 0; int last_xritag = NO_XRI; + struct lpfc_sli_ring *pring; LIST_HEAD(prep_sgl_list); LIST_HEAD(blck_sgl_list); LIST_HEAD(allc_sgl_list); LIST_HEAD(post_sgl_list); LIST_HEAD(free_sgl_list); + pring = &phba->sli.ring[LPFC_ELS_RING]; spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &allc_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); total_cnt = phba->sli4_hba.els_xri_cnt; @@ -6207,8 +6213,10 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) /* push els sgls posted to the availble list */ if (!list_empty(&post_sgl_list)) { spin_lock_irq(&phba->hbalock); + spin_lock(&pring->ring_lock); list_splice_init(&post_sgl_list, &phba->sli4_hba.lpfc_sgl_list); + spin_unlock(&pring->ring_lock); spin_unlock_irq(&phba->hbalock); } else { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, -- cgit v1.2.3-55-g7522