aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2018-05-25 00:08:57 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-28 22:40:32 -0400
commitdc19e3b4a80e0bb1e5f080473fffa0ac8c0694a6 (patch)
tree48d9b5139e2e809b4245f980e09bf0c3537939c5
parent3e1fb1b8abf0c862a7f5d39cb3354a1fd5e9f96a (diff)
scsi: lpfc: Fix MDS diagnostics failure (Rx < Tx)
MDS diagnostics fail because of frame count mismatch. Unavailability of SGL is the trigger for this issue. If ELS SGL is not available to process MDS frame, IOCB is put in FCP txq but not attempted to post afterwards. So, driver stops processing incoming frames as it runs out of IOCB. lpfc_drain_txq attempts to submit IOCBS that are queued in ELS txq but MDS frames are posted to FCP WQ. Attempt to submit IOCBs that are present in FCP txq when MDS loopback is running. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c19
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index cf2cbaa241b9..2fef54fab86d 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -708,8 +708,7 @@ lpfc_work_done(struct lpfc_hba *phba)
708 HA_RXMASK)); 708 HA_RXMASK));
709 } 709 }
710 } 710 }
711 if ((phba->sli_rev == LPFC_SLI_REV4) && 711 if (phba->sli_rev == LPFC_SLI_REV4)
712 (!list_empty(&pring->txq)))
713 lpfc_drain_txq(phba); 712 lpfc_drain_txq(phba);
714 /* 713 /*
715 * Turn on Ring interrupts 714 * Turn on Ring interrupts
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 6b709cd4140b..4b70d53acb72 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -19069,9 +19069,22 @@ lpfc_drain_txq(struct lpfc_hba *phba)
19069 struct lpfc_sglq *sglq; 19069 struct lpfc_sglq *sglq;
19070 union lpfc_wqe128 wqe; 19070 union lpfc_wqe128 wqe;
19071 uint32_t txq_cnt = 0; 19071 uint32_t txq_cnt = 0;
19072 struct lpfc_queue *wq;
19072 19073
19073 pring = lpfc_phba_elsring(phba); 19074 if (phba->link_flag & LS_MDS_LOOPBACK) {
19074 if (unlikely(!pring)) 19075 /* MDS WQE are posted only to first WQ*/
19076 wq = phba->sli4_hba.fcp_wq[0];
19077 if (unlikely(!wq))
19078 return 0;
19079 pring = wq->pring;
19080 } else {
19081 wq = phba->sli4_hba.els_wq;
19082 if (unlikely(!wq))
19083 return 0;
19084 pring = lpfc_phba_elsring(phba);
19085 }
19086
19087 if (unlikely(!pring) || list_empty(&pring->txq))
19075 return 0; 19088 return 0;
19076 19089
19077 spin_lock_irqsave(&pring->ring_lock, iflags); 19090 spin_lock_irqsave(&pring->ring_lock, iflags);
@@ -19112,7 +19125,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
19112 fail_msg = "to convert bpl to sgl"; 19125 fail_msg = "to convert bpl to sgl";
19113 else if (lpfc_sli4_iocb2wqe(phba, piocbq, &wqe)) 19126 else if (lpfc_sli4_iocb2wqe(phba, piocbq, &wqe))
19114 fail_msg = "to convert iocb to wqe"; 19127 fail_msg = "to convert iocb to wqe";
19115 else if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) 19128 else if (lpfc_sli4_wq_put(wq, &wqe))
19116 fail_msg = " - Wq is full"; 19129 fail_msg = " - Wq is full";
19117 else 19130 else
19118 lpfc_sli_ringtxcmpl_put(phba, pring, piocbq); 19131 lpfc_sli_ringtxcmpl_put(phba, pring, piocbq);