f2fs: flush dirty nat entries when exceeding threshold
PATCH 1/2 f2fs: flush dirty nat entries when exceeding threshold
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 preparing 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, we give another chance to f2fs_balance_fs_bg to do checkpoint to flush nat entries for reusing in free nid cache when dirty entry count exceeds 10% of max count.
--- fs/f2fs/node.h | 8 ++++++++ fs/f2fs/segment.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-)
fs/f2fs/node.h +8 -0
@@ -25,6 +25,8 @@/* control the memory footprint threshold (10MB per 1GB ram) */ #define DEF_RAM_THRESHOLD 10 +#define DEF_DIRTY_NAT_THRESHOLD 10/* 10% over max nid */ +/* vector size for gang look-up from nat cache that consists of radix tree */ #define NATVEC_SIZE 64#define SETVEC_SIZE 32
@@ -117,6 +119,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_THRESHOLD /100 ; +} +enum mem_type {FREE_NIDS ,/* indicates the free nid list */ NAT_ENTRIES ,/* indicates the cached nat entry */
fs/f2fs/segment.c +2 -1
@@ -291,8 +291,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 );
Signature · 1 line
2.6.3
Jaegeuk Kim
maintainerHi Chao,
Quoted 42 lines · Chao Yu
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 preparing for following fstrim test.
1. rm -rf
/mnt/dir
2. mkdir/mnt/dir/
3. cp -axTpwd//mnt/dir/
4. goto 1During 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, we give another chance to
f2fs_balance_fs_bgto do checkpoint to flush nat entries for reusing in free nid cache when dirty entry count exceeds 10% of max count.Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/node.h | 8 ++++++++ fs/f2fs/segment.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-)fs/f2fs/node.h +2
-0@@ -25,6 +25,8 @@/* control the memory footprint threshold (10MB per 1GB ram) */ #define DEF_RAM_THRESHOLD 10 +#define DEF_DIRTY_NAT_THRESHOLD 10/* 10% over max nid */ +/* vector size for gang look-up from nat cache that consists of radix tree */ #define NATVEC_SIZE 64#define SETVEC_SIZE 32
fs/f2fs/node.h static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, · line 125
Quoted 7 lines
fs/f2fs/node.h +4
-0@@ -117,6 +119,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_THRESHOLD /100 ;
Need to add a sysfs entry?
Thanks,
Quoted 23 lines
fs/f2fs/node.h +2
-0+} +enum mem_type {FREE_NIDS ,/* indicates the free nid list */ NAT_ENTRIES ,/* indicates the cached nat entry */ fs/f2fs/segment.c +2
-1@@ -291,8 +291,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 );Signature · 1 line
2.6.3
Hi Jaegeuk,
Quoted 55 lines
-----Original Message-----
From: Jaegeuk Kim [mailto:[email protected]]
Sent: Sunday, January 17, 2016 4:30 AM
To: Chao Yu
Cc: [email protected]; [email protected]
Subject: Re: [PATCH 1/2] f2fs: flush dirty nat entries when exceeding thresholdHi Chao,
Quoted 45 lines · Chao Yu
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 preparing for following fstrim test.
1. rm -rf
/mnt/dir
2. mkdir/mnt/dir/
3. cp -axTpwd//mnt/dir/
4. goto 1During 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, we give another chance to
f2fs_balance_fs_bgto do checkpoint to flush nat entries for reusing in free nid cache when dirty entry count exceeds 10% of max count.Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/node.h | 8 ++++++++ fs/f2fs/segment.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-)fs/f2fs/node.h +2
-0@@ -25,6 +25,8 @@/* control the memory footprint threshold (10MB per 1GB ram) */ #define DEF_RAM_THRESHOLD 10 +#define DEF_DIRTY_NAT_THRESHOLD 10/* 10% over max nid */ +/* vector size for gang look-up from nat cache that consists of radix tree */ #define NATVEC_SIZE 64#define SETVEC_SIZE 32@@ -117,6 +119,12 @@ static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, raw_ne->version = ni->version; }
Quoted 6 lines
fs/f2fs/node.h static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, · line 125
Quoted 4 lines
fs/f2fs/node.h +4
-0+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_THRESHOLD /100 ;Need to add a sysfs entry?
Agreed, let me export the sysfs entry in another patch, distinguishing with current bug fixing patch.
Thanks,
Quoted 26 lines
Thanks,
Quoted 23 lines
fs/f2fs/node.h +2
-0+} +enum mem_type {FREE_NIDS ,/* indicates the free nid list */ NAT_ENTRIES ,/* indicates the cached nat entry */ fs/f2fs/segment.c +2
-2@@ -291,8 +291,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