Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173626
b: refs/heads/master
c: 4a84067
h: refs/heads/master
v: v3
  • Loading branch information
Vasu Dev authored and James Bottomley committed Dec 4, 2009
1 parent eca1b8c commit ba5fb22
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 14caf44c69184ed72d46a2f883311daf27a4192f
refs/heads/master: 4a84067dbfce436b81779e585bf712b02ceee552
10 changes: 8 additions & 2 deletions trunk/drivers/scsi/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
38 changes: 38 additions & 0 deletions trunk/drivers/scsi/scsi_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/scsi/scsi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -941,6 +942,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
Expand Down
41 changes: 39 additions & 2 deletions trunk/drivers/scsi/scsi_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,13 +771,46 @@ 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;
}

static struct device_attribute sdev_attr_queue_depth_rw =
__ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
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)
Expand Down Expand Up @@ -866,8 +899,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
}

/* 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) {
Expand Down
9 changes: 6 additions & 3 deletions trunk/include/scsi/scsi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit ba5fb22

Please sign in to comment.