]> git.itanic.dy.fi Git - linux-stable/commitdiff
s390/dasd: configurable IFCC handling
authorStefan Haberland <sth@linux.vnet.ibm.com>
Tue, 19 Dec 2017 15:18:38 +0000 (16:18 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 22 Feb 2018 14:31:23 +0000 (15:31 +0100)
Make the behavior in case of constant IFCC/CCC errors configurable.
Add a sysfs attribute to switch between path disabled after threshold
exceeded (default) and message only.

Reviewed-by: Jan Hoeppner <hoeppner@linux.vnet.ibm.com>
Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/uapi/asm/dasd.h
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_devmap.c

index 451c601406b6901e6fd71fddaecbf431eb6715fd..832be5c2584f7018e814c8e5b4c691062c9b5e46 100644 (file)
@@ -68,25 +68,27 @@ typedef struct dasd_information2_t {
 #define DASD_FORMAT_CDL  2
 /*
  * values to be used for dasd_information_t.features
- * 0x00: default features
- * 0x01: readonly (ro)
- * 0x02: use diag discipline (diag)
- * 0x04: set the device initially online (internal use only)
- * 0x08: enable ERP related logging
- * 0x10: allow I/O to fail on lost paths
- * 0x20: allow I/O to fail when a lock was stolen
- * 0x40: give access to raw eckd data
- * 0x80: enable discard support
+ * 0x100: default features
+ * 0x001: readonly (ro)
+ * 0x002: use diag discipline (diag)
+ * 0x004: set the device initially online (internal use only)
+ * 0x008: enable ERP related logging
+ * 0x010: allow I/O to fail on lost paths
+ * 0x020: allow I/O to fail when a lock was stolen
+ * 0x040: give access to raw eckd data
+ * 0x080: enable discard support
+ * 0x100: enable autodisable for IFCC errors (default)
  */
-#define DASD_FEATURE_DEFAULT        0x00
-#define DASD_FEATURE_READONLY       0x01
-#define DASD_FEATURE_USEDIAG        0x02
-#define DASD_FEATURE_INITIAL_ONLINE  0x04
-#define DASD_FEATURE_ERPLOG         0x08
-#define DASD_FEATURE_FAILFAST       0x10
-#define DASD_FEATURE_FAILONSLCK      0x20
-#define DASD_FEATURE_USERAW         0x40
-#define DASD_FEATURE_DISCARD        0x80
+#define DASD_FEATURE_READONLY        0x001
+#define DASD_FEATURE_USEDIAG         0x002
+#define DASD_FEATURE_INITIAL_ONLINE   0x004
+#define DASD_FEATURE_ERPLOG          0x008
+#define DASD_FEATURE_FAILFAST        0x010
+#define DASD_FEATURE_FAILONSLCK       0x020
+#define DASD_FEATURE_USERAW          0x040
+#define DASD_FEATURE_DISCARD         0x080
+#define DASD_FEATURE_PATH_AUTODISABLE 0x100
+#define DASD_FEATURE_DEFAULT         DASD_FEATURE_PATH_AUTODISABLE
 
 #define DASD_PARTN_BITS 2
 
index ee14d8e45c971863c6aef252ecbadba64d365826..ee73b0607e47c7c6fc108aa6c7ffa05924ee3d74 100644 (file)
@@ -2214,15 +2214,28 @@ static void dasd_3990_erp_disable_path(struct dasd_device *device, __u8 lpum)
 {
        int pos = pathmask_to_pos(lpum);
 
+       if (!(device->features & DASD_FEATURE_PATH_AUTODISABLE)) {
+               dev_err(&device->cdev->dev,
+                       "Path %x.%02x (pathmask %02x) is operational despite excessive IFCCs\n",
+                       device->path[pos].cssid, device->path[pos].chpid, lpum);
+               goto out;
+       }
+
        /* no remaining path, cannot disable */
-       if (!(dasd_path_get_opm(device) & ~lpum))
-               return;
+       if (!(dasd_path_get_opm(device) & ~lpum)) {
+               dev_err(&device->cdev->dev,
+                       "Last path %x.%02x (pathmask %02x) is operational despite excessive IFCCs\n",
+                       device->path[pos].cssid, device->path[pos].chpid, lpum);
+               goto out;
+       }
 
        dev_err(&device->cdev->dev,
                "Path %x.%02x (pathmask %02x) is disabled - IFCC threshold exceeded\n",
                device->path[pos].cssid, device->path[pos].chpid, lpum);
        dasd_path_remove_opm(device, lpum);
        dasd_path_add_ifccpm(device, lpum);
+
+out:
        device->path[pos].errorclk = 0;
        atomic_set(&device->path[pos].error_count, 0);
 }
index e7cd28ff1984460540f70fd203326b08f2d5c8f9..b9ebb565ee2c70aa4672d539a4ac2d2236dc7fa8 100644 (file)
@@ -1550,9 +1550,49 @@ dasd_path_threshold_store(struct device *dev, struct device_attribute *attr,
        dasd_put_device(device);
        return count;
 }
-
 static DEVICE_ATTR(path_threshold, 0644, dasd_path_threshold_show,
                   dasd_path_threshold_store);
+
+/*
+ * configure if path is disabled after IFCC/CCC error threshold is
+ * exceeded
+ */
+static ssize_t
+dasd_path_autodisable_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct dasd_devmap *devmap;
+       int flag;
+
+       devmap = dasd_find_busid(dev_name(dev));
+       if (!IS_ERR(devmap))
+               flag = (devmap->features & DASD_FEATURE_PATH_AUTODISABLE) != 0;
+       else
+               flag = (DASD_FEATURE_DEFAULT &
+                       DASD_FEATURE_PATH_AUTODISABLE) != 0;
+       return snprintf(buf, PAGE_SIZE, flag ? "1\n" : "0\n");
+}
+
+static ssize_t
+dasd_path_autodisable_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t count)
+{
+       unsigned int val;
+       int rc;
+
+       if (kstrtouint(buf, 0, &val) || val > 1)
+               return -EINVAL;
+
+       rc = dasd_set_feature(to_ccwdev(dev),
+                             DASD_FEATURE_PATH_AUTODISABLE, val);
+
+       return rc ? : count;
+}
+
+static DEVICE_ATTR(path_autodisable, 0644,
+                  dasd_path_autodisable_show,
+                  dasd_path_autodisable_store);
 /*
  * interval for IFCC/CCC checks
  * meaning time with no IFCC/CCC error before the error counter
@@ -1623,6 +1663,7 @@ static struct attribute * dasd_attrs[] = {
        &dev_attr_host_access_count.attr,
        &dev_attr_path_masks.attr,
        &dev_attr_path_threshold.attr,
+       &dev_attr_path_autodisable.attr,
        &dev_attr_path_interval.attr,
        &dev_attr_path_reset.attr,
        &dev_attr_hpf.attr,