]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: mpt3sas: Introduce module parameter to override queue depth
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Thu, 22 Aug 2019 06:19:01 +0000 (02:19 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 29 Aug 2019 21:55:53 +0000 (17:55 -0400)
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: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c

index 745e0e13b7ab36c017b7b83a39fcda3b423a9159..faca0a5e71f89b94719f008f6018916fe37a7b55 100644 (file)
@@ -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,
index da29005d72bd622022ce56ee230a406adccc4443..7d696952b376394ec0ba8016e90fb54401060c66 100644 (file)
@@ -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,
 };
 
index 9904775493d0a4283ae77a43e71f55e50f189487..d0c2f8d6f2a2f893358fb2fc11882f6bf1f7bc18 100644 (file)
@@ -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 */