[SCSI] megaraid_sas: Add throttlequeuedepth module parameter
authoradam radford <aradford@gmail.com>
Wed, 18 Jul 2012 01:20:03 +0000 (18:20 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 24 Aug 2012 09:10:28 +0000 (13:10 +0400)
This allows a user to adjust the queue depth of the adapter when throttled due
to I/O timeout.

Signed-off-by: Adam Radford <aradford@gmail.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c

index e8f89264768109f69b075d83ce019f40f8967471..f65025d63bc8a47227a4714c45045ccd27706830 100644 (file)
@@ -747,6 +747,7 @@ struct megasas_ctrl_info {
 #define        MEGASAS_RESET_NOTICE_INTERVAL           5
 #define MEGASAS_IOCTL_CMD                      0
 #define MEGASAS_DEFAULT_CMD_TIMEOUT            90
+#define MEGASAS_THROTTLE_QUEUE_DEPTH           16
 
 /*
  * FW reports the maximum of number of commands that it can accept (maximum
@@ -1364,6 +1365,7 @@ struct megasas_instance {
        unsigned long bar;
        long reset_flags;
        struct mutex reset_mutex;
+       int throttlequeuedepth;
 };
 
 enum {
index dc27598785e5d781ff9790697f8b3a5960921d85..f8f0a165dfb678f14e2cc84090f87a22b3fa7357 100644 (file)
@@ -71,6 +71,11 @@ static int msix_disable;
 module_param(msix_disable, int, S_IRUGO);
 MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
 
+static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
+module_param(throttlequeuedepth, int, S_IRUGO);
+MODULE_PARM_DESC(throttlequeuedepth,
+       "Adapter queue depth when throttled due to I/O timeout. Default: 16");
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGASAS_VERSION);
 MODULE_AUTHOR("megaraidlinux@lsi.com");
@@ -1595,8 +1600,9 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
 {
        unsigned long flags;
        if (instance->flag & MEGASAS_FW_BUSY
-               && time_after(jiffies, instance->last_time + 5 * HZ)
-               && atomic_read(&instance->fw_outstanding) < 17) {
+           && time_after(jiffies, instance->last_time + 5 * HZ)
+           && atomic_read(&instance->fw_outstanding) <
+           instance->throttlequeuedepth + 1) {
 
                spin_lock_irqsave(instance->host->host_lock, flags);
                instance->flag &= ~MEGASAS_FW_BUSY;
@@ -1914,7 +1920,7 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
                /* FW is busy, throttle IO */
                spin_lock_irqsave(instance->host->host_lock, flags);
 
-               instance->host->can_queue = 16;
+               instance->host->can_queue = instance->throttlequeuedepth;
                instance->last_time = jiffies;
                instance->flag |= MEGASAS_FW_BUSY;
 
@@ -3577,6 +3583,24 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
        kfree(ctrl_info);
 
+       /* Check for valid throttlequeuedepth module parameter */
+       if (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY ||
+           instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) {
+               if (throttlequeuedepth > (instance->max_fw_cmds -
+                                         MEGASAS_SKINNY_INT_CMDS))
+                       instance->throttlequeuedepth =
+                               MEGASAS_THROTTLE_QUEUE_DEPTH;
+               else
+                       instance->throttlequeuedepth = throttlequeuedepth;
+       } else {
+               if (throttlequeuedepth > (instance->max_fw_cmds -
+                                         MEGASAS_INT_CMDS))
+                       instance->throttlequeuedepth =
+                               MEGASAS_THROTTLE_QUEUE_DEPTH;
+               else
+                       instance->throttlequeuedepth = throttlequeuedepth;
+       }
+
         /*
        * Setup tasklet for cmd completion
        */