} 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.
 
        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);
 
 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()];
 }
 
 
  * @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
        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;