Commit 9ab089d3 authored by Chandrakanth Patil's avatar Chandrakanth Patil Committed by Martin K. Petersen

scsi: megaraid_sas: Introduce module parameter for default queue depth

This patch provides a module parameter and sysfs interface to select
whether the queue depth for each device should be based on the value
suggested by firmware (the default) or the maximum supported by the
controller (can_queue).

Although we have a sysfs interface per sdev to change the queue depth of
individual scsi devices, this implementation provides a single sysfs entry
per shost to switch between the controller max and the value reported by
firmware. The module parameter can provide an interface for one time grub
settings and provides persistent settings across the boot.

[mkp: tweaked commit desc]
Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarChandrakanth Patil <chandrakanth.patil@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d1436e45
...@@ -2429,6 +2429,7 @@ struct megasas_instance { ...@@ -2429,6 +2429,7 @@ struct megasas_instance {
u8 adapter_type; u8 adapter_type;
bool consistent_mask_64bit; bool consistent_mask_64bit;
bool support_nvme_passthru; bool support_nvme_passthru;
bool enable_sdev_max_qd;
u8 task_abort_tmo; u8 task_abort_tmo;
u8 max_reset_tmo; u8 max_reset_tmo;
u8 snapdump_wait_time; u8 snapdump_wait_time;
......
...@@ -109,6 +109,10 @@ int event_log_level = MFI_EVT_CLASS_CRITICAL; ...@@ -109,6 +109,10 @@ int event_log_level = MFI_EVT_CLASS_CRITICAL;
module_param(event_log_level, int, 0644); module_param(event_log_level, int, 0644);
MODULE_PARM_DESC(event_log_level, "Asynchronous event logging level- range is: -2(CLASS_DEBUG) to 4(CLASS_DEAD), Default: 2(CLASS_CRITICAL)"); MODULE_PARM_DESC(event_log_level, "Asynchronous event logging level- range is: -2(CLASS_DEBUG) to 4(CLASS_DEAD), Default: 2(CLASS_CRITICAL)");
unsigned int enable_sdev_max_qd;
module_param(enable_sdev_max_qd, int, 0444);
MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION); MODULE_VERSION(MEGASAS_VERSION);
MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com"); MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
...@@ -1941,25 +1945,19 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) ...@@ -1941,25 +1945,19 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size)
blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1); blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1);
} }
/* /*
* megasas_set_static_target_properties - * megasas_set_fw_assisted_qd -
* Device property set by driver are static and it is not required to be * set device queue depth to can_queue
* updated after OCR. * set device queue depth to fw assisted qd
*
* set io timeout
* set device queue depth
* set nvme device properties. see - megasas_set_nvme_device_properties
* *
* @sdev: scsi device * @sdev: scsi device
* @is_target_prop true, if fw provided target properties. * @is_target_prop true, if fw provided target properties.
*/ */
static void megasas_set_static_target_properties(struct scsi_device *sdev, static void megasas_set_fw_assisted_qd(struct scsi_device *sdev,
bool is_target_prop) bool is_target_prop)
{ {
u8 interface_type; u8 interface_type;
u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN;
u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
u32 tgt_device_qd; u32 tgt_device_qd;
struct megasas_instance *instance; struct megasas_instance *instance;
struct MR_PRIV_DEVICE *mr_device_priv_data; struct MR_PRIV_DEVICE *mr_device_priv_data;
...@@ -1968,11 +1966,6 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev, ...@@ -1968,11 +1966,6 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev,
mr_device_priv_data = sdev->hostdata; mr_device_priv_data = sdev->hostdata;
interface_type = mr_device_priv_data->interface_type; interface_type = mr_device_priv_data->interface_type;
/*
* The RAID firmware may require extended timeouts.
*/
blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
switch (interface_type) { switch (interface_type) {
case SAS_PD: case SAS_PD:
device_qd = MEGASAS_SAS_QD; device_qd = MEGASAS_SAS_QD;
...@@ -1990,18 +1983,49 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev, ...@@ -1990,18 +1983,49 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev,
if (tgt_device_qd && if (tgt_device_qd &&
(tgt_device_qd <= instance->host->can_queue)) (tgt_device_qd <= instance->host->can_queue))
device_qd = tgt_device_qd; device_qd = tgt_device_qd;
}
/* max_io_size_kb will be set to non zero for if (instance->enable_sdev_max_qd && interface_type != UNKNOWN_DRIVE)
* nvme based vd and syspd. device_qd = instance->host->can_queue;
*/
scsi_change_queue_depth(sdev, device_qd);
}
/*
* megasas_set_static_target_properties -
* Device property set by driver are static and it is not required to be
* updated after OCR.
*
* set io timeout
* set device queue depth
* set nvme device properties. see - megasas_set_nvme_device_properties
*
* @sdev: scsi device
* @is_target_prop true, if fw provided target properties.
*/
static void megasas_set_static_target_properties(struct scsi_device *sdev,
bool is_target_prop)
{
u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
struct megasas_instance *instance;
instance = megasas_lookup_instance(sdev->host->host_no);
/*
* The RAID firmware may require extended timeouts.
*/
blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
/* max_io_size_kb will be set to non zero for
* nvme based vd and syspd.
*/
if (is_target_prop)
max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb);
}
if (instance->nvme_page_size && max_io_size_kb) if (instance->nvme_page_size && max_io_size_kb)
megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10));
scsi_change_queue_depth(sdev, device_qd); megasas_set_fw_assisted_qd(sdev, is_target_prop);
} }
...@@ -3281,6 +3305,48 @@ fw_cmds_outstanding_show(struct device *cdev, ...@@ -3281,6 +3305,48 @@ fw_cmds_outstanding_show(struct device *cdev,
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding)); return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding));
} }
static ssize_t
enable_sdev_max_qd_show(struct device *cdev,
struct device_attribute *attr, char *buf)
{
struct Scsi_Host *shost = class_to_shost(cdev);
struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
return snprintf(buf, PAGE_SIZE, "%d\n", instance->enable_sdev_max_qd);
}
static ssize_t
enable_sdev_max_qd_store(struct device *cdev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct Scsi_Host *shost = class_to_shost(cdev);
struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
u32 val = 0;
bool is_target_prop;
int ret_target_prop = DCMD_FAILED;
struct scsi_device *sdev;
if (kstrtou32(buf, 0, &val) != 0) {
pr_err("megasas: could not set enable_sdev_max_qd\n");
return -EINVAL;
}
mutex_lock(&instance->reset_mutex);
if (val)
instance->enable_sdev_max_qd = true;
else
instance->enable_sdev_max_qd = false;
shost_for_each_device(sdev, shost) {
ret_target_prop = megasas_get_target_prop(instance, sdev);
is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false;
megasas_set_fw_assisted_qd(sdev, is_target_prop);
}
mutex_unlock(&instance->reset_mutex);
return strlen(buf);
}
static ssize_t static ssize_t
dump_system_regs_show(struct device *cdev, dump_system_regs_show(struct device *cdev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
...@@ -3310,6 +3376,7 @@ static DEVICE_ATTR_RW(fw_crash_state); ...@@ -3310,6 +3376,7 @@ static DEVICE_ATTR_RW(fw_crash_state);
static DEVICE_ATTR_RO(page_size); static DEVICE_ATTR_RO(page_size);
static DEVICE_ATTR_RO(ldio_outstanding); static DEVICE_ATTR_RO(ldio_outstanding);
static DEVICE_ATTR_RO(fw_cmds_outstanding); static DEVICE_ATTR_RO(fw_cmds_outstanding);
static DEVICE_ATTR_RW(enable_sdev_max_qd);
static DEVICE_ATTR_RO(dump_system_regs); static DEVICE_ATTR_RO(dump_system_regs);
static DEVICE_ATTR_RO(raid_map_id); static DEVICE_ATTR_RO(raid_map_id);
...@@ -3320,6 +3387,7 @@ static struct device_attribute *megaraid_host_attrs[] = { ...@@ -3320,6 +3387,7 @@ static struct device_attribute *megaraid_host_attrs[] = {
&dev_attr_page_size, &dev_attr_page_size,
&dev_attr_ldio_outstanding, &dev_attr_ldio_outstanding,
&dev_attr_fw_cmds_outstanding, &dev_attr_fw_cmds_outstanding,
&dev_attr_enable_sdev_max_qd,
&dev_attr_dump_system_regs, &dev_attr_dump_system_regs,
&dev_attr_raid_map_id, &dev_attr_raid_map_id,
NULL, NULL,
...@@ -5891,6 +5959,8 @@ static int megasas_init_fw(struct megasas_instance *instance) ...@@ -5891,6 +5959,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
MR_MAX_RAID_MAP_SIZE_MASK); MR_MAX_RAID_MAP_SIZE_MASK);
} }
instance->enable_sdev_max_qd = enable_sdev_max_qd;
switch (instance->adapter_type) { switch (instance->adapter_type) {
case VENTURA_SERIES: case VENTURA_SERIES:
fusion->pcie_bw_limitation = true; fusion->pcie_bw_limitation = true;
......
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