Commit c23df309 authored by Jiucheng Xu's avatar Jiucheng Xu Committed by Gao Xiang
Browse files

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: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: default avatarJiucheng Xu <jiucheng.xu@amlogic.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent eade5404
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1445,6 +1445,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
				       int bios)
{
	struct erofs_sb_info *const sbi = EROFS_SB(io->sb);
	int gfp_flag;

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

static void z_erofs_fill_bio_vec(struct bio_vec *bvec,