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/2016, 10:44 AM, Junichi Nomura wrote:
> 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.

Right! I have no idea, how the hunk could have got lost.

thanks,
-- 
js
suse labs
--
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]