Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: add sysfs entries to select the gc policy

Add sysfs entry gc_idle to control the gc policy. Where
gc_idle = 1 corresponds to selecting a cost benefit approach,
while gc_idle = 2 corresponds to selecting a greedy approach
to garbage collection. The selection is mutually exclusive one
approach will work at any point. If gc_idle = 0, then this
option is disabled.

Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
Reviewed-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
[Jaegeuk Kim: change the select_gc_type() flow slightly]
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>

authored by

Namjae Jeon and committed by
Jaegeuk Kim
d2dc095f b59d0bae

+30 -3
+6
Documentation/ABI/testing/sysfs-fs-f2fs
··· 18 18 Description: 19 19 Controls the default sleep time for gc_thread. Time 20 20 is in milliseconds. 21 + 22 + What: /sys/fs/f2fs/<disk>/gc_idle 23 + Date: July 2013 24 + Contact: "Namjae Jeon" <namjae.jeon@samsung.com> 25 + Description: 26 + Controls the victim selection policy for garbage collection.
+6
Documentation/filesystems/f2fs.txt
··· 158 158 time for the garbage collection thread. Time is 159 159 in milliseconds. 160 160 161 + gc_idle This parameter controls the selection of victim 162 + policy for garbage collection. Setting gc_idle = 0 163 + (default) will disable this option. Setting 164 + gc_idle = 1 will select the Cost Benefit approach 165 + & setting gc_idle = 2 will select the greedy aproach. 166 + 161 167 ================================================================================ 162 168 USAGE 163 169 ================================================================================
+13 -3
fs/f2fs/gc.c
··· 106 106 gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME; 107 107 gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME; 108 108 109 + gc_th->gc_idle = 0; 110 + 109 111 sbi->gc_thread = gc_th; 110 112 init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); 111 113 sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi, ··· 132 130 sbi->gc_thread = NULL; 133 131 } 134 132 135 - static int select_gc_type(int gc_type) 133 + static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type) 136 134 { 137 - return (gc_type == BG_GC) ? GC_CB : GC_GREEDY; 135 + int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY; 136 + 137 + if (gc_th && gc_th->gc_idle) { 138 + if (gc_th->gc_idle == 1) 139 + gc_mode = GC_CB; 140 + else if (gc_th->gc_idle == 2) 141 + gc_mode = GC_GREEDY; 142 + } 143 + return gc_mode; 138 144 } 139 145 140 146 static void select_policy(struct f2fs_sb_info *sbi, int gc_type, ··· 155 145 p->dirty_segmap = dirty_i->dirty_segmap[type]; 156 146 p->ofs_unit = 1; 157 147 } else { 158 - p->gc_mode = select_gc_type(gc_type); 148 + p->gc_mode = select_gc_type(sbi->gc_thread, gc_type); 159 149 p->dirty_segmap = dirty_i->dirty_segmap[DIRTY]; 160 150 p->ofs_unit = sbi->segs_per_sec; 161 151 }
+3
fs/f2fs/gc.h
··· 30 30 unsigned int min_sleep_time; 31 31 unsigned int max_sleep_time; 32 32 unsigned int no_gc_sleep_time; 33 + 34 + /* for changing gc mode */ 35 + unsigned int gc_idle; 33 36 }; 34 37 35 38 struct inode_entry {
+2
fs/f2fs/super.c
··· 148 148 F2FS_RW_ATTR(gc_min_sleep_time, min_sleep_time); 149 149 F2FS_RW_ATTR(gc_max_sleep_time, max_sleep_time); 150 150 F2FS_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time); 151 + F2FS_RW_ATTR(gc_idle, gc_idle); 151 152 152 153 #define ATTR_LIST(name) (&f2fs_attr_##name.attr) 153 154 static struct attribute *f2fs_attrs[] = { 154 155 ATTR_LIST(gc_min_sleep_time), 155 156 ATTR_LIST(gc_max_sleep_time), 156 157 ATTR_LIST(gc_no_gc_sleep_time), 158 + ATTR_LIST(gc_idle), 157 159 NULL, 158 160 }; 159 161