diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-11-15 02:38:35 +0100 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-11-25 19:15:57 +0100 |
commit | 7702bdbe505a22380dd958e2ee35124c7c414806 (patch) | |
tree | 8dc084fff9df8d1330389b877514977b7eb97ecf /fs | |
parent | f2fs: fix redundant block allocation (diff) | |
download | linux-7702bdbe505a22380dd958e2ee35124c7c414806.tar.xz linux-7702bdbe505a22380dd958e2ee35124c7c414806.zip |
f2fs: avoid BG_GC in f2fs_balance_fs
If many threads hit has_not_enough_free_secs() in f2fs_balance_fs() at the same
time, all the threads would do FG_GC or BG_GC.
In this critical path, we totally don't need to do BG_GC at all.
Let's avoid that.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
-rw-r--r-- | fs/f2fs/file.c | 2 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 7 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 2 |
4 files changed, 8 insertions, 5 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a1dcc60ae946..c963fa8d6895 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2183,7 +2183,7 @@ int f2fs_migrate_page(struct address_space *, struct page *, struct page *, int start_gc_thread(struct f2fs_sb_info *); void stop_gc_thread(struct f2fs_sb_info *); block_t start_bidx_of_node(unsigned int, struct inode *); -int f2fs_gc(struct f2fs_sb_info *, bool); +int f2fs_gc(struct f2fs_sb_info *, bool, bool); void build_gc_manager(struct f2fs_sb_info *); /* diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 39616de92a55..9ea89ca8fd0b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1849,7 +1849,7 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg) mutex_lock(&sbi->gc_mutex); } - ret = f2fs_gc(sbi, sync); + ret = f2fs_gc(sbi, sync, true); out: mnt_drop_write_file(filp); return ret; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index a7b2c13404f8..36f6cfc613d3 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -82,7 +82,7 @@ static int gc_thread_func(void *data) stat_inc_bggc_count(sbi); /* if return value is not zero, no victim was selected */ - if (f2fs_gc(sbi, test_opt(sbi, FORCE_FG_GC))) + if (f2fs_gc(sbi, test_opt(sbi, FORCE_FG_GC), true)) wait_ms = gc_th->no_gc_sleep_time; trace_f2fs_background_gc(sbi->sb, wait_ms, @@ -909,7 +909,7 @@ next: return sec_freed; } -int f2fs_gc(struct f2fs_sb_info *sbi, bool sync) +int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background) { unsigned int segno; int gc_type = sync ? FG_GC : BG_GC; @@ -950,6 +950,9 @@ gc_more: if (ret) goto stop; } + } else if (gc_type == BG_GC && !background) { + /* f2fs_balance_fs doesn't need to do BG_GC in critical path. */ + goto stop; } if (segno == NULL_SEGNO && !__get_victim(sbi, &segno, gc_type)) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 1869bc3973d5..20eedf0eb751 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -366,7 +366,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need) */ if (has_not_enough_free_secs(sbi, 0, 0)) { mutex_lock(&sbi->gc_mutex); - f2fs_gc(sbi, false); + f2fs_gc(sbi, false, false); } } |