ignatenkobrain / rpms / kernel

Forked from rpms/kernel 3 years ago
Clone
b37f23
From 87029b097c79483c8a03c68a065a78973e0456db Mon Sep 17 00:00:00 2001
b37f23
From: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
b37f23
Date: Tue, 10 Jan 2017 18:20:50 -0500
b37f23
Subject: [PATCH 08/11] scsi: megaraid_sas: Enable or Disable Fast path based
b37f23
 on the PCI Threshold Bandwidth
b37f23
b37f23
Large SEQ IO workload should sent as non fast path commands
b37f23
b37f23
Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
b37f23
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
b37f23
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
b37f23
---
b37f23
 drivers/scsi/megaraid/megaraid_sas.h        |  8 +++++
b37f23
 drivers/scsi/megaraid/megaraid_sas_base.c   | 48 +++++++++++++++++++++++++++++
b37f23
 drivers/scsi/megaraid/megaraid_sas_fp.c     |  7 +++++
b37f23
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 ++++++----
b37f23
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +-
b37f23
 5 files changed, 74 insertions(+), 7 deletions(-)
b37f23
b37f23
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
b37f23
index d5205c4..f6ac1b2 100644
b37f23
--- a/drivers/scsi/megaraid/megaraid_sas.h
b37f23
+++ b/drivers/scsi/megaraid/megaraid_sas.h
b37f23
@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT {
b37f23
 #define MFI_1068_FW_HANDSHAKE_OFFSET		0x64
b37f23
 #define MFI_1068_FW_READY			0xDDDD0000
b37f23
 
b37f23
+#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ
b37f23
+
b37f23
 #define MR_MAX_REPLY_QUEUES_OFFSET              0X0000001F
b37f23
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET          0X003FC000
b37f23
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
b37f23
@@ -2101,6 +2103,10 @@ struct megasas_instance {
b37f23
 	atomic_t ldio_outstanding;
b37f23
 	atomic_t fw_reset_no_pci_access;
b37f23
 
b37f23
+	atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */
b37f23
+	atomic_t r1_write_fp_capable;
b37f23
+
b37f23
+
b37f23
 	struct megasas_instance_template *instancet;
b37f23
 	struct tasklet_struct isr_tasklet;
b37f23
 	struct work_struct work_init;
b37f23
@@ -2143,6 +2149,7 @@ struct megasas_instance {
b37f23
 	long reset_flags;
b37f23
 	struct mutex reset_mutex;
b37f23
 	struct timer_list sriov_heartbeat_timer;
b37f23
+	struct timer_list r1_fp_hold_timer;
b37f23
 	char skip_heartbeat_timer_del;
b37f23
 	u8 requestorId;
b37f23
 	char PlasmaFW111;
b37f23
@@ -2159,6 +2166,7 @@ struct megasas_instance {
b37f23
 	bool is_ventura;
b37f23
 	bool msix_combined;
b37f23
 	u16 max_raid_mapsize;
b37f23
+	u64 pci_threshold_bandwidth; /* used to control the fp writes */
b37f23
 };
b37f23
 struct MR_LD_VF_MAP {
b37f23
 	u32 size;
b37f23
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
b37f23
index 8b0c686..cab3be8 100644
b37f23
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
b37f23
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
b37f23
@@ -1959,6 +1959,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
b37f23
 	}
b37f23
 	/* Complete outstanding ioctls when adapter is killed */
b37f23
 	megasas_complete_outstanding_ioctls(instance);
b37f23
+	if (instance->is_ventura)
b37f23
+		del_timer_sync(&instance->r1_fp_hold_timer);
b37f23
+
b37f23
 }
b37f23
 
b37f23
  /**
b37f23
@@ -2457,6 +2460,24 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
b37f23
 	}
b37f23
 }
b37f23
 
b37f23
+/*Handler for disabling/enabling raid 1 fast paths*/
b37f23
+void megasas_change_r1_fp_status(unsigned long instance_addr)
b37f23
+{
b37f23
+	struct megasas_instance *instance =
b37f23
+			(struct megasas_instance *)instance_addr;
b37f23
+	if (atomic64_read(&instance->bytes_wrote) >=
b37f23
+					instance->pci_threshold_bandwidth) {
b37f23
+
b37f23
+		atomic64_set(&instance->bytes_wrote, 0);
b37f23
+		atomic_set(&instance->r1_write_fp_capable, 0);
b37f23
+	} else {
b37f23
+		atomic64_set(&instance->bytes_wrote, 0);
b37f23
+		atomic_set(&instance->r1_write_fp_capable, 1);
b37f23
+	}
b37f23
+	mod_timer(&instance->r1_fp_hold_timer,
b37f23
+	 jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
b37f23
+}
b37f23
+
b37f23
 /**
b37f23
  * megasas_wait_for_outstanding -	Wait for all outstanding cmds
b37f23
  * @instance:				Adapter soft state
b37f23
@@ -5403,6 +5424,17 @@ static int megasas_init_fw(struct megasas_instance *instance)
b37f23
 			instance->skip_heartbeat_timer_del = 1;
b37f23
 	}
b37f23
 
b37f23
+	if (instance->is_ventura) {
b37f23
+		atomic64_set(&instance->bytes_wrote, 0);
b37f23
+		atomic_set(&instance->r1_write_fp_capable, 1);
b37f23
+		megasas_start_timer(instance,
b37f23
+			    &instance->r1_fp_hold_timer,
b37f23
+			    megasas_change_r1_fp_status,
b37f23
+			    MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
b37f23
+				dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n",
b37f23
+				MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
b37f23
+	}
b37f23
+
b37f23
 	return 0;
b37f23
 
b37f23
 fail_get_ld_pd_list:
b37f23
@@ -6202,6 +6234,9 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
b37f23
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
b37f23
 		del_timer_sync(&instance->sriov_heartbeat_timer);
b37f23
 
b37f23
+	if (instance->is_ventura)
b37f23
+		del_timer_sync(&instance->r1_fp_hold_timer);
b37f23
+
b37f23
 	megasas_flush_cache(instance);
b37f23
 	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
b37f23
 
b37f23
@@ -6321,6 +6356,16 @@ megasas_resume(struct pci_dev *pdev)
b37f23
 	megasas_setup_jbod_map(instance);
b37f23
 	instance->unload = 0;
b37f23
 
b37f23
+	if (instance->is_ventura) {
b37f23
+		atomic64_set(&instance->bytes_wrote, 0);
b37f23
+		atomic_set(&instance->r1_write_fp_capable, 1);
b37f23
+		megasas_start_timer(instance,
b37f23
+			    &instance->r1_fp_hold_timer,
b37f23
+			    megasas_change_r1_fp_status,
b37f23
+			    MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
b37f23
+	}
b37f23
+
b37f23
+
b37f23
 	/*
b37f23
 	 * Initiate AEN (Asynchronous Event Notification)
b37f23
 	 */
b37f23
@@ -6381,6 +6426,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
b37f23
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
b37f23
 		del_timer_sync(&instance->sriov_heartbeat_timer);
b37f23
 
b37f23
+	if (instance->is_ventura)
b37f23
+		del_timer_sync(&instance->r1_fp_hold_timer);
b37f23
+
b37f23
 	if (instance->fw_crash_state != UNAVAILABLE)
b37f23
 		megasas_free_host_crash_buffer(instance);
b37f23
 	scsi_remove_host(instance->host);
b37f23
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
b37f23
index e45affe..5cad7c6 100644
b37f23
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
b37f23
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
b37f23
@@ -197,6 +197,9 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
b37f23
 
b37f23
 	if (instance->max_raid_mapsize) {
b37f23
 		fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
b37f23
+		if (fw_map_dyn->pci_threshold_bandwidth)
b37f23
+			instance->pci_threshold_bandwidth =
b37f23
+			le64_to_cpu(fw_map_dyn->pci_threshold_bandwidth);
b37f23
 #if VD_EXT_DEBUG
b37f23
 		dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n",
b37f23
 			le32_to_cpu(fw_map_dyn->raid_map_size),
b37f23
@@ -204,6 +207,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
b37f23
 		dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n",
b37f23
 			le32_to_cpu(fw_map_dyn->desc_table_size),
b37f23
 			le32_to_cpu(fw_map_dyn->desc_table_num_elements));
b37f23
+		dev_dbg(&instance->pdev->dev, "PCIThreasholdBandwidth %llu\n",
b37f23
+			instance->pci_threshold_bandwidth);
b37f23
 		dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n",
b37f23
 			drv_map, fw_map_dyn->ld_count);
b37f23
 #endif
b37f23
@@ -434,6 +439,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
b37f23
 			sizeof(struct MR_DEV_HANDLE_INFO) *
b37f23
 			MAX_RAIDMAP_PHYSICAL_DEVICES);
b37f23
 	}
b37f23
+	if (instance->is_ventura && !instance->pci_threshold_bandwidth)
b37f23
+		instance->pci_threshold_bandwidth = ULLONG_MAX;
b37f23
 }
b37f23
 
b37f23
 /*
b37f23
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
b37f23
index 1802c57..5689a44 100644
b37f23
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
b37f23
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
b37f23
@@ -95,6 +95,7 @@ extern unsigned int resetwaittime;
b37f23
 extern unsigned int dual_qdepth_disable;
b37f23
 static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
b37f23
 static void megasas_free_reply_fusion(struct megasas_instance *instance);
b37f23
+void megasas_change_r1_fp_status(unsigned long instance_addr);
b37f23
 
b37f23
 
b37f23
 
b37f23
@@ -2628,8 +2629,9 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
b37f23
 	 *	to get new command
b37f23
 	 */
b37f23
 	if (cmd->is_raid_1_fp_write &&
b37f23
-		atomic_inc_return(&instance->fw_outstanding) >
b37f23
-			(instance->host->can_queue)) {
b37f23
+		(atomic_inc_return(&instance->fw_outstanding) >
b37f23
+			(instance->host->can_queue) ||
b37f23
+		(!atomic_read(&instance->r1_write_fp_capable)))) {
b37f23
 		megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
b37f23
 		atomic_dec(&instance->fw_outstanding);
b37f23
 	} else if (cmd->is_raid_1_fp_write) {
b37f23
@@ -2638,17 +2640,19 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
b37f23
 		megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
b37f23
 	}
b37f23
 
b37f23
-
b37f23
 	/*
b37f23
 	 * Issue the command to the FW
b37f23
 	 */
b37f23
+	if (scmd->sc_data_direction == PCI_DMA_TODEVICE && instance->is_ventura)
b37f23
+		atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
b37f23
 
b37f23
 	megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura);
b37f23
 
b37f23
-	if (r1_cmd)
b37f23
+	if (r1_cmd) {
b37f23
+		atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
b37f23
 		megasas_fire_cmd_fusion(instance, r1_cmd->request_desc,
b37f23
-				instance->is_ventura);
b37f23
-
b37f23
+			instance->is_ventura);
b37f23
+	}
b37f23
 
b37f23
 	return 0;
b37f23
 }
b37f23
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
b37f23
index b24262a..f7384c1 100644
b37f23
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
b37f23
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
b37f23
@@ -977,7 +977,7 @@ struct MR_FW_RAID_MAP_DYNAMIC {
b37f23
 	u32 desc_table_size;  /* Total Size of desc table */
b37f23
 	/* Total Number of elements in the desc table */
b37f23
 	u32 desc_table_num_elements;
b37f23
-	u64	reserved1;
b37f23
+	u64	pci_threshold_bandwidth;
b37f23
 	u32	reserved2[3];	/*future use */
b37f23
 	/* timeout value used by driver in FP IOs */
b37f23
 	u8 fp_pd_io_timeout_sec;
b37f23
-- 
b37f23
1.8.3.1
b37f23