Skip to content

Commit 9bbf5fe

Browse files
Coly LiMike Snitzer
authored andcommitted
dm thin: fix deadlock when swapping to thin device
This is an already known issue that dm-thin volume cannot be used as swap, otherwise a deadlock may happen when dm-thin internal memory demand triggers swap I/O on the dm-thin volume itself. But thanks to commit a666e5c ("dm: fix deadlock when swapping to encrypted device"), the limit_swap_bios target flag can also be used for dm-thin to avoid the recursive I/O when it is used as swap. Fix is to simply set ti->limit_swap_bios to true in both pool_ctr() and thin_ctr(). In my test, I create a dm-thin volume /dev/vg/swap and use it as swap device. Then I run fio on another dm-thin volume /dev/vg/main and use large --blocksize to trigger swap I/O onto /dev/vg/swap. The following fio command line is used in my test, fio --name recursive-swap-io --lockmem 1 --iodepth 128 \ --ioengine libaio --filename /dev/vg/main --rw randrw \ --blocksize 1M --numjobs 32 --time_based --runtime=12h Without this fix, the whole system can be locked up within 15 seconds. With this fix, there is no any deadlock or hung task observed after 2 hours of running fio. Furthermore, if blocksize is changed from 1M to 128M, after around 30 seconds fio has no visible I/O, and the out-of-memory killer message shows up in kernel message. After around 20 minutes all fio processes are killed and the whole system is back to being alive. This is exactly what is expected when recursive I/O happens on dm-thin volume when it is used as swap. Depends-on: a666e5c ("dm: fix deadlock when swapping to encrypted device") Cc: [email protected] Signed-off-by: Coly Li <[email protected]> Acked-by: Mikulas Patocka <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent d695e44 commit 9bbf5fe

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

drivers/md/dm-thin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3369,6 +3369,7 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
33693369
pt->low_water_blocks = low_water_blocks;
33703370
pt->adjusted_pf = pt->requested_pf = pf;
33713371
ti->num_flush_bios = 1;
3372+
ti->limit_swap_bios = true;
33723373

33733374
/*
33743375
* Only need to enable discards if the pool should pass
@@ -4249,6 +4250,7 @@ static int thin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
42494250
goto bad;
42504251

42514252
ti->num_flush_bios = 1;
4253+
ti->limit_swap_bios = true;
42524254
ti->flush_supported = true;
42534255
ti->accounts_remapped_io = true;
42544256
ti->per_io_data_size = sizeof(struct dm_thin_endio_hook);

0 commit comments

Comments
 (0)