Messages in this thread | | | Subject | Re: [PATCH] fuse: avoid deadlock when write fuse inode | From | Huang Jianan <> | Date | Tue, 2 Feb 2021 12:11:32 +0800 |
| |
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 <huangjianan@oppo.com> > Signed-off-by: Guo Weichao <guoweichao@oppo.com> > --- > 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; >
| |