Commit 51e3b2ad authored by Suganath Prabu's avatar Suganath Prabu Committed by Martin K. Petersen

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: default avatarSuganath Prabu <suganath-prabu.subramani@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 320e77ac
...@@ -1382,6 +1382,16 @@ union reply_descriptor { ...@@ -1382,6 +1382,16 @@ union reply_descriptor {
} u; } 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 * _base_process_reply_queue - Process reply descriptors from reply
* descriptor post queue. * descriptor post queue.
...@@ -2845,6 +2855,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) ...@@ -2845,6 +2855,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
if (!_base_is_controller_msix_enabled(ioc)) if (!_base_is_controller_msix_enabled(ioc))
return; 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); 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) ...@@ -3248,6 +3263,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr)
static inline u8 static inline u8
_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc) _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()]; return ioc->cpu_msix_table[raw_smp_processor_id()];
} }
......
...@@ -1024,6 +1024,9 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); ...@@ -1024,6 +1024,9 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
* @msix_vector_count: number msix vectors * @msix_vector_count: number msix vectors
* @cpu_msix_table: table for mapping cpus to msix index * @cpu_msix_table: table for mapping cpus to msix index
* @cpu_msix_table_sz: table size * @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 * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands
* @scsi_io_cb_idx: shost generated commands * @scsi_io_cb_idx: shost generated commands
* @tm_cb_idx: task management commands * @tm_cb_idx: task management commands
...@@ -1200,6 +1203,8 @@ struct MPT3SAS_ADAPTER { ...@@ -1200,6 +1203,8 @@ struct MPT3SAS_ADAPTER {
u32 ioc_reset_count; u32 ioc_reset_count;
MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
u32 non_operational_loop; u32 non_operational_loop;
atomic64_t total_io_cnt;
bool msix_load_balance;
/* internal commands, callback index */ /* internal commands, callback index */
u8 scsi_io_cb_idx; u8 scsi_io_cb_idx;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment