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