Messages in this thread | | | Subject | Re: [fuse-devel] [PATCH] fuse: avoid deadlock when write fuse inode | From | Huang Jianan <> | Date | Sun, 7 Feb 2021 09:47:35 +0800 |
| |
friendly ping ... 😁
On 2021/2/2 12:11, Huang Jianan via fuse-devel wrote: > 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; > >
| |