Hi all,
This patch works well in our product, but I am not sure this is the correct way to solve this problem. I think that the inode->i_count shouldn't be zero after iput is executed in dentry_unlink_inode, then the inode won't be writeback. But i haven't found where iget is missing. Thanks, Jianan On 2021/2/2 12:08, Huang Jianan wrote:
We found the following deadlock situations in low memory scenarios: Thread A Thread B - __writeback_single_inode - fuse_write_inode - fuse_simple_request - __fuse_request_send - request_wait_answer - fuse_dev_splice_read - fuse_copy_fill - __alloc_pages_direct_reclaim - do_shrink_slab - super_cache_scan - shrink_dentry_list - dentry_unlink_inode - iput_final - inode_wait_for_writeback The request and inode processed by Thread A and B are the same, which causes a deadlock. To avoid this, we remove the __GFP_FS flag when allocating memory in fuse_copy_fill, so there will be no memory reclaimation in super_cache_scan. Signed-off-by: Huang Jianan <[email protected]> Signed-off-by: Guo Weichao <[email protected]> --- fs/fuse/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 588f8d1240aa..e580b9d04c25 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -721,7 +721,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) if (cs->nr_segs >= cs->pipe->max_usage) return -EIO;- page = alloc_page(GFP_HIGHUSER);+ page = alloc_page(GFP_HIGHUSER & ~__GFP_FS); if (!page) return -ENOMEM;

