Re: [patch added to 3.12-stable] dm: fix AB-BA deadlock in __dm_destroy()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/20/16 17:20, Jiri Slaby wrote:
> commit 2a708cff93f1845b9239bc7d6310aef54e716c6a upstream.
> 
> __dm_destroy() takes io_barrier SRCU lock (dm_get_live_table) and
> suspend_lock in reverse order.  Doing so can cause AB-BA deadlock:
> 
>   __dm_destroy                    dm_swap_table
>   ---------------------------------------------------
>                                   mutex_lock(suspend_lock)
>   dm_get_live_table()
>     srcu_read_lock(io_barrier)
>                                   dm_sync_table()
>                                     synchronize_srcu(io_barrier)
>                                       .. waiting for dm_put_live_table()
>   mutex_lock(suspend_lock)
>     .. waiting for suspend_lock
> 
> Fix this by taking the locks in proper order.
> 
> Signed-off-by: Jun'ichi Nomura <j-nomura@xxxxxxxxxxxxx>
> Fixes: ab7c7bb6f4ab ("dm: hold suspend_lock while suspending device during device deletion")
> Acked-by: Mikulas Patocka <mpatocka@xxxxxxxxxx>
> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx>
> Signed-off-by: Jiri Slaby <jslaby@xxxxxxx>
> ---
>  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 5a0b1742f794..de444d3ae293 100644
> --- a/drivers/md/dm.c
> +++ b/drivers/md/dm.c
> @@ -2444,14 +2444,14 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
>  	 * do not race with internal suspend.
>  	 */
>  	mutex_lock(&md->suspend_lock);
> +	map = dm_get_live_table(md, &srcu_idx);
>  	if (!dm_suspended_md(md)) {
>  		dm_table_presuspend_targets(map);
>  		dm_table_postsuspend_targets(map);
>  	}
> -	mutex_unlock(&md->suspend_lock);
> -
>  	/* dm_put_live_table must be before msleep, otherwise deadlock is possible */
>  	dm_put_live_table(md, srcu_idx);
> +	mutex_unlock(&md->suspend_lock);
>  
>  	/*
>  	 * Rare, but there may be I/O requests still going to complete,

I don't have 3.12-stable tree at hand but this patch looks incorrect.

The patch misses the part of upstream patch that removes existing
dm_get_live_table().  By just adding dm_get_live_table(), you will
have unbalanced numbers of get and put and break refcounting of md.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]