aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-07 23:45:08 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-07 23:45:08 -0500
commitb1c57c1caa753cec299e62bb4272da0e85a01ef0 (patch)
tree05d7338349557e5f62ca84a00c362bc669e50f90 /fs/f2fs
parentfb5566da9181d33ecdd9892e44f90320e7d4cc9f (diff)
f2fs: add a sysfs entry to control max_victim_search
Previously during SSR and GC, the maximum number of retrials to find a victim segment was hard-coded by MAX_VICTIM_SEARCH, 4096 by default. This number makes an effect on IO locality, when SSR mode is activated, which results in performance fluctuation on some low-end devices. If max_victim_search = 4, the victim will be searched like below. ("D" represents a dirty segment, and "*" indicates a selected victim segment.) D1 D2 D3 D4 D5 D6 D7 D8 D9 [ * ] [ * ] [ * ] [ ....] This patch adds a sysfs entry to control the number dynamically through: /sys/fs/f2fs/$dev/max_victim_search Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/f2fs.h3
-rw-r--r--fs/f2fs/gc.c4
-rw-r--r--fs/f2fs/gc.h2
-rw-r--r--fs/f2fs/super.c6
4 files changed, 12 insertions, 3 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b69f190fb195..5f7dc4f6eb09 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -451,6 +451,9 @@ struct f2fs_sb_info {
451 struct f2fs_gc_kthread *gc_thread; /* GC thread */ 451 struct f2fs_gc_kthread *gc_thread; /* GC thread */
452 unsigned int cur_victim_sec; /* current victim section num */ 452 unsigned int cur_victim_sec; /* current victim section num */
453 453
454 /* maximum # of trials to find a victim segment for SSR and GC */
455 unsigned int max_victim_search;
456
454 /* 457 /*
455 * for stat information. 458 * for stat information.
456 * one is for the LFS mode, and the other is for the SSR mode. 459 * one is for the LFS mode, and the other is for the SSR mode.
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 599f546d042c..9117ccaf254a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -163,8 +163,8 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
163 p->ofs_unit = sbi->segs_per_sec; 163 p->ofs_unit = sbi->segs_per_sec;
164 } 164 }
165 165
166 if (p->max_search > MAX_VICTIM_SEARCH) 166 if (p->max_search > sbi->max_victim_search)
167 p->max_search = MAX_VICTIM_SEARCH; 167 p->max_search = sbi->max_victim_search;
168 168
169 p->offset = sbi->last_victim[p->gc_mode]; 169 p->offset = sbi->last_victim[p->gc_mode];
170} 170}
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index 507056d22205..5d5eb6047bf4 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -20,7 +20,7 @@
20#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ 20#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */
21 21
22/* Search max. number of dirty segments to select a victim segment */ 22/* Search max. number of dirty segments to select a victim segment */
23#define MAX_VICTIM_SEARCH 4096 /* covers 8GB */ 23#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
24 24
25struct f2fs_gc_kthread { 25struct f2fs_gc_kthread {
26 struct task_struct *f2fs_gc_task; 26 struct task_struct *f2fs_gc_task;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f16da92a7899..b070f3010ce9 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -74,6 +74,7 @@ static match_table_t f2fs_tokens = {
74enum { 74enum {
75 GC_THREAD, /* struct f2fs_gc_thread */ 75 GC_THREAD, /* struct f2fs_gc_thread */
76 SM_INFO, /* struct f2fs_sm_info */ 76 SM_INFO, /* struct f2fs_sm_info */
77 F2FS_SBI, /* struct f2fs_sb_info */
77}; 78};
78 79
79struct f2fs_attr { 80struct f2fs_attr {
@@ -91,6 +92,8 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
91 return (unsigned char *)sbi->gc_thread; 92 return (unsigned char *)sbi->gc_thread;
92 else if (struct_type == SM_INFO) 93 else if (struct_type == SM_INFO)
93 return (unsigned char *)SM_I(sbi); 94 return (unsigned char *)SM_I(sbi);
95 else if (struct_type == F2FS_SBI)
96 return (unsigned char *)sbi;
94 return NULL; 97 return NULL;
95} 98}
96 99
@@ -180,6 +183,7 @@ F2FS_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); 183F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards);
181F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 184F2FS_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); 185F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
186F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
183 187
184#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 188#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
185static struct attribute *f2fs_attrs[] = { 189static struct attribute *f2fs_attrs[] = {
@@ -191,6 +195,7 @@ static struct attribute *f2fs_attrs[] = {
191 ATTR_LIST(max_small_discards), 195 ATTR_LIST(max_small_discards),
192 ATTR_LIST(ipu_policy), 196 ATTR_LIST(ipu_policy),
193 ATTR_LIST(min_ipu_util), 197 ATTR_LIST(min_ipu_util),
198 ATTR_LIST(max_victim_search),
194 NULL, 199 NULL,
195}; 200};
196 201
@@ -775,6 +780,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
775 sbi->node_ino_num = le32_to_cpu(raw_super->node_ino); 780 sbi->node_ino_num = le32_to_cpu(raw_super->node_ino);
776 sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino); 781 sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino);
777 sbi->cur_victim_sec = NULL_SECNO; 782 sbi->cur_victim_sec = NULL_SECNO;
783 sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH;
778 784
779 for (i = 0; i < NR_COUNT_TYPE; i++) 785 for (i = 0; i < NR_COUNT_TYPE; i++)
780 atomic_set(&sbi->nr_pages[i], 0); 786 atomic_set(&sbi->nr_pages[i], 0);