OSDN Git Service

lpfc: fix discovery timeout during nameserver login
authorJames Smart <james.smart@emulex.com>
Wed, 3 Sep 2014 16:56:40 +0000 (12:56 -0400)
committerChristoph Hellwig <hch@lst.de>
Tue, 16 Sep 2014 16:10:08 +0000 (09:10 -0700)
Fix discovery timeout during nameserver login

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c

index 7a5d81a..30ec80f 100644 (file)
@@ -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;
 }
index 1953b3b..7f54916 100644 (file)
@@ -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 */
index 27221cb..8f3be2a 100644 (file)
@@ -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,