diff options
author | James Smart <james.smart@emulex.com> | 2013-05-31 17:05:36 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-26 13:48:54 -0400 |
commit | c2b9712edd32967d84befe8628270a85f1b7e5a6 (patch) | |
tree | 3248cf835f24bd3738b212697a5d8784c4896176 /drivers/scsi/lpfc | |
parent | b230b8a298d1f042fb501a4bbdbc954c927e9ff1 (diff) |
[SCSI] lpfc 8.3.40: Fixed a race condition between SLI host and port failed FCF rediscovery
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 97 |
1 files changed, 35 insertions, 62 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7e5a2b16521f..cba2d955777b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4050,52 +4050,6 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba) | |||
4050 | } | 4050 | } |
4051 | 4051 | ||
4052 | /** | 4052 | /** |
4053 | * lpfc_sli4_perform_inuse_fcf_recovery - Perform inuse fcf recovery | ||
4054 | * @vport: pointer to lpfc hba data structure. | ||
4055 | * | ||
4056 | * This routine is to perform FCF recovery when the in-use FCF either dead or | ||
4057 | * got modified. | ||
4058 | **/ | ||
4059 | static void | ||
4060 | lpfc_sli4_perform_inuse_fcf_recovery(struct lpfc_hba *phba, | ||
4061 | struct lpfc_acqe_fip *acqe_fip) | ||
4062 | { | ||
4063 | int rc; | ||
4064 | |||
4065 | spin_lock_irq(&phba->hbalock); | ||
4066 | /* Mark the fast failover process in progress */ | ||
4067 | phba->fcf.fcf_flag |= FCF_DEAD_DISC; | ||
4068 | spin_unlock_irq(&phba->hbalock); | ||
4069 | |||
4070 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | ||
4071 | "2771 Start FCF fast failover process due to in-use " | ||
4072 | "FCF DEAD/MODIFIED event: evt_tag:x%x, index:x%x\n", | ||
4073 | acqe_fip->event_tag, acqe_fip->index); | ||
4074 | rc = lpfc_sli4_redisc_fcf_table(phba); | ||
4075 | if (rc) { | ||
4076 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, | ||
4077 | "2772 Issue FCF rediscover mabilbox command " | ||
4078 | "failed, fail through to FCF dead event\n"); | ||
4079 | spin_lock_irq(&phba->hbalock); | ||
4080 | phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; | ||
4081 | spin_unlock_irq(&phba->hbalock); | ||
4082 | /* | ||
4083 | * Last resort will fail over by treating this as a link | ||
4084 | * down to FCF registration. | ||
4085 | */ | ||
4086 | lpfc_sli4_fcf_dead_failthrough(phba); | ||
4087 | } else { | ||
4088 | /* Reset FCF roundrobin bmask for new discovery */ | ||
4089 | lpfc_sli4_clear_fcf_rr_bmask(phba); | ||
4090 | /* | ||
4091 | * Handling fast FCF failover to a DEAD FCF event is | ||
4092 | * considered equalivant to receiving CVL to all vports. | ||
4093 | */ | ||
4094 | lpfc_sli4_perform_all_vport_cvl(phba); | ||
4095 | } | ||
4096 | } | ||
4097 | |||
4098 | /** | ||
4099 | * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event | 4053 | * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event |
4100 | * @phba: pointer to lpfc hba data structure. | 4054 | * @phba: pointer to lpfc hba data structure. |
4101 | * @acqe_link: pointer to the async fcoe completion queue entry. | 4055 | * @acqe_link: pointer to the async fcoe completion queue entry. |
@@ -4160,22 +4114,9 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, | |||
4160 | break; | 4114 | break; |
4161 | } | 4115 | } |
4162 | 4116 | ||
4163 | /* If FCF has been in discovered state, perform rediscovery | 4117 | /* If the FCF has been in discovered state, do nothing. */ |
4164 | * only if the FCF with the same index of the in-use FCF got | 4118 | if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { |
4165 | * modified during normal operation. Otherwise, do nothing. | ||
4166 | */ | ||
4167 | if (phba->pport->port_state > LPFC_FLOGI) { | ||
4168 | spin_unlock_irq(&phba->hbalock); | 4119 | spin_unlock_irq(&phba->hbalock); |
4169 | if (phba->fcf.current_rec.fcf_indx == | ||
4170 | acqe_fip->index) { | ||
4171 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, | ||
4172 | "3300 In-use FCF (%d) " | ||
4173 | "modified, perform FCF " | ||
4174 | "rediscovery\n", | ||
4175 | acqe_fip->index); | ||
4176 | lpfc_sli4_perform_inuse_fcf_recovery(phba, | ||
4177 | acqe_fip); | ||
4178 | } | ||
4179 | break; | 4120 | break; |
4180 | } | 4121 | } |
4181 | spin_unlock_irq(&phba->hbalock); | 4122 | spin_unlock_irq(&phba->hbalock); |
@@ -4228,7 +4169,39 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, | |||
4228 | * is no longer valid as we are not in the middle of FCF | 4169 | * is no longer valid as we are not in the middle of FCF |
4229 | * failover process already. | 4170 | * failover process already. |
4230 | */ | 4171 | */ |
4231 | lpfc_sli4_perform_inuse_fcf_recovery(phba, acqe_fip); | 4172 | spin_lock_irq(&phba->hbalock); |
4173 | /* Mark the fast failover process in progress */ | ||
4174 | phba->fcf.fcf_flag |= FCF_DEAD_DISC; | ||
4175 | spin_unlock_irq(&phba->hbalock); | ||
4176 | |||
4177 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | ||
4178 | "2771 Start FCF fast failover process due to " | ||
4179 | "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " | ||
4180 | "\n", acqe_fip->event_tag, acqe_fip->index); | ||
4181 | rc = lpfc_sli4_redisc_fcf_table(phba); | ||
4182 | if (rc) { | ||
4183 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | | ||
4184 | LOG_DISCOVERY, | ||
4185 | "2772 Issue FCF rediscover mabilbox " | ||
4186 | "command failed, fail through to FCF " | ||
4187 | "dead event\n"); | ||
4188 | spin_lock_irq(&phba->hbalock); | ||
4189 | phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; | ||
4190 | spin_unlock_irq(&phba->hbalock); | ||
4191 | /* | ||
4192 | * Last resort will fail over by treating this | ||
4193 | * as a link down to FCF registration. | ||
4194 | */ | ||
4195 | lpfc_sli4_fcf_dead_failthrough(phba); | ||
4196 | } else { | ||
4197 | /* Reset FCF roundrobin bmask for new discovery */ | ||
4198 | lpfc_sli4_clear_fcf_rr_bmask(phba); | ||
4199 | /* | ||
4200 | * Handling fast FCF failover to a DEAD FCF event is | ||
4201 | * considered equalivant to receiving CVL to all vports. | ||
4202 | */ | ||
4203 | lpfc_sli4_perform_all_vport_cvl(phba); | ||
4204 | } | ||
4232 | break; | 4205 | break; |
4233 | case LPFC_FIP_EVENT_TYPE_CVL: | 4206 | case LPFC_FIP_EVENT_TYPE_CVL: |
4234 | phba->fcoe_cvl_eventtag = acqe_fip->event_tag; | 4207 | phba->fcoe_cvl_eventtag = acqe_fip->event_tag; |