linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: James Smart <jsmart2021@gmail.com>
To: linux-scsi@vger.kernel.org
Cc: James Smart <jsmart2021@gmail.com>,
	Dick Kennedy <dick.kennedy@broadcom.com>
Subject: [PATCH 10/16] lpfc: Revise interrupt coalescing for missing scenarios
Date: Fri, 18 Oct 2019 14:18:26 -0700	[thread overview]
Message-ID: <20191018211832.7917-11-jsmart2021@gmail.com> (raw)
In-Reply-To: <20191018211832.7917-1-jsmart2021@gmail.com>

The existing "auto eq delay" mechanism was sometimes skipping over
an eq, not ramping the coalescing down under light load fast enough,
and in other cases never kicked in as cpu sharing by multiple vectors
didn't quite add up right.

Tweak the interrupt mechanism such that:
- Add a flag to the eq to force checking for colaescing values
  when being serviced in the interrupt handler.  The flag will
  be set by any CQ bound to the EQ whenever the number of CQ
  elements process in a single scan meets or exceeds the hardware
  queue notify level. E.g. there's a significant number of
  completions happening.
- In the heartbeat work item that checks coalescing:
 - Replace the structure that was counting the number of EQs
   that interrupted on a single cpu with a new structure that
   looks at the EQ to see whether EQ currently has a coalescing
   value (thus it should be re-evaluate) or was marked by the
   new flag indicating heavy completions.
 - When a cpu, which may be servicing multiple vectors, had
   at least 1 EQ that should be checked, a new coalescing delay
   is calculated based on the number of interrupts that occurred
   on the cpu.
 - The new coalescing value is then applied to the EQs that
   had interrupted on the cpu.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 -
 drivers/scsi/lpfc/lpfc_init.c | 51 ++++++++++++++++++-------------------------
 drivers/scsi/lpfc/lpfc_sli.c  |  3 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  1 +
 4 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 1cd3016f7783..ac86b80230e7 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -210,7 +210,6 @@ struct lpfc_sli_intf {
 #define LPFC_MAX_IMAX          5000000
 #define LPFC_DEF_IMAX          0
 
-#define LPFC_IMAX_THRESHOLD    1000
 #define LPFC_MAX_AUTO_EQ_DELAY 120
 #define LPFC_EQ_DELAY_STEP     15
 #define LPFC_EQD_ISR_TRIGGER   20000
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 8292b66e4b07..316a2c2beb0c 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1235,10 +1235,9 @@ lpfc_hb_eq_delay_work(struct work_struct *work)
 					     struct lpfc_hba, eq_delay_work);
 	struct lpfc_eq_intr_info *eqi, *eqi_new;
 	struct lpfc_queue *eq, *eq_next;
-	unsigned char *eqcnt = NULL;
+	unsigned char *ena_delay = NULL;
 	uint32_t usdelay;
 	int i;
-	bool update = false;
 
 	if (!phba->cfg_auto_imax || phba->pport->load_flag & FC_UNLOADING)
 		return;
@@ -1247,44 +1246,36 @@ lpfc_hb_eq_delay_work(struct work_struct *work)
 	    phba->pport->fc_flag & FC_OFFLINE_MODE)
 		goto requeue;
 
-	eqcnt = kcalloc(num_possible_cpus(), sizeof(unsigned char),
-			GFP_KERNEL);
-	if (!eqcnt)
+	ena_delay = kcalloc(phba->sli4_hba.num_possible_cpu, sizeof(*ena_delay),
+			    GFP_KERNEL);
+	if (!ena_delay)
 		goto requeue;
 
-	if (phba->cfg_irq_chann > 1) {
-		/* Loop thru all IRQ vectors */
-		for (i = 0; i < phba->cfg_irq_chann; i++) {
-			/* Get the EQ corresponding to the IRQ vector */
-			eq = phba->sli4_hba.hba_eq_hdl[i].eq;
-			if (!eq)
-				continue;
-			if (eq->q_mode) {
-				update = true;
-				break;
-			}
-			if (eqcnt[eq->last_cpu] < 2)
-				eqcnt[eq->last_cpu]++;
+	for (i = 0; i < phba->cfg_irq_chann; i++) {
+		/* Get the EQ corresponding to the IRQ vector */
+		eq = phba->sli4_hba.hba_eq_hdl[i].eq;
+		if (!eq)
+			continue;
+		if (eq->q_mode || eq->q_flag & HBA_EQ_DELAY_CHK) {
+			eq->q_flag &= ~HBA_EQ_DELAY_CHK;
+			ena_delay[eq->last_cpu] = 1;
 		}
-	} else
-		update = true;
+	}
 
 	for_each_present_cpu(i) {
 		eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
-		if (!update && eqcnt[i] < 2) {
-			eqi->icnt = 0;
-			continue;
+		if (ena_delay[i]) {
+			usdelay = (eqi->icnt >> 10) * LPFC_EQ_DELAY_STEP;
+			if (usdelay > LPFC_MAX_AUTO_EQ_DELAY)
+				usdelay = LPFC_MAX_AUTO_EQ_DELAY;
+		} else {
+			usdelay = 0;
 		}
 
-		usdelay = (eqi->icnt / LPFC_IMAX_THRESHOLD) *
-			   LPFC_EQ_DELAY_STEP;
-		if (usdelay > LPFC_MAX_AUTO_EQ_DELAY)
-			usdelay = LPFC_MAX_AUTO_EQ_DELAY;
-
 		eqi->icnt = 0;
 
 		list_for_each_entry_safe(eq, eq_next, &eqi->list, cpu_list) {
-			if (eq->last_cpu != i) {
+			if (unlikely(eq->last_cpu != i)) {
 				eqi_new = per_cpu_ptr(phba->sli4_hba.eq_info,
 						      eq->last_cpu);
 				list_move_tail(&eq->cpu_list, &eqi_new->list);
@@ -1296,7 +1287,7 @@ lpfc_hb_eq_delay_work(struct work_struct *work)
 		}
 	}
 
-	kfree(eqcnt);
+	kfree(ena_delay);
 
 requeue:
 	queue_delayed_work(phba->wq, &phba->eq_delay_work,
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index bb0e155eb32c..0e6674bd15c6 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -13640,6 +13640,7 @@ __lpfc_sli4_process_cq(struct lpfc_hba *phba, struct lpfc_queue *cq,
 			phba->sli4_hba.sli4_write_cq_db(phba, cq, consumed,
 						LPFC_QUEUE_NOARM);
 			consumed = 0;
+			cq->assoc_qp->q_flag |= HBA_EQ_DELAY_CHK;
 		}
 
 		if (count == LPFC_NVMET_CQ_NOTIFY)
@@ -14278,7 +14279,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
 	fpeq->last_cpu = raw_smp_processor_id();
 
 	if (icnt > LPFC_EQD_ISR_TRIGGER &&
-	    phba->cfg_irq_chann == 1 &&
+	    fpeq->q_flag & HBA_EQ_DELAY_CHK &&
 	    phba->cfg_auto_imax &&
 	    fpeq->q_mode != LPFC_MAX_AUTO_EQ_DELAY &&
 	    phba->sli.sli_flag & LPFC_SLI_USE_EQDR)
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 0d4882a9e634..c9e068ca0fec 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -199,6 +199,7 @@ struct lpfc_queue {
 	uint8_t q_flag;
 #define HBA_NVMET_WQFULL	0x1 /* We hit WQ Full condition for NVMET */
 #define HBA_NVMET_CQ_NOTIFY	0x1 /* LPFC_NVMET_CQ_NOTIFY CQEs this EQE */
+#define HBA_EQ_DELAY_CHK	0x2 /* EQ is a candidate for coalescing */
 #define LPFC_NVMET_CQ_NOTIFY	4
 	void __iomem *db_regaddr;
 	uint16_t dpp_enable;
-- 
2.13.7


  parent reply	other threads:[~2019-10-18 21:19 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-18 21:18 [PATCH 00/16] lpfc: Update lpfc to revision 12.6.0.0 James Smart
2019-10-18 21:18 ` [PATCH 01/16] lpfc: fix lpfc_nvmet_mrq to be bound by hdw queue count James Smart
2019-10-18 21:18 ` [PATCH 02/16] lpfc: Fix reporting of read-only fw error errors James Smart
2019-10-25  1:03   ` Martin K. Petersen
2019-10-25 16:15     ` James Smart
2019-10-18 21:18 ` [PATCH 03/16] lpfc: Fix lockdep errors in sli_ringtx_put James Smart
2019-10-18 21:18 ` [PATCH 04/16] lpfc: Fix SLI3 hba in loop mode not discovering devices James Smart
2019-10-18 21:18 ` [PATCH 05/16] lpfc: Fix bad ndlp ptr in xri aborted handling James Smart
2019-10-18 21:18 ` [PATCH 06/16] lpfc: Fix hardlockup in lpfc_abort_handler James Smart
2019-10-18 21:18 ` [PATCH 07/16] lpfc: fix coverity error of dereference after null check James Smart
2019-10-18 21:18 ` [PATCH 08/16] lpfc: Slight fast-path Performance optimizations James Smart
2019-10-18 21:18 ` [PATCH 09/16] lpfc: Remove lock contention target write path James Smart
2019-10-18 21:18 ` James Smart [this message]
2019-10-18 21:18 ` [PATCH 11/16] lpfc: Make FW logging dynamically configurable James Smart
2019-10-18 21:18 ` [PATCH 12/16] lpfc: Add log macros to allow print by serverity or verbocity setting James Smart
2019-10-18 21:18 ` [PATCH 13/16] lpfc: Add FA-WWN Async Event reporting James Smart
2019-10-18 21:18 ` [PATCH 14/16] lpfc: Add FC-AL support to lpe32000 models James Smart
2019-10-18 21:18 ` [PATCH 15/16] lpfc: Add additional discovery log messages James Smart
2019-10-18 21:18 ` [PATCH 16/16] lpfc: Update lpfc version to 12.6.0.0 James Smart
2019-10-25  1:03 ` [PATCH 00/16] lpfc: Update lpfc to revision 12.6.0.0 Martin K. Petersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191018211832.7917-11-jsmart2021@gmail.com \
    --to=jsmart2021@gmail.com \
    --cc=dick.kennedy@broadcom.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).