From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932114AbcBZBeP (ORCPT ); Thu, 25 Feb 2016 20:34:15 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:36302 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932066AbcBZBeN (ORCPT ); Thu, 25 Feb 2016 20:34:13 -0500 X-AuditID: cbfee61b-f793c6d00000236c-41-56cfab930ba3 From: Chao Yu To: Jaegeuk Kim Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/2] f2fs: fix to avoid deadlock when merging inline data Date: Fri, 26 Feb 2016 09:33:04 +0800 Message-id: <016b01d17035$cc056be0$641043a0$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-index: AdFwNX+6cTeB62g6QpaoHGHb7124qw== Content-language: zh-cn X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t9jAd3Jq8+HGVw6KG3xZP0sZotLi9wt Lu+aw+bA7LFpVSebx+4Fn5k8Pm+SC2CO4rJJSc3JLEst0rdL4Mo496SNveCBTEVb822WBsaN El2MHBwSAiYSU75ZdjFyApliEhfurWfrYuTiEBJYyihxatYpVgjnFaPE6a5dzCBVbAIqEss7 /jOB2CJA9qFFl9lBbGYBD4nGju+sILawgI9E77WlYHEWAVWJz9MOM4Is4xWwlFgygxskzCsg KPFj8j0WiFYtifU7jzNB2PISm9e8ZYY4SEFix9nXjBCr9CSWnrgHVSMusfHILZYJjAKzkIya hWTULCSjZiFpWcDIsopRIrUguaA4KT3XKC+1XK84Mbe4NC9dLzk/dxMjOISfSe9gPLzL/RCj AAejEg8vw8+zYUKsiWXFlbmHGCU4mJVEeC+XnQ8T4k1JrKxKLcqPLyrNSS0+xCjNwaIkzvv4 /7owIYH0xJLU7NTUgtQimCwTB6dUA6OW9tXKoybGL6aL3HhvHRfw/EygeScP49e3zHWqn/xe Ff3e+X75tg/b47+4M6mEJR3dfTbs9L9QNWd23pOXAzYvPtFQvDk5svbH7Bi3l+a3CuPNVm/y VTmxdPq7jEcP/v3jZJt89uCr93KfJUvkr+64ZytTrr7aXENlZvJauyvW3o1/tTY+nZylxFKc kWioxVxUnAgA5wQSSl0CAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When testing with fsstress, kworker and user threads were both blocked: INFO: task kworker/u16:1:16580 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kworker/u16:1 D ffff8803f2595390 0 16580 2 0x00000000 Workqueue: writeback bdi_writeback_workfn (flush-251:0) ffff8802730e5760 0000000000000046 ffff880274729fc0 0000000000012440 ffff8802730e5fd8 ffff8802730e4010 0000000000012440 0000000000012440 ffff8802730e5fd8 0000000000012440 ffff880274729fc0 ffff88026eb50000 Call Trace: [] schedule+0x29/0x70 [] rwsem_down_read_failed+0xa5/0xf9 [] call_rwsem_down_read_failed+0x14/0x30 [] f2fs_write_data_page+0x31b/0x420 [f2fs] [] __f2fs_writepage+0x1a/0x50 [f2fs] [] f2fs_write_data_pages+0xe0/0x290 [f2fs] [] do_writepages+0x23/0x40 [] __writeback_single_inode+0x4e/0x250 [] writeback_sb_inodes+0x2c1/0x470 [] __writeback_inodes_wb+0x9e/0xd0 [] wb_writeback+0x1fb/0x2d0 [] wb_do_writeback+0x9c/0x220 [] bdi_writeback_workfn+0x72/0x1c0 [] process_one_work+0x1de/0x5b0 [] worker_thread+0x11f/0x3e0 [] kthread+0xde/0xf0 [] ret_from_fork+0x58/0x90 fsstress thread stack: [] sleep_on_page+0xe/0x20 [] __lock_page+0x67/0x70 [] find_lock_page+0x50/0x80 [] find_or_create_page+0x3f/0xb0 [] sync_node_pages+0x259/0x810 [f2fs] [] write_checkpoint+0x1a4/0xce0 [f2fs] [] f2fs_sync_fs+0x7c/0xd0 [f2fs] [] f2fs_sync_file+0x143/0x5f0 [f2fs] [] vfs_fsync_range+0x2b/0x40 [] vfs_fsync+0x1c/0x20 [] do_fsync+0x41/0x70 [] SyS_fdatasync+0x13/0x20 [] system_call_fastpath+0x16/0x1b [] 0xffffffffffffffff The reason of this issue is: CPU0: CPU1: - f2fs_write_data_pages - f2fs_sync_fs - write_checkpoint - block_operations - f2fs_lock_all - down_write(sbi->cp_rwsem) - lock_page(page) - f2fs_write_data_page - sync_node_pages - flush_inline_data - pagecache_get_page(page, GFP_LOCK) - f2fs_lock_op - down_read(sbi->cp_rwsem) This patch alters to use trylock_page in flush_inline_data to fix this ABBA deadlock issue. Signed-off-by: Chao Yu --- v2: - fix the wrong error handling. fs/f2fs/node.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 7b613dd..d714b60 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1203,10 +1203,13 @@ static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino) if (!inode) return; - page = pagecache_get_page(inode->i_mapping, 0, FGP_LOCK|FGP_NOWAIT, 0); + page = pagecache_get_page(inode->i_mapping, 0, FGP_NOWAIT, 0); if (!page) goto iput_out; + if (!trylock_page(page)) + goto release_out; + if (!PageUptodate(page)) goto page_out; @@ -1221,7 +1224,9 @@ static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino) else set_page_dirty(page); page_out: - f2fs_put_page(page, 1); + unlock_page(page); +release_out: + f2fs_put_page(page, 0); iput_out: iput(inode); } -- 2.7.0