Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <hsiangkao@linux.alibaba.com>
Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>

authored by

Jiucheng Xu and committed by
Gao Xiang
c23df309 eade5404

+3
+3
fs/erofs/zdata.c
··· 1445 1445 int bios) 1446 1446 { 1447 1447 struct erofs_sb_info *const sbi = EROFS_SB(io->sb); 1448 + int gfp_flag; 1448 1449 1449 1450 /* wake up the caller thread for sync decompression */ 1450 1451 if (io->sync) { ··· 1478 1477 sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON; 1479 1478 return; 1480 1479 } 1480 + gfp_flag = memalloc_noio_save(); 1481 1481 z_erofs_decompressqueue_work(&io->u.work); 1482 + memalloc_noio_restore(gfp_flag); 1482 1483 } 1483 1484 1484 1485 static void z_erofs_fill_bio_vec(struct bio_vec *bvec,