mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
scsi: lpfc: Fix incorrect txcmplq_cnt during cleanup in lpfc_sli_abort_ring()
When a port is offline in lpfc_sli_abort_ring, the phba->txcmplq is cleared but the phba->txcmplq_cnt is not reset to zero. This can sometimes result in a phba->txcmplq_cnt that never reaches zero, which hangs the cleanup process. Update lpfc_sli_abort_ring so that txcmplq_cnt is reset to zero and also ensure that the LPFC_IO_ON_TXCMPLQ flag is properly cleared. Signed-off-by: Justin Tee <justin.tee@broadcom.com> Link: https://patch.msgid.link/20260212213008.149873-9-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
6b0bcf4b64
commit
2da10bcaa5
|
|
@ -4572,59 +4572,41 @@ void
|
|||
lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
||||
{
|
||||
LIST_HEAD(tx_completions);
|
||||
LIST_HEAD(txcmplq_completions);
|
||||
spinlock_t *plock; /* for transmit queue access */
|
||||
struct lpfc_iocbq *iocb, *next_iocb;
|
||||
int offline;
|
||||
|
||||
if (pring->ringno == LPFC_ELS_RING) {
|
||||
if (phba->sli_rev >= LPFC_SLI_REV4)
|
||||
plock = &pring->ring_lock;
|
||||
else
|
||||
plock = &phba->hbalock;
|
||||
|
||||
if (pring->ringno == LPFC_ELS_RING)
|
||||
lpfc_fabric_abort_hba(phba);
|
||||
}
|
||||
|
||||
offline = pci_channel_offline(phba->pcidev);
|
||||
|
||||
/* Error everything on txq and txcmplq
|
||||
* First do the txq.
|
||||
*/
|
||||
if (phba->sli_rev >= LPFC_SLI_REV4) {
|
||||
spin_lock_irq(&pring->ring_lock);
|
||||
list_splice_init(&pring->txq, &tx_completions);
|
||||
pring->txq_cnt = 0;
|
||||
|
||||
if (offline) {
|
||||
list_splice_init(&pring->txcmplq,
|
||||
&txcmplq_completions);
|
||||
} else {
|
||||
/* Next issue ABTS for everything on the txcmplq */
|
||||
list_for_each_entry_safe(iocb, next_iocb,
|
||||
&pring->txcmplq, list)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring,
|
||||
iocb, NULL);
|
||||
}
|
||||
spin_unlock_irq(&pring->ring_lock);
|
||||
} else {
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
list_splice_init(&pring->txq, &tx_completions);
|
||||
pring->txq_cnt = 0;
|
||||
|
||||
if (offline) {
|
||||
list_splice_init(&pring->txcmplq, &txcmplq_completions);
|
||||
} else {
|
||||
/* Next issue ABTS for everything on the txcmplq */
|
||||
list_for_each_entry_safe(iocb, next_iocb,
|
||||
&pring->txcmplq, list)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring,
|
||||
iocb, NULL);
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
/* Cancel everything on txq */
|
||||
spin_lock_irq(plock);
|
||||
list_splice_init(&pring->txq, &tx_completions);
|
||||
pring->txq_cnt = 0;
|
||||
|
||||
if (offline) {
|
||||
/* Cancel all the IOCBs from the completions list */
|
||||
lpfc_sli_cancel_iocbs(phba, &txcmplq_completions,
|
||||
IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
|
||||
/* Cancel everything on txcmplq */
|
||||
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
|
||||
iocb->cmd_flag &= ~LPFC_IO_ON_TXCMPLQ;
|
||||
list_splice_init(&pring->txcmplq, &tx_completions);
|
||||
pring->txcmplq_cnt = 0;
|
||||
} else {
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
/* Issue ABTS for everything on the txcmplq */
|
||||
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
|
||||
}
|
||||
spin_unlock_irq(plock);
|
||||
|
||||
if (!offline)
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
/* Cancel all the IOCBs from the completions list */
|
||||
lpfc_sli_cancel_iocbs(phba, &tx_completions, IOSTAT_LOCAL_REJECT,
|
||||
IOERR_SLI_ABORTED);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user