|
@@ -1008,6 +1008,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
|
|
else
|
|
|
sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_lxritag);
|
|
|
|
|
|
+ /*
|
|
|
+ ** This should have been removed from the txcmplq before calling
|
|
|
+ ** iocbq_release. The normal completion
|
|
|
+ ** path should have already done the list_del_init.
|
|
|
+ */
|
|
|
+ if (unlikely(!list_empty(&iocbq->list))) {
|
|
|
+ if (iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)
|
|
|
+ iocbq->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
|
|
|
+ list_del_init(&iocbq->list);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
if (sglq) {
|
|
|
if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
|
|
|
(sglq->state != SGL_XRI_ABORTED)) {
|
|
@@ -1024,7 +1036,7 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
|
|
&phba->sli4_hba.lpfc_sgl_list);
|
|
|
|
|
|
/* Check if TXQ queue needs to be serviced */
|
|
|
- if (pring->txq_cnt)
|
|
|
+ if (!list_empty(&pring->txq))
|
|
|
lpfc_worker_wake_up(phba);
|
|
|
}
|
|
|
}
|
|
@@ -1055,6 +1067,14 @@ __lpfc_sli_release_iocbq_s3(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
|
|
{
|
|
|
size_t start_clean = offsetof(struct lpfc_iocbq, iocb);
|
|
|
|
|
|
+ /*
|
|
|
+ ** This should have been removed from the txcmplq before calling
|
|
|
+ ** iocbq_release. The normal completion
|
|
|
+ ** path should have already done the list_del_init.
|
|
|
+ */
|
|
|
+ if (unlikely(!list_empty(&iocbq->list)))
|
|
|
+ list_del_init(&iocbq->list);
|
|
|
+
|
|
|
/*
|
|
|
* Clean all volatile data fields, preserve iotag and node struct.
|
|
|
*/
|
|
@@ -1121,7 +1141,6 @@ lpfc_sli_cancel_iocbs(struct lpfc_hba *phba, struct list_head *iocblist,
|
|
|
|
|
|
while (!list_empty(iocblist)) {
|
|
|
list_remove_head(iocblist, piocb, struct lpfc_iocbq, list);
|
|
|
-
|
|
|
if (!piocb->iocb_cmpl)
|
|
|
lpfc_sli_release_iocbq(phba, piocb);
|
|
|
else {
|
|
@@ -1309,9 +1328,6 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|
|
{
|
|
|
list_add_tail(&piocb->list, &pring->txcmplq);
|
|
|
piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ;
|
|
|
- pring->txcmplq_cnt++;
|
|
|
- if (pring->txcmplq_cnt > pring->txcmplq_max)
|
|
|
- pring->txcmplq_max = pring->txcmplq_cnt;
|
|
|
|
|
|
if ((unlikely(pring->ringno == LPFC_ELS_RING)) &&
|
|
|
(piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
|
|
@@ -1343,8 +1359,6 @@ lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
|
|
struct lpfc_iocbq *cmd_iocb;
|
|
|
|
|
|
list_remove_head((&pring->txq), cmd_iocb, struct lpfc_iocbq, list);
|
|
|
- if (cmd_iocb != NULL)
|
|
|
- pring->txq_cnt--;
|
|
|
return cmd_iocb;
|
|
|
}
|
|
|
|
|
@@ -1613,8 +1627,9 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
|
|
* (c) link attention events can be processed (fcp ring only)
|
|
|
* (d) IOCB processing is not blocked by the outstanding mbox command.
|
|
|
*/
|
|
|
- if (pring->txq_cnt &&
|
|
|
- lpfc_is_link_up(phba) &&
|
|
|
+
|
|
|
+ if (lpfc_is_link_up(phba) &&
|
|
|
+ (!list_empty(&pring->txq)) &&
|
|
|
(pring->ringno != phba->sli.fcp_ring ||
|
|
|
phba->sli.sli_flag & LPFC_PROCESS_LA)) {
|
|
|
|
|
@@ -2611,7 +2626,6 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
|
|
|
cmd_iocb = phba->sli.iocbq_lookup[iotag];
|
|
|
list_del_init(&cmd_iocb->list);
|
|
|
if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) {
|
|
|
- pring->txcmplq_cnt--;
|
|
|
cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
|
|
|
}
|
|
|
return cmd_iocb;
|
|
@@ -2649,7 +2663,6 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
|
|
|
/* remove from txcmpl queue list */
|
|
|
list_del_init(&cmd_iocb->list);
|
|
|
cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
|
|
|
- pring->txcmplq_cnt--;
|
|
|
return cmd_iocb;
|
|
|
}
|
|
|
}
|
|
@@ -3498,7 +3511,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
|
|
*/
|
|
|
spin_lock_irq(&phba->hbalock);
|
|
|
list_splice_init(&pring->txq, &completions);
|
|
|
- pring->txq_cnt = 0;
|
|
|
|
|
|
/* Next issue ABTS for everything on the txcmplq */
|
|
|
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
|
|
@@ -3535,11 +3547,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
|
|
|
spin_lock_irq(&phba->hbalock);
|
|
|
/* Retrieve everything on txq */
|
|
|
list_splice_init(&pring->txq, &txq);
|
|
|
- pring->txq_cnt = 0;
|
|
|
|
|
|
/* Retrieve everything on the txcmplq */
|
|
|
list_splice_init(&pring->txcmplq, &txcmplq);
|
|
|
- pring->txcmplq_cnt = 0;
|
|
|
|
|
|
/* Indicate the I/O queues are flushed */
|
|
|
phba->hba_flag |= HBA_FCP_IOQ_FLUSH;
|
|
@@ -7614,7 +7624,6 @@ __lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|
|
{
|
|
|
/* Insert the caller's iocb in the txq tail for later processing. */
|
|
|
list_add_tail(&piocb->list, &pring->txq);
|
|
|
- pring->txq_cnt++;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -8386,7 +8395,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
|
|
|
piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
|
|
|
sglq = NULL;
|
|
|
else {
|
|
|
- if (pring->txq_cnt) {
|
|
|
+ if (!list_empty(&pring->txq)) {
|
|
|
if (!(flag & SLI_IOCB_RET_IOCB)) {
|
|
|
__lpfc_sli_ringtx_put(phba,
|
|
|
pring, piocb);
|
|
@@ -9054,7 +9063,6 @@ lpfc_sli_host_down(struct lpfc_vport *vport)
|
|
|
if (iocb->vport != vport)
|
|
|
continue;
|
|
|
list_move_tail(&iocb->list, &completions);
|
|
|
- pring->txq_cnt--;
|
|
|
}
|
|
|
|
|
|
/* Next issue ABTS for everything on the txcmplq */
|
|
@@ -9123,8 +9131,6 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
|
|
|
* given to the FW yet.
|
|
|
*/
|
|
|
list_splice_init(&pring->txq, &completions);
|
|
|
- pring->txq_cnt = 0;
|
|
|
-
|
|
|
}
|
|
|
spin_unlock_irqrestore(&phba->hbalock, flags);
|
|
|
|
|
@@ -9965,6 +9971,9 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
|
|
|
long timeleft, timeout_req = 0;
|
|
|
int retval = IOCB_SUCCESS;
|
|
|
uint32_t creg_val;
|
|
|
+ struct lpfc_iocbq *iocb;
|
|
|
+ int txq_cnt = 0;
|
|
|
+ int txcmplq_cnt = 0;
|
|
|
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
|
|
|
/*
|
|
|
* If the caller has provided a response iocbq buffer, then context2
|
|
@@ -10012,9 +10021,17 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
|
|
|
retval = IOCB_TIMEDOUT;
|
|
|
}
|
|
|
} else if (retval == IOCB_BUSY) {
|
|
|
- lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
|
- "2818 Max IOCBs %d txq cnt %d txcmplq cnt %d\n",
|
|
|
- phba->iocb_cnt, pring->txq_cnt, pring->txcmplq_cnt);
|
|
|
+ if (phba->cfg_log_verbose & LOG_SLI) {
|
|
|
+ list_for_each_entry(iocb, &pring->txq, list) {
|
|
|
+ txq_cnt++;
|
|
|
+ }
|
|
|
+ list_for_each_entry(iocb, &pring->txcmplq, list) {
|
|
|
+ txcmplq_cnt++;
|
|
|
+ }
|
|
|
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
|
+ "2818 Max IOCBs %d txq cnt %d txcmplq cnt %d\n",
|
|
|
+ phba->iocb_cnt, txq_cnt, txcmplq_cnt);
|
|
|
+ }
|
|
|
return retval;
|
|
|
} else {
|
|
|
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
@@ -11297,16 +11314,25 @@ lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|
|
struct lpfc_iocbq *irspiocbq;
|
|
|
unsigned long iflags;
|
|
|
struct lpfc_sli_ring *pring = cq->pring;
|
|
|
+ int txq_cnt = 0;
|
|
|
+ int txcmplq_cnt = 0;
|
|
|
+ int fcp_txcmplq_cnt = 0;
|
|
|
|
|
|
/* Get an irspiocbq for later ELS response processing use */
|
|
|
irspiocbq = lpfc_sli_get_iocbq(phba);
|
|
|
if (!irspiocbq) {
|
|
|
+ if (!list_empty(&pring->txq))
|
|
|
+ txq_cnt++;
|
|
|
+ if (!list_empty(&pring->txcmplq))
|
|
|
+ txcmplq_cnt++;
|
|
|
+ if (!list_empty(&phba->sli.ring[LPFC_FCP_RING].txcmplq))
|
|
|
+ fcp_txcmplq_cnt++;
|
|
|
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
|
|
"0387 NO IOCBQ data: txq_cnt=%d iocb_cnt=%d "
|
|
|
"fcp_txcmplq_cnt=%d, els_txcmplq_cnt=%d\n",
|
|
|
- pring->txq_cnt, phba->iocb_cnt,
|
|
|
- phba->sli.ring[LPFC_FCP_RING].txcmplq_cnt,
|
|
|
- phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt);
|
|
|
+ txq_cnt, phba->iocb_cnt,
|
|
|
+ fcp_txcmplq_cnt,
|
|
|
+ txcmplq_cnt);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -16244,14 +16270,19 @@ lpfc_drain_txq(struct lpfc_hba *phba)
|
|
|
char *fail_msg = NULL;
|
|
|
struct lpfc_sglq *sglq;
|
|
|
union lpfc_wqe wqe;
|
|
|
+ int txq_cnt = 0;
|
|
|
|
|
|
spin_lock_irqsave(&phba->hbalock, iflags);
|
|
|
- if (pring->txq_cnt > pring->txq_max)
|
|
|
- pring->txq_max = pring->txq_cnt;
|
|
|
+ list_for_each_entry(piocbq, &pring->txq, list) {
|
|
|
+ txq_cnt++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (txq_cnt > pring->txq_max)
|
|
|
+ pring->txq_max = txq_cnt;
|
|
|
|
|
|
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
|
|
|
|
|
- while (pring->txq_cnt) {
|
|
|
+ while (!list_empty(&pring->txq)) {
|
|
|
spin_lock_irqsave(&phba->hbalock, iflags);
|
|
|
|
|
|
piocbq = lpfc_sli_ringtx_get(phba, pring);
|
|
@@ -16259,7 +16290,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
|
|
|
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
|
|
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
|
|
"2823 txq empty and txq_cnt is %d\n ",
|
|
|
- pring->txq_cnt);
|
|
|
+ txq_cnt);
|
|
|
break;
|
|
|
}
|
|
|
sglq = __lpfc_sli_get_sglq(phba, piocbq);
|
|
@@ -16268,6 +16299,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
|
|
|
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
|
|
break;
|
|
|
}
|
|
|
+ txq_cnt--;
|
|
|
|
|
|
/* The xri and iocb resources secured,
|
|
|
* attempt to issue request
|
|
@@ -16299,5 +16331,5 @@ lpfc_drain_txq(struct lpfc_hba *phba)
|
|
|
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
|
|
IOERR_SLI_ABORTED);
|
|
|
|
|
|
- return pring->txq_cnt;
|
|
|
+ return txq_cnt;
|
|
|
}
|