diff mbox series

[4/6] mpt3sas: Load balance to improve performance and avoid soft lockups.

Message ID 1550123171-15993-5-git-send-email-suganath-prabu.subramani@broadcom.com (mailing list archive)
State Superseded
Headers show
Series Irq poll to address cpu lockup. | expand

Commit Message

Suganath Prabu S Feb. 14, 2019, 5:46 a.m. UTC
Driver uses "reply descriptor post queues" in round robin
fashion so that IO's are distributed to all the available
reply descriptor post queues equally.
With this each reply descriptor post queue load is balanced.

This is enabled only if CPUs count to MSI-X vector
count ratio is X:1 (where X > 1)
This improves performance and also fixes soft lockups.

Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 21 +++++++++++++++++++++
 drivers/scsi/mpt3sas/mpt3sas_base.h |  5 +++++
 2 files changed, 26 insertions(+)
diff mbox series

Patch

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 1f358bc..aadd9e2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1382,6 +1382,16 @@  union reply_descriptor {
 	} u;
 };
 
+static u32 base_mod64(u64 dividend, u32 divisor)
+{
+	u32 remainder;
+
+	if (!divisor)
+		pr_err("mpt3sas: DIVISOR is zero, in div fn\n");
+	remainder = do_div(dividend, divisor);
+	return remainder;
+}
+
 /**
  * _base_process_reply_queue - Process reply descriptors from reply
  *		descriptor post queue.
@@ -2845,6 +2855,11 @@  _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
 
 	if (!_base_is_controller_msix_enabled(ioc))
 		return;
+	ioc->msix_load_balance = false;
+	if (ioc->reply_queue_count < num_online_cpus()) {
+		ioc->msix_load_balance = true;
+		return;
+	}
 
 	memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz);
 
@@ -3248,6 +3263,12 @@  mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr)
 static inline u8
 _base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
 {
+	/* Enables reply_queue load balancing */
+	if (ioc->msix_load_balance)
+		return ioc->reply_queue_count ?
+		    base_mod64(atomic64_add_return(1,
+		    &ioc->total_io_cnt), ioc->reply_queue_count) : 0;
+
 	return ioc->cpu_msix_table[raw_smp_processor_id()];
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index fb572cd..3895407 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1024,6 +1024,9 @@  typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
  * @msix_vector_count: number msix vectors
  * @cpu_msix_table: table for mapping cpus to msix index
  * @cpu_msix_table_sz: table size
+ * @total_io_cnt: Gives total IO count, used to load balance the interrupts
+ * @msix_load_balance: Enables load balancing of interrupts across
+ * the multiple MSIXs
  * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands
  * @scsi_io_cb_idx: shost generated commands
  * @tm_cb_idx: task management commands
@@ -1200,6 +1203,8 @@  struct MPT3SAS_ADAPTER {
 	u32		ioc_reset_count;
 	MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
 	u32             non_operational_loop;
+	atomic64_t      total_io_cnt;
+	bool            msix_load_balance;
 
 	/* internal commands, callback index */
 	u8		scsi_io_cb_idx;