summaryrefslogtreecommitdiff
path: root/drivers/scsi/mpt3sas/mpt3sas_base.c
diff options
context:
space:
mode:
authorSuganath Prabu <suganath-prabu.subramani@broadcom.com>2019-02-15 02:40:28 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2019-03-18 17:16:43 -0400
commit51e3b2ad6de2b135d0fc7170f1b133f4e7a7639d (patch)
treec36b532d14e54a65827af0b1fa6be3925b153e99 /drivers/scsi/mpt3sas/mpt3sas_base.c
parent320e77acb32774b6addfe38d562956fad70c5f0d (diff)
scsi: mpt3sas: Load balance to improve performance and avoid soft lockups
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> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_base.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9a36ea93cfbd..3c3e4745a7b8 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()];
}