summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorRen Mingxin <renmx@cn.fujitsu.com>2013-11-11 12:44:56 (GMT)
committerJames Bottomley <JBottomley@Parallels.com>2013-12-19 15:39:02 (GMT)
commitbb3b621a33d60fc2baddf31597ade01243e00a2c (patch)
tree73fae0429ce43ce37845e207cb36da2e8f54d42c /drivers/scsi/scsi_sysfs.c
parent76ad3e5956bf0bc8871ebd19ebda03f2287c966a (diff)
downloadlinux-bb3b621a33d60fc2baddf31597ade01243e00a2c.tar.xz
[SCSI] Set the minimum valid value of 'eh_deadline' as 0
The former minimum valid value of 'eh_deadline' is 1s, which means the earliest occasion to shorten EH is 1 second later since a command is failed or timed out. But if we want to skip EH steps ASAP, we have to wait until the first EH step is finished. If the duration of the first EH step is long, this waiting time is excruciating. So, it is necessary to accept 0 as the minimum valid value for 'eh_deadline'. According to my test, with Hannes' patchset 'New EH command timeout handler' as well, the minimum IO time is improved from 73s (eh_deadline = 1) to 43s(eh_deadline = 0) when commands are timed out by disabling RSCN and target port. Signed-off-by: Ren Mingxin <renmx@cn.fujitsu.com> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 8ff62c2..9117d0b 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -287,7 +287,9 @@ show_shost_eh_deadline(struct device *dev,
{
struct Scsi_Host *shost = class_to_shost(dev);
- return sprintf(buf, "%d\n", shost->eh_deadline / HZ);
+ if (shost->eh_deadline == -1)
+ return snprintf(buf, strlen("off") + 2, "off\n");
+ return sprintf(buf, "%u\n", shost->eh_deadline / HZ);
}
static ssize_t
@@ -296,22 +298,34 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
{
struct Scsi_Host *shost = class_to_shost(dev);
int ret = -EINVAL;
- int deadline;
- unsigned long flags;
+ unsigned long deadline, flags;
if (shost->transportt && shost->transportt->eh_strategy_handler)
return ret;
- if (sscanf(buf, "%d\n", &deadline) == 1) {
- spin_lock_irqsave(shost->host_lock, flags);
- if (scsi_host_in_recovery(shost))
- ret = -EBUSY;
- else {
+ if (!strncmp(buf, "off", strlen("off")))
+ deadline = -1;
+ else {
+ ret = kstrtoul(buf, 10, &deadline);
+ if (ret)
+ return ret;
+ if (deadline * HZ > UINT_MAX)
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (scsi_host_in_recovery(shost))
+ ret = -EBUSY;
+ else {
+ if (deadline == -1)
+ shost->eh_deadline = -1;
+ else
shost->eh_deadline = deadline * HZ;
- ret = count;
- }
- spin_unlock_irqrestore(shost->host_lock, flags);
+
+ ret = count;
}
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
return ret;
}