[SCSI] lpfc 8.3.38: Fixed circular locking dependency and inconsistent lock state...
authorJames Smart <james.smart@emulex.com>
Fri, 1 Mar 2013 21:37:44 +0000 (16:37 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Tue, 9 Apr 2013 22:20:29 +0000 (15:20 -0700)
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c

index 8ab3e96..4decb86 100644 (file)
@@ -2990,6 +2990,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
        struct lpfc_dmabuf *mp;
        int rc;
        struct fcf_record *fcf_record;
+       uint32_t fc_flags = 0;
 
        spin_lock_irq(&phba->hbalock);
        switch (bf_get(lpfc_mbx_read_top_link_spd, la)) {
@@ -3021,11 +3022,8 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
                                "1309 Link Up Event npiv not supported in loop "
                                "topology\n");
                                /* Get Loop Map information */
-               if (bf_get(lpfc_mbx_read_top_il, la)) {
-                       spin_lock(shost->host_lock);
-                       vport->fc_flag |= FC_LBIT;
-                       spin_unlock(shost->host_lock);
-               }
+               if (bf_get(lpfc_mbx_read_top_il, la))
+                       fc_flags |= FC_LBIT;
 
                vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la);
                i = la->lilpBde64.tus.f.bdeSize;
@@ -3074,12 +3072,16 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
                                phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
                }
                vport->fc_myDID = phba->fc_pref_DID;
-               spin_lock(shost->host_lock);
-               vport->fc_flag |= FC_LBIT;
-               spin_unlock(shost->host_lock);
+               fc_flags |= FC_LBIT;
        }
        spin_unlock_irq(&phba->hbalock);
 
+       if (fc_flags) {
+               spin_lock_irq(shost->host_lock);
+               vport->fc_flag |= fc_flags;
+               spin_unlock_irq(shost->host_lock);
+       }
+
        lpfc_linkup(phba);
        sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!sparam_mbox)
index 057c7c1..5da2972 100644 (file)
@@ -2914,9 +2914,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba)
                        sglq_entry->state = SGL_FREED;
                        list_add_tail(&sglq_entry->list, &els_sgl_list);
                }
-               spin_lock(&phba->hbalock);
+               spin_lock_irq(&phba->hbalock);
                list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list);
-               spin_unlock(&phba->hbalock);
+               spin_unlock_irq(&phba->hbalock);
        } else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) {
                /* els xri-sgl shrinked */
                xri_cnt = phba->sli4_hba.els_xri_cnt - els_xri_cnt;
@@ -3014,9 +3014,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba)
                psb->cur_iocbq.sli4_lxritag = lxri;
                psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri];
        }
-       spin_lock(&phba->scsi_buf_list_lock);
+       spin_lock_irq(&phba->scsi_buf_list_lock);
        list_splice_init(&scsi_sgl_list, &phba->lpfc_scsi_buf_list);
-       spin_unlock(&phba->scsi_buf_list_lock);
+       spin_unlock_irq(&phba->scsi_buf_list_lock);
 
        return 0;
 
index e75210d..74b8710 100644 (file)
@@ -885,9 +885,9 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba)
        int num_posted, rc = 0;
 
        /* get all SCSI buffers need to repost to a local list */
-       spin_lock(&phba->scsi_buf_list_lock);
+       spin_lock_irq(&phba->scsi_buf_list_lock);
        list_splice_init(&phba->lpfc_scsi_buf_list, &post_sblist);
-       spin_unlock(&phba->scsi_buf_list_lock);
+       spin_unlock_irq(&phba->scsi_buf_list_lock);
 
        /* post the list of scsi buffer sgls to port if available */
        if (!list_empty(&post_sblist)) {
index 5fade54..568cebe 100644 (file)
@@ -5999,9 +5999,9 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba)
        LIST_HEAD(post_sgl_list);
        LIST_HEAD(free_sgl_list);
 
-       spin_lock(&phba->hbalock);
+       spin_lock_irq(&phba->hbalock);
        list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &allc_sgl_list);
-       spin_unlock(&phba->hbalock);
+       spin_unlock_irq(&phba->hbalock);
 
        list_for_each_entry_safe(sglq_entry, sglq_entry_next,
                                 &allc_sgl_list, list) {
@@ -6102,10 +6102,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(&phba->hbalock);
+               spin_lock_irq(&phba->hbalock);
                list_splice_init(&post_sgl_list,
                                 &phba->sli4_hba.lpfc_sgl_list);
-               spin_unlock(&phba->hbalock);
+               spin_unlock_irq(&phba->hbalock);
        } else {
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
                                "3161 Failure to post els sgl to port.\n");