diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-12 15:08:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-12 15:08:46 -0400 |
commit | 1a2acc9e9214699a99389e323e6686e9e0e2ca67 (patch) | |
tree | 8f8072ba0624ceb63ac0115a81d85435323fe79c /block | |
parent | d8c3291c73b958243b33f8509d4507e76dafd055 (diff) |
Revert "[BLOCK] Fix oops on removal of SD/MMC card"
This reverts commit 56cf6504fc1c0c221b82cebc16a444b684140fb7.
Both Erik Mouw and Andrew Vasquez independently pinpointed this commit
as causing problems, where the slab cache for a driver is never released
(most obviously causing problems when immediately re-loading that
driver, resulting in a "kmem_cache_create: duplicate cache <xyz>"
message, but it can also cause other trouble).
James Bottomley dug into it, and reports:
"OK, here's the scoop. The problem patch adds a get of driverfs_dev in
add_disk(), but doesn't put it again until disk_release() (which occurs
on final put_disk() of the gendisk).
However, in SCSI, the driverfs_dev is the sdev_gendev. That means
there's a reference held on sdev_gendev until final disk put.
Unfortunately, we use the driver model driver_remove to trigger
del_gendisk (which removes the gendisk from visibility and decrements
the refcount), so we've introduced an unbreakable deadlock in the
reference counting with this.
I suggest simply reversing this patch at the moment. If Russell and
Jens can tell me what they're trying to do I'll see if there's another
way to do it."
so hereby the patch gets reverted, waiting for a better fix.
Cc: Jens Axboe <axboe@suse.de>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: James Bottomley <James.Bottomley@SteelEye.com>
Cc: Erik Mouw <erik@harddisk-recovery.com>
Cc: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'block')
-rw-r--r-- | block/genhd.c | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/block/genhd.c b/block/genhd.c index d96572589621..5a8d3bf02f17 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -182,7 +182,6 @@ static int exact_lock(dev_t dev, void *data) | |||
182 | */ | 182 | */ |
183 | void add_disk(struct gendisk *disk) | 183 | void add_disk(struct gendisk *disk) |
184 | { | 184 | { |
185 | get_device(disk->driverfs_dev); | ||
186 | disk->flags |= GENHD_FL_UP; | 185 | disk->flags |= GENHD_FL_UP; |
187 | blk_register_region(MKDEV(disk->major, disk->first_minor), | 186 | blk_register_region(MKDEV(disk->major, disk->first_minor), |
188 | disk->minors, NULL, exact_match, exact_lock, disk); | 187 | disk->minors, NULL, exact_match, exact_lock, disk); |
@@ -428,7 +427,6 @@ static struct attribute * default_attrs[] = { | |||
428 | static void disk_release(struct kobject * kobj) | 427 | static void disk_release(struct kobject * kobj) |
429 | { | 428 | { |
430 | struct gendisk *disk = to_disk(kobj); | 429 | struct gendisk *disk = to_disk(kobj); |
431 | put_device(disk->driverfs_dev); | ||
432 | kfree(disk->random); | 430 | kfree(disk->random); |
433 | kfree(disk->part); | 431 | kfree(disk->part); |
434 | free_disk_stats(disk); | 432 | free_disk_stats(disk); |