[Devel] [PATCH 0/4] fix deadlock between synchronous reqs and fuse_invalidate_files

Kirill Tkhai ktkhai at virtuozzo.com
Fri May 17 18:08:02 MSK 2019


On 15.05.2019 11:53, Pavel Butsykin wrote:
> One more deadlock with fuse_invalidate_files():
> 
> [<ffffffff92ba7cc4>] __lock_page+0x74/0x90
> [<ffffffff92bb9a75>] invalidate_inode_pages2_range+0x445/0x470
> [<ffffffff92bb9ab7>] invalidate_inode_pages2+0x17/0x20
> [<ffffffffc034cde5>] fuse_invalidate_files+0x235/0x270 [fuse]
> [<ffffffffc033d3fb>] fuse_dev_do_write+0x7fb/0xe20 [fuse]
> [<ffffffffc033ddc1>] fuse_dev_write+0x71/0xa0 [fuse]
> [<ffffffff92c3c2e6>] do_sync_write+0x96/0xe0
> [<ffffffff92c3cdc0>] vfs_write+0xc0/0x1f0
> [<ffffffff92c3dbef>] SyS_write+0x7f/0xf0
> [<ffffffff9315589b>] system_call_fastpath+0x22/0x27
> 
> This happened because synchronous kio read request was not dropped by kill_requests:
> 
> PID: 20684  TASK: ffff9543c2e71160  CPU: 5   COMMAND: "co_io"
> [ffff9547b0faf9f8] __schedule at ffffffff93148a9f
> [ffff9547b0fafa88] schedule at ffffffff93148fe9
> [ffff9547b0fafa98] kpcs_req_send at ffffffffc047dab5 [fuse_kio_pcs]
> [ffff9547b0fafb08] __fuse_request_send at ffffffffc033a987 [fuse]
> [ffff9547b0fafb40] fuse_request_check_and_send at ffffffffc033e097 [fuse]
> [ffff9547b0fafb50] fuse_send_read at ffffffffc03463ec [fuse]
> [ffff9547b0fafb90] __fuse_readpage at ffffffffc03475ad [fuse]
> [ffff9547b0fafc40] fuse_readpage at ffffffffc0347a3c [fuse]
> [ffff9547b0fafca0] generic_file_read_iter at ffffffff92baa186
> [ffff9547b0fafd58] generic_file_aio_read at ffffffff92baa5c5
> [ffff9547b0fafdc0] fuse_file_aio_read at ffffffffc0343788 [fuse]
> [ffff9547b0fafdf0] do_sync_read at ffffffff92c3c206
> [ffff9547b0fafed0] vfs_read at ffffffff92c3cc2f
> [ffff9547b0faff00] sys_pread64 at ffffffff92c3dcf2
> [ffff9547b0faff50] system_call_fastpath at ffffffff9315589b 
> 
>  struct pcs_fuse_req {
>  req = {
>     list = {
>       next = 0xffff95479374eb18,
>       prev = 0xffff9547acf76e00
>     },
>     ...
>     page_cache = 1,
>     page_needs_release = 0,
>     killed = 0,
>     ...
>     ff = 0x0,
>     io_inode = 0xffff95445da0b740,
> 
> The fuse_file pointer was not initialized in req->ff, that means we can't check
> ff->ff_state inside pcs_fuse_submit(), despite the fact that this request has
> locked pages. It's believed that requests with an empty req->ff don't have pages,
> therefore, such requests may not be synchronized with fuse_invalidate_files().
> However, synchronous requests don't reference ff, but pass it as a parameter to
> fuse_request_check_and_send(). 
> 
> This patchset fixes it.
> 
> Pavel Butsykin (4):
>   fs/fuse kio: forward fuse_file pointer to kpcs_req_send()
>   fs/fuse kio: add pending kio requests to kqueue
>   fs/fuse kio: style fix in pcs_fuse_submit()
>   fs/fuse kio: keep fuse_file for requests waiting for shrink
> 
>  fs/fuse/dev.c                      |   6 +-
>  fs/fuse/file.c                     |   1 +
>  fs/fuse/fuse_i.h                   |   4 +-
>  fs/fuse/kio/pcs/fuse_io.c          |   5 ++
>  fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 120 +++++++++++++++++++++++++------------
>  5 files changed, 93 insertions(+), 43 deletions(-)

Looks OK for me.

Reviewed-by: Kirill Tkhai <ktkhai at virtuozzo.com>


More information about the Devel mailing list