Commit c1ce1b02bb25640567dc484dc94d3a195d21e705

Authored by Jaegeuk Kim
1 parent a7ffdbe22c

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
... ... @@ -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;
... ... @@ -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;
... ... @@ -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;
... ... @@ -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:
... ... @@ -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),