[SCSI] lpfc 8.3.40: Fixed a race condition between SLI host and port failed FCF redis...
authorJames Smart <james.smart@emulex.com>
Fri, 31 May 2013 21:05:36 +0000 (17:05 -0400)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 26 Jun 2013 17:48:54 +0000 (10:48 -0700)
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/lpfc/lpfc_init.c

index 7e5a2b1..cba2d95 100644 (file)
@@ -4049,52 +4049,6 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
        lpfc_destroy_vport_work_array(phba, vports);
 }
 
-/**
- * lpfc_sli4_perform_inuse_fcf_recovery - Perform inuse fcf recovery
- * @vport: pointer to lpfc hba data structure.
- *
- * This routine is to perform FCF recovery when the in-use FCF either dead or
- * got modified.
- **/
-static void
-lpfc_sli4_perform_inuse_fcf_recovery(struct lpfc_hba *phba,
-                                    struct lpfc_acqe_fip *acqe_fip)
-{
-       int rc;
-
-       spin_lock_irq(&phba->hbalock);
-       /* Mark the fast failover process in progress */
-       phba->fcf.fcf_flag |= FCF_DEAD_DISC;
-       spin_unlock_irq(&phba->hbalock);
-
-       lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-                       "2771 Start FCF fast failover process due to in-use "
-                       "FCF DEAD/MODIFIED event: evt_tag:x%x, index:x%x\n",
-                       acqe_fip->event_tag, acqe_fip->index);
-       rc = lpfc_sli4_redisc_fcf_table(phba);
-       if (rc) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
-                               "2772 Issue FCF rediscover mabilbox command "
-                               "failed, fail through to FCF dead event\n");
-               spin_lock_irq(&phba->hbalock);
-               phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
-               spin_unlock_irq(&phba->hbalock);
-               /*
-                * Last resort will fail over by treating this as a link
-                * down to FCF registration.
-                */
-               lpfc_sli4_fcf_dead_failthrough(phba);
-       } else {
-               /* Reset FCF roundrobin bmask for new discovery */
-               lpfc_sli4_clear_fcf_rr_bmask(phba);
-               /*
-                * Handling fast FCF failover to a DEAD FCF event is
-                * considered equalivant to receiving CVL to all vports.
-                */
-               lpfc_sli4_perform_all_vport_cvl(phba);
-       }
-}
-
 /**
  * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
  * @phba: pointer to lpfc hba data structure.
@@ -4160,22 +4114,9 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
                        break;
                }
 
-               /* If FCF has been in discovered state, perform rediscovery
-                * only if the FCF with the same index of the in-use FCF got
-                * modified during normal operation. Otherwise, do nothing.
-                */
-               if (phba->pport->port_state > LPFC_FLOGI) {
+               /* If the FCF has been in discovered state, do nothing. */
+               if (phba->fcf.fcf_flag & FCF_SCAN_DONE) {
                        spin_unlock_irq(&phba->hbalock);
-                       if (phba->fcf.current_rec.fcf_indx ==
-                           acqe_fip->index) {
-                               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
-                                               "3300 In-use FCF (%d) "
-                                               "modified, perform FCF "
-                                               "rediscovery\n",
-                                               acqe_fip->index);
-                               lpfc_sli4_perform_inuse_fcf_recovery(phba,
-                                                                    acqe_fip);
-                       }
                        break;
                }
                spin_unlock_irq(&phba->hbalock);
@@ -4228,7 +4169,39 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
                 * is no longer valid as we are not in the middle of FCF
                 * failover process already.
                 */
-               lpfc_sli4_perform_inuse_fcf_recovery(phba, acqe_fip);
+               spin_lock_irq(&phba->hbalock);
+               /* Mark the fast failover process in progress */
+               phba->fcf.fcf_flag |= FCF_DEAD_DISC;
+               spin_unlock_irq(&phba->hbalock);
+
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                               "2771 Start FCF fast failover process due to "
+                               "FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
+                               "\n", acqe_fip->event_tag, acqe_fip->index);
+               rc = lpfc_sli4_redisc_fcf_table(phba);
+               if (rc) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+                                       LOG_DISCOVERY,
+                                       "2772 Issue FCF rediscover mabilbox "
+                                       "command failed, fail through to FCF "
+                                       "dead event\n");
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * Last resort will fail over by treating this
+                        * as a link down to FCF registration.
+                        */
+                       lpfc_sli4_fcf_dead_failthrough(phba);
+               } else {
+                       /* Reset FCF roundrobin bmask for new discovery */
+                       lpfc_sli4_clear_fcf_rr_bmask(phba);
+                       /*
+                        * Handling fast FCF failover to a DEAD FCF event is
+                        * considered equalivant to receiving CVL to all vports.
+                        */
+                       lpfc_sli4_perform_all_vport_cvl(phba);
+               }
                break;
        case LPFC_FIP_EVENT_TYPE_CVL:
                phba->fcoe_cvl_eventtag = acqe_fip->event_tag;