Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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;
+48 −0
Original line number Diff line number Diff line
@@ -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 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
	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 @@ megasas_resume(struct pci_dev *pdev)
	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);
+7 −0
Original line number Diff line number Diff line
@@ -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;
}

/*
+10 −6
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ extern unsigned int resetwaittime;
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 @@ megasas_build_and_issue_cmd_fusion(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 @@ megasas_build_and_issue_cmd_fusion(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);

	}

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -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;