Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c9ab6f5 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.10: Added round robin FCF failover



- Added round robin FCF failover on initial or FCF rediscovery FLOGI failure.

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent fc2b989b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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 *);
@@ -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 *);
+82 −9
Original line number Diff line number Diff line
@@ -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 */
@@ -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;
@@ -841,9 +890,19 @@ 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:
	lpfc_nlp_put(ndlp);
@@ -6075,21 +6134,18 @@ mbox_err_exit:
}

/**
 * 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;
@@ -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);
Loading