Skip to content

Commit

Permalink
[SCSI] lpfc 8.3.10: Added round robin FCF failover
Browse files Browse the repository at this point in the history
- Added round robin FCF failover on initial or FCF rediscovery FLOGI failure.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
James Smart authored and James Bottomley committed Mar 3, 2010
1 parent fc2b989 commit 0c9ab6f
Show file tree
Hide file tree
Showing 8 changed files with 802 additions and 162 deletions.
4 changes: 4 additions & 0 deletions drivers/scsi/lpfc/lpfc_crtn.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *);
void lpfc_port_link_failure(struct lpfc_vport *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
void lpfc_retry_pport_discovery(struct lpfc_hba *);

void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
Expand Down Expand Up @@ -222,6 +223,9 @@ void lpfc_unregister_unused_fcf(struct lpfc_hba *);
int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *);
void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *);
void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);

int lpfc_mem_alloc(struct lpfc_hba *, int align);
void lpfc_mem_free(struct lpfc_hba *);
Expand Down
91 changes: 82 additions & 9 deletions drivers/scsi/lpfc/lpfc_els.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp = cmdiocb->context1;
struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
struct serv_parm *sp;
uint16_t fcf_index;
int rc;

/* Check to see if link went down during discovery */
Expand All @@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
vport->port_state);

if (irsp->ulpStatus) {
/*
* In case of FIP mode, perform round robin FCF failover
* due to new FCF discovery
*/
if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
(phba->fcf.fcf_flag & FCF_DISCOVERY)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
"2611 FLOGI failed on registered "
"FCF record fcf_index:%d, trying "
"to perform round robin failover\n",
phba->fcf.current_rec.fcf_indx);
fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
/*
* Exhausted the eligible FCF record list,
* fail through to retry FLOGI on current
* FCF record.
*/
lpfc_printf_log(phba, KERN_WARNING,
LOG_FIP | LOG_ELS,
"2760 FLOGI exhausted FCF "
"round robin failover list, "
"retry FLOGI on the current "
"registered FCF index:%d\n",
phba->fcf.current_rec.fcf_indx);
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
} else {
rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
fcf_index);
if (rc) {
lpfc_printf_log(phba, KERN_WARNING,
LOG_FIP | LOG_ELS,
"2761 FLOGI round "
"robin FCF failover "
"read FCF failed "
"rc:x%x, fcf_index:"
"%d\n", rc,
phba->fcf.current_rec.fcf_indx);
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
} else
goto out;
}
}

/* Check for retry */
if (lpfc_els_retry(phba, cmdiocb, rspiocb))
goto out;
Expand Down Expand Up @@ -841,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
else
rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);

if (!rc)
if (!rc) {
/* Mark the FCF discovery process done */
lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
"2769 FLOGI successful on FCF record: "
"current_fcf_index:x%x, terminate FCF "
"round robin failover process\n",
phba->fcf.current_rec.fcf_indx);
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
goto out;
}
}

flogifail:
Expand Down Expand Up @@ -6075,21 +6134,18 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
}

/**
* lpfc_retry_pport_discovery - Start timer to retry FLOGI.
* lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
* @phba: pointer to lpfc hba data structure.
*
* This routine abort all pending discovery commands and
* start a timer to retry FLOGI for the physical port
* discovery.
* This routine cancels the retry delay timers to all the vports.
**/
void
lpfc_retry_pport_discovery(struct lpfc_hba *phba)
lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
{
struct lpfc_vport **vports;
struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost;
int i;
uint32_t link_state;
int i;

/* Treat this failure as linkdown for all vports */
link_state = phba->link_state;
Expand All @@ -6107,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba)
}
lpfc_destroy_vport_work_array(phba, vports);
}
}

/**
* lpfc_retry_pport_discovery - Start timer to retry FLOGI.
* @phba: pointer to lpfc hba data structure.
*
* This routine abort all pending discovery commands and
* start a timer to retry FLOGI for the physical port
* discovery.
**/
void
lpfc_retry_pport_discovery(struct lpfc_hba *phba)
{
struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost;

/* Cancel the all vports retry delay retry timers */
lpfc_cancel_all_vport_retry_delay_timer(phba);

/* If fabric require FLOGI, then re-instantiate physical login */
ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
if (!ndlp)
return;


shost = lpfc_shost_from_vport(phba->pport);
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
spin_lock_irq(shost->host_lock);
Expand Down
Loading

0 comments on commit 0c9ab6f

Please sign in to comment.