aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-11-06 23:13:42 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-22 20:18:07 -0500
commit216fbd64437452d23db54ae845916facd7215caa (patch)
treef69e3387f49964d41e5386287290822c047764e2 /fs
parent5dcd8a71505186a124640f9f7c5c81fb269cc476 (diff)
f2fs: introduce sysfs entry to control in-place-update policy
This patch introduces new sysfs entries for users to control the policy of in-place-updates, namely IPU, in f2fs. Sometimes f2fs suffers from performance degradation due to its out-of-place update policy that produces many additional node block writes. If the storage performance is very dependant on the amount of data writes instead of IO patterns, we'd better drop this out-of-place update policy. This patch suggests 5 polcies and their triggering conditions as follows. [sysfs entry name = ipu_policy] 0: F2FS_IPU_FORCE all the time, 1: F2FS_IPU_SSR if SSR mode is activated, 2: F2FS_IPU_UTIL if FS utilization is over threashold, 3: F2FS_IPU_SSR_UTIL if SSR mode is activated and FS utilization is over threashold, 4: F2FS_IPU_DISABLE disable IPU. (=default option) [sysfs entry name = min_ipu_util] This parameter controls the threshold to trigger in-place-updates. The number indicates percentage of the filesystem utilization, and used by F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. For more details, see need_inplace_update() in segment.h. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/f2fs.h3
-rw-r--r--fs/f2fs/segment.c2
-rw-r--r--fs/f2fs/segment.h44
-rw-r--r--fs/f2fs/super.c4
4 files changed, 47 insertions, 6 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 022ce324b166..1b05a628670a 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -325,6 +325,9 @@ struct f2fs_sm_info {
325 struct list_head discard_list; /* 4KB discard list */ 325 struct list_head discard_list; /* 4KB discard list */
326 int nr_discards; /* # of discards in the list */ 326 int nr_discards; /* # of discards in the list */
327 int max_discards; /* max. discards to be issued */ 327 int max_discards; /* max. discards to be issued */
328
329 unsigned int ipu_policy; /* in-place-update policy */
330 unsigned int min_ipu_util; /* in-place-update threshold */
328}; 331};
329 332
330/* 333/*
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 0b2e8ceec983..5b890ce74b15 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1799,6 +1799,8 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
1799 sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main); 1799 sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
1800 sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); 1800 sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
1801 sm_info->rec_prefree_segments = DEF_RECLAIM_PREFREE_SEGMENTS; 1801 sm_info->rec_prefree_segments = DEF_RECLAIM_PREFREE_SEGMENTS;
1802 sm_info->ipu_policy = F2FS_IPU_DISABLE;
1803 sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
1802 1804
1803 INIT_LIST_HEAD(&sm_info->discard_list); 1805 INIT_LIST_HEAD(&sm_info->discard_list);
1804 sm_info->nr_discards = 0; 1806 sm_info->nr_discards = 0;
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index ea563760f4b7..e9a10bdd7fed 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -476,19 +476,51 @@ static inline int utilization(struct f2fs_sb_info *sbi)
476 476
477/* 477/*
478 * Sometimes f2fs may be better to drop out-of-place update policy. 478 * Sometimes f2fs may be better to drop out-of-place update policy.
479 * So, if fs utilization is over MIN_IPU_UTIL, then f2fs tries to write 479 * And, users can control the policy through sysfs entries.
480 * data in the original place likewise other traditional file systems. 480 * There are five policies with triggering conditions as follows.
481 * But, currently set 100 in percentage, which means it is disabled. 481 * F2FS_IPU_FORCE - all the time,
482 * See below need_inplace_update(). 482 * F2FS_IPU_SSR - if SSR mode is activated,
483 * F2FS_IPU_UTIL - if FS utilization is over threashold,
484 * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
485 * threashold,
486 * F2FS_IPUT_DISABLE - disable IPU. (=default option)
483 */ 487 */
484#define MIN_IPU_UTIL 100 488#define DEF_MIN_IPU_UTIL 70
489
490enum {
491 F2FS_IPU_FORCE,
492 F2FS_IPU_SSR,
493 F2FS_IPU_UTIL,
494 F2FS_IPU_SSR_UTIL,
495 F2FS_IPU_DISABLE,
496};
497
485static inline bool need_inplace_update(struct inode *inode) 498static inline bool need_inplace_update(struct inode *inode)
486{ 499{
487 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 500 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
501
502 /* IPU can be done only for the user data */
488 if (S_ISDIR(inode->i_mode)) 503 if (S_ISDIR(inode->i_mode))
489 return false; 504 return false;
490 if (need_SSR(sbi) && utilization(sbi) > MIN_IPU_UTIL) 505
506 switch (SM_I(sbi)->ipu_policy) {
507 case F2FS_IPU_FORCE:
491 return true; 508 return true;
509 case F2FS_IPU_SSR:
510 if (need_SSR(sbi))
511 return true;
512 break;
513 case F2FS_IPU_UTIL:
514 if (utilization(sbi) > SM_I(sbi)->min_ipu_util)
515 return true;
516 break;
517 case F2FS_IPU_SSR_UTIL:
518 if (need_SSR(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util)
519 return true;
520 break;
521 case F2FS_IPU_DISABLE:
522 break;
523 }
492 return false; 524 return false;
493} 525}
494 526
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 5c574fa1143c..f16da92a7899 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -178,6 +178,8 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
178F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); 178F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
179F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 179F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
180F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); 180F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards);
181F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
182F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
181 183
182#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 184#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
183static struct attribute *f2fs_attrs[] = { 185static struct attribute *f2fs_attrs[] = {
@@ -187,6 +189,8 @@ static struct attribute *f2fs_attrs[] = {
187 ATTR_LIST(gc_idle), 189 ATTR_LIST(gc_idle),
188 ATTR_LIST(reclaim_segments), 190 ATTR_LIST(reclaim_segments),
189 ATTR_LIST(max_small_discards), 191 ATTR_LIST(max_small_discards),
192 ATTR_LIST(ipu_policy),
193 ATTR_LIST(min_ipu_util),
190 NULL, 194 NULL,
191}; 195};
192 196