Commit b1c57c1caa753cec299e62bb4272da0e85a01ef0
1 parent
fb5566da91
Exists in
master
and in
16 other branches
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>
Showing 4 changed files with 12 additions and 3 deletions Side-by-side Diff
fs/f2fs/f2fs.h
... | ... | @@ -451,6 +451,9 @@ |
451 | 451 | struct f2fs_gc_kthread *gc_thread; /* GC thread */ |
452 | 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 | 458 | * for stat information. |
456 | 459 | * one is for the LFS mode, and the other is for the SSR mode. |
fs/f2fs/gc.c
... | ... | @@ -163,8 +163,8 @@ |
163 | 163 | p->ofs_unit = sbi->segs_per_sec; |
164 | 164 | } |
165 | 165 | |
166 | - if (p->max_search > MAX_VICTIM_SEARCH) | |
167 | - p->max_search = MAX_VICTIM_SEARCH; | |
166 | + if (p->max_search > sbi->max_victim_search) | |
167 | + p->max_search = sbi->max_victim_search; | |
168 | 168 | |
169 | 169 | p->offset = sbi->last_victim[p->gc_mode]; |
170 | 170 | } |
fs/f2fs/gc.h
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | #define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ |
21 | 21 | |
22 | 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 | 25 | struct f2fs_gc_kthread { |
26 | 26 | struct task_struct *f2fs_gc_task; |
fs/f2fs/super.c
... | ... | @@ -74,6 +74,7 @@ |
74 | 74 | enum { |
75 | 75 | GC_THREAD, /* struct f2fs_gc_thread */ |
76 | 76 | SM_INFO, /* struct f2fs_sm_info */ |
77 | + F2FS_SBI, /* struct f2fs_sb_info */ | |
77 | 78 | }; |
78 | 79 | |
79 | 80 | struct f2fs_attr { |
... | ... | @@ -91,6 +92,8 @@ |
91 | 92 | return (unsigned char *)sbi->gc_thread; |
92 | 93 | else if (struct_type == SM_INFO) |
93 | 94 | return (unsigned char *)SM_I(sbi); |
95 | + else if (struct_type == F2FS_SBI) | |
96 | + return (unsigned char *)sbi; | |
94 | 97 | return NULL; |
95 | 98 | } |
96 | 99 | |
... | ... | @@ -180,6 +183,7 @@ |
180 | 183 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); |
181 | 184 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); |
182 | 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 | 188 | #define ATTR_LIST(name) (&f2fs_attr_##name.attr) |
185 | 189 | static struct attribute *f2fs_attrs[] = { |
... | ... | @@ -191,6 +195,7 @@ |
191 | 195 | ATTR_LIST(max_small_discards), |
192 | 196 | ATTR_LIST(ipu_policy), |
193 | 197 | ATTR_LIST(min_ipu_util), |
198 | + ATTR_LIST(max_victim_search), | |
194 | 199 | NULL, |
195 | 200 | }; |
196 | 201 | |
... | ... | @@ -775,6 +780,7 @@ |
775 | 780 | sbi->node_ino_num = le32_to_cpu(raw_super->node_ino); |
776 | 781 | sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino); |
777 | 782 | sbi->cur_victim_sec = NULL_SECNO; |
783 | + sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH; | |
778 | 784 | |
779 | 785 | for (i = 0; i < NR_COUNT_TYPE; i++) |
780 | 786 | atomic_set(&sbi->nr_pages[i], 0); |