diff options
author | Chao Yu <yuchao0@huawei.com> | 2021-01-11 12:42:53 +0300 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2021-01-28 02:20:05 +0300 |
commit | 3afae09ffea5e08f523823be99a784675995d6bb (patch) | |
tree | 058c9900cfbaf6358cf07d7fbb83233848108247 /fs/f2fs/compress.c | |
parent | 794c43f716845e2d48ce195ed5c4179a4e05ce5f (diff) | |
download | linux-3afae09ffea5e08f523823be99a784675995d6bb.tar.xz |
f2fs: compress: fix potential deadlock
generic/269 reports a hangtask issue, the root cause is ABBA deadlock
described as below:
Thread A Thread B
- down_write(&sbi->gc_lock) -- A
- f2fs_write_data_pages
- lock all pages in cluster -- B
- f2fs_write_multi_pages
- f2fs_write_raw_pages
- f2fs_write_single_data_page
- f2fs_balance_fs
- down_write(&sbi->gc_lock) -- A
- f2fs_gc
- do_garbage_collect
- ra_data_block
- pagecache_get_page -- B
To fix this, it needs to avoid calling f2fs_balance_fs() if there is
still cluster pages been locked in context of cluster writeback, so
instead, let's call f2fs_balance_fs() in the end of
f2fs_write_raw_pages() when all cluster pages were unlocked.
Fixes: 4c8ff7095bef ("f2fs: support data compression")
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/compress.c')
-rw-r--r-- | fs/f2fs/compress.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1696f9183ff5..77fa342de38f 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1455,7 +1455,7 @@ retry_write: ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted, NULL, NULL, wbc, io_type, - compr_blocks); + compr_blocks, false); if (ret) { if (ret == AOP_WRITEPAGE_ACTIVATE) { unlock_page(cc->rpages[i]); @@ -1490,6 +1490,9 @@ retry_write: *submitted += _submitted; } + + f2fs_balance_fs(F2FS_M_SB(mapping), true); + return 0; out_err: for (++i; i < cc->cluster_size; i++) { |