| From 4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 Mon Sep 17 00:00:00 2001 |
| From: Dan Williams <dan.j.williams@intel.com> |
| Date: Wed, 10 Jun 2015 23:47:14 -0400 |
| Subject: block: fix ext_dev_lock lockdep report |
| |
| From: Dan Williams <dan.j.williams@intel.com> |
| |
| commit 4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 upstream. |
| |
| ================================= |
| [ 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: 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| block/genhd.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| --- a/block/genhd.c |
| +++ b/block/genhd.c |
| @@ -422,9 +422,9 @@ int blk_alloc_devt(struct hd_struct *par |
| /* allocate ext devt */ |
| idr_preload(GFP_KERNEL); |
| |
| - spin_lock(&ext_devt_lock); |
| + spin_lock_bh(&ext_devt_lock); |
| idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); |
| - spin_unlock(&ext_devt_lock); |
| + spin_unlock_bh(&ext_devt_lock); |
| |
| idr_preload_end(); |
| if (idx < 0) |
| @@ -449,9 +449,9 @@ void blk_free_devt(dev_t devt) |
| return; |
| |
| if (MAJOR(devt) == BLOCK_EXT_MAJOR) { |
| - spin_lock(&ext_devt_lock); |
| + spin_lock_bh(&ext_devt_lock); |
| idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
| - spin_unlock(&ext_devt_lock); |
| + spin_unlock_bh(&ext_devt_lock); |
| } |
| } |
| |
| @@ -691,13 +691,13 @@ struct gendisk *get_gendisk(dev_t devt, |
| } else { |
| struct hd_struct *part; |
| |
| - spin_lock(&ext_devt_lock); |
| + spin_lock_bh(&ext_devt_lock); |
| part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
| if (part && get_disk(part_to_disk(part))) { |
| *partno = part->partno; |
| disk = part_to_disk(part); |
| } |
| - spin_unlock(&ext_devt_lock); |
| + spin_unlock_bh(&ext_devt_lock); |
| } |
| |
| return disk; |