[S390] cio: improve error recovery for internal I/Os
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Mon, 7 Dec 2009 11:51:40 +0000 (12:51 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Mon, 7 Dec 2009 11:51:33 +0000 (12:51 +0100)
Improve error recovery for internal I/Os by repeating each I/O
256 times per path to cope with long-running non-permanent error
conditions. Also retry each path twice to cope with link flapping,
i.e. single paths becoming unavailable in the order in which they
are tried.

Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/cio/ccwreq.c
drivers/s390/cio/device_id.c
drivers/s390/cio/device_pgid.c
drivers/s390/cio/io_sch.h

index a6e205a384b2c88300224c36c09ca0f8d2b95cf7..9509e3860934a81b396288ca3492853c7edd3709 100644 (file)
@@ -82,7 +82,7 @@ static void ccwreq_do(struct ccw_device *cdev)
                /* Perform start function. */
                sch->lpm = 0xff;
                memset(&cdev->private->irb, 0, sizeof(struct irb));
-               rc = cio_start(sch, cp, req->mask);
+               rc = cio_start(sch, cp, (u8) req->mask);
                if (rc == 0) {
                        /* I/O started successfully. */
                        ccw_device_set_timeout(cdev, req->timeout);
@@ -116,7 +116,8 @@ void ccw_request_start(struct ccw_device *cdev)
 {
        struct ccw_request *req = &cdev->private->req;
 
-       req->mask       = 0x80;
+       /* Try all paths twice to counter link flapping. */
+       req->mask       = 0x8080;
        req->retries    = req->maxretries;
        req->mask       = lpm_adjust(req->mask, req->lpm);
        req->drc        = 0;
@@ -212,7 +213,7 @@ static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status)
        }  __attribute__ ((packed)) data;
        data.dev_id     = cdev->private->dev_id;
        data.retries    = req->retries;
-       data.lpm        = req->mask;
+       data.lpm        = (u8) req->mask;
        data.status     = (u8) status;
        CIO_TRACE_EVENT(2, "reqstat");
        CIO_HEX_EVENT(2, &data, sizeof(data));
index 4728644ed85c5c72521ca761276de3a326ff73b6..78a0b43862c5feb41c0888812c978f686f5f4891 100644 (file)
@@ -21,7 +21,7 @@
 #include "device.h"
 #include "io_sch.h"
 
-#define SENSE_ID_RETRIES       5
+#define SENSE_ID_RETRIES       256
 #define SENSE_ID_TIMEOUT       (10 * HZ)
 #define SENSE_ID_MIN_LEN       4
 #define SENSE_ID_BASIC_LEN     7
index 5bcefeaff744aeea26d5aabd5666c53ff8976a64..aad188e43b4fe4f6ad260eb168efddd4fb3852d2 100644 (file)
@@ -20,7 +20,7 @@
 #include "device.h"
 #include "io_sch.h"
 
-#define PGID_RETRIES   5
+#define PGID_RETRIES   256
 #define PGID_TIMEOUT   (10 * HZ)
 
 /*
index dbc69a5a043e0ffaa9b0c3f97e8e920e1855f992..d72ae4c93af9beb497c8d4de9a01a4c70f0ac9aa 100644 (file)
@@ -109,7 +109,7 @@ struct ccw_request {
        void (*callback)(struct ccw_device *, void *, int);
        void *data;
        /* These fields are used internally. */
-       u8 mask;
+       u16 mask;
        u16 retries;
        int drc;
        int cancel:1;