2016-10-10 12:41:44

by Tahsin Erdogan

[permalink] [raw]
Subject: [PATCH] dm: free io_barrier after blk_cleanup_queue call

dm_old_request_fn() has paths that access md->io_barrier. The party
destroying io_barrier should ensure that no future execution
of dm_old_request_fn() is possible. Move destruction to below
blk_cleanup_queue() to ensure this.

Signed-off-by: Tahsin Erdogan <[email protected]>
---
drivers/md/dm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index be35258324c1..ec513ee864f2 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1423,8 +1423,6 @@ static void cleanup_mapped_device(struct mapped_device *md)
if (md->bs)
bioset_free(md->bs);

- cleanup_srcu_struct(&md->io_barrier);
-
if (md->disk) {
spin_lock(&_minor_lock);
md->disk->private_data = NULL;
@@ -1436,6 +1434,8 @@ static void cleanup_mapped_device(struct mapped_device *md)
if (md->queue)
blk_cleanup_queue(md->queue);

+ cleanup_srcu_struct(&md->io_barrier);
+
if (md->bdev) {
bdput(md->bdev);
md->bdev = NULL;
--
2.8.0.rc3.226.g39d4020


2016-10-10 13:25:47

by Mike Snitzer

[permalink] [raw]
Subject: Re: dm: free io_barrier after blk_cleanup_queue call

On Mon, Oct 10 2016 at 8:35am -0400,
Tahsin Erdogan <[email protected]> wrote:

> dm_old_request_fn() has paths that access md->io_barrier. The party
> destroying io_barrier should ensure that no future execution
> of dm_old_request_fn() is possible. Move destruction to below
> blk_cleanup_queue() to ensure this.

I have to believe this was born out of code inspection rather than
actual need (due to crash, etc)?

The cleanup order isn't relevant. The reference counting of a DM device
governs whether a DM device (and its associated 'struct mapped_device')
can be destroyed. Please have a look at __dm_destroy, particularly:
* No one should increment the reference count of the mapped_device,
* after the mapped_device state becomes DMF_FREEING.

Mike

2016-10-10 14:52:09

by Tahsin Erdogan

[permalink] [raw]
Subject: Re: dm: free io_barrier after blk_cleanup_queue call

On Mon, Oct 10, 2016 at 6:25 AM, Mike Snitzer <[email protected]> wrote:
> I have to believe this was born out of code inspection rather than
> actual need (due to crash, etc)?

This got originated from several crashes I have seen with 4.3 kernel.
The crashes
were caused by null dereferencing of io_barrier->per_cpu_ref.

The issue may no longer be relevant after commit c91852ff0815
("dm: optimize dm_request_fn()") because conditions for accessing
io_barrier may not longer exist. But fix should be considered for
forked stable trees.