Commit 8dc8d29a authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen
Browse files

scsi: mpt3sas: Introduce module parameter to override 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
protocol-specific value set by the driver (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
driver default.

[mkp: tweaked commit desc]

Signed-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dd93b143
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1232,6 +1232,7 @@ struct MPT3SAS_ADAPTER {
	u16		thresh_hold;
	u8		high_iops_queues;
	u32		drv_support_bitmap;
	bool		enable_sdev_max_qd;

	/* internal commands, callback index */
	u8		scsi_io_cb_idx;
@@ -1587,6 +1588,7 @@ struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
struct _raid_device *
mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle);
void mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth);

/* config shared API */
u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
+102 −0
Original line number Diff line number Diff line
@@ -3400,6 +3400,107 @@ drv_support_bitmap_show(struct device *cdev,
}
static DEVICE_ATTR_RO(drv_support_bitmap);

/**
 * enable_sdev_max_qd_show - display whether sdev max qd is enabled/disabled
 * @cdev - pointer to embedded class device
 * @buf - the buffer returned
 *
 * A sysfs read/write shost attribute. This attribute is used to set the
 * targets queue depth to HBA IO queue depth if this attribute is enabled.
 */
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 MPT3SAS_ADAPTER *ioc = shost_priv(shost);

	return snprintf(buf, PAGE_SIZE, "%d\n", ioc->enable_sdev_max_qd);
}

/**
 * enable_sdev_max_qd_store - Enable/disable sdev max qd
 * @cdev - pointer to embedded class device
 * @buf - the buffer returned
 *
 * A sysfs read/write shost attribute. This attribute is used to set the
 * targets queue depth to HBA IO queue depth if this attribute is enabled.
 * If this attribute is disabled then targets will have corresponding default
 * queue depth.
 */
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 MPT3SAS_ADAPTER *ioc = shost_priv(shost);
	struct MPT3SAS_DEVICE *sas_device_priv_data;
	struct MPT3SAS_TARGET *sas_target_priv_data;
	int val = 0;
	struct scsi_device *sdev;
	struct _raid_device *raid_device;
	int qdepth;

	if (kstrtoint(buf, 0, &val) != 0)
		return -EINVAL;

	switch (val) {
	case 0:
		ioc->enable_sdev_max_qd = 0;
		shost_for_each_device(sdev, ioc->shost) {
			sas_device_priv_data = sdev->hostdata;
			if (!sas_device_priv_data)
				continue;
			sas_target_priv_data = sas_device_priv_data->sas_target;
			if (!sas_target_priv_data)
				continue;

			if (sas_target_priv_data->flags &
			    MPT_TARGET_FLAGS_VOLUME) {
				raid_device =
				    mpt3sas_raid_device_find_by_handle(ioc,
				    sas_target_priv_data->handle);

				switch (raid_device->volume_type) {
				case MPI2_RAID_VOL_TYPE_RAID0:
					if (raid_device->device_info &
					    MPI2_SAS_DEVICE_INFO_SSP_TARGET)
						qdepth =
						    MPT3SAS_SAS_QUEUE_DEPTH;
					else
						qdepth =
						    MPT3SAS_SATA_QUEUE_DEPTH;
					break;
				case MPI2_RAID_VOL_TYPE_RAID1E:
				case MPI2_RAID_VOL_TYPE_RAID1:
				case MPI2_RAID_VOL_TYPE_RAID10:
				case MPI2_RAID_VOL_TYPE_UNKNOWN:
				default:
					qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
				}
			} else if (sas_target_priv_data->flags &
			    MPT_TARGET_FLAGS_PCIE_DEVICE)
				qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
			else
				qdepth = MPT3SAS_SAS_QUEUE_DEPTH;

			mpt3sas_scsih_change_queue_depth(sdev, qdepth);
		}
		break;
	case 1:
		ioc->enable_sdev_max_qd = 1;
		shost_for_each_device(sdev, ioc->shost)
			mpt3sas_scsih_change_queue_depth(sdev,
			    shost->can_queue);
		break;
	default:
		return -EINVAL;
	}

	return strlen(buf);
}
static DEVICE_ATTR_RW(enable_sdev_max_qd);

struct device_attribute *mpt3sas_host_attrs[] = {
	&dev_attr_version_fw,
	&dev_attr_version_bios,
@@ -3427,6 +3528,7 @@ struct device_attribute *mpt3sas_host_attrs[] = {
	&dev_attr_diag_trigger_mpi,
	&dev_attr_drv_support_bitmap,
	&dev_attr_BRM_status,
	&dev_attr_enable_sdev_max_qd,
	NULL,
};

+36 −4
Original line number Diff line number Diff line
@@ -155,6 +155,10 @@ static int prot_mask = -1;
module_param(prot_mask, int, 0444);
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");

static bool enable_sdev_max_qd;
module_param(enable_sdev_max_qd, bool, 0444);
MODULE_PARM_DESC(enable_sdev_max_qd,
	"Enable sdev max qd as can_queue, def=disabled(0)");

/* raid transport support */
static struct raid_template *mpt3sas_raid_template;
@@ -1519,7 +1523,13 @@ scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)

	max_depth = shost->can_queue;

	/* limit max device queue for SATA to 32 */
	/*
	 * limit max device queue for SATA to 32 if enable_sdev_max_qd
	 * is disabled.
	 */
	if (ioc->enable_sdev_max_qd)
		goto not_sata;

	sas_device_priv_data = sdev->hostdata;
	if (!sas_device_priv_data)
		goto not_sata;
@@ -1548,6 +1558,25 @@ scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
	return scsi_change_queue_depth(sdev, qdepth);
}

/**
 * mpt3sas_scsih_change_queue_depth - setting device queue depth
 * @sdev: scsi device struct
 * @qdepth: requested queue depth
 *
 * Returns nothing.
 */
void
mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
	struct Scsi_Host *shost = sdev->host;
	struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);

	if (ioc->enable_sdev_max_qd)
		qdepth = shost->can_queue;

	scsih_change_queue_depth(sdev, qdepth);
}

/**
 * scsih_target_alloc - target add routine
 * @starget: scsi target struct
@@ -2306,7 +2335,7 @@ scsih_slave_configure(struct scsi_device *sdev)
						MPT3SAS_RAID_MAX_SECTORS);
		}

		scsih_change_queue_depth(sdev, qdepth);
		mpt3sas_scsih_change_queue_depth(sdev, qdepth);

		/* raid transport support */
		if (!ioc->is_warpdrive)
@@ -2370,7 +2399,7 @@ scsih_slave_configure(struct scsi_device *sdev)

		pcie_device_put(pcie_device);
		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
		scsih_change_queue_depth(sdev, qdepth);
		mpt3sas_scsih_change_queue_depth(sdev, qdepth);
		/* Enable QUEUE_FLAG_NOMERGES flag, so that IOs won't be
		 ** merged and can eliminate holes created during merging
		 ** operation.
@@ -2430,7 +2459,7 @@ scsih_slave_configure(struct scsi_device *sdev)
		_scsih_display_sata_capabilities(ioc, handle, sdev);


	scsih_change_queue_depth(sdev, qdepth);
	mpt3sas_scsih_change_queue_depth(sdev, qdepth);

	if (ssp_target) {
		sas_read_port_mode_page(sdev);
@@ -10507,6 +10536,9 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	 * Enable MEMORY MOVE support flag.
	 */
	ioc->drv_support_bitmap |= MPT_DRV_SUPPORT_BITMAP_MEMMOVE;

	ioc->enable_sdev_max_qd = enable_sdev_max_qd;

	/* misc semaphores and spin locks */
	mutex_init(&ioc->reset_in_progress_mutex);
	/* initializing pci_access_mutex lock */