Commit a93ff37a authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.18: Add logic to detect last devloss timeout

Added driver logic to detect the last devloss timeout of remote nodes which
was still in use of FCF. At that point, the driver should set the last
in-use remote node devloss timeout flag if it was not already set and should
perform proper action on the in-use FCF and recover of FCF from firmware,
depending on the state the driver's FIP engine is in.

Find eligible FCF through FCF table rescan or the next new FCF event when
FCF table rescan turned out empty eligible FCF, and the successful flogi
into an FCF shall clear the HBA_DEVLOSS_TMO flag, indicating the successful
recovery from devloss timeout.

[jejb: add delay.h include to lpfc_hbadisc.c to fix ppc compile]
Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 12265f68
......@@ -552,9 +552,11 @@ struct lpfc_hba {
#define ELS_XRI_ABORT_EVENT 0x40
#define ASYNC_EVENT 0x80
#define LINK_DISABLED 0x100 /* Link disabled by user */
#define FCF_DISC_INPROGRESS 0x200 /* FCF discovery in progress */
#define HBA_FIP_SUPPORT 0x400 /* FIP support in HBA */
#define HBA_AER_ENABLED 0x800 /* AER enabled with HBA */
#define FCF_TS_INPROG 0x200 /* FCF table scan in progress */
#define FCF_RR_INPROG 0x400 /* FCF roundrobin flogi in progress */
#define HBA_FIP_SUPPORT 0x800 /* FIP support in HBA */
#define HBA_AER_ENABLED 0x1000 /* AER enabled with HBA */
#define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
struct lpfc_dmabuf slim2p;
......
......@@ -229,6 +229,7 @@ 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_sli4_fcf_rr_next_proc(struct lpfc_vport *, uint16_t);
int lpfc_mem_alloc(struct lpfc_hba *, int align);
void lpfc_mem_free(struct lpfc_hba *);
......
......@@ -795,7 +795,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (irsp->ulpStatus) {
/*
* In case of FIP mode, perform round robin FCF failover
* In case of FIP mode, perform roundrobin FCF failover
* due to new FCF discovery
*/
if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
......@@ -803,49 +803,17 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
(irsp->ulpStatus != IOSTAT_LOCAL_REJECT) &&
(irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
"2611 FLOGI failed on registered "
"FCF record fcf_index(%d), status: "
"x%x/x%x, tmo:x%x, trying to perform "
"round robin failover\n",
"2611 FLOGI failed on FCF (x%x), "
"status:x%x/x%x, tmo:x%x, perform "
"roundrobin FCF failover\n",
phba->fcf.current_rec.fcf_indx,
irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout);
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 Completed one round "
"of FLOGI FCF round robin "
"failover list, retry FLOGI "
"on currently registered "
"FCF index:%d\n",
phba->fcf.current_rec.fcf_indx);
} else {
lpfc_printf_log(phba, KERN_INFO,
LOG_FIP | LOG_ELS,
"2794 FLOGI FCF round robin "
"failover to FCF index x%x\n",
fcf_index);
rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
fcf_index);
rc = lpfc_sli4_fcf_rr_next_proc(vport, 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);
else
goto out;
}
}
/* FLOGI failure */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
......@@ -934,6 +902,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_nlp_put(ndlp);
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
spin_unlock_irq(&phba->hbalock);
goto out;
}
......@@ -942,13 +911,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (phba->hba_flag & HBA_FIP_SUPPORT)
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",
"2769 FLOGI to FCF (x%x) "
"completed successfully\n",
phba->fcf.current_rec.fcf_indx);
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
spin_unlock_irq(&phba->hbalock);
goto out;
}
......
This diff is collapsed.
......@@ -2936,8 +2936,7 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
phba->fcf.fcf_flag |= FCF_REDISC_EVT;
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2776 FCF rediscover wait timer expired, post "
"a worker thread event for FCF table scan\n");
"2776 FCF rediscover quiescent timer expired\n");
/* wake up worker thread */
lpfc_worker_wake_up(phba);
}
......@@ -3312,35 +3311,34 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF)
lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
LOG_DISCOVERY,
"2546 New FCF found event: "
"evt_tag:x%x, fcf_index:x%x\n",
"2546 New FCF event, evt_tag:x%x, "
"index:x%x\n",
acqe_fcoe->event_tag,
acqe_fcoe->index);
else
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
LOG_DISCOVERY,
"2788 FCF parameter modified event: "
"evt_tag:x%x, fcf_index:x%x\n",
"2788 FCF param modified event, "
"evt_tag:x%x, index:x%x\n",
acqe_fcoe->event_tag,
acqe_fcoe->index);
if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
/*
* During period of FCF discovery, read the FCF
* table record indexed by the event to update
* FCF round robin failover eligible FCF bmask.
* FCF roundrobin failover eligible FCF bmask.
*/
lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
LOG_DISCOVERY,
"2779 Read new FCF record with "
"fcf_index:x%x for updating FCF "
"round robin failover bmask\n",
"2779 Read FCF (x%x) for updating "
"roundrobin FCF failover bmask\n",
acqe_fcoe->index);
rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
}
/* If the FCF discovery is in progress, do nothing. */
spin_lock_irq(&phba->hbalock);
if (phba->hba_flag & FCF_DISC_INPROGRESS) {
if (phba->hba_flag & FCF_TS_INPROG) {
spin_unlock_irq(&phba->hbalock);
break;
}
......@@ -3359,15 +3357,15 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
/* Otherwise, scan the entire FCF table and re-discover SAN */
lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
"2770 Start FCF table scan due to new FCF "
"event: evt_tag:x%x, fcf_index:x%x\n",
"2770 Start FCF table scan per async FCF "
"event, evt_tag:x%x, index:x%x\n",
acqe_fcoe->event_tag, acqe_fcoe->index);
rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
LPFC_FCOE_FCF_GET_FIRST);
if (rc)
lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
"2547 Issue FCF scan read FCF mailbox "
"command failed 0x%x\n", rc);
"command failed (x%x)\n", rc);
break;
case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
......@@ -3379,9 +3377,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
"2549 FCF disconnected from network index 0x%x"
" tag 0x%x\n", acqe_fcoe->index,
acqe_fcoe->event_tag);
"2549 FCF (x%x) disconnected from network, "
"tag:x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
/*
* If we are in the middle of FCF failover process, clear
* the corresponding FCF bit in the roundrobin bitmap.
......@@ -3495,9 +3492,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
LOG_DISCOVERY,
"2773 Start FCF fast failover due "
"to CVL event: evt_tag:x%x\n",
acqe_fcoe->event_tag);
"2773 Start FCF failover per CVL, "
"evt_tag:x%x\n", acqe_fcoe->event_tag);
rc = lpfc_sli4_redisc_fcf_table(phba);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
......@@ -3647,8 +3643,7 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
/* Scan FCF table from the first entry to re-discover SAN */
lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
"2777 Start FCF table scan after FCF "
"rediscovery quiescent period over\n");
"2777 Start post-quiescent FCF table scan\n");
rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
if (rc)
lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
......@@ -4166,7 +4161,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
goto out_free_active_sgl;
}
/* Allocate eligible FCF bmask memory for FCF round robin failover */
/* Allocate eligible FCF bmask memory for FCF roundrobin failover */
longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
GFP_KERNEL);
......
......@@ -5921,7 +5921,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
* lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution
* @phba: Pointer to HBA context object.
*
* This routine performs a round robin SCSI command to SLI4 FCP WQ index
* This routine performs a roundrobin SCSI command to SLI4 FCP WQ index
* distribution. This is called by __lpfc_sli_issue_iocb_s4() with the hbalock
* held.
*
......@@ -12242,13 +12242,15 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
/* Issue the mailbox command asynchronously */
mboxq->vport = phba->pport;
mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
spin_lock_irq(&phba->hbalock);
phba->hba_flag |= FCF_TS_INPROG;
spin_unlock_irq(&phba->hbalock);
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
error = -EIO;
else {
spin_lock_irq(&phba->hbalock);
phba->hba_flag |= FCF_DISC_INPROGRESS;
spin_unlock_irq(&phba->hbalock);
/* Reset eligible FCF count for new scan */
if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
phba->fcf.eligible_fcf_cnt = 0;
......@@ -12258,21 +12260,21 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
if (error) {
if (mboxq)
lpfc_sli4_mbox_cmd_free(phba, mboxq);
/* FCF scan failed, clear FCF_DISC_INPROGRESS flag */
/* FCF scan failed, clear FCF_TS_INPROG flag */
spin_lock_irq(&phba->hbalock);
phba->hba_flag &= ~FCF_DISC_INPROGRESS;
phba->hba_flag &= ~FCF_TS_INPROG;
spin_unlock_irq(&phba->hbalock);
}
return error;
}
/**
* lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
* lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for roundrobin fcf.
* @phba: pointer to lpfc hba data structure.
* @fcf_index: FCF table entry offset.
*
* This routine is invoked to read an FCF record indicated by @fcf_index
* and to use it for FLOGI round robin FCF failover.
* and to use it for FLOGI roundrobin FCF failover.
*
* Return 0 if the mailbox command is submitted sucessfully, none 0
* otherwise.
......@@ -12318,7 +12320,7 @@ lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
* @fcf_index: FCF table entry offset.
*
* This routine is invoked to read an FCF record indicated by @fcf_index to
* determine whether it's eligible for FLOGI round robin failover list.
* determine whether it's eligible for FLOGI roundrobin failover list.
*
* Return 0 if the mailbox command is submitted sucessfully, none 0
* otherwise.
......@@ -12364,7 +12366,7 @@ lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
*
* This routine is to get the next eligible FCF record index in a round
* robin fashion. If the next eligible FCF record index equals to the
* initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
* initial roundrobin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
* shall be returned, otherwise, the next eligible FCF record's index
* shall be returned.
**/
......@@ -12392,28 +12394,10 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
return LPFC_FCOE_FCF_NEXT_NONE;
}
/* Check roundrobin failover index bmask stop condition */
if (next_fcf_index == phba->fcf.fcf_rr_init_indx) {
if (!(phba->fcf.fcf_flag & FCF_REDISC_RRU)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
"2847 Round robin failover FCF index "
"search hit stop condition:x%x\n",
next_fcf_index);
return LPFC_FCOE_FCF_NEXT_NONE;
}
/* The roundrobin failover index bmask updated, start over */
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2848 Round robin failover FCF index bmask "
"updated, start over\n");
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_REDISC_RRU;
spin_unlock_irq(&phba->hbalock);
return phba->fcf.fcf_rr_init_indx;
}
"2845 Get next roundrobin failover FCF (x%x)\n",
next_fcf_index);
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2845 Get next round robin failover "
"FCF index x%x\n", next_fcf_index);
return next_fcf_index;
}
......@@ -12422,7 +12406,7 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
* @phba: pointer to lpfc hba data structure.
*
* This routine sets the FCF record index in to the eligible bmask for
* round robin failover search. It checks to make sure that the index
* roundrobin failover search. It checks to make sure that the index
* does not go beyond the range of the driver allocated bmask dimension
* before setting the bit.
*
......@@ -12434,22 +12418,16 @@ lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
{
if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2610 HBA FCF index reached driver's "
"book keeping dimension: fcf_index:%d, "
"driver_bmask_max:%d\n",
"2610 FCF (x%x) reached driver's book "
"keeping dimension:x%x\n",
fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
return -EINVAL;
}
/* Set the eligible FCF record index bmask */
set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
/* Set the roundrobin index bmask updated */
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag |= FCF_REDISC_RRU;
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2790 Set FCF index x%x to round robin failover "
"2790 Set FCF (x%x) to roundrobin FCF failover "
"bmask\n", fcf_index);
return 0;
......@@ -12460,7 +12438,7 @@ lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
* @phba: pointer to lpfc hba data structure.
*
* This routine clears the FCF record index from the eligible bmask for
* round robin failover search. It checks to make sure that the index
* roundrobin failover search. It checks to make sure that the index
* does not go beyond the range of the driver allocated bmask dimension
* before clearing the bit.
**/
......@@ -12469,9 +12447,8 @@ lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
{
if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2762 HBA FCF index goes beyond driver's "
"book keeping dimension: fcf_index:%d, "
"driver_bmask_max:%d\n",
"2762 FCF (x%x) reached driver's book "
"keeping dimension:x%x\n",
fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
return;
}
......@@ -12479,7 +12456,7 @@ lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2791 Clear FCF index x%x from round robin failover "
"2791 Clear FCF (x%x) from roundrobin failover "
"bmask\n", fcf_index);
}
......@@ -12530,8 +12507,7 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
}
} else {
lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
"2775 Start FCF rediscovery quiescent period "
"wait timer before scaning FCF table\n");
"2775 Start FCF rediscover quiescent timer\n");
/*
* Start FCF rediscovery wait timer for pending FCF
* before rescan FCF record table.
......
......@@ -23,6 +23,9 @@
#define LPFC_GET_QE_REL_INT 32
#define LPFC_RPI_LOW_WATER_MARK 10
#define LPFC_UNREG_FCF 1
#define LPFC_SKIP_UNREG_FCF 0
/* Amount of time in seconds for waiting FCF rediscovery to complete */
#define LPFC_FCF_REDISCOVER_WAIT_TMO 2000 /* msec */
......@@ -163,9 +166,8 @@ struct lpfc_fcf {
#define FCF_REDISC_PEND 0x80 /* FCF rediscovery pending */
#define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
#define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
#define FCF_REDISC_RRU 0x400 /* Roundrobin bitmap updated */
#define FCF_REDISC_PROG (FCF_REDISC_PEND | FCF_REDISC_EVT)
uint32_t addr_mode;
uint16_t fcf_rr_init_indx;
uint32_t eligible_fcf_cnt;
struct lpfc_fcf_rec current_rec;
struct lpfc_fcf_rec failover_rec;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment