Skip to content

Commit bd293d0

Browse files
biger410snitm
authored andcommitted
dm bufio: fix deadlock with loop device
When thin-volume is built on loop device, if available memory is low, the following deadlock can be triggered: One process P1 allocates memory with GFP_FS flag, direct alloc fails, memory reclaim invokes memory shrinker in dm_bufio, dm_bufio_shrink_scan() runs, mutex dm_bufio_client->lock is acquired, then P1 waits for dm_buffer IO to complete in __try_evict_buffer(). But this IO may never complete if issued to an underlying loop device that forwards it using direct-IO, which allocates memory using GFP_KERNEL (see: do_blockdev_direct_IO()). If allocation fails, memory reclaim will invoke memory shrinker in dm_bufio, dm_bufio_shrink_scan() will be invoked, and since the mutex is already held by P1 the loop thread will hang, and IO will never complete. Resulting in ABBA deadlock. Cc: [email protected] Signed-off-by: Junxiao Bi <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 2e60238 commit bd293d0

File tree

1 file changed

+1
-3
lines changed

1 file changed

+1
-3
lines changed

drivers/md/dm-bufio.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1599,9 +1599,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
15991599
unsigned long freed;
16001600

16011601
c = container_of(shrink, struct dm_bufio_client, shrinker);
1602-
if (sc->gfp_mask & __GFP_FS)
1603-
dm_bufio_lock(c);
1604-
else if (!dm_bufio_trylock(c))
1602+
if (!dm_bufio_trylock(c))
16051603
return SHRINK_STOP;
16061604

16071605
freed = __scan(c, sc->nr_to_scan, sc->gfp_mask);

0 commit comments

Comments
 (0)