summaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2012-09-11 15:10:58 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-09-17 09:58:18 +0200
commit12d7b1078bb374fc3e2955b9f2815415a66157b6 (patch)
treec99de58b079166e536a83a1b869daaa2fcfbe323 /drivers/s390/block/dasd.c
parents390/mm: fix user access page-table walk code (diff)
downloadlinux-12d7b1078bb374fc3e2955b9f2815415a66157b6.tar.xz
linux-12d7b1078bb374fc3e2955b9f2815415a66157b6.zip
s390/dasd: fix pathgroup race
If a new path is available we need to verify the path data. If it is the first path for a device the stop bits are removed after path verification. If a pathgroup is established we need to set system characteristics for the lcu. Therefore I/O has to be started. If the device is stopped the set system characteristics worker may block the path verification worker and the device is blocked. Turn on failfast for set system characteristics CQR to prevent a deadlock with the path verification worker. If a pathgroup is established on a device that is not in use trigger path verification. Maybe we were not informed about a working path. Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com> Reviewed-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r--drivers/s390/block/dasd.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 6498d15f874f..0595c763dafd 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2157,6 +2157,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
(!dasd_eer_enabled(device))) {
cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -EAGAIN;
continue;
}
/* Don't try to start requests if device is stopped */
@@ -3270,6 +3271,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
dasd_schedule_device_bh(device);
}
if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) {
+ if (!(device->path_data.opm & eventlpm) &&
+ !(device->path_data.tbvpm & eventlpm)) {
+ /*
+ * we can not establish a pathgroup on an
+ * unavailable path, so trigger a path
+ * verification first
+ */
+ device->path_data.tbvpm |= eventlpm;
+ dasd_schedule_device_bh(device);
+ }
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Pathgroup re-established\n");
if (device->discipline->kick_validate)