Daniel Wagner dbfc3d
From: James Smart <jsmart2021@gmail.com>
Daniel Wagner dbfc3d
Date: Fri, 3 Dec 2021 16:26:42 -0800
Daniel Wagner dbfc3d
Subject: scsi: lpfc: Cap CMF read bytes to MBPI
Takashi Iwai cb7f69
Patch-mainline: v5.17-rc1
Daniel Wagner dbfc3d
Git-commit: 05116ef9c4b444f7fdbb56f9e13c2ec941726639
Daniel Wagner dbfc3d
References: bsc#1194266
Daniel Wagner dbfc3d
Daniel Wagner dbfc3d
Ensure read bytes data does not go over MBPI for CMF timer intervals that
Daniel Wagner dbfc3d
are purposely shortened.
Daniel Wagner dbfc3d
Daniel Wagner dbfc3d
Link: https://lore.kernel.org/r/20211204002644.116455-8-jsmart2021@gmail.com
Daniel Wagner dbfc3d
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Daniel Wagner dbfc3d
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Daniel Wagner dbfc3d
Signed-off-by: James Smart <jsmart2021@gmail.com>
Daniel Wagner dbfc3d
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Daniel Wagner dbfc3d
Acked-by: Daniel Wagner <dwagner@suse.de>
Daniel Wagner dbfc3d
---
Daniel Wagner dbfc3d
 drivers/scsi/lpfc/lpfc.h      |    2 +-
Daniel Wagner dbfc3d
 drivers/scsi/lpfc/lpfc_init.c |   11 ++++++++++-
Daniel Wagner dbfc3d
 2 files changed, 11 insertions(+), 2 deletions(-)
Daniel Wagner dbfc3d
Daniel Wagner dbfc3d
--- a/drivers/scsi/lpfc/lpfc.h
Daniel Wagner dbfc3d
+++ b/drivers/scsi/lpfc/lpfc.h
Daniel Wagner dbfc3d
@@ -1027,7 +1027,7 @@ struct lpfc_hba {
Daniel Wagner dbfc3d
 					 */
Daniel Wagner dbfc3d
 #define HBA_PCI_ERR		0x80000 /* The PCI slot is offline */
Daniel Wagner dbfc3d
 #define HBA_FLOGI_ISSUED	0x100000 /* FLOGI was issued */
Daniel Wagner dbfc3d
-#define HBA_CGN_RSVD1		0x200000 /* Reserved CGN flag */
Daniel Wagner dbfc3d
+#define HBA_SHORT_CMF		0x200000 /* shorter CMF timer routine */
Daniel Wagner dbfc3d
 #define HBA_CGN_DAY_WRAP	0x400000 /* HBA Congestion info day wraps */
Daniel Wagner dbfc3d
 #define HBA_DEFER_FLOGI		0x800000 /* Defer FLOGI till read_sparm cmpl */
Daniel Wagner dbfc3d
 #define HBA_SETUP		0x1000000 /* Signifies HBA setup is completed */
Daniel Wagner dbfc3d
--- a/drivers/scsi/lpfc/lpfc_init.c
Daniel Wagner dbfc3d
+++ b/drivers/scsi/lpfc/lpfc_init.c
Daniel Wagner dbfc3d
@@ -6003,8 +6003,13 @@ lpfc_cmf_timer(struct hrtimer *timer)
Daniel Wagner dbfc3d
 		if (ms && ms < LPFC_CMF_INTERVAL) {
Daniel Wagner dbfc3d
 			cnt = div_u64(total, ms); /* bytes per ms */
Daniel Wagner dbfc3d
 			cnt *= LPFC_CMF_INTERVAL; /* what total should be */
Daniel Wagner dbfc3d
-			if (cnt > mbpi)
Daniel Wagner dbfc3d
+
Daniel Wagner dbfc3d
+			/* If the timeout is scheduled to be shorter,
Daniel Wagner dbfc3d
+			 * this value may skew the data, so cap it at mbpi.
Daniel Wagner dbfc3d
+			 */
Daniel Wagner dbfc3d
+			if ((phba->hba_flag & HBA_SHORT_CMF) && cnt > mbpi)
Daniel Wagner dbfc3d
 				cnt = mbpi;
Daniel Wagner dbfc3d
+
Daniel Wagner dbfc3d
 			extra = cnt - total;
Daniel Wagner dbfc3d
 		}
Daniel Wagner dbfc3d
 		lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra);
Daniel Wagner dbfc3d
@@ -6087,6 +6092,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
Daniel Wagner dbfc3d
 	/* Each minute save Fabric and Driver congestion information */
Daniel Wagner dbfc3d
 	lpfc_cgn_save_evt_cnt(phba);
Daniel Wagner dbfc3d
 
Daniel Wagner dbfc3d
+	phba->hba_flag &= ~HBA_SHORT_CMF;
Daniel Wagner dbfc3d
+
Daniel Wagner dbfc3d
 	/* Since we need to call lpfc_cgn_save_evt_cnt every minute, on the
Daniel Wagner dbfc3d
 	 * minute, adjust our next timer interval, if needed, to ensure a
Daniel Wagner dbfc3d
 	 * 1 minute granularity when we get the next timer interrupt.
Daniel Wagner dbfc3d
@@ -6097,6 +6104,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
Daniel Wagner dbfc3d
 						  jiffies);
Daniel Wagner dbfc3d
 		if (timer_interval <= 0)
Daniel Wagner dbfc3d
 			timer_interval = LPFC_CMF_INTERVAL;
Daniel Wagner dbfc3d
+		else
Daniel Wagner dbfc3d
+			phba->hba_flag |= HBA_SHORT_CMF;
Daniel Wagner dbfc3d
 
Daniel Wagner dbfc3d
 		/* If we adjust timer_interval, max_bytes_per_interval
Daniel Wagner dbfc3d
 		 * needs to be adjusted as well.