Skip to content

Commit 1db4b36

Browse files
Yongpeng YangJaegeuk Kim
authored andcommitted
f2fs: optimize NAT block loading during checkpoint write
Under stress tests with frequent metadata operations, checkpoint write time can become excessively long. Analysis shows that the slowdown is caused by synchronous, one-by-one reads of NAT blocks during checkpoint processing. The issue can be reproduced with the following workload: 1. seq 1 650000 | xargs -P 16 -n 1 touch 2. sync # avoid checkpoint write during deleting 3. delete 1 file every 455 files 4. echo 3 > /proc/sys/vm/drop_caches 5. sync # trigger checkpoint write This patch submits read I/O for all NAT blocks required in the __flush_nat_entry_set() phase in advance, reducing the overhead of synchronous waiting for individual NAT block reads. The NAT block flush latency before and after the change is as below: | |NAT blocks accessed|NAT blocks read|Flush time (ms)| |-------------|-------------------|---------------|---------------| |Before change|1205 |1191 |158 | |After change |1264 |1242 |11 | With a similar number of NAT blocks accessed and read from disk, adding NAT block readahead reduces the total NAT block flush time by more than 90%. Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 7c9ee0e commit 1db4b36

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

fs/f2fs/node.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3179,7 +3179,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
31793179
struct f2fs_journal *journal = curseg->journal;
31803180
struct nat_entry_set *setvec[NAT_VEC_SIZE];
31813181
struct nat_entry_set *set, *tmp;
3182-
unsigned int found;
3182+
unsigned int found, entry_count = 0;
31833183
nid_t set_idx = 0;
31843184
LIST_HEAD(sets);
31853185
int err = 0;
@@ -3219,6 +3219,18 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
32193219
MAX_NAT_JENTRIES(sbi, journal));
32203220
}
32213221

3222+
/*
3223+
* Readahead the current NAT block to prevent read requests from
3224+
* being issued and waited on one by one.
3225+
*/
3226+
list_for_each_entry(set, &sets, set_list) {
3227+
entry_count += set->entry_cnt;
3228+
if (!enabled_nat_bits(sbi, cpc) &&
3229+
__has_cursum_space(sbi, journal,
3230+
entry_count, NAT_JOURNAL))
3231+
continue;
3232+
f2fs_ra_meta_pages(sbi, set->set, 1, META_NAT, true);
3233+
}
32223234
/* flush dirty nats in nat entry set */
32233235
list_for_each_entry_safe(set, tmp, &sets, set_list) {
32243236
err = __flush_nat_entry_set(sbi, set, cpc);

0 commit comments

Comments
 (0)