Commit c1ce1b02bb25640567dc484dc94d3a195d21e705
1 parent
a7ffdbe22c
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
f2fs: give an option to enable in-place-updates during fsync to users
If user wrote F2FS_IPU_FSYNC:4 in /sys/fs/f2fs/ipu_policy, f2fs_sync_file only starts to try in-place-updates. And, if the number of dirty pages is over /sys/fs/f2fs/min_fsync_blocks, it keeps out-of-order manner. Otherwise, it triggers in-place-updates. This may be used by storage showing very high random write performance. For example, it can be used when, Seq. writes (Data) + wait + Seq. writes (Node) is pretty much slower than, Rand. writes (Data) Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Showing 7 changed files with 33 additions and 10 deletions Side-by-side Diff
Documentation/ABI/testing/sysfs-fs-f2fs
... | ... | @@ -44,6 +44,13 @@ |
44 | 44 | Controls the FS utilization condition for the in-place-update |
45 | 45 | policies. |
46 | 46 | |
47 | +What: /sys/fs/f2fs/<disk>/min_fsync_blocks | |
48 | +Date: September 2014 | |
49 | +Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> | |
50 | +Description: | |
51 | + Controls the dirty page count condition for the in-place-update | |
52 | + policies. | |
53 | + | |
47 | 54 | What: /sys/fs/f2fs/<disk>/max_small_discards |
48 | 55 | Date: November 2013 |
49 | 56 | Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com> |
Documentation/filesystems/f2fs.txt
... | ... | @@ -194,12 +194,19 @@ |
194 | 194 | updates in f2fs. There are five policies: |
195 | 195 | 0: F2FS_IPU_FORCE, 1: F2FS_IPU_SSR, |
196 | 196 | 2: F2FS_IPU_UTIL, 3: F2FS_IPU_SSR_UTIL, |
197 | - 4: F2FS_IPU_DISABLE. | |
197 | + 4: F2FS_IPU_FSYNC, 5: F2FS_IPU_DISABLE. | |
198 | 198 | |
199 | 199 | min_ipu_util This parameter controls the threshold to trigger |
200 | 200 | in-place-updates. The number indicates percentage |
201 | 201 | of the filesystem utilization, and used by |
202 | 202 | F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. |
203 | + | |
204 | + min_fsync_blocks This parameter controls the threshold to trigger | |
205 | + in-place-updates when F2FS_IPU_FSYNC mode is set. | |
206 | + The number indicates the number of dirty pages | |
207 | + when fsync needs to flush on its call path. If | |
208 | + the number is less than this value, it triggers | |
209 | + in-place-updates. | |
203 | 210 | |
204 | 211 | max_victim_search This parameter controls the number of trials to |
205 | 212 | find a victim segment when conducting SSR and |
fs/f2fs/f2fs.h
... | ... | @@ -386,6 +386,7 @@ |
386 | 386 | |
387 | 387 | unsigned int ipu_policy; /* in-place-update policy */ |
388 | 388 | unsigned int min_ipu_util; /* in-place-update threshold */ |
389 | + unsigned int min_fsync_blocks; /* threshold for fsync */ | |
389 | 390 | |
390 | 391 | /* for flush command control */ |
391 | 392 | struct flush_cmd_control *cmd_control_info; |
fs/f2fs/file.c
... | ... | @@ -154,12 +154,11 @@ |
154 | 154 | trace_f2fs_sync_file_enter(inode); |
155 | 155 | |
156 | 156 | /* if fdatasync is triggered, let's do in-place-update */ |
157 | - if (datasync) | |
157 | + if (get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) | |
158 | 158 | set_inode_flag(fi, FI_NEED_IPU); |
159 | - | |
160 | 159 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
161 | - if (datasync) | |
162 | - clear_inode_flag(fi, FI_NEED_IPU); | |
160 | + clear_inode_flag(fi, FI_NEED_IPU); | |
161 | + | |
163 | 162 | if (ret) { |
164 | 163 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); |
165 | 164 | return ret; |
fs/f2fs/segment.c
... | ... | @@ -1928,8 +1928,9 @@ |
1928 | 1928 | sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); |
1929 | 1929 | sm_info->rec_prefree_segments = sm_info->main_segments * |
1930 | 1930 | DEF_RECLAIM_PREFREE_SEGMENTS / 100; |
1931 | - sm_info->ipu_policy = F2FS_IPU_DISABLE; | |
1931 | + sm_info->ipu_policy = F2FS_IPU_FSYNC; | |
1932 | 1932 | sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; |
1933 | + sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; | |
1933 | 1934 | |
1934 | 1935 | INIT_LIST_HEAD(&sm_info->discard_list); |
1935 | 1936 | sm_info->nr_discards = 0; |
fs/f2fs/segment.h
... | ... | @@ -472,15 +472,20 @@ |
472 | 472 | * F2FS_IPU_UTIL - if FS utilization is over threashold, |
473 | 473 | * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over |
474 | 474 | * threashold, |
475 | + * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash | |
476 | + * storages. IPU will be triggered only if the # of dirty | |
477 | + * pages over min_fsync_blocks. | |
475 | 478 | * F2FS_IPUT_DISABLE - disable IPU. (=default option) |
476 | 479 | */ |
477 | 480 | #define DEF_MIN_IPU_UTIL 70 |
481 | +#define DEF_MIN_FSYNC_BLOCKS 8 | |
478 | 482 | |
479 | 483 | enum { |
480 | 484 | F2FS_IPU_FORCE, |
481 | 485 | F2FS_IPU_SSR, |
482 | 486 | F2FS_IPU_UTIL, |
483 | 487 | F2FS_IPU_SSR_UTIL, |
488 | + F2FS_IPU_FSYNC, | |
484 | 489 | F2FS_IPU_DISABLE, |
485 | 490 | }; |
486 | 491 | |
... | ... | @@ -492,10 +497,6 @@ |
492 | 497 | if (S_ISDIR(inode->i_mode)) |
493 | 498 | return false; |
494 | 499 | |
495 | - /* this is only set during fdatasync */ | |
496 | - if (is_inode_flag_set(F2FS_I(inode), FI_NEED_IPU)) | |
497 | - return true; | |
498 | - | |
499 | 500 | switch (SM_I(sbi)->ipu_policy) { |
500 | 501 | case F2FS_IPU_FORCE: |
501 | 502 | return true; |
... | ... | @@ -509,6 +510,11 @@ |
509 | 510 | break; |
510 | 511 | case F2FS_IPU_SSR_UTIL: |
511 | 512 | if (need_SSR(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util) |
513 | + return true; | |
514 | + break; | |
515 | + case F2FS_IPU_FSYNC: | |
516 | + /* this is only set during fdatasync */ | |
517 | + if (is_inode_flag_set(F2FS_I(inode), FI_NEED_IPU)) | |
512 | 518 | return true; |
513 | 519 | break; |
514 | 520 | case F2FS_IPU_DISABLE: |
fs/f2fs/super.c
... | ... | @@ -190,6 +190,7 @@ |
190 | 190 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); |
191 | 191 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); |
192 | 192 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); |
193 | +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); | |
193 | 194 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); |
194 | 195 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); |
195 | 196 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); |
... | ... | @@ -204,6 +205,7 @@ |
204 | 205 | ATTR_LIST(max_small_discards), |
205 | 206 | ATTR_LIST(ipu_policy), |
206 | 207 | ATTR_LIST(min_ipu_util), |
208 | + ATTR_LIST(min_fsync_blocks), | |
207 | 209 | ATTR_LIST(max_victim_search), |
208 | 210 | ATTR_LIST(dir_level), |
209 | 211 | ATTR_LIST(ram_thresh), |