Commit 3e5eadb1 authored by Sasikumar Chandrasekaran's avatar Sasikumar Chandrasekaran Committed by Martin K. Petersen

scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth

Large SEQ IO workload should sent as non fast path commands
Signed-off-by: default avatarSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9581ebeb
...@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT { ...@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT {
#define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64
#define MFI_1068_FW_READY 0xDDDD0000 #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_OFFSET 0X0000001F
#define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000
#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14
...@@ -2101,6 +2103,10 @@ struct megasas_instance { ...@@ -2101,6 +2103,10 @@ struct megasas_instance {
atomic_t ldio_outstanding; atomic_t ldio_outstanding;
atomic_t fw_reset_no_pci_access; 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 megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet; struct tasklet_struct isr_tasklet;
struct work_struct work_init; struct work_struct work_init;
...@@ -2142,6 +2148,7 @@ struct megasas_instance { ...@@ -2142,6 +2148,7 @@ struct megasas_instance {
long reset_flags; long reset_flags;
struct mutex reset_mutex; struct mutex reset_mutex;
struct timer_list sriov_heartbeat_timer; struct timer_list sriov_heartbeat_timer;
struct timer_list r1_fp_hold_timer;
char skip_heartbeat_timer_del; char skip_heartbeat_timer_del;
u8 requestorId; u8 requestorId;
char PlasmaFW111; char PlasmaFW111;
...@@ -2158,6 +2165,7 @@ struct megasas_instance { ...@@ -2158,6 +2165,7 @@ struct megasas_instance {
bool is_ventura; bool is_ventura;
bool msix_combined; bool msix_combined;
u16 max_raid_mapsize; u16 max_raid_mapsize;
u64 pci_threshold_bandwidth; /* used to control the fp writes */
}; };
struct MR_LD_VF_MAP { struct MR_LD_VF_MAP {
u32 size; u32 size;
......
...@@ -1940,6 +1940,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) ...@@ -1940,6 +1940,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
} }
/* Complete outstanding ioctls when adapter is killed */ /* Complete outstanding ioctls when adapter is killed */
megasas_complete_outstanding_ioctls(instance); 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) ...@@ -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 * megasas_wait_for_outstanding - Wait for all outstanding cmds
* @instance: Adapter soft state * @instance: Adapter soft state
...@@ -5362,6 +5383,17 @@ static int megasas_init_fw(struct megasas_instance *instance) ...@@ -5362,6 +5383,17 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->skip_heartbeat_timer_del = 1; 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; return 0;
fail_get_ld_pd_list: fail_get_ld_pd_list:
...@@ -6152,6 +6184,9 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -6152,6 +6184,9 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
if (instance->requestorId && !instance->skip_heartbeat_timer_del) if (instance->requestorId && !instance->skip_heartbeat_timer_del)
del_timer_sync(&instance->sriov_heartbeat_timer); del_timer_sync(&instance->sriov_heartbeat_timer);
if (instance->is_ventura)
del_timer_sync(&instance->r1_fp_hold_timer);
megasas_flush_cache(instance); megasas_flush_cache(instance);
megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
...@@ -6278,6 +6313,16 @@ megasas_resume(struct pci_dev *pdev) ...@@ -6278,6 +6313,16 @@ megasas_resume(struct pci_dev *pdev)
megasas_setup_jbod_map(instance); megasas_setup_jbod_map(instance);
instance->unload = 0; 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) * Initiate AEN (Asynchronous Event Notification)
*/ */
...@@ -6366,6 +6411,9 @@ static void megasas_detach_one(struct pci_dev *pdev) ...@@ -6366,6 +6411,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
if (instance->requestorId && !instance->skip_heartbeat_timer_del) if (instance->requestorId && !instance->skip_heartbeat_timer_del)
del_timer_sync(&instance->sriov_heartbeat_timer); 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) if (instance->fw_crash_state != UNAVAILABLE)
megasas_free_host_crash_buffer(instance); megasas_free_host_crash_buffer(instance);
scsi_remove_host(instance->host); scsi_remove_host(instance->host);
......
...@@ -197,6 +197,9 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) ...@@ -197,6 +197,9 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
if (instance->max_raid_mapsize) { if (instance->max_raid_mapsize) {
fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; 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 #if VD_EXT_DEBUG
dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n",
le32_to_cpu(fw_map_dyn->raid_map_size), le32_to_cpu(fw_map_dyn->raid_map_size),
...@@ -204,6 +207,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) ...@@ -204,6 +207,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", 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_size),
le32_to_cpu(fw_map_dyn->desc_table_num_elements)); 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", dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n",
drv_map, fw_map_dyn->ld_count); drv_map, fw_map_dyn->ld_count);
#endif #endif
...@@ -434,6 +439,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) ...@@ -434,6 +439,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
sizeof(struct MR_DEV_HANDLE_INFO) * sizeof(struct MR_DEV_HANDLE_INFO) *
MAX_RAIDMAP_PHYSICAL_DEVICES); MAX_RAIDMAP_PHYSICAL_DEVICES);
} }
if (instance->is_ventura && !instance->pci_threshold_bandwidth)
instance->pci_threshold_bandwidth = ULLONG_MAX;
} }
/* /*
......
...@@ -95,6 +95,7 @@ extern unsigned int resetwaittime; ...@@ -95,6 +95,7 @@ extern unsigned int resetwaittime;
extern unsigned int dual_qdepth_disable; extern unsigned int dual_qdepth_disable;
static void megasas_free_rdpq_fusion(struct megasas_instance *instance); static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
static void megasas_free_reply_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 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, ...@@ -2628,8 +2629,9 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
* to get new command * to get new command
*/ */
if (cmd->is_raid_1_fp_write && if (cmd->is_raid_1_fp_write &&
atomic_inc_return(&instance->fw_outstanding) > (atomic_inc_return(&instance->fw_outstanding) >
(instance->host->can_queue)) { (instance->host->can_queue) ||
(!atomic_read(&instance->r1_write_fp_capable)))) {
megasas_fpio_to_ldio(instance, cmd, cmd->scmd); megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
atomic_dec(&instance->fw_outstanding); atomic_dec(&instance->fw_outstanding);
} else if (cmd->is_raid_1_fp_write) { } else if (cmd->is_raid_1_fp_write) {
...@@ -2638,17 +2640,19 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, ...@@ -2638,17 +2640,19 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd); megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
} }
/* /*
* Issue the command to the FW * 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); 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, megasas_fire_cmd_fusion(instance, r1_cmd->request_desc,
instance->is_ventura); instance->is_ventura);
}
return 0; return 0;
} }
......
...@@ -977,7 +977,7 @@ struct MR_FW_RAID_MAP_DYNAMIC { ...@@ -977,7 +977,7 @@ struct MR_FW_RAID_MAP_DYNAMIC {
u32 desc_table_size; /* Total Size of desc table */ u32 desc_table_size; /* Total Size of desc table */
/* Total Number of elements in the desc table */ /* Total Number of elements in the desc table */
u32 desc_table_num_elements; u32 desc_table_num_elements;
u64 reserved1; u64 pci_threshold_bandwidth;
u32 reserved2[3]; /*future use */ u32 reserved2[3]; /*future use */
/* timeout value used by driver in FP IOs */ /* timeout value used by driver in FP IOs */
u8 fp_pd_io_timeout_sec; u8 fp_pd_io_timeout_sec;
......
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