From: Vasu Dev <vasu.dev@intel.com>
To: linux-scsi@vger.kernel.org, devel@open-fcoe.org,
James.Bottomley@HansenPartnership.com, michaelc@cs.wisc.edu,
christof.schmitt@de.ibm.com
Subject: [PATCH v4 5/7] scsi-ml: adds queue_depth ramp up code
Date: Thu, 22 Oct 2009 15:46:33 -0700 [thread overview]
Message-ID: <20091022224627.20122.78013.stgit@vifc.jf.intel.com> (raw)
In-Reply-To: <20091016004700.22451.42962.stgit@vifc.jf.intel.com>
Current FC HBA queue_depth ramp up code depends on last queue
full time. The sdev already has last_queue_full_time field to
track last queue full time but stored value is truncated by
last four bits.
So this patch updates last_queue_full_time without truncating
last 4 bits to store full value and then updates its only
current usages in scsi_track_queue_full to ignore last four bits
to keep current usages same while also use this field
in added ramp up code.
Adds scsi_handle_queue_ramp_up to ramp up queue_depth on
successful completion of IO. The scsi_handle_queue_ramp_up will
do ramp up on all luns of a target, just same as ramp down done
on all luns on a target.
The ramp up is skipped in case the change_queue_depth is not
supported by LLD or already reached to added max_queue_depth.
Updates added max_queue_depth on every new update to default
queue_depth value.
The ramp up is also skipped if lapsed time since either last
queue ramp up or down is less than LLD specified
queue_ramp_up_period.
Adds queue_ramp_up_period to sysfs but only if change_queue_depth
is supported since ramp up and queue_ramp_up_period is needed only
in case change_queue_depth is supported first.
Initializes queue_ramp_up_period to 120HZ jiffies as initial
default value, it is same as used in existing lpfc and qla2xxx.
-v2
Combined all ramp code into this single patch.
-v3
Moves max_queue_depth initialization after slave_configure is
called from after slave_alloc calling done. Also adjusted
max_queue_depth check to skip ramp up if current queue_depth
is >= max_queue_depth.
-v4
Changes sdev->queue_ramp_up_period unit to ms when using sysfs i/f
to store or show its value.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
---
drivers/scsi/scsi.c | 10 ++++++++--
drivers/scsi/scsi_error.c | 38 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/scsi_scan.c | 3 +++
drivers/scsi/scsi_sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++--
include/scsi/scsi_device.h | 9 ++++++---
5 files changed, 94 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index dd098ca..a60da55 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -940,10 +940,16 @@ EXPORT_SYMBOL(scsi_adjust_queue_depth);
*/
int scsi_track_queue_full(struct scsi_device *sdev, int depth)
{
- if ((jiffies >> 4) == sdev->last_queue_full_time)
+
+ /*
+ * Don't let QUEUE_FULLs on the same
+ * jiffies count, they could all be from
+ * same event.
+ */
+ if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
return 0;
- sdev->last_queue_full_time = (jiffies >> 4);
+ sdev->last_queue_full_time = jiffies;
if (sdev->last_queue_full_depth != depth) {
sdev->last_queue_full_count = 1;
sdev->last_queue_full_depth = depth;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 7b1e20f..08ed506 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -331,6 +331,42 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
}
}
+static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
+{
+ struct scsi_host_template *sht = sdev->host->hostt;
+ struct scsi_device *tmp_sdev;
+
+ if (!sht->change_queue_depth ||
+ sdev->queue_depth >= sdev->max_queue_depth)
+ return;
+
+ if (time_before(jiffies,
+ sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
+ return;
+
+ if (time_before(jiffies,
+ sdev->last_queue_full_time + sdev->queue_ramp_up_period))
+ return;
+
+ /*
+ * Walk all devices of a target and do
+ * ramp up on them.
+ */
+ shost_for_each_device(tmp_sdev, sdev->host) {
+ if (tmp_sdev->channel != sdev->channel ||
+ tmp_sdev->id != sdev->id ||
+ tmp_sdev->queue_depth == sdev->max_queue_depth)
+ continue;
+ /*
+ * call back into LLD to increase queue_depth by one
+ * with ramp up reason code.
+ */
+ sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1,
+ SCSI_QDEPTH_RAMP_UP);
+ sdev->last_queue_ramp_up = jiffies;
+ }
+}
+
static void scsi_handle_queue_full(struct scsi_device *sdev)
{
struct scsi_host_template *sht = sdev->host->hostt;
@@ -393,6 +429,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
*/
switch (status_byte(scmd->result)) {
case GOOD:
+ scsi_handle_queue_ramp_up(scmd->device);
case COMMAND_TERMINATED:
return SUCCESS;
case CHECK_CONDITION:
@@ -1425,6 +1462,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
*/
return ADD_TO_MLQUEUE;
case GOOD:
+ scsi_handle_queue_ramp_up(scmd->device);
case COMMAND_TERMINATED:
return SUCCESS;
case TASK_ABORTED:
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index cb6338f..2847a86 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -251,6 +251,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
sdev->model = scsi_null_device_strs;
sdev->rev = scsi_null_device_strs;
sdev->host = shost;
+ sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
sdev->id = starget->id;
sdev->lun = lun;
sdev->channel = starget->channel;
@@ -940,6 +941,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
}
}
+ sdev->max_queue_depth = sdev->queue_depth;
+
/*
* Ok, the device is now all set up, we can
* register it and tell the rest of the kernel
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 4c59336..3a9e805 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -771,6 +771,8 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr,
if (retval < 0)
return retval;
+ sdev->max_queue_depth = sdev->queue_depth;
+
return count;
}
@@ -779,6 +781,37 @@ static struct device_attribute sdev_attr_queue_depth_rw =
sdev_store_queue_depth_rw);
static ssize_t
+sdev_show_queue_ramp_up_period(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_device *sdev;
+ sdev = to_scsi_device(dev);
+ return snprintf(buf, 20, "%u\n",
+ jiffies_to_msecs(sdev->queue_ramp_up_period));
+}
+
+static ssize_t
+sdev_store_queue_ramp_up_period(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ unsigned long period;
+
+ if (strict_strtoul(buf, 10, &period))
+ return -EINVAL;
+
+ sdev->queue_ramp_up_period = msecs_to_jiffies(period);
+ return period;
+}
+
+static struct device_attribute sdev_attr_queue_ramp_up_period =
+ __ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
+ sdev_show_queue_ramp_up_period,
+ sdev_store_queue_ramp_up_period);
+
+static ssize_t
sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -870,8 +903,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
get_device(&sdev->sdev_gendev);
/* create queue files, which may be writable, depending on the host */
- if (sdev->host->hostt->change_queue_depth)
- error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
+ if (sdev->host->hostt->change_queue_depth) {
+ error = device_create_file(&sdev->sdev_gendev,
+ &sdev_attr_queue_depth_rw);
+ error = device_create_file(&sdev->sdev_gendev,
+ &sdev_attr_queue_ramp_up_period);
+ }
else
error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
if (error) {
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 9af48cb..92c4c3b 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -81,11 +81,14 @@ struct scsi_device {
struct list_head starved_entry;
struct scsi_cmnd *current_cmnd; /* currently active command */
unsigned short queue_depth; /* How deep of a queue we want */
+ unsigned short max_queue_depth; /* max queue depth */
unsigned short last_queue_full_depth; /* These two are used by */
unsigned short last_queue_full_count; /* scsi_track_queue_full() */
- unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
- jiffie count on our counter, they
- could all be from the same event. */
+ unsigned long last_queue_full_time; /* last queue full time */
+ unsigned long queue_ramp_up_period; /* ramp up period in jiffies */
+#define SCSI_DEFAULT_RAMP_UP_PERIOD (120 * HZ)
+
+ unsigned long last_queue_ramp_up; /* last queue ramp up time */
unsigned int id, lun, channel;
next prev parent reply other threads:[~2009-10-22 22:46 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-16 0:46 [PATCH v2 1/7] scsi-ml: modify change_queue_depth to take in reason why it is being called Vasu Dev
[not found] ` <20091016004639.22451.76363.stgit-M4Lc0Xp98oKtqXYlAKuG4QC/G2K4zDHf@public.gmane.org>
2009-10-16 0:46 ` [PATCH v2 2/7] scsi error: have scsi-ml call change_queue_depth to handle QUEUE_FULL Vasu Dev
2009-10-16 0:46 ` [PATCH v2 3/7] libfc: convert libfc calling scsi_track_queue_full Vasu Dev
2009-10-16 0:46 ` [PATCH v2 4/7] fcoe, libfc: fix an libfc issue with queue ramp down in libfc Vasu Dev
2009-10-16 0:47 ` [PATCH v2 5/7] scsi-ml: adds queue_depth ramp up code Vasu Dev
[not found] ` <20091016004700.22451.42962.stgit-M4Lc0Xp98oKtqXYlAKuG4QC/G2K4zDHf@public.gmane.org>
2009-10-16 9:29 ` Christof Schmitt
[not found] ` <20091016092912.GA7199-VuU8Q2ydlaqCpDFQwvYvMTJtLkR7yuzc@public.gmane.org>
2009-10-16 18:16 ` Vasu Dev
2009-10-16 23:08 ` [PATCH v3] " Vasu Dev
[not found] ` <20091016230824.18916.84116.stgit-M4Lc0Xp98oKtqXYlAKuG4QC/G2K4zDHf@public.gmane.org>
2009-10-20 18:54 ` Christof Schmitt
2009-10-20 22:32 ` Vasu Dev
2009-10-20 23:14 ` [Open-FCoE] " Joe Eykholt
[not found] ` <4ADE444D.5090307-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
2009-10-21 7:49 ` Christof Schmitt
2009-10-21 17:45 ` [Open-FCoE] " Vasu Dev
[not found] ` <20091021074944.GA3563-VuU8Q2ydlaqCpDFQwvYvMTJtLkR7yuzc@public.gmane.org>
2009-10-21 17:54 ` Giridhar Malavali
2009-10-21 13:11 ` [Open-FCoE] " James Smart
2009-10-21 13:37 ` Michael Reed
2009-10-22 22:46 ` Vasu Dev [this message]
2009-10-23 13:53 ` [PATCH v4 5/7] " Christof Schmitt
2009-10-23 17:51 ` Giridhar Malavali
2009-10-16 0:47 ` [PATCH v2 6/7] libfc: adds queue_depth ramp up to libfc Vasu Dev
2009-10-16 0:47 ` [PATCH v2 7/7] zfcp: Adapt change_queue_depth for queue full tracking Vasu Dev
2009-10-28 22:48 ` [PATCH v2 1/7] scsi-ml: modify change_queue_depth to take in reason why it is being called James Bottomley
[not found] ` <1256770118.2989.24.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-10-29 1:43 ` Vasu Dev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091022224627.20122.78013.stgit@vifc.jf.intel.com \
--to=vasu.dev@intel.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=christof.schmitt@de.ibm.com \
--cc=devel@open-fcoe.org \
--cc=linux-scsi@vger.kernel.org \
--cc=michaelc@cs.wisc.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.