aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2013-05-31 17:05:36 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-06-26 13:48:54 -0400
commitc2b9712edd32967d84befe8628270a85f1b7e5a6 (patch)
tree3248cf835f24bd3738b212697a5d8784c4896176 /drivers/scsi/lpfc
parentb230b8a298d1f042fb501a4bbdbc954c927e9ff1 (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.c97
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 **/
4059static void
4060lpfc_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;