Large SEQ IO workload should sent as non fast path commands

Signed-off-by: Sasikumar Chandrasekaran <sasikumar...@broadcom.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
Changes v6 -> v7:
-None

 drivers/scsi/megaraid/megaraid_sas.h        |  8 +++++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 48 +++++++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas_fp.c     |  7 +++++
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 ++++++----
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +-
 5 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 6ddf994..0696903 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT {
 #define MFI_1068_FW_HANDSHAKE_OFFSET           0x64
 #define MFI_1068_FW_READY                      0xDDDD0000
 
+#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ
+
 #define MR_MAX_REPLY_QUEUES_OFFSET              0X0000001F
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET          0X003FC000
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
@@ -2101,6 +2103,10 @@ struct megasas_instance {
        atomic_t ldio_outstanding;
        atomic_t fw_reset_no_pci_access;
 
+       atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */
+       atomic_t r1_write_fp_capable;
+
+
        struct megasas_instance_template *instancet;
        struct tasklet_struct isr_tasklet;
        struct work_struct work_init;
@@ -2142,6 +2148,7 @@ struct megasas_instance {
        long reset_flags;
        struct mutex reset_mutex;
        struct timer_list sriov_heartbeat_timer;
+       struct timer_list r1_fp_hold_timer;
        char skip_heartbeat_timer_del;
        u8 requestorId;
        char PlasmaFW111;
@@ -2158,6 +2165,7 @@ struct megasas_instance {
        bool is_ventura;
        bool msix_combined;
        u16 max_raid_mapsize;
+       u64 pci_threshold_bandwidth; /* used to control the fp writes */
 };
 struct MR_LD_VF_MAP {
        u32 size;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 19bc350..eba1078 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1940,6 +1940,9 @@ void megaraid_sas_kill_hba(struct megasas_instance 
*instance)
        }
        /* Complete outstanding ioctls when adapter is killed */
        megasas_complete_outstanding_ioctls(instance);
+       if (instance->is_ventura)
+               del_timer_sync(&instance->r1_fp_hold_timer);
+
 }
 
  /**
@@ -2438,6 +2441,24 @@ void megasas_sriov_heartbeat_handler(unsigned long 
instance_addr)
        }
 }
 
+/*Handler for disabling/enabling raid 1 fast paths*/
+void megasas_change_r1_fp_status(unsigned long instance_addr)
+{
+       struct megasas_instance *instance =
+                       (struct megasas_instance *)instance_addr;
+       if (atomic64_read(&instance->bytes_wrote) >=
+                                       instance->pci_threshold_bandwidth) {
+
+               atomic64_set(&instance->bytes_wrote, 0);
+               atomic_set(&instance->r1_write_fp_capable, 0);
+       } else {
+               atomic64_set(&instance->bytes_wrote, 0);
+               atomic_set(&instance->r1_write_fp_capable, 1);
+       }
+       mod_timer(&instance->r1_fp_hold_timer,
+        jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+}
+
 /**
  * megasas_wait_for_outstanding -      Wait for all outstanding cmds
  * @instance:                          Adapter soft state
@@ -5362,6 +5383,17 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
                        instance->skip_heartbeat_timer_del = 1;
        }
 
+       if (instance->is_ventura) {
+               atomic64_set(&instance->bytes_wrote, 0);
+               atomic_set(&instance->r1_write_fp_capable, 1);
+               megasas_start_timer(instance,
+                           &instance->r1_fp_hold_timer,
+                           megasas_change_r1_fp_status,
+                           MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+                               dev_info(&instance->pdev->dev, "starting the 
raid 1 fp timer with interval %d\n",
+                               MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+       }
+
        return 0;
 
 fail_get_ld_pd_list:
@@ -6152,6 +6184,9 @@ static void megasas_shutdown_controller(struct 
megasas_instance *instance,
        if (instance->requestorId && !instance->skip_heartbeat_timer_del)
                del_timer_sync(&instance->sriov_heartbeat_timer);
 
+       if (instance->is_ventura)
+               del_timer_sync(&instance->r1_fp_hold_timer);
+
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
 
@@ -6278,6 +6313,16 @@ static void megasas_shutdown_controller(struct 
megasas_instance *instance,
        megasas_setup_jbod_map(instance);
        instance->unload = 0;
 
+       if (instance->is_ventura) {
+               atomic64_set(&instance->bytes_wrote, 0);
+               atomic_set(&instance->r1_write_fp_capable, 1);
+               megasas_start_timer(instance,
+                           &instance->r1_fp_hold_timer,
+                           megasas_change_r1_fp_status,
+                           MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+       }
+
+
        /*
         * Initiate AEN (Asynchronous Event Notification)
         */
@@ -6366,6 +6411,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
        if (instance->requestorId && !instance->skip_heartbeat_timer_del)
                del_timer_sync(&instance->sriov_heartbeat_timer);
 
+       if (instance->is_ventura)
+               del_timer_sync(&instance->r1_fp_hold_timer);
+
        if (instance->fw_crash_state != UNAVAILABLE)
                megasas_free_host_crash_buffer(instance);
        scsi_remove_host(instance->host);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index f1384b0..322a72b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -197,6 +197,9 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
 
        if (instance->max_raid_mapsize) {
                fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
+               if (fw_map_dyn->pci_threshold_bandwidth)
+                       instance->pci_threshold_bandwidth =
+                       le64_to_cpu(fw_map_dyn->pci_threshold_bandwidth);
 #if VD_EXT_DEBUG
                dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x 
fw_map_dyn->descTableOffset 0x%x\n",
                        le32_to_cpu(fw_map_dyn->raid_map_size),
@@ -204,6 +207,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
                dev_dbg(&instance->pdev->dev, "descTableSize 0x%x 
descTableNumElements 0x%x\n",
                        le32_to_cpu(fw_map_dyn->desc_table_size),
                        le32_to_cpu(fw_map_dyn->desc_table_num_elements));
+               dev_dbg(&instance->pdev->dev, "PCIThreasholdBandwidth %llu\n",
+                       instance->pci_threshold_bandwidth);
                dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n",
                        drv_map, fw_map_dyn->ld_count);
 #endif
@@ -434,6 +439,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
                        sizeof(struct MR_DEV_HANDLE_INFO) *
                        MAX_RAIDMAP_PHYSICAL_DEVICES);
        }
+       if (instance->is_ventura && !instance->pci_threshold_bandwidth)
+               instance->pci_threshold_bandwidth = ULLONG_MAX;
 }
 
 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index ac424ba..4d655e4 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -95,6 +95,7 @@ void megasas_start_timer(struct megasas_instance *instance,
 extern unsigned int dual_qdepth_disable;
 static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
 static void megasas_free_reply_fusion(struct megasas_instance *instance);
+void megasas_change_r1_fp_status(unsigned long instance_addr);
 
 
 
@@ -2628,8 +2629,9 @@ void megasas_prepare_secondRaid1_IO(struct 
megasas_instance *instance,
         *      to get new command
         */
        if (cmd->is_raid_1_fp_write &&
-               atomic_inc_return(&instance->fw_outstanding) >
-                       (instance->host->can_queue)) {
+               (atomic_inc_return(&instance->fw_outstanding) >
+                       (instance->host->can_queue) ||
+               (!atomic_read(&instance->r1_write_fp_capable)))) {
                megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
                atomic_dec(&instance->fw_outstanding);
        } else if (cmd->is_raid_1_fp_write) {
@@ -2638,17 +2640,19 @@ void megasas_prepare_secondRaid1_IO(struct 
megasas_instance *instance,
                megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
        }
 
-
        /*
         * Issue the command to the FW
         */
+       if (scmd->sc_data_direction == PCI_DMA_TODEVICE && instance->is_ventura)
+               atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
 
        megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura);
 
-       if (r1_cmd)
+       if (r1_cmd) {
+               atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
                megasas_fire_cmd_fusion(instance, r1_cmd->request_desc,
-                               instance->is_ventura);
-
+                       instance->is_ventura);
+       }
 
        return 0;
 }
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h 
b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index a9bc9c0..391aae6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -977,7 +977,7 @@ struct MR_FW_RAID_MAP_DYNAMIC {
        u32 desc_table_size;  /* Total Size of desc table */
        /* Total Number of elements in the desc table */
        u32 desc_table_num_elements;
-       u64     reserved1;
+       u64     pci_threshold_bandwidth;
        u32     reserved2[3];   /*future use */
        /* timeout value used by driver in FP IOs */
        u8 fp_pd_io_timeout_sec;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to