mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
f2fs: make BG GC more aggressive for zoned devices
Since we don't have any GC on device side for zoned devices, need more aggressive BG GC. So, tune the parameters for that. Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
0638a3197c
commit
5062b5bed4
@ -2879,13 +2879,26 @@ static inline bool is_inflight_io(struct f2fs_sb_info *sbi, int type)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_inflight_read_io(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
return get_pages(sbi, F2FS_RD_DATA) || get_pages(sbi, F2FS_DIO_READ);
|
||||
}
|
||||
|
||||
static inline bool is_idle(struct f2fs_sb_info *sbi, int type)
|
||||
{
|
||||
bool zoned_gc = (type == GC_TIME &&
|
||||
F2FS_HAS_FEATURE(sbi, F2FS_FEATURE_BLKZONED));
|
||||
|
||||
if (sbi->gc_mode == GC_URGENT_HIGH)
|
||||
return true;
|
||||
|
||||
if (is_inflight_io(sbi, type))
|
||||
return false;
|
||||
if (zoned_gc) {
|
||||
if (is_inflight_read_io(sbi))
|
||||
return false;
|
||||
} else {
|
||||
if (is_inflight_io(sbi, type))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sbi->gc_mode == GC_URGENT_MID)
|
||||
return true;
|
||||
@ -2894,6 +2907,9 @@ static inline bool is_idle(struct f2fs_sb_info *sbi, int type)
|
||||
(type == DISCARD_TIME || type == GC_TIME))
|
||||
return true;
|
||||
|
||||
if (zoned_gc)
|
||||
return true;
|
||||
|
||||
return f2fs_time_over(sbi, type);
|
||||
}
|
||||
|
||||
|
25
fs/f2fs/gc.c
25
fs/f2fs/gc.c
@ -116,7 +116,17 @@ static int gc_thread_func(void *data)
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (has_enough_invalid_blocks(sbi))
|
||||
if (f2fs_sb_has_blkzoned(sbi)) {
|
||||
if (has_enough_free_blocks(sbi, LIMIT_NO_ZONED_GC)) {
|
||||
wait_ms = gc_th->no_gc_sleep_time;
|
||||
f2fs_up_write(&sbi->gc_lock);
|
||||
goto next;
|
||||
}
|
||||
if (wait_ms == gc_th->no_gc_sleep_time)
|
||||
wait_ms = gc_th->max_sleep_time;
|
||||
}
|
||||
|
||||
if (need_to_boost_gc(sbi))
|
||||
decrease_sleep_time(gc_th, &wait_ms);
|
||||
else
|
||||
increase_sleep_time(gc_th, &wait_ms);
|
||||
@ -179,9 +189,16 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
|
||||
return -ENOMEM;
|
||||
|
||||
gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
|
||||
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
|
||||
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
|
||||
gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
|
||||
|
||||
if (f2fs_sb_has_blkzoned(sbi)) {
|
||||
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME_ZONED;
|
||||
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME_ZONED;
|
||||
gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME_ZONED;
|
||||
} else {
|
||||
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
|
||||
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
|
||||
gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
|
||||
}
|
||||
|
||||
gc_th->gc_wake = false;
|
||||
|
||||
|
21
fs/f2fs/gc.h
21
fs/f2fs/gc.h
@ -15,6 +15,11 @@
|
||||
#define DEF_GC_THREAD_MAX_SLEEP_TIME 60000
|
||||
#define DEF_GC_THREAD_NOGC_SLEEP_TIME 300000 /* wait 5 min */
|
||||
|
||||
/* GC sleep parameters for zoned deivces */
|
||||
#define DEF_GC_THREAD_MIN_SLEEP_TIME_ZONED 10
|
||||
#define DEF_GC_THREAD_MAX_SLEEP_TIME_ZONED 20
|
||||
#define DEF_GC_THREAD_NOGC_SLEEP_TIME_ZONED 60000
|
||||
|
||||
/* choose candidates from sections which has age of more than 7 days */
|
||||
#define DEF_GC_THREAD_AGE_THRESHOLD (60 * 60 * 24 * 7)
|
||||
#define DEF_GC_THREAD_CANDIDATE_RATIO 20 /* select 20% oldest sections as candidates */
|
||||
@ -25,6 +30,9 @@
|
||||
#define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */
|
||||
#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */
|
||||
|
||||
#define LIMIT_NO_ZONED_GC 60 /* percentage over total user space of no gc for zoned devices */
|
||||
#define LIMIT_BOOST_ZONED_GC 25 /* percentage over total user space of boosted gc for zoned devices */
|
||||
|
||||
#define DEF_GC_FAILED_PINNED_FILES 2048
|
||||
#define MAX_GC_FAILED_PINNED_FILES USHRT_MAX
|
||||
|
||||
@ -152,6 +160,12 @@ static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th,
|
||||
*wait -= min_time;
|
||||
}
|
||||
|
||||
static inline bool has_enough_free_blocks(struct f2fs_sb_info *sbi,
|
||||
unsigned int limit_perc)
|
||||
{
|
||||
return free_sections(sbi) > ((sbi->total_sections * limit_perc) / 100);
|
||||
}
|
||||
|
||||
static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
block_t user_block_count = sbi->user_block_count;
|
||||
@ -167,3 +181,10 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
|
||||
free_user_blocks(sbi) <
|
||||
limit_free_user_blocks(invalid_user_blocks));
|
||||
}
|
||||
|
||||
static inline bool need_to_boost_gc(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
if (f2fs_sb_has_blkzoned(sbi))
|
||||
return !has_enough_free_blocks(sbi, LIMIT_BOOST_ZONED_GC);
|
||||
return has_enough_invalid_blocks(sbi);
|
||||
}
|
||||
|
@ -706,6 +706,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
|
||||
if (!strcmp(name, "on")) {
|
||||
F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON;
|
||||
} else if (!strcmp(name, "off")) {
|
||||
if (f2fs_sb_has_blkzoned(sbi)) {
|
||||
f2fs_warn(sbi, "zoned devices need bggc");
|
||||
kfree(name);
|
||||
return -EINVAL;
|
||||
}
|
||||
F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_OFF;
|
||||
} else if (!strcmp(name, "sync")) {
|
||||
F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_SYNC;
|
||||
|
Loading…
Reference in New Issue
Block a user