From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754472AbcARKcK (ORCPT ); Mon, 18 Jan 2016 05:32:10 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:39431 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753977AbcARKcH (ORCPT ); Mon, 18 Jan 2016 05:32:07 -0500 X-AuditID: cbfee61a-f79266d000003652-93-569cbf1de0c1 From: Chao Yu To: Jaegeuk Kim Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/4] f2fs: flush dirty nat entries when exceeding threshold Date: Mon, 18 Jan 2016 18:31:18 +0800 Message-id: <01ad01d151db$75eae0f0$61c0a2d0$@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: AdFR21i743sgZHQaSt6I0N6NdEt/7w== Content-language: zh-cn X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrNLMWRmVeSWpSXmKPExsVy+t9jQV3Z/XPCDDrOGlg8WT+L2eLSIneL y7vmsDkwe2xa1cnmsXvBZyaPz5vkApijuGxSUnMyy1KL9O0SuDIWTd7EWPBApGLFq/VsDYyf BboYOTkkBEwkph9tYoWwxSQu3FvPBmILCcxilDjb6NLFyAVkv2KU+Lv7PiNIgk1ARWJ5x38m EFsEyD606DI7iM0s4CHR2PEdbJCwgJ/Ek41PweIsAqoSd9p+gfXyClhK/O/8yQphC0r8mHyP BaJXS2L9zuNMELa8xOY1b5khDlKQ2HH2NSPELj2Jq7PboHaJS2w8cotlAiPQlQijZiEZNQvJ qFlIWhYwsqxilEgtSC4oTkrPNcxLLdcrTswtLs1L10vOz93ECA7iZ1I7GA/ucj/EKMDBqMTD 63B2dpgQa2JZcWXuIUYJDmYlEd7g9XPChHhTEiurUovy44tKc1KLDzFKc7AoifPWXooMExJI TyxJzU5NLUgtgskycXBKNTAKW20XrGV44F2aserHZD2/Vaq2wX1ea2W2uSV0r30y75DHxJL+ qu/CudOy1qh+af+54W2o5GaevA4zQyXlZVqz8v1/PUjjrZXjZemQSp++wnh3UYbV9RwJCd+f QUdrk60lxV/NP/Pqy0ahDSqKPRz7NnC9ZXFgUvw7gYfp6CX7GoUIRob76UosxRmJhlrMRcWJ AOKofWBeAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When testing f2fs with xfstest, generic/251 is stuck for long time, the case uses below serials to obtain fresh released space in device, in order to prepare for following fstrim test. 1. rm -rf /mnt/dir 2. mkdir /mnt/dir/ 3. cp -axT `pwd`/ /mnt/dir/ 4. goto 1 During preparing step, all nat entries will be cached in nat cache, most of them are dirty entries with invalid blkaddr, which means nodes related to these entries have been truncated, and they could be reused after the dirty entries been checkpointed. However, there was no checkpoint been triggered, so nid allocators (e.g. mkdir, creat) will run into long journey of iterating all NAT pages, looking for free nids in alloc_nid->build_free_nids. Here, in f2fs_balance_fs_bg we give another chance to do checkpoint to flush nat entries for reusing them in free nid cache when dirty entry count exceeds 10% of max count. Signed-off-by: Chao Yu --- v2: - update comments. --- fs/f2fs/node.h | 9 +++++++++ fs/f2fs/segment.c | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index d4d1f63..bd119c0 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -25,6 +25,9 @@ /* control the memory footprint threshold (10MB per 1GB ram) */ #define DEF_RAM_THRESHOLD 10 +/* control dirty nats ratio threshold (default: 10% over max nid count) */ +#define DEF_DIRTY_NAT_RATIO_THRESHOLD 10 + /* vector size for gang look-up from nat cache that consists of radix tree */ #define NATVEC_SIZE 64 #define SETVEC_SIZE 32 @@ -117,6 +120,12 @@ static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, raw_ne->version = ni->version; } +static inline bool excess_dirty_nats(struct f2fs_sb_info *sbi) +{ + return NM_I(sbi)->dirty_nat_cnt >= NM_I(sbi)->max_nid * + DEF_DIRTY_NAT_RATIO_THRESHOLD / 100; +} + enum mem_type { FREE_NIDS, /* indicates the free nid list */ NAT_ENTRIES, /* indicates the cached nat entry */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 0246acc..070988b 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -292,8 +292,9 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) /* checkpoint is the only way to shrink partial cached entries */ if (!available_free_memory(sbi, NAT_ENTRIES) || - excess_prefree_segs(sbi) || !available_free_memory(sbi, INO_ENTRIES) || + excess_prefree_segs(sbi) || + excess_dirty_nats(sbi) || (is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) { if (test_opt(sbi, DATA_FLUSH)) sync_dirty_inodes(sbi, FILE_INODE); -- 2.6.3