This patch controls gc interval time according to fragmented ratio. It is difference between total free segments and usable free segments due to fragmentation. Background gc is for defragmentation. Signed-off-by: Changman Lee <cm224.lee@xxxxxxxxxxx> --- fs/f2fs/gc.c | 2 +- fs/f2fs/gc.h | 34 ++++++++-------------------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 742135a..68694c7 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -71,7 +71,7 @@ static int gc_thread_func(void *data) continue; } - if (has_enough_invalid_blocks(sbi)) + if (fragmented_ratio(sbi) > GC_FRAGMENT_RATIO_REF) wait_ms = decrease_sleep_time(wait_ms); else wait_ms = increase_sleep_time(wait_ms); diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index 30b2db0..07ca40d 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h @@ -16,8 +16,7 @@ #define GC_THREAD_MIN_SLEEP_TIME 10000 /* milliseconds */ #define GC_THREAD_MAX_SLEEP_TIME 30000 #define GC_THREAD_NOGC_SLEEP_TIME 10000 -#define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */ -#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ +#define GC_FRAGMENT_RATIO_REF 30 /* Search max. number of dirty segments to select a victim segment */ #define MAX_VICTIM_SEARCH 20 @@ -44,18 +43,6 @@ static inline block_t free_user_blocks(struct f2fs_sb_info *sbi) << sbi->log_blocks_per_seg; } -static inline block_t limit_invalid_user_blocks(struct f2fs_sb_info *sbi) -{ - return (long)(sbi->user_block_count * LIMIT_INVALID_BLOCK) / 100; -} - -static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi) -{ - block_t reclaimable_user_blocks = sbi->user_block_count - - written_block_count(sbi); - return (long)(reclaimable_user_blocks * LIMIT_FREE_BLOCK) / 100; -} - static inline long increase_sleep_time(long wait) { wait += GC_THREAD_MIN_SLEEP_TIME; @@ -72,19 +59,14 @@ static inline long decrease_sleep_time(long wait) return wait; } -static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) +static inline int fragmented_ratio(struct f2fs_sb_info *sbi) { - block_t invalid_user_blocks = sbi->user_block_count - - written_block_count(sbi); - /* - * Background GC is triggered with the following condition. - * 1. There are a number of invalid blocks. - * 2. There is not enough free space. - */ - if (invalid_user_blocks > limit_invalid_user_blocks(sbi) && - free_user_blocks(sbi) < limit_free_user_blocks(sbi)) - return true; - return false; + int free_segs = SM_I(sbi)->main_segments - + (written_block_count(sbi) >> sbi->log_blocks_per_seg); + int avail_free_segs = free_segments(sbi); + int ratio = (free_segs - avail_free_segs) * 100 / free_segs; + + return ratio; } static inline int is_idle(struct f2fs_sb_info *sbi) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html