aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorChandrakanth Patil <chandrakanth.patil@broadcom.com>2019-06-25 07:04:31 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-06-27 00:07:35 -0400
commit132147d7f620eed4a7bee815eba03561258fc21e (patch)
tree98a5c222f35079fbce83e7518fc4a6c1ec36da4b /drivers/scsi/megaraid
parent58136856167d10adc2a190aff88d13b33eafb9e2 (diff)
scsi: megaraid_sas: Add support for High IOPS queues
Aero controllers support balanced performance mode through the ability to configure queues with different properties. Reply queues with interrupt coalescing enabled are called "high iops reply queues" and reply queues with interrupt coalescing disabled are called "low latency reply queues". The driver configures a combination of high iops and low latency reply queues if: - HBA is an AERO controller; - MSI-X vectors supported by the HBA is 128; - Total CPU count in the system more than high iops queue count; - Driver is loaded with default max_msix_vectors module parameter; and - System booted in non-kdump mode. Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com> Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h6
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c135
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c11
3 files changed, 135 insertions, 17 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 83baac3b8a8e..5b17d0fa162b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1640,6 +1640,7 @@ enum FW_BOOT_CONTEXT {
1640#define MR_ATOMIC_DESCRIPTOR_SUPPORT_OFFSET (1 << 24) 1640#define MR_ATOMIC_DESCRIPTOR_SUPPORT_OFFSET (1 << 24)
1641 1641
1642#define MR_CAN_HANDLE_64_BIT_DMA_OFFSET (1 << 25) 1642#define MR_CAN_HANDLE_64_BIT_DMA_OFFSET (1 << 25)
1643#define MR_INTR_COALESCING_SUPPORT_OFFSET (1 << 26)
1643 1644
1644#define MEGASAS_WATCHDOG_THREAD_INTERVAL 1000 1645#define MEGASAS_WATCHDOG_THREAD_INTERVAL 1000
1645#define MEGASAS_WAIT_FOR_NEXT_DMA_MSECS 20 1646#define MEGASAS_WAIT_FOR_NEXT_DMA_MSECS 20
@@ -2250,6 +2251,9 @@ enum MR_PD_TYPE {
2250#define MR_DEFAULT_NVME_MDTS_KB 128 2251#define MR_DEFAULT_NVME_MDTS_KB 128
2251#define MR_NVME_PAGE_SIZE_MASK 0x000000FF 2252#define MR_NVME_PAGE_SIZE_MASK 0x000000FF
2252 2253
2254/*Aero performance parameters*/
2255#define MR_HIGH_IOPS_QUEUE_COUNT 8
2256
2253struct megasas_instance { 2257struct megasas_instance {
2254 2258
2255 unsigned int *reply_map; 2259 unsigned int *reply_map;
@@ -2433,6 +2437,8 @@ struct megasas_instance {
2433 bool atomic_desc_support; 2437 bool atomic_desc_support;
2434 bool support_seqnum_jbod_fp; 2438 bool support_seqnum_jbod_fp;
2435 bool support_pci_lane_margining; 2439 bool support_pci_lane_margining;
2440 u8 low_latency_index_start;
2441 bool balanced_mode;
2436}; 2442};
2437 2443
2438struct MR_LD_VF_MAP { 2444struct MR_LD_VF_MAP {
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 4c7a0930b1a1..0abef940b67b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5472,6 +5472,8 @@ megasas_setup_irqs_ioapic(struct megasas_instance *instance)
5472 __func__, __LINE__); 5472 __func__, __LINE__);
5473 return -1; 5473 return -1;
5474 } 5474 }
5475 instance->balanced_mode = false;
5476 instance->low_latency_index_start = 0;
5475 return 0; 5477 return 0;
5476} 5478}
5477 5479
@@ -5610,9 +5612,11 @@ skip_alloc:
5610static void megasas_setup_reply_map(struct megasas_instance *instance) 5612static void megasas_setup_reply_map(struct megasas_instance *instance)
5611{ 5613{
5612 const struct cpumask *mask; 5614 const struct cpumask *mask;
5613 unsigned int queue, cpu; 5615 unsigned int queue, cpu, low_latency_index_start;
5614 5616
5615 for (queue = 0; queue < instance->msix_vectors; queue++) { 5617 low_latency_index_start = instance->low_latency_index_start;
5618
5619 for (queue = low_latency_index_start; queue < instance->msix_vectors; queue++) {
5616 mask = pci_irq_get_affinity(instance->pdev, queue); 5620 mask = pci_irq_get_affinity(instance->pdev, queue);
5617 if (!mask) 5621 if (!mask)
5618 goto fallback; 5622 goto fallback;
@@ -5623,8 +5627,14 @@ static void megasas_setup_reply_map(struct megasas_instance *instance)
5623 return; 5627 return;
5624 5628
5625fallback: 5629fallback:
5626 for_each_possible_cpu(cpu) 5630 queue = low_latency_index_start;
5627 instance->reply_map[cpu] = cpu % instance->msix_vectors; 5631 for_each_possible_cpu(cpu) {
5632 instance->reply_map[cpu] = queue;
5633 if (queue == (instance->msix_vectors - 1))
5634 queue = low_latency_index_start;
5635 else
5636 queue++;
5637 }
5628} 5638}
5629 5639
5630/** 5640/**
@@ -5661,6 +5671,66 @@ int megasas_get_device_list(struct megasas_instance *instance)
5661 5671
5662 return SUCCESS; 5672 return SUCCESS;
5663} 5673}
5674
5675static int
5676__megasas_alloc_irq_vectors(struct megasas_instance *instance)
5677{
5678 int i, irq_flags;
5679 struct irq_affinity desc = { .pre_vectors = instance->low_latency_index_start };
5680 struct irq_affinity *descp = &desc;
5681
5682 irq_flags = PCI_IRQ_MSIX;
5683
5684 if (instance->smp_affinity_enable)
5685 irq_flags |= PCI_IRQ_AFFINITY;
5686 else
5687 descp = NULL;
5688
5689 i = pci_alloc_irq_vectors_affinity(instance->pdev,
5690 instance->low_latency_index_start,
5691 instance->msix_vectors, irq_flags, descp);
5692
5693 return i;
5694}
5695
5696/**
5697 * megasas_alloc_irq_vectors - Allocate IRQ vectors/enable MSI-x vectors
5698 * @instance: Adapter soft state
5699 * return: void
5700 */
5701static void
5702megasas_alloc_irq_vectors(struct megasas_instance *instance)
5703{
5704 int i;
5705 unsigned int num_msix_req;
5706
5707 i = __megasas_alloc_irq_vectors(instance);
5708
5709 if (instance->balanced_mode && (i != instance->msix_vectors)) {
5710 if (instance->msix_vectors)
5711 pci_free_irq_vectors(instance->pdev);
5712 /* Disable Balanced IOPS mode and try realloc vectors */
5713 instance->balanced_mode = false;
5714 instance->low_latency_index_start = 1;
5715 num_msix_req = num_online_cpus() + instance->low_latency_index_start;
5716
5717 instance->msix_vectors = min(num_msix_req,
5718 instance->msix_vectors);
5719
5720 i = __megasas_alloc_irq_vectors(instance);
5721
5722 }
5723
5724 dev_info(&instance->pdev->dev,
5725 "requested/available msix %d/%d\n", instance->msix_vectors, i);
5726
5727 if (i > 0)
5728 instance->msix_vectors = i;
5729 else
5730 instance->msix_vectors = 0;
5731
5732}
5733
5664/** 5734/**
5665 * megasas_init_fw - Initializes the FW 5735 * megasas_init_fw - Initializes the FW
5666 * @instance: Adapter soft state 5736 * @instance: Adapter soft state
@@ -5680,6 +5750,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
5680 int i, j, loop; 5750 int i, j, loop;
5681 struct IOV_111 *iovPtr; 5751 struct IOV_111 *iovPtr;
5682 struct fusion_context *fusion; 5752 struct fusion_context *fusion;
5753 bool intr_coalescing;
5754 unsigned int num_msix_req;
5683 5755
5684 fusion = instance->ctrl_context; 5756 fusion = instance->ctrl_context;
5685 5757
@@ -5799,7 +5871,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
5799 msix_enable = (instance->instancet->read_fw_status_reg(instance) & 5871 msix_enable = (instance->instancet->read_fw_status_reg(instance) &
5800 0x4000000) >> 0x1a; 5872 0x4000000) >> 0x1a;
5801 if (msix_enable && !msix_disable) { 5873 if (msix_enable && !msix_disable) {
5802 int irq_flags = PCI_IRQ_MSIX;
5803 5874
5804 scratch_pad_1 = megasas_readl 5875 scratch_pad_1 = megasas_readl
5805 (instance, &instance->reg_set->outbound_scratch_pad_1); 5876 (instance, &instance->reg_set->outbound_scratch_pad_1);
@@ -5865,19 +5936,49 @@ static int megasas_init_fw(struct megasas_instance *instance)
5865 } else /* MFI adapters */ 5936 } else /* MFI adapters */
5866 instance->msix_vectors = 1; 5937 instance->msix_vectors = 1;
5867 5938
5868 /* Don't bother allocating more MSI-X vectors than cpus */ 5939
5869 instance->msix_vectors = min(instance->msix_vectors, 5940 /*
5870 (unsigned int)num_online_cpus()); 5941 * For Aero (if some conditions are met), driver will configure a
5871 if (instance->smp_affinity_enable) 5942 * few additional reply queues with interrupt coalescing enabled.
5872 irq_flags |= PCI_IRQ_AFFINITY; 5943 * These queues with interrupt coalescing enabled are called
5873 i = pci_alloc_irq_vectors(instance->pdev, 1, 5944 * High IOPS queues and rest of reply queues (based on number of
5874 instance->msix_vectors, irq_flags); 5945 * logical CPUs) are termed as Low latency queues.
5875 if (i > 0) { 5946 *
5876 instance->msix_vectors = i; 5947 * Total Number of reply queues = High IOPS queues + low latency queues
5877 } else { 5948 *
5878 instance->msix_vectors = 0; 5949 * For rest of fusion adapters, 1 additional reply queue will be
5950 * reserved for management commands, rest of reply queues
5951 * (based on number of logical CPUs) will be used for IOs and
5952 * referenced as IO queues.
5953 * Total Number of reply queues = 1 + IO queues
5954 *
5955 * MFI adapters supports single MSI-x so single reply queue
5956 * will be used for IO and management commands.
5957 */
5958
5959 intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ?
5960 true : false;
5961 if (intr_coalescing &&
5962 (num_online_cpus() >= MR_HIGH_IOPS_QUEUE_COUNT) &&
5963 (instance->msix_vectors == MEGASAS_MAX_MSIX_QUEUES))
5964 instance->balanced_mode = true;
5965 else
5966 instance->balanced_mode = false;
5967
5968 if (instance->balanced_mode)
5969 instance->low_latency_index_start =
5970 MR_HIGH_IOPS_QUEUE_COUNT;
5971 else
5972 instance->low_latency_index_start = 1;
5973
5974 num_msix_req = num_online_cpus() + instance->low_latency_index_start;
5975
5976 instance->msix_vectors = min(num_msix_req,
5977 instance->msix_vectors);
5978
5979 megasas_alloc_irq_vectors(instance);
5980 if (!instance->msix_vectors)
5879 instance->msix_load_balance = false; 5981 instance->msix_load_balance = false;
5880 }
5881 } 5982 }
5882 /* 5983 /*
5883 * MSI-X host index 0 is common for all adapter. 5984 * MSI-X host index 0 is common for all adapter.
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index e12434130231..44bfbe8d2ce5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1058,6 +1058,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
1058 u32 scratch_pad_1; 1058 u32 scratch_pad_1;
1059 ktime_t time; 1059 ktime_t time;
1060 bool cur_fw_64bit_dma_capable; 1060 bool cur_fw_64bit_dma_capable;
1061 bool cur_intr_coalescing;
1061 1062
1062 fusion = instance->ctrl_context; 1063 fusion = instance->ctrl_context;
1063 1064
@@ -1091,6 +1092,16 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
1091 goto fail_fw_init; 1092 goto fail_fw_init;
1092 } 1093 }
1093 1094
1095 cur_intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ?
1096 true : false;
1097
1098 if ((instance->low_latency_index_start ==
1099 MR_HIGH_IOPS_QUEUE_COUNT) && cur_intr_coalescing)
1100 instance->balanced_mode = true;
1101
1102 dev_info(&instance->pdev->dev, "Balanced mode :%s\n",
1103 instance->balanced_mode ? "Yes" : "No");
1104
1094 instance->fw_sync_cache_support = (scratch_pad_1 & 1105 instance->fw_sync_cache_support = (scratch_pad_1 &
1095 MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0; 1106 MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0;
1096 dev_info(&instance->pdev->dev, "FW supports sync cache\t: %s\n", 1107 dev_info(&instance->pdev->dev, "FW supports sync cache\t: %s\n",