aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-10-23 04:51:21 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 07:17:59 -0400
commitb45620229dd67ff1daffa8adce57f37b37860f78 (patch)
tree22f8577437188e6699fa9d1f05841ea1f545a68f /drivers/scsi/scsi_sysfs.c
parent6b1e5a45d4eaa75e28f2d170ea43ab8fc6dd34d8 (diff)
[SCSI] Add 'eh_deadline' to limit SCSI EH runtime
This patchs adds an 'eh_deadline' sysfs attribute to the scsi host which limits the overall runtime of the SCSI EH. The 'eh_deadline' value is stored in the now obsolete field 'resetting'. When a command is failed the start time of the EH is stored in 'last_reset'. If the overall runtime of the SCSI EH is longer than last_reset + eh_deadline, the EH is short-circuited and falls through to issue a host reset only. [jejb: add comments in Scsi_Host about new fields] 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.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index a73471074a02..8ff62c26a41c 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -281,6 +281,42 @@ exit_store_host_reset:
281 281
282static DEVICE_ATTR(host_reset, S_IWUSR, NULL, store_host_reset); 282static DEVICE_ATTR(host_reset, S_IWUSR, NULL, store_host_reset);
283 283
284static ssize_t
285show_shost_eh_deadline(struct device *dev,
286 struct device_attribute *attr, char *buf)
287{
288 struct Scsi_Host *shost = class_to_shost(dev);
289
290 return sprintf(buf, "%d\n", shost->eh_deadline / HZ);
291}
292
293static ssize_t
294store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
295 const char *buf, size_t count)
296{
297 struct Scsi_Host *shost = class_to_shost(dev);
298 int ret = -EINVAL;
299 int deadline;
300 unsigned long flags;
301
302 if (shost->transportt && shost->transportt->eh_strategy_handler)
303 return ret;
304
305 if (sscanf(buf, "%d\n", &deadline) == 1) {
306 spin_lock_irqsave(shost->host_lock, flags);
307 if (scsi_host_in_recovery(shost))
308 ret = -EBUSY;
309 else {
310 shost->eh_deadline = deadline * HZ;
311 ret = count;
312 }
313 spin_unlock_irqrestore(shost->host_lock, flags);
314 }
315 return ret;
316}
317
318static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline);
319
284shost_rd_attr(unique_id, "%u\n"); 320shost_rd_attr(unique_id, "%u\n");
285shost_rd_attr(host_busy, "%hu\n"); 321shost_rd_attr(host_busy, "%hu\n");
286shost_rd_attr(cmd_per_lun, "%hd\n"); 322shost_rd_attr(cmd_per_lun, "%hd\n");
@@ -308,6 +344,7 @@ static struct attribute *scsi_sysfs_shost_attrs[] = {
308 &dev_attr_prot_capabilities.attr, 344 &dev_attr_prot_capabilities.attr,
309 &dev_attr_prot_guard_type.attr, 345 &dev_attr_prot_guard_type.attr,
310 &dev_attr_host_reset.attr, 346 &dev_attr_host_reset.attr,
347 &dev_attr_eh_deadline.attr,
311 NULL 348 NULL
312}; 349};
313 350