aboutsummaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2015-06-10 23:47:14 -0400
committerJens Axboe <axboe@fb.com>2015-06-11 11:01:40 -0400
commit4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 (patch)
tree4d4c03cbb69145550b693052c6b3dd198110bbc1 /block/genhd.c
parentc3b4afca7023b5aa0531912364246e67f79b3010 (diff)
block: fix ext_dev_lock lockdep report
================================= [ INFO: inconsistent lock state ] 4.1.0-rc7+ #217 Tainted: G O --------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. swapper/6/0 [HC0[0]:SC1[1]:HE1:SE0] takes: (ext_devt_lock){+.?...}, at: [<ffffffff8143a60c>] blk_free_devt+0x3c/0x70 {SOFTIRQ-ON-W} state was registered at: [<ffffffff810bf6b1>] __lock_acquire+0x461/0x1e70 [<ffffffff810c1947>] lock_acquire+0xb7/0x290 [<ffffffff818ac3a8>] _raw_spin_lock+0x38/0x50 [<ffffffff8143a07d>] blk_alloc_devt+0x6d/0xd0 <-- take the lock in process context [..] [<ffffffff810bf64e>] __lock_acquire+0x3fe/0x1e70 [<ffffffff810c00ad>] ? __lock_acquire+0xe5d/0x1e70 [<ffffffff810c1947>] lock_acquire+0xb7/0x290 [<ffffffff8143a60c>] ? blk_free_devt+0x3c/0x70 [<ffffffff818ac3a8>] _raw_spin_lock+0x38/0x50 [<ffffffff8143a60c>] ? blk_free_devt+0x3c/0x70 [<ffffffff8143a60c>] blk_free_devt+0x3c/0x70 <-- take the lock in softirq [<ffffffff8143bfec>] part_release+0x1c/0x50 [<ffffffff8158edf6>] device_release+0x36/0xb0 [<ffffffff8145ac2b>] kobject_cleanup+0x7b/0x1a0 [<ffffffff8145aad0>] kobject_put+0x30/0x70 [<ffffffff8158f147>] put_device+0x17/0x20 [<ffffffff8143c29c>] delete_partition_rcu_cb+0x16c/0x180 [<ffffffff8143c130>] ? read_dev_sector+0xa0/0xa0 [<ffffffff810e0e0f>] rcu_process_callbacks+0x2ff/0xa90 [<ffffffff810e0dcf>] ? rcu_process_callbacks+0x2bf/0xa90 [<ffffffff81067e2e>] __do_softirq+0xde/0x600 Neil sees this in his tests and it also triggers on pmem driver unbind for the libnvdimm tests. This fix is on top of an initial fix by Keith for incorrect usage of mutex_lock() in this path: 2da78092dda1 "block: Fix dev_t minor allocation lifetime". Both this and 2da78092dda1 are candidates for -stable. Fixes: 2da78092dda1 ("block: Fix dev_t minor allocation lifetime") Cc: <stable@vger.kernel.org> Cc: Keith Busch <keith.busch@intel.com> Reported-by: NeilBrown <neilb@suse.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 666e11b83983..ea982eadaf63 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -422,9 +422,9 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
422 /* allocate ext devt */ 422 /* allocate ext devt */
423 idr_preload(GFP_KERNEL); 423 idr_preload(GFP_KERNEL);
424 424
425 spin_lock(&ext_devt_lock); 425 spin_lock_bh(&ext_devt_lock);
426 idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); 426 idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT);
427 spin_unlock(&ext_devt_lock); 427 spin_unlock_bh(&ext_devt_lock);
428 428
429 idr_preload_end(); 429 idr_preload_end();
430 if (idx < 0) 430 if (idx < 0)
@@ -449,9 +449,9 @@ void blk_free_devt(dev_t devt)
449 return; 449 return;
450 450
451 if (MAJOR(devt) == BLOCK_EXT_MAJOR) { 451 if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
452 spin_lock(&ext_devt_lock); 452 spin_lock_bh(&ext_devt_lock);
453 idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); 453 idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
454 spin_unlock(&ext_devt_lock); 454 spin_unlock_bh(&ext_devt_lock);
455 } 455 }
456} 456}
457 457
@@ -690,13 +690,13 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
690 } else { 690 } else {
691 struct hd_struct *part; 691 struct hd_struct *part;
692 692
693 spin_lock(&ext_devt_lock); 693 spin_lock_bh(&ext_devt_lock);
694 part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); 694 part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
695 if (part && get_disk(part_to_disk(part))) { 695 if (part && get_disk(part_to_disk(part))) {
696 *partno = part->partno; 696 *partno = part->partno;
697 disk = part_to_disk(part); 697 disk = part_to_disk(part);
698 } 698 }
699 spin_unlock(&ext_devt_lock); 699 spin_unlock_bh(&ext_devt_lock);
700 } 700 }
701 701
702 return disk; 702 return disk;