Merge patch series "Update lpfc to revision 14.4.0.4"

Justin Tee <justintee8345@gmail.com> says:

Update lpfc to revision 14.4.0.4

This patch set contains diagnostic logging improvements, a minor clean
up when submitting abort requests, a bug fix related to reset and
errata paths, and modifications to FLOGI and PRLO ELS command
handling.

The patches were cut against Martin's 6.11/scsi-queue tree.

Link: https://lore.kernel.org/r/20240726231512.92867-1-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Martin K. Petersen 2024-08-02 21:48:54 -04:00
commit 52448d5fa3
8 changed files with 112 additions and 46 deletions

View File

@ -306,6 +306,14 @@ struct lpfc_stats {
struct lpfc_hba;
/* Data structure to keep withheld FLOGI_ACC information */
struct lpfc_defer_flogi_acc {
bool flag;
u16 rx_id;
u16 ox_id;
struct lpfc_nodelist *ndlp;
};
#define LPFC_VMID_TIMER 300 /* timer interval in seconds */
@ -1430,9 +1438,7 @@ struct lpfc_hba {
uint16_t vlan_id;
struct list_head fcf_conn_rec_list;
bool defer_flogi_acc_flag;
uint16_t defer_flogi_acc_rx_id;
uint16_t defer_flogi_acc_ox_id;
struct lpfc_defer_flogi_acc defer_flogi_acc;
spinlock_t ct_ev_lock; /* synchronize access to ct_ev_waiters */
struct list_head ct_ev_waiters;

View File

@ -1099,8 +1099,10 @@ stop_rr_fcf_flogi:
sp->cmn.priority_tagging, kref_read(&ndlp->kref));
/* reinitialize the VMID datastructure before returning */
if (lpfc_is_vmid_enabled(phba))
if (lpfc_is_vmid_enabled(phba)) {
lpfc_reinit_vmid(vport);
vport->vmid_flag = 0;
}
if (sp->cmn.priority_tagging)
vport->phba->pport->vmid_flag |= (LPFC_VMID_ISSUE_QFPA |
LPFC_VMID_TYPE_PRIO);
@ -1390,7 +1392,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
phba->link_flag &= ~LS_EXTERNAL_LOOPBACK;
/* Check for a deferred FLOGI ACC condition */
if (phba->defer_flogi_acc_flag) {
if (phba->defer_flogi_acc.flag) {
/* lookup ndlp for received FLOGI */
ndlp = lpfc_findnode_did(vport, 0);
if (!ndlp)
@ -1404,34 +1406,38 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (phba->sli_rev == LPFC_SLI_REV4) {
bf_set(wqe_ctxt_tag,
&defer_flogi_acc.wqe.xmit_els_rsp.wqe_com,
phba->defer_flogi_acc_rx_id);
phba->defer_flogi_acc.rx_id);
bf_set(wqe_rcvoxid,
&defer_flogi_acc.wqe.xmit_els_rsp.wqe_com,
phba->defer_flogi_acc_ox_id);
phba->defer_flogi_acc.ox_id);
} else {
icmd = &defer_flogi_acc.iocb;
icmd->ulpContext = phba->defer_flogi_acc_rx_id;
icmd->ulpContext = phba->defer_flogi_acc.rx_id;
icmd->unsli3.rcvsli3.ox_id =
phba->defer_flogi_acc_ox_id;
phba->defer_flogi_acc.ox_id;
}
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
" ox_id: x%x, hba_flag x%lx\n",
phba->defer_flogi_acc_rx_id,
phba->defer_flogi_acc_ox_id, phba->hba_flag);
phba->defer_flogi_acc.rx_id,
phba->defer_flogi_acc.ox_id, phba->hba_flag);
/* Send deferred FLOGI ACC */
lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, &defer_flogi_acc,
ndlp, NULL);
phba->defer_flogi_acc_flag = false;
vport->fc_myDID = did;
phba->defer_flogi_acc.flag = false;
/* Decrement ndlp reference count to indicate the node can be
* released when other references are removed.
/* Decrement the held ndlp that was incremented when the
* deferred flogi acc flag was set.
*/
lpfc_nlp_put(ndlp);
if (phba->defer_flogi_acc.ndlp) {
lpfc_nlp_put(phba->defer_flogi_acc.ndlp);
phba->defer_flogi_acc.ndlp = NULL;
}
vport->fc_myDID = did;
}
return 0;
@ -5240,9 +5246,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* ACC to LOGO completes to NPort <nlp_DID> */
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"0109 ACC to LOGO completes to NPort x%x refcnt %d "
"Data: x%x x%x x%x\n",
ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp->nlp_flag,
ndlp->nlp_state, ndlp->nlp_rpi);
"last els x%x Data: x%x x%x x%x\n",
ndlp->nlp_DID, kref_read(&ndlp->kref),
ndlp->nlp_last_elscmd, ndlp->nlp_flag, ndlp->nlp_state,
ndlp->nlp_rpi);
/* This clause allows the LOGO ACC to complete and free resources
* for the Fabric Domain Controller. It does deliberately skip
@ -5254,18 +5261,22 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out;
if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
/* If PLOGI is being retried, PLOGI completion will cleanup the
* node. The NLP_NPR_2B_DISC flag needs to be retained to make
* progress on nodes discovered from last RSCN.
*/
if ((ndlp->nlp_flag & NLP_DELAY_TMO) &&
(ndlp->nlp_last_elscmd == ELS_CMD_PLOGI))
goto out;
if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
lpfc_unreg_rpi(vport, ndlp);
/* If came from PRLO, then PRLO_ACC is done.
* Start rediscovery now.
*/
if (ndlp->nlp_last_elscmd == ELS_CMD_PRLO) {
spin_lock_irq(&ndlp->lock);
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
spin_unlock_irq(&ndlp->lock);
ndlp->nlp_prev_state = ndlp->nlp_state;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
}
}
out:
/*
* The driver received a LOGO from the rport and has ACK'd it.
@ -8454,9 +8465,9 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
/* Defer ACC response until AFTER we issue a FLOGI */
if (!test_bit(HBA_FLOGI_ISSUED, &phba->hba_flag)) {
phba->defer_flogi_acc_rx_id = bf_get(wqe_ctxt_tag,
phba->defer_flogi_acc.rx_id = bf_get(wqe_ctxt_tag,
&wqe->xmit_els_rsp.wqe_com);
phba->defer_flogi_acc_ox_id = bf_get(wqe_rcvoxid,
phba->defer_flogi_acc.ox_id = bf_get(wqe_rcvoxid,
&wqe->xmit_els_rsp.wqe_com);
vport->fc_myDID = did;
@ -8464,11 +8475,17 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"3344 Deferring FLOGI ACC: rx_id: x%x,"
" ox_id: x%x, hba_flag x%lx\n",
phba->defer_flogi_acc_rx_id,
phba->defer_flogi_acc_ox_id, phba->hba_flag);
phba->defer_flogi_acc.rx_id,
phba->defer_flogi_acc.ox_id, phba->hba_flag);
phba->defer_flogi_acc_flag = true;
phba->defer_flogi_acc.flag = true;
/* This nlp_get is paired with nlp_puts that reset the
* defer_flogi_acc.flag back to false. We need to retain
* a kref on the ndlp until the deferred FLOGI ACC is
* processed or cancelled.
*/
phba->defer_flogi_acc.ndlp = lpfc_nlp_get(ndlp);
return 0;
}
@ -10504,7 +10521,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
/* retain node if our response is deferred */
if (phba->defer_flogi_acc_flag)
if (phba->defer_flogi_acc.flag)
break;
if (newnode)
lpfc_disc_state_machine(vport, ndlp, NULL,
@ -10742,7 +10759,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
rjt_exp = LSEXP_NOTHING_MORE;
/* Unknown ELS command <elsCmd> received from NPORT <did> */
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0115 Unknown ELS command x%x "
"received from NPORT x%x\n", cmd, did);
if (newnode)

View File

@ -175,7 +175,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
ndlp->nlp_state, ndlp->fc4_xpt_flags);
/* Don't schedule a worker thread event if the vport is going down. */
if (test_bit(FC_UNLOADING, &vport->load_flag)) {
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
!test_bit(HBA_SETUP, &phba->hba_flag)) {
spin_lock_irqsave(&ndlp->lock, iflags);
ndlp->rport = NULL;
@ -1254,7 +1255,14 @@ lpfc_linkdown(struct lpfc_hba *phba)
lpfc_scsi_dev_block(phba);
offline = pci_channel_offline(phba->pcidev);
phba->defer_flogi_acc_flag = false;
/* Decrement the held ndlp if there is a deferred flogi acc */
if (phba->defer_flogi_acc.flag) {
if (phba->defer_flogi_acc.ndlp) {
lpfc_nlp_put(phba->defer_flogi_acc.ndlp);
phba->defer_flogi_acc.ndlp = NULL;
}
}
phba->defer_flogi_acc.flag = false;
/* Clear external loopback plug detected flag */
phba->link_flag &= ~LS_EXTERNAL_LOOPBACK;
@ -1376,7 +1384,7 @@ lpfc_linkup_port(struct lpfc_vport *vport)
(vport != phba->pport))
return;
if (phba->defer_flogi_acc_flag) {
if (phba->defer_flogi_acc.flag) {
clear_bit(FC_ABORT_DISCOVERY, &vport->fc_flag);
clear_bit(FC_RSCN_MODE, &vport->fc_flag);
clear_bit(FC_NLP_MORE, &vport->fc_flag);

View File

@ -2652,8 +2652,26 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* flush the target */
lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);
/* Treat like rcv logo */
lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
/* Send PRLO_ACC */
spin_lock_irq(&ndlp->lock);
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(&ndlp->lock);
lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
/* Save ELS_CMD_PRLO as the last elscmd and then set to NPR.
* lpfc_cmpl_els_logo_acc is expected to restart discovery.
*/
ndlp->nlp_last_elscmd = ELS_CMD_PRLO;
ndlp->nlp_prev_state = ndlp->nlp_state;
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_ELS | LOG_DISCOVERY,
"3422 DID x%06x nflag x%x lastels x%x ref cnt %u\n",
ndlp->nlp_DID, ndlp->nlp_flag,
ndlp->nlp_last_elscmd,
kref_read(&ndlp->kref));
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
return ndlp->nlp_state;
}

View File

@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
iocb = &lpfc_cmd->cur_iocbq;
if (phba->sli_rev == LPFC_SLI_REV4) {
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
if (!pring_s4) {
/* if the io_wq & pring are gone, the port was reset. */
if (!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq ||
!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring) {
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"2877 SCSI Layer I/O Abort Request "
"IO CMPL Status x%x ID %d LUN %llu "
"HBA_SETUP %d\n", FAILED,
cmnd->device->id,
(u64)cmnd->device->lun,
test_bit(HBA_SETUP, &phba->hba_flag));
ret = FAILED;
goto out_unlock_hba;
}
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
spin_lock(&pring_s4->ring_lock);
}
/* the command is in process of being cancelled */

View File

@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
/* Look on all the FCP Rings for the iotag */
if (phba->sli_rev >= LPFC_SLI_REV4) {
for (i = 0; i < phba->cfg_hdw_queue; i++) {
if (!phba->sli4_hba.hdwq ||
!phba->sli4_hba.hdwq[i].io_wq) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"7777 hdwq's deleted %lx "
"%lx %x %x\n",
phba->pport->load_flag,
phba->hba_flag,
phba->link_state,
phba->sli.sli_flag);
return;
}
pring = phba->sli4_hba.hdwq[i].io_wq->pring;
spin_lock_irq(&pring->ring_lock);
@ -12473,8 +12484,6 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
cmdiocb->iocb.ulpClass,
LPFC_WQE_CQ_ID_DEFAULT, ia, false);
abtsiocbp->vport = vport;
/* ABTS WQE must go to the same WQ as the WQE to be aborted */
abtsiocbp->hba_wqidx = cmdiocb->hba_wqidx;
if (cmdiocb->cmd_flag & LPFC_IO_FCP)

View File

@ -20,7 +20,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "14.4.0.3"
#define LPFC_DRIVER_VERSION "14.4.0.4"
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */

View File

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term *
* Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
* Broadcom refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@ -321,6 +321,5 @@ lpfc_reinit_vmid(struct lpfc_vport *vport)
if (!hash_empty(vport->hash_table))
hash_for_each_safe(vport->hash_table, bucket, tmp, cur, hnode)
hash_del(&cur->hnode);
vport->vmid_flag = 0;
write_unlock(&vport->vmid_lock);
}