Skip to content

Commit c23df30

Browse files
Jiucheng Xuhsiangkao
authored andcommitted
erofs: add GFP_NOIO in the bio completion if needed
The bio completion path in the process context (e.g. dm-verity) will directly call into decompression rather than trigger another workqueue context for minimal scheduling latencies, which can then call vm_map_ram() with GFP_KERNEL. Due to insufficient memory, vm_map_ram() may generate memory swapping I/O, which can cause submit_bio_wait to deadlock in some scenarios. Trimmed down the call stack, as follows: f2fs_submit_read_io submit_bio //bio_list is initialized. mmc_blk_mq_recovery z_erofs_endio vm_map_ram __pte_alloc_kernel __alloc_pages_direct_reclaim shrink_folio_list __swap_writepage submit_bio_wait //bio_list is non-NULL, hang!!! Use memalloc_noio_{save,restore}() to wrap up this path. Reviewed-by: Gao Xiang <[email protected]> Signed-off-by: Jiucheng Xu <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]>
1 parent eade540 commit c23df30

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

fs/erofs/zdata.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
14451445
int bios)
14461446
{
14471447
struct erofs_sb_info *const sbi = EROFS_SB(io->sb);
1448+
int gfp_flag;
14481449

14491450
/* wake up the caller thread for sync decompression */
14501451
if (io->sync) {
@@ -1477,7 +1478,9 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
14771478
sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON;
14781479
return;
14791480
}
1481+
gfp_flag = memalloc_noio_save();
14801482
z_erofs_decompressqueue_work(&io->u.work);
1483+
memalloc_noio_restore(gfp_flag);
14811484
}
14821485

14831486
static void z_erofs_fill_bio_vec(struct bio_vec *bvec,

0 commit comments

Comments
 (0)