diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2008-08-21 13:46:39 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-08-21 13:46:41 -0400 |
commit | 91c36919a456589f4f073671474a1f899e0d3c2b (patch) | |
tree | 63cb2ee1afd9b00bf2ea4959482d58f402bb21f3 /drivers/s390/block/dasd.c | |
parent | 49fd38bdaa96f093fcad3176a781a4d0de8f8602 (diff) |
[S390] cio: call ccw driver notify function with lock held
Calling a ccw driver's notify function without the ccw device lock
held opens up a race window between discovery and handling of a change
in the device operational state. As a result, the device driver may
encounter unexpected device malfunction, leading to out-of-retry
situations or similar.
Remove race by extending the ccw device lock from state change
discovery to the calling of the notify function.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@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.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1b6c52ef7339..acb78017e7d0 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2333,13 +2333,11 @@ int dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2333 | { | 2333 | { |
2334 | struct dasd_device *device; | 2334 | struct dasd_device *device; |
2335 | struct dasd_ccw_req *cqr; | 2335 | struct dasd_ccw_req *cqr; |
2336 | unsigned long flags; | ||
2337 | int ret; | 2336 | int ret; |
2338 | 2337 | ||
2339 | device = dasd_device_from_cdev(cdev); | 2338 | device = dasd_device_from_cdev_locked(cdev); |
2340 | if (IS_ERR(device)) | 2339 | if (IS_ERR(device)) |
2341 | return 0; | 2340 | return 0; |
2342 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); | ||
2343 | ret = 0; | 2341 | ret = 0; |
2344 | switch (event) { | 2342 | switch (event) { |
2345 | case CIO_GONE: | 2343 | case CIO_GONE: |
@@ -2369,7 +2367,6 @@ int dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2369 | ret = 1; | 2367 | ret = 1; |
2370 | break; | 2368 | break; |
2371 | } | 2369 | } |
2372 | spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); | ||
2373 | dasd_put_device(device); | 2370 | dasd_put_device(device); |
2374 | return ret; | 2371 | return ret; |
2375 | } | 2372 | } |