Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

James Smart and committed by
James Bottomley
c2b9712e b230b8a2

+35 -62
+35 -62
drivers/scsi/lpfc/lpfc_init.c
··· 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 4053 * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event 4100 4054 * @phba: pointer to lpfc hba data structure. 4101 4055 * @acqe_link: pointer to the async fcoe completion queue entry. ··· 4114 4160 break; 4115 4161 } 4116 4162 4117 - /* If FCF has been in discovered state, perform rediscovery 4118 - * only if the FCF with the same index of the in-use FCF got 4119 - * modified during normal operation. Otherwise, do nothing. 4120 - */ 4121 - if (phba->pport->port_state > LPFC_FLOGI) { 4163 + /* If the FCF has been in discovered state, do nothing. */ 4164 + if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { 4122 4165 spin_unlock_irq(&phba->hbalock); 4123 - if (phba->fcf.current_rec.fcf_indx == 4124 - acqe_fip->index) { 4125 - lpfc_printf_log(phba, KERN_ERR, LOG_FIP, 4126 - "3300 In-use FCF (%d) " 4127 - "modified, perform FCF " 4128 - "rediscovery\n", 4129 - acqe_fip->index); 4130 - lpfc_sli4_perform_inuse_fcf_recovery(phba, 4131 - acqe_fip); 4132 - } 4133 4166 break; 4134 4167 } 4135 4168 spin_unlock_irq(&phba->hbalock); ··· 4169 4228 * is no longer valid as we are not in the middle of FCF 4170 4229 * failover process already. 4171 4230 */ 4172 - lpfc_sli4_perform_inuse_fcf_recovery(phba, acqe_fip); 4231 + spin_lock_irq(&phba->hbalock); 4232 + /* Mark the fast failover process in progress */ 4233 + phba->fcf.fcf_flag |= FCF_DEAD_DISC; 4234 + spin_unlock_irq(&phba->hbalock); 4235 + 4236 + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, 4237 + "2771 Start FCF fast failover process due to " 4238 + "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " 4239 + "\n", acqe_fip->event_tag, acqe_fip->index); 4240 + rc = lpfc_sli4_redisc_fcf_table(phba); 4241 + if (rc) { 4242 + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | 4243 + LOG_DISCOVERY, 4244 + "2772 Issue FCF rediscover mabilbox " 4245 + "command failed, fail through to FCF " 4246 + "dead event\n"); 4247 + spin_lock_irq(&phba->hbalock); 4248 + phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; 4249 + spin_unlock_irq(&phba->hbalock); 4250 + /* 4251 + * Last resort will fail over by treating this 4252 + * as a link down to FCF registration. 4253 + */ 4254 + lpfc_sli4_fcf_dead_failthrough(phba); 4255 + } else { 4256 + /* Reset FCF roundrobin bmask for new discovery */ 4257 + lpfc_sli4_clear_fcf_rr_bmask(phba); 4258 + /* 4259 + * Handling fast FCF failover to a DEAD FCF event is 4260 + * considered equalivant to receiving CVL to all vports. 4261 + */ 4262 + lpfc_sli4_perform_all_vport_cvl(phba); 4263 + } 4173 4264 break; 4174 4265 case LPFC_FIP_EVENT_TYPE_CVL: 4175 4266 phba->fcoe_cvl_eventtag = acqe_fip->event_tag;