diff options
author | Horst Hummel <horst.hummel@de.ibm.com> | 2005-09-03 18:57:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:26 -0400 |
commit | c6eb7b7703ac4b3401b74f411c8c51ded214bf19 (patch) | |
tree | 1cb3563cb83f80347dbc3e4bd30c4635d401e87a /drivers/s390/block/dasd_devmap.c | |
parent | 942eaabd5d77522223a311ed9bddaaa3cefde27d (diff) |
[PATCH] s390: deadlock in dasd_devmap
Reintroduce a read-only copy of the devmap features in the device struct.
This is necessary to solve a deadlock on the dasd_devmap_lock which is
acquired by dasd_get_features called from the dasd tasklet. The current
implementation of devmap doesn't allow to call any devmap function from
interrupt or softirq context.
Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index d948566bb24a..bda896d9d788 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * functions may not be called from interrupt context. In particular | 11 | * functions may not be called from interrupt context. In particular |
12 | * dasd_get_device is a no-no from interrupt context. | 12 | * dasd_get_device is a no-no from interrupt context. |
13 | * | 13 | * |
14 | * $Revision: 1.40 $ | 14 | * $Revision: 1.43 $ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
@@ -513,6 +513,7 @@ dasd_create_device(struct ccw_device *cdev) | |||
513 | if (!devmap->device) { | 513 | if (!devmap->device) { |
514 | devmap->device = device; | 514 | devmap->device = device; |
515 | device->devindex = devmap->devindex; | 515 | device->devindex = devmap->devindex; |
516 | device->features = devmap->features; | ||
516 | get_device(&cdev->dev); | 517 | get_device(&cdev->dev); |
517 | device->cdev = cdev; | 518 | device->cdev = cdev; |
518 | rc = 0; | 519 | rc = 0; |
@@ -643,6 +644,8 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf | |||
643 | devmap->features |= DASD_FEATURE_READONLY; | 644 | devmap->features |= DASD_FEATURE_READONLY; |
644 | else | 645 | else |
645 | devmap->features &= ~DASD_FEATURE_READONLY; | 646 | devmap->features &= ~DASD_FEATURE_READONLY; |
647 | if (devmap->device) | ||
648 | devmap->device->features = devmap->features; | ||
646 | if (devmap->device && devmap->device->gdp) | 649 | if (devmap->device && devmap->device->gdp) |
647 | set_disk_ro(devmap->device->gdp, ro_flag); | 650 | set_disk_ro(devmap->device->gdp, ro_flag); |
648 | spin_unlock(&dasd_devmap_lock); | 651 | spin_unlock(&dasd_devmap_lock); |
@@ -758,7 +761,8 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag) | |||
758 | devmap->features |= feature; | 761 | devmap->features |= feature; |
759 | else | 762 | else |
760 | devmap->features &= ~feature; | 763 | devmap->features &= ~feature; |
761 | 764 | if (devmap->device) | |
765 | devmap->device->features = devmap->features; | ||
762 | spin_unlock(&dasd_devmap_lock); | 766 | spin_unlock(&dasd_devmap_lock); |
763 | return 0; | 767 | return 0; |
764 | } | 768 | } |