diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-01-07 23:45:08 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-01-07 23:45:08 -0500 |
commit | b1c57c1caa753cec299e62bb4272da0e85a01ef0 (patch) | |
tree | 05d7338349557e5f62ca84a00c362bc669e50f90 /fs/f2fs | |
parent | fb5566da9181d33ecdd9892e44f90320e7d4cc9f (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.h | 3 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 4 | ||||
-rw-r--r-- | fs/f2fs/gc.h | 2 | ||||
-rw-r--r-- | fs/f2fs/super.c | 6 |
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 | ||
25 | struct f2fs_gc_kthread { | 25 | struct 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 = { | |||
74 | enum { | 74 | enum { |
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 | ||
79 | struct f2fs_attr { | 80 | struct 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); | |||
180 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); | 183 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); |
181 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); | 184 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); |
182 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); | 185 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); |
186 | F2FS_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) |
185 | static struct attribute *f2fs_attrs[] = { | 189 | static 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); |