Skip to content

Commit eb03836

Browse files
Justin Teemartinkpetersen
authored andcommitted
scsi: lpfc: Add cleanup of nvmels_wq after HBA reset
An HBA reset request that is executed when there are outstanding NVME-LS commands can cause delays for the reset process to complete. Fix by introducing a new routine called lpfc_nvmels_flush_cmd() that walks the phba->nvmels_wq list and cancels outstanding submitted NVME-LS requests speeding up the HBA reset process. Signed-off-by: Justin Tee <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 98f8d35 commit eb03836

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

drivers/scsi/lpfc/lpfc_crtn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@ void lpfc_wqe_cmd_template(void);
660660
void lpfc_nvmet_cmd_template(void);
661661
void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
662662
uint32_t stat, uint32_t param);
663+
void lpfc_nvmels_flush_cmd(struct lpfc_hba *phba);
663664
extern int lpfc_enable_nvmet_cnt;
664665
extern unsigned long long lpfc_enable_nvmet[];
665666
extern int lpfc_no_hba_reset_cnt;

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,7 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
19431943

19441944
lpfc_offline_prep(phba, mbx_action);
19451945
lpfc_sli_flush_io_rings(phba);
1946+
lpfc_nvmels_flush_cmd(phba);
19461947
lpfc_offline(phba);
19471948
/* release interrupt for possible resource change */
19481949
lpfc_sli4_disable_intr(phba);

drivers/scsi/lpfc/lpfc_nvme.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
22312231
struct lpfc_hba *phba = vport->phba;
22322232
struct lpfc_sli4_hdw_queue *qp;
22332233
int abts_scsi, abts_nvme;
2234+
u16 nvmels_cnt;
22342235

22352236
/* Host transport has to clean up and confirm requiring an indefinite
22362237
* wait. Print a message if a 10 second wait expires and renew the
@@ -2243,6 +2244,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
22432244
pending = 0;
22442245
abts_scsi = 0;
22452246
abts_nvme = 0;
2247+
nvmels_cnt = 0;
22462248
for (i = 0; i < phba->cfg_hdw_queue; i++) {
22472249
qp = &phba->sli4_hba.hdwq[i];
22482250
if (!vport->localport || !qp || !qp->io_wq)
@@ -2255,6 +2257,11 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
22552257
abts_scsi += qp->abts_scsi_io_bufs;
22562258
abts_nvme += qp->abts_nvme_io_bufs;
22572259
}
2260+
if (phba->sli4_hba.nvmels_wq) {
2261+
pring = phba->sli4_hba.nvmels_wq->pring;
2262+
if (pring)
2263+
nvmels_cnt = pring->txcmplq_cnt;
2264+
}
22582265
if (!vport->localport ||
22592266
test_bit(HBA_PCI_ERR, &vport->phba->bit_flags) ||
22602267
phba->link_state == LPFC_HBA_ERROR ||
@@ -2263,10 +2270,10 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport,
22632270

22642271
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
22652272
"6176 Lport x%px Localport x%px wait "
2266-
"timed out. Pending %d [%d:%d]. "
2273+
"timed out. Pending %d [%d:%d:%d]. "
22672274
"Renewing.\n",
22682275
lport, vport->localport, pending,
2269-
abts_scsi, abts_nvme);
2276+
abts_scsi, abts_nvme, nvmels_cnt);
22702277
continue;
22712278
}
22722279
break;
@@ -2841,3 +2848,43 @@ lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
28412848
(pwqeIn->cmd_cmpl)(phba, pwqeIn, pwqeIn);
28422849
#endif
28432850
}
2851+
2852+
/**
2853+
* lpfc_nvmels_flush_cmd - Clean up outstanding nvmels commands for a port
2854+
* @phba: Pointer to HBA context object.
2855+
*
2856+
**/
2857+
void
2858+
lpfc_nvmels_flush_cmd(struct lpfc_hba *phba)
2859+
{
2860+
#if (IS_ENABLED(CONFIG_NVME_FC))
2861+
LIST_HEAD(cancel_list);
2862+
struct lpfc_sli_ring *pring = NULL;
2863+
struct lpfc_iocbq *piocb, *tmp_iocb;
2864+
unsigned long iflags;
2865+
2866+
if (phba->sli4_hba.nvmels_wq)
2867+
pring = phba->sli4_hba.nvmels_wq->pring;
2868+
2869+
if (unlikely(!pring))
2870+
return;
2871+
2872+
spin_lock_irqsave(&phba->hbalock, iflags);
2873+
spin_lock(&pring->ring_lock);
2874+
list_splice_init(&pring->txq, &cancel_list);
2875+
pring->txq_cnt = 0;
2876+
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
2877+
if (piocb->cmd_flag & LPFC_IO_NVME_LS) {
2878+
list_move_tail(&piocb->list, &cancel_list);
2879+
pring->txcmplq_cnt--;
2880+
piocb->cmd_flag &= ~LPFC_IO_ON_TXCMPLQ;
2881+
}
2882+
}
2883+
spin_unlock(&pring->ring_lock);
2884+
spin_unlock_irqrestore(&phba->hbalock, iflags);
2885+
2886+
if (!list_empty(&cancel_list))
2887+
lpfc_sli_cancel_iocbs(phba, &cancel_list, IOSTAT_LOCAL_REJECT,
2888+
IOERR_SLI_DOWN);
2889+
#endif
2890+
}

0 commit comments

Comments
 (0)