* [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices
@ 2024-08-29 21:52 Daeho Jeong
2024-08-29 21:52 ` [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity Daeho Jeong
` (6 more replies)
0 siblings, 7 replies; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
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>
---
fs/f2fs/f2fs.h | 20 ++++++++++++++++++--
fs/f2fs/gc.c | 25 +++++++++++++++++++++----
fs/f2fs/gc.h | 22 ++++++++++++++++++++++
fs/f2fs/super.c | 8 +++++++-
4 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ac19c61f0c3e..5e4db3ba534a 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2854,13 +2854,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;
@@ -2869,6 +2882,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);
}
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 724bbcb447d3..46e3bc26b78a 100644
--- a/fs/f2fs/gc.c
+++ b/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;
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index a8ea3301b815..14ae85f33235 100644
--- a/fs/f2fs/gc.h
+++ b/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,10 @@
#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_MIGRATION_GRANULARITY_ZONED 3
+
#define DEF_GC_FAILED_PINNED_FILES 2048
#define MAX_GC_FAILED_PINNED_FILES USHRT_MAX
@@ -152,6 +161,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 +182,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);
+}
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 3959fd137cc9..790ec9d030c9 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -707,6 +707,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;
@@ -3785,7 +3790,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
sbi->next_victim_seg[BG_GC] = NULL_SEGNO;
sbi->next_victim_seg[FG_GC] = NULL_SEGNO;
sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH;
- sbi->migration_granularity = SEGS_PER_SEC(sbi);
+ sbi->migration_granularity = f2fs_sb_has_blkzoned(sbi) ?
+ DEF_MIGRATION_GRANULARITY_ZONED : SEGS_PER_SEC(sbi);
sbi->seq_file_ra_mul = MIN_RA_MUL;
sbi->max_fragment_chunk = DEF_FRAGMENT_SIZE;
sbi->max_fragment_hole = DEF_FRAGMENT_SIZE;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-06 2:56 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 3/7] f2fs: add reserved_segments sysfs node Daeho Jeong
` (5 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
Now we do readahead for a full section by not considering
migration_granularity and it triggers unnecessary read. So, make it read
with the correct amount.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
fs/f2fs/gc.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 46e3bc26b78a..b5d3fd40b17a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1708,24 +1708,33 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
struct blk_plug plug;
unsigned int segno = start_segno;
unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
+ unsigned int sec_end_segno;
int seg_freed = 0, migrated = 0;
unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
SUM_TYPE_DATA : SUM_TYPE_NODE;
unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
int submitted = 0;
- if (__is_large_section(sbi))
- end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
+ if (__is_large_section(sbi)) {
+ sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
- /*
- * zone-capacity can be less than zone-size in zoned devices,
- * resulting in less than expected usable segments in the zone,
- * calculate the end segno in the zone which can be garbage collected
- */
- if (f2fs_sb_has_blkzoned(sbi))
- end_segno -= SEGS_PER_SEC(sbi) -
+ /*
+ * zone-capacity can be less than zone-size in zoned devices,
+ * resulting in less than expected usable segments in the zone,
+ * calculate the end segno in the zone which can be garbage
+ * collected
+ */
+ if (f2fs_sb_has_blkzoned(sbi))
+ sec_end_segno -= SEGS_PER_SEC(sbi) -
f2fs_usable_segs_in_sec(sbi, segno);
+ if (gc_type == BG_GC)
+ end_segno = start_segno + sbi->migration_granularity;
+
+ if (end_segno > sec_end_segno)
+ end_segno = sec_end_segno;
+ }
+
sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
/* readahead multi ssa blocks those have contiguous address */
@@ -1762,9 +1771,6 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (get_valid_blocks(sbi, segno, false) == 0)
goto freed;
- if (gc_type == BG_GC && __is_large_section(sbi) &&
- migrated >= sbi->migration_granularity)
- goto skip;
if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
goto skip;
@@ -1803,7 +1809,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (__is_large_section(sbi))
sbi->next_victim_seg[gc_type] =
- (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
+ (segno + 1 < sec_end_segno) ?
+ segno + 1 : NULL_SEGNO;
skip:
f2fs_put_page(sum_page, 0);
}
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/7] f2fs: add reserved_segments sysfs node
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
2024-08-29 21:52 ` [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-06 3:04 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices Daeho Jeong
` (4 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
For the fine tuning of GC behavior, add reserved_segments sysfs node.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++
fs/f2fs/sysfs.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index cad6c3dc1f9c..4fcd0f824bde 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -763,3 +763,9 @@ Date: November 2023
Contact: "Chao Yu" <chao@kernel.org>
Description: It controls to enable/disable IO aware feature for background discard.
By default, the value is 1 which indicates IO aware is on.
+
+What: /sys/fs/f2fs/<disk>/reserved_segments
+Date: August 2024
+Contact: "Daeho Jeong" <daehojeong@google.com>
+Description: In order to fine tune GC behavior, we can control the number of
+ reserved segments.
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index fee7ee45ceaa..2ed773132f40 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -969,6 +969,7 @@ SM_INFO_GENERAL_RW_ATTR(min_fsync_blocks);
SM_INFO_GENERAL_RW_ATTR(min_seq_blocks);
SM_INFO_GENERAL_RW_ATTR(min_hot_blocks);
SM_INFO_GENERAL_RW_ATTR(min_ssr_sections);
+SM_INFO_GENERAL_RW_ATTR(reserved_segments);
/* DCC_INFO ATTR */
DCC_INFO_RW_ATTR(max_small_discards, max_discards);
@@ -1138,6 +1139,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(min_seq_blocks),
ATTR_LIST(min_hot_blocks),
ATTR_LIST(min_ssr_sections),
+ ATTR_LIST(reserved_segments),
ATTR_LIST(max_victim_search),
ATTR_LIST(migration_granularity),
ATTR_LIST(dir_level),
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
2024-08-29 21:52 ` [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity Daeho Jeong
2024-08-29 21:52 ` [PATCH 3/7] f2fs: add reserved_segments sysfs node Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-06 3:37 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 5/7] f2fs: do FG_GC when GC boosting is required " Daeho Jeong
` (3 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
Need bigger BG GC migration granularity when free section is running
low.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
fs/f2fs/gc.c | 13 +++++++++++--
fs/f2fs/gc.h | 1 +
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index b5d3fd40b17a..d6d71aab94f3 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1728,8 +1728,17 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
sec_end_segno -= SEGS_PER_SEC(sbi) -
f2fs_usable_segs_in_sec(sbi, segno);
- if (gc_type == BG_GC)
- end_segno = start_segno + sbi->migration_granularity;
+ if (gc_type == BG_GC) {
+ unsigned int migration_granularity =
+ sbi->migration_granularity;
+
+ if (f2fs_sb_has_blkzoned(sbi) &&
+ !has_enough_free_blocks(sbi,
+ LIMIT_BOOST_ZONED_GC))
+ migration_granularity *= BOOST_GC_MULTIPLE;
+
+ end_segno = start_segno + migration_granularity;
+ }
if (end_segno > sec_end_segno)
end_segno = sec_end_segno;
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index 14ae85f33235..33848d550153 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -33,6 +33,7 @@
#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_MIGRATION_GRANULARITY_ZONED 3
+#define BOOST_GC_MULTIPLE 5
#define DEF_GC_FAILED_PINNED_FILES 2048
#define MAX_GC_FAILED_PINNED_FILES USHRT_MAX
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 5/7] f2fs: do FG_GC when GC boosting is required for zoned devices
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
` (2 preceding siblings ...)
2024-08-29 21:52 ` [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-06 6:34 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent Daeho Jeong
` (2 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
Under low free section count, we need to use FG_GC instead of BG_GC to
recover free sections.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
fs/f2fs/f2fs.h | 1 +
fs/f2fs/gc.c | 24 +++++++++++++++++-------
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 5e4db3ba534a..ee1fafc65e95 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1294,6 +1294,7 @@ struct f2fs_gc_control {
bool should_migrate_blocks; /* should migrate blocks */
bool err_gc_skipped; /* return EAGAIN if GC skipped */
unsigned int nr_free_secs; /* # of free sections to do GC */
+ bool one_time; /* require one time GC in one migration unit */
};
/*
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index d6d71aab94f3..37b47a8d95f1 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -81,6 +81,8 @@ static int gc_thread_func(void *data)
continue;
}
+ gc_control.one_time = false;
+
/*
* [GC triggering condition]
* 0. GC is not conducted currently.
@@ -126,15 +128,19 @@ static int gc_thread_func(void *data)
wait_ms = gc_th->max_sleep_time;
}
- if (need_to_boost_gc(sbi))
+ if (need_to_boost_gc(sbi)) {
decrease_sleep_time(gc_th, &wait_ms);
- else
+ if (f2fs_sb_has_blkzoned(sbi))
+ gc_control.one_time = true;
+ } else {
increase_sleep_time(gc_th, &wait_ms);
+ }
do_gc:
stat_inc_gc_call_count(sbi, foreground ?
FOREGROUND : BACKGROUND);
- sync_mode = F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC;
+ sync_mode = (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC) ||
+ gc_control.one_time;
/* foreground GC was been triggered via f2fs_balance_fs() */
if (foreground)
@@ -1701,7 +1707,7 @@ static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,
static int do_garbage_collect(struct f2fs_sb_info *sbi,
unsigned int start_segno,
struct gc_inode_list *gc_list, int gc_type,
- bool force_migrate)
+ bool force_migrate, bool one_time)
{
struct page *sum_page;
struct f2fs_summary_block *sum;
@@ -1728,7 +1734,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
sec_end_segno -= SEGS_PER_SEC(sbi) -
f2fs_usable_segs_in_sec(sbi, segno);
- if (gc_type == BG_GC) {
+ if (gc_type == BG_GC || one_time) {
unsigned int migration_granularity =
sbi->migration_granularity;
@@ -1908,7 +1914,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
}
seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type,
- gc_control->should_migrate_blocks);
+ gc_control->should_migrate_blocks,
+ gc_control->one_time);
if (seg_freed < 0)
goto stop;
@@ -1919,6 +1926,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
total_sec_freed++;
}
+ if (gc_control->one_time)
+ goto stop;
+
if (gc_type == FG_GC) {
sbi->cur_victim_sec = NULL_SEGNO;
@@ -2044,7 +2054,7 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
};
do_garbage_collect(sbi, segno, &gc_list, FG_GC,
- dry_run_sections == 0);
+ dry_run_sections == 0, false);
put_gc_inode(&gc_list);
if (!dry_run && get_valid_blocks(sbi, segno, true))
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
` (3 preceding siblings ...)
2024-08-29 21:52 ` [PATCH 5/7] f2fs: do FG_GC when GC boosting is required " Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-06 6:35 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC Daeho Jeong
2024-09-06 2:21 ` [f2fs-dev] [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Chao Yu
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
Added control knobs for gc_no_zoned_gc_percent and
gc_boost_zoned_gc_percent.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 14 ++++++++++++++
fs/f2fs/gc.c | 12 +++++++++---
fs/f2fs/gc.h | 4 ++++
fs/f2fs/sysfs.c | 4 ++++
4 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 4fcd0f824bde..265baec879fd 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -769,3 +769,17 @@ Date: August 2024
Contact: "Daeho Jeong" <daehojeong@google.com>
Description: In order to fine tune GC behavior, we can control the number of
reserved segments.
+
+What: /sys/fs/f2fs/<disk>/gc_no_zoned_gc_percent
+Date: August 2024
+Contact: "Daeho Jeong" <daehojeong@google.com>
+Description: If the percentage of free sections over total sections is above this
+ number, F2FS do not garbage collection for zoned devices through the
+ background GC thread. the default number is "60".
+
+What: /sys/fs/f2fs/<disk>/gc_boost_zoned_gc_percent
+Date: August 2024
+Contact: "Daeho Jeong" <daehojeong@google.com>
+Description: If the percentage of free sections over total sections is under this
+ number, F2FS boosts garbage collection for zoned devices through the
+ background GC thread. the default number is "25".
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 37b47a8d95f1..6b79c43a57e3 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -119,7 +119,8 @@ static int gc_thread_func(void *data)
}
if (f2fs_sb_has_blkzoned(sbi)) {
- if (has_enough_free_blocks(sbi, LIMIT_NO_ZONED_GC)) {
+ if (has_enough_free_blocks(sbi,
+ gc_th->no_zoned_gc_percent)) {
wait_ms = gc_th->no_gc_sleep_time;
f2fs_up_write(&sbi->gc_lock);
goto next;
@@ -200,10 +201,14 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *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;
+ gc_th->no_zoned_gc_percent = LIMIT_NO_ZONED_GC;
+ gc_th->boost_zoned_gc_percent = LIMIT_BOOST_ZONED_GC;
} 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->no_zoned_gc_percent = 0;
+ gc_th->boost_zoned_gc_percent = 0;
}
gc_th->gc_wake = false;
@@ -1740,8 +1745,9 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (f2fs_sb_has_blkzoned(sbi) &&
!has_enough_free_blocks(sbi,
- LIMIT_BOOST_ZONED_GC))
- migration_granularity *= BOOST_GC_MULTIPLE;
+ sbi->gc_thread->boost_zoned_gc_percent))
+ migration_granularity *=
+ BOOST_GC_MULTIPLE;
end_segno = start_segno + migration_granularity;
}
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index 33848d550153..e8195eb4ca6d 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -61,6 +61,10 @@ struct f2fs_gc_kthread {
* caller of f2fs_balance_fs()
* will wait on this wait queue.
*/
+
+ /* for gc control for zoned devices */
+ unsigned int no_zoned_gc_percent;
+ unsigned int boost_zoned_gc_percent;
};
struct gc_inode_list {
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 2ed773132f40..647f6660f4df 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -960,6 +960,8 @@ GC_THREAD_RW_ATTR(gc_urgent_sleep_time, urgent_sleep_time);
GC_THREAD_RW_ATTR(gc_min_sleep_time, min_sleep_time);
GC_THREAD_RW_ATTR(gc_max_sleep_time, max_sleep_time);
GC_THREAD_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);
+GC_THREAD_RW_ATTR(gc_no_zoned_gc_percent, no_zoned_gc_percent);
+GC_THREAD_RW_ATTR(gc_boost_zoned_gc_percent, boost_zoned_gc_percent);
/* SM_INFO ATTR */
SM_INFO_RW_ATTR(reclaim_segments, rec_prefree_segments);
@@ -1117,6 +1119,8 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(gc_min_sleep_time),
ATTR_LIST(gc_max_sleep_time),
ATTR_LIST(gc_no_gc_sleep_time),
+ ATTR_LIST(gc_no_zoned_gc_percent),
+ ATTR_LIST(gc_boost_zoned_gc_percent),
ATTR_LIST(gc_idle),
ATTR_LIST(gc_urgent),
ATTR_LIST(reclaim_segments),
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
` (4 preceding siblings ...)
2024-08-29 21:52 ` [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent Daeho Jeong
@ 2024-08-29 21:52 ` Daeho Jeong
2024-09-09 9:22 ` [f2fs-dev] " Chao Yu
2024-09-06 2:21 ` [f2fs-dev] [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Chao Yu
6 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-08-29 21:52 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
From: Daeho Jeong <daehojeong@google.com>
We need to introduce a valid block ratio threshold not to trigger
excessive GC for zoned deivces. The initial value of it is 95%. So, F2FS
will stop the thread from intiating GC for sections having valid blocks
exceeding the ratio.
Signed-off-by: Daeho Jeong <daehojeong@google.com>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 8 ++++++++
fs/f2fs/f2fs.h | 2 +-
fs/f2fs/gc.c | 15 +++++++++++----
fs/f2fs/gc.h | 2 ++
fs/f2fs/segment.c | 6 ++++--
fs/f2fs/segment.h | 1 +
fs/f2fs/sysfs.c | 2 ++
7 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 265baec879fd..2d3e42af0e63 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -783,3 +783,11 @@ Contact: "Daeho Jeong" <daehojeong@google.com>
Description: If the percentage of free sections over total sections is under this
number, F2FS boosts garbage collection for zoned devices through the
background GC thread. the default number is "25".
+
+What: /sys/fs/f2fs/<disk>/gc_valid_thresh_ratio
+Date: August 2024
+Contact: "Daeho Jeong" <daehojeong@google.com>
+Description: It controls the valid block ratio threshold not to trigger excessive GC
+ for zoned deivces. The initial value of it is 95(%). F2FS will stop the
+ background GC thread from intiating GC for sections having valid blocks
+ exceeding the ratio.
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ee1fafc65e95..8220b3189780 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3918,7 +3918,7 @@ void f2fs_destroy_garbage_collection_cache(void);
/* victim selection function for cleaning and SSR */
int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
int gc_type, int type, char alloc_mode,
- unsigned long long age);
+ unsigned long long age, bool one_time);
/*
* recovery.c
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 6b79c43a57e3..feb80345aca3 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -196,6 +196,7 @@ 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->valid_thresh_ratio = DEF_GC_THREAD_VALID_THRESH_RATIO;
if (f2fs_sb_has_blkzoned(sbi)) {
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME_ZONED;
@@ -396,6 +397,10 @@ static inline unsigned int get_gc_cost(struct f2fs_sb_info *sbi,
if (p->alloc_mode == SSR)
return get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+ if (p->one_time_gc && (get_valid_blocks(sbi, segno, true) >=
+ BLKS_PER_SEC(sbi) * sbi->gc_thread->valid_thresh_ratio / 100))
+ return UINT_MAX;
+
/* alloc_mode == LFS */
if (p->gc_mode == GC_GREEDY)
return get_valid_blocks(sbi, segno, true);
@@ -770,7 +775,7 @@ static int f2fs_gc_pinned_control(struct inode *inode, int gc_type,
*/
int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
int gc_type, int type, char alloc_mode,
- unsigned long long age)
+ unsigned long long age, bool one_time)
{
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
struct sit_info *sm = SIT_I(sbi);
@@ -787,6 +792,7 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
p.alloc_mode = alloc_mode;
p.age = age;
p.age_threshold = sbi->am.age_threshold;
+ p.one_time_gc = one_time;
retry:
select_policy(sbi, gc_type, type, &p);
@@ -1698,13 +1704,14 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
}
static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,
- int gc_type)
+ int gc_type, bool one_time)
{
struct sit_info *sit_i = SIT_I(sbi);
int ret;
down_write(&sit_i->sentry_lock);
- ret = f2fs_get_victim(sbi, victim, gc_type, NO_CHECK_TYPE, LFS, 0);
+ ret = f2fs_get_victim(sbi, victim, gc_type, NO_CHECK_TYPE,
+ LFS, 0, one_time);
up_write(&sit_i->sentry_lock);
return ret;
}
@@ -1908,7 +1915,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
goto stop;
}
retry:
- ret = __get_victim(sbi, &segno, gc_type);
+ ret = __get_victim(sbi, &segno, gc_type, gc_control->one_time);
if (ret) {
/* allow to search victim from sections has pinned data */
if (ret == -ENODATA && gc_type == FG_GC &&
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index e8195eb4ca6d..59872daf88ee 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -25,6 +25,7 @@
#define DEF_GC_THREAD_CANDIDATE_RATIO 20 /* select 20% oldest sections as candidates */
#define DEF_GC_THREAD_MAX_CANDIDATE_COUNT 10 /* select at most 10 sections as candidates */
#define DEF_GC_THREAD_AGE_WEIGHT 60 /* age weight */
+#define DEF_GC_THREAD_VALID_THRESH_RATIO 95 /* do not GC over 95% valid block ratio for one time GC */
#define DEFAULT_ACCURACY_CLASS 10000 /* accuracy class */
#define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */
@@ -65,6 +66,7 @@ struct f2fs_gc_kthread {
/* for gc control for zoned devices */
unsigned int no_zoned_gc_percent;
unsigned int boost_zoned_gc_percent;
+ unsigned int valid_thresh_ratio;
};
struct gc_inode_list {
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 78c3198a6308..26f5abc62461 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3052,7 +3052,8 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
sanity_check_seg_type(sbi, seg_type);
/* f2fs_need_SSR() already forces to do this */
- if (!f2fs_get_victim(sbi, &segno, BG_GC, seg_type, alloc_mode, age)) {
+ if (!f2fs_get_victim(sbi, &segno, BG_GC, seg_type,
+ alloc_mode, age, false)) {
curseg->next_segno = segno;
return 1;
}
@@ -3079,7 +3080,8 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
for (; cnt-- > 0; reversed ? i-- : i++) {
if (i == seg_type)
continue;
- if (!f2fs_get_victim(sbi, &segno, BG_GC, i, alloc_mode, age)) {
+ if (!f2fs_get_victim(sbi, &segno, BG_GC, i,
+ alloc_mode, age, false)) {
curseg->next_segno = segno;
return 1;
}
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index bfc01a521cb9..43db2d3e8c85 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -188,6 +188,7 @@ struct victim_sel_policy {
unsigned int min_segno; /* segment # having min. cost */
unsigned long long age; /* mtime of GCed section*/
unsigned long long age_threshold;/* age threshold */
+ bool one_time_gc; /* one time GC */
};
struct seg_entry {
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 647f6660f4df..d9d47c0698d1 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -962,6 +962,7 @@ GC_THREAD_RW_ATTR(gc_max_sleep_time, max_sleep_time);
GC_THREAD_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);
GC_THREAD_RW_ATTR(gc_no_zoned_gc_percent, no_zoned_gc_percent);
GC_THREAD_RW_ATTR(gc_boost_zoned_gc_percent, boost_zoned_gc_percent);
+GC_THREAD_RW_ATTR(gc_valid_thresh_ratio, valid_thresh_ratio);
/* SM_INFO ATTR */
SM_INFO_RW_ATTR(reclaim_segments, rec_prefree_segments);
@@ -1121,6 +1122,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(gc_no_gc_sleep_time),
ATTR_LIST(gc_no_zoned_gc_percent),
ATTR_LIST(gc_boost_zoned_gc_percent),
+ ATTR_LIST(gc_valid_thresh_ratio),
ATTR_LIST(gc_idle),
ATTR_LIST(gc_urgent),
ATTR_LIST(reclaim_segments),
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
` (5 preceding siblings ...)
2024-08-29 21:52 ` [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC Daeho Jeong
@ 2024-09-06 2:21 ` Chao Yu
6 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-06 2:21 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> 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>
Thanks,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity
2024-08-29 21:52 ` [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity Daeho Jeong
@ 2024-09-06 2:56 ` Chao Yu
2024-09-06 20:23 ` Daeho Jeong
0 siblings, 1 reply; 16+ messages in thread
From: Chao Yu @ 2024-09-06 2:56 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> Now we do readahead for a full section by not considering
> migration_granularity and it triggers unnecessary read. So, make it read
> with the correct amount.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
> ---
> fs/f2fs/gc.c | 33 ++++++++++++++++++++-------------
> 1 file changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 46e3bc26b78a..b5d3fd40b17a 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1708,24 +1708,33 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
> struct blk_plug plug;
> unsigned int segno = start_segno;
> unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
> + unsigned int sec_end_segno;
> int seg_freed = 0, migrated = 0;
> unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
> SUM_TYPE_DATA : SUM_TYPE_NODE;
> unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
> int submitted = 0;
>
> - if (__is_large_section(sbi))
> - end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
> + if (__is_large_section(sbi)) {
> + sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
>
> - /*
> - * zone-capacity can be less than zone-size in zoned devices,
> - * resulting in less than expected usable segments in the zone,
> - * calculate the end segno in the zone which can be garbage collected
> - */
> - if (f2fs_sb_has_blkzoned(sbi))
> - end_segno -= SEGS_PER_SEC(sbi) -
> + /*
> + * zone-capacity can be less than zone-size in zoned devices,
> + * resulting in less than expected usable segments in the zone,
> + * calculate the end segno in the zone which can be garbage
> + * collected
> + */
> + if (f2fs_sb_has_blkzoned(sbi))
> + sec_end_segno -= SEGS_PER_SEC(sbi) -
> f2fs_usable_segs_in_sec(sbi, segno);
>
> + if (gc_type == BG_GC)
> + end_segno = start_segno + sbi->migration_granularity;
> +
> + if (end_segno > sec_end_segno)
> + end_segno = sec_end_segno;
> + }
> +
> sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
>
> /* readahead multi ssa blocks those have contiguous address */
> @@ -1762,9 +1771,6 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
>
> if (get_valid_blocks(sbi, segno, false) == 0)
> goto freed;
> - if (gc_type == BG_GC && __is_large_section(sbi) &&
> - migrated >= sbi->migration_granularity)
It seems we change the logic from migrating "migration_granularity" segments which
has valid blocks to scanning "migration_granularity" segments and try migrating
valid blocks in those segments.
IIUC, when background GC recycle sparse zone, it will take gc thread more round,
it seems low efficient. How do you think of keeping previous implementation?
Thanks,
> - goto skip;
> if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
> goto skip;
>
> @@ -1803,7 +1809,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
>
> if (__is_large_section(sbi))
> sbi->next_victim_seg[gc_type] =
> - (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
> + (segno + 1 < sec_end_segno) ?
> + segno + 1 : NULL_SEGNO;
> skip:
> f2fs_put_page(sum_page, 0);
> }
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 3/7] f2fs: add reserved_segments sysfs node
2024-08-29 21:52 ` [PATCH 3/7] f2fs: add reserved_segments sysfs node Daeho Jeong
@ 2024-09-06 3:04 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-06 3:04 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> For the fine tuning of GC behavior, add reserved_segments sysfs node.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Thanks,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices
2024-08-29 21:52 ` [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices Daeho Jeong
@ 2024-09-06 3:37 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-06 3:37 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> Need bigger BG GC migration granularity when free section is running
> low.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Thanks,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 5/7] f2fs: do FG_GC when GC boosting is required for zoned devices
2024-08-29 21:52 ` [PATCH 5/7] f2fs: do FG_GC when GC boosting is required " Daeho Jeong
@ 2024-09-06 6:34 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-06 6:34 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> Under low free section count, we need to use FG_GC instead of BG_GC to
> recover free sections.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
> ---
> fs/f2fs/f2fs.h | 1 +
> fs/f2fs/gc.c | 24 +++++++++++++++++-------
> 2 files changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 5e4db3ba534a..ee1fafc65e95 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1294,6 +1294,7 @@ struct f2fs_gc_control {
> bool should_migrate_blocks; /* should migrate blocks */
> bool err_gc_skipped; /* return EAGAIN if GC skipped */
bool one_time; /* require one time GC in one migration unit */
In order to avoid unnecessary padding for alignment.
Thanks,
> unsigned int nr_free_secs; /* # of free sections to do GC */
> + bool one_time; /* require one time GC in one migration unit */
> };
>
> /*
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index d6d71aab94f3..37b47a8d95f1 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -81,6 +81,8 @@ static int gc_thread_func(void *data)
> continue;
> }
>
> + gc_control.one_time = false;
> +
> /*
> * [GC triggering condition]
> * 0. GC is not conducted currently.
> @@ -126,15 +128,19 @@ static int gc_thread_func(void *data)
> wait_ms = gc_th->max_sleep_time;
> }
>
> - if (need_to_boost_gc(sbi))
> + if (need_to_boost_gc(sbi)) {
> decrease_sleep_time(gc_th, &wait_ms);
> - else
> + if (f2fs_sb_has_blkzoned(sbi))
> + gc_control.one_time = true;
> + } else {
> increase_sleep_time(gc_th, &wait_ms);
> + }
> do_gc:
> stat_inc_gc_call_count(sbi, foreground ?
> FOREGROUND : BACKGROUND);
>
> - sync_mode = F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC;
> + sync_mode = (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC) ||
> + gc_control.one_time;
>
> /* foreground GC was been triggered via f2fs_balance_fs() */
> if (foreground)
> @@ -1701,7 +1707,7 @@ static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,
> static int do_garbage_collect(struct f2fs_sb_info *sbi,
> unsigned int start_segno,
> struct gc_inode_list *gc_list, int gc_type,
> - bool force_migrate)
> + bool force_migrate, bool one_time)
> {
> struct page *sum_page;
> struct f2fs_summary_block *sum;
> @@ -1728,7 +1734,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
> sec_end_segno -= SEGS_PER_SEC(sbi) -
> f2fs_usable_segs_in_sec(sbi, segno);
>
> - if (gc_type == BG_GC) {
> + if (gc_type == BG_GC || one_time) {
> unsigned int migration_granularity =
> sbi->migration_granularity;
>
> @@ -1908,7 +1914,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
> }
>
> seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type,
> - gc_control->should_migrate_blocks);
> + gc_control->should_migrate_blocks,
> + gc_control->one_time);
> if (seg_freed < 0)
> goto stop;
>
> @@ -1919,6 +1926,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
> total_sec_freed++;
> }
>
> + if (gc_control->one_time)
> + goto stop;
> +
> if (gc_type == FG_GC) {
> sbi->cur_victim_sec = NULL_SEGNO;
>
> @@ -2044,7 +2054,7 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
> };
>
> do_garbage_collect(sbi, segno, &gc_list, FG_GC,
> - dry_run_sections == 0);
> + dry_run_sections == 0, false);
> put_gc_inode(&gc_list);
>
> if (!dry_run && get_valid_blocks(sbi, segno, true))
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent
2024-08-29 21:52 ` [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent Daeho Jeong
@ 2024-09-06 6:35 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-06 6:35 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> Added control knobs for gc_no_zoned_gc_percent and
> gc_boost_zoned_gc_percent.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Thanks,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity
2024-09-06 2:56 ` [f2fs-dev] " Chao Yu
@ 2024-09-06 20:23 ` Daeho Jeong
2024-09-09 8:18 ` Chao Yu
0 siblings, 1 reply; 16+ messages in thread
From: Daeho Jeong @ 2024-09-06 20:23 UTC (permalink / raw)
To: Chao Yu; +Cc: linux-kernel, linux-f2fs-devel, kernel-team, Daeho Jeong
On Thu, Sep 5, 2024 at 7:56 PM Chao Yu <chao@kernel.org> wrote:
>
> On 2024/8/30 5:52, Daeho Jeong wrote:
> > From: Daeho Jeong <daehojeong@google.com>
> >
> > Now we do readahead for a full section by not considering
> > migration_granularity and it triggers unnecessary read. So, make it read
> > with the correct amount.
> >
> > Signed-off-by: Daeho Jeong <daehojeong@google.com>
> > ---
> > fs/f2fs/gc.c | 33 ++++++++++++++++++++-------------
> > 1 file changed, 20 insertions(+), 13 deletions(-)
> >
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index 46e3bc26b78a..b5d3fd40b17a 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -1708,24 +1708,33 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
> > struct blk_plug plug;
> > unsigned int segno = start_segno;
> > unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
> > + unsigned int sec_end_segno;
> > int seg_freed = 0, migrated = 0;
> > unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
> > SUM_TYPE_DATA : SUM_TYPE_NODE;
> > unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
> > int submitted = 0;
> >
> > - if (__is_large_section(sbi))
> > - end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
> > + if (__is_large_section(sbi)) {
> > + sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
> >
> > - /*
> > - * zone-capacity can be less than zone-size in zoned devices,
> > - * resulting in less than expected usable segments in the zone,
> > - * calculate the end segno in the zone which can be garbage collected
> > - */
> > - if (f2fs_sb_has_blkzoned(sbi))
> > - end_segno -= SEGS_PER_SEC(sbi) -
> > + /*
> > + * zone-capacity can be less than zone-size in zoned devices,
> > + * resulting in less than expected usable segments in the zone,
> > + * calculate the end segno in the zone which can be garbage
> > + * collected
> > + */
> > + if (f2fs_sb_has_blkzoned(sbi))
> > + sec_end_segno -= SEGS_PER_SEC(sbi) -
> > f2fs_usable_segs_in_sec(sbi, segno);
> >
> > + if (gc_type == BG_GC)
> > + end_segno = start_segno + sbi->migration_granularity;
> > +
> > + if (end_segno > sec_end_segno)
> > + end_segno = sec_end_segno;
> > + }
> > +
> > sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
> >
> > /* readahead multi ssa blocks those have contiguous address */
> > @@ -1762,9 +1771,6 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
> >
> > if (get_valid_blocks(sbi, segno, false) == 0)
> > goto freed;
> > - if (gc_type == BG_GC && __is_large_section(sbi) &&
> > - migrated >= sbi->migration_granularity)
>
> It seems we change the logic from migrating "migration_granularity" segments which
> has valid blocks to scanning "migration_granularity" segments and try migrating
> valid blocks in those segments.
>
> IIUC, when background GC recycle sparse zone, it will take gc thread more round,
> it seems low efficient. How do you think of keeping previous implementation?
I got your point. However, with zoned devices having 1GB sections, per
every round, we should
touch almost 2MB size of ssa block pages, even though we didn't need
to do it. Maybe, we can introduce
another sysfs node like migration_window_limit, which can be set as
double as migration_granuality by default,
limiting the size of scanning.
>
> Thanks,
>
> > - goto skip;
> > if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
> > goto skip;
> >
> > @@ -1803,7 +1809,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
> >
> > if (__is_large_section(sbi))
> > sbi->next_victim_seg[gc_type] =
> > - (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
> > + (segno + 1 < sec_end_segno) ?
> > + segno + 1 : NULL_SEGNO;
> > skip:
> > f2fs_put_page(sum_page, 0);
> > }
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity
2024-09-06 20:23 ` Daeho Jeong
@ 2024-09-09 8:18 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-09 8:18 UTC (permalink / raw)
To: Daeho Jeong
Cc: chao, linux-kernel, linux-f2fs-devel, kernel-team, Daeho Jeong
On 2024/9/7 4:23, Daeho Jeong wrote:
> On Thu, Sep 5, 2024 at 7:56 PM Chao Yu <chao@kernel.org> wrote:
>>
>> On 2024/8/30 5:52, Daeho Jeong wrote:
>>> From: Daeho Jeong <daehojeong@google.com>
>>>
>>> Now we do readahead for a full section by not considering
>>> migration_granularity and it triggers unnecessary read. So, make it read
>>> with the correct amount.
>>>
>>> Signed-off-by: Daeho Jeong <daehojeong@google.com>
>>> ---
>>> fs/f2fs/gc.c | 33 ++++++++++++++++++++-------------
>>> 1 file changed, 20 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>>> index 46e3bc26b78a..b5d3fd40b17a 100644
>>> --- a/fs/f2fs/gc.c
>>> +++ b/fs/f2fs/gc.c
>>> @@ -1708,24 +1708,33 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
>>> struct blk_plug plug;
>>> unsigned int segno = start_segno;
>>> unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
>>> + unsigned int sec_end_segno;
>>> int seg_freed = 0, migrated = 0;
>>> unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
>>> SUM_TYPE_DATA : SUM_TYPE_NODE;
>>> unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
>>> int submitted = 0;
>>>
>>> - if (__is_large_section(sbi))
>>> - end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
>>> + if (__is_large_section(sbi)) {
>>> + sec_end_segno = rounddown(end_segno, SEGS_PER_SEC(sbi));
>>>
>>> - /*
>>> - * zone-capacity can be less than zone-size in zoned devices,
>>> - * resulting in less than expected usable segments in the zone,
>>> - * calculate the end segno in the zone which can be garbage collected
>>> - */
>>> - if (f2fs_sb_has_blkzoned(sbi))
>>> - end_segno -= SEGS_PER_SEC(sbi) -
>>> + /*
>>> + * zone-capacity can be less than zone-size in zoned devices,
>>> + * resulting in less than expected usable segments in the zone,
>>> + * calculate the end segno in the zone which can be garbage
>>> + * collected
>>> + */
>>> + if (f2fs_sb_has_blkzoned(sbi))
>>> + sec_end_segno -= SEGS_PER_SEC(sbi) -
>>> f2fs_usable_segs_in_sec(sbi, segno);
>>>
>>> + if (gc_type == BG_GC)
>>> + end_segno = start_segno + sbi->migration_granularity;
>>> +
>>> + if (end_segno > sec_end_segno)
>>> + end_segno = sec_end_segno;
>>> + }
>>> +
>>> sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
>>>
>>> /* readahead multi ssa blocks those have contiguous address */
>>> @@ -1762,9 +1771,6 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
>>>
>>> if (get_valid_blocks(sbi, segno, false) == 0)
>>> goto freed;
>>> - if (gc_type == BG_GC && __is_large_section(sbi) &&
>>> - migrated >= sbi->migration_granularity)
>>
>> It seems we change the logic from migrating "migration_granularity" segments which
>> has valid blocks to scanning "migration_granularity" segments and try migrating
>> valid blocks in those segments.
>>
>> IIUC, when background GC recycle sparse zone, it will take gc thread more round,
>> it seems low efficient. How do you think of keeping previous implementation?
>
> I got your point. However, with zoned devices having 1GB sections, per
> every round, we should
> touch almost 2MB size of ssa block pages, even though we didn't need
> to do it. Maybe, we can introduce
Yes, or can we:
a) just read SSA block for segment which has valid blocks;
b) limit readahead size to a threshold as you proposed.
Thanks,
> another sysfs node like migration_window_limit, which can be set as
> double as migration_granuality by default,
> limiting the size of scanning.
>
>>
>> Thanks,
>>
>>> - goto skip;
>>> if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
>>> goto skip;
>>>
>>> @@ -1803,7 +1809,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
>>>
>>> if (__is_large_section(sbi))
>>> sbi->next_victim_seg[gc_type] =
>>> - (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
>>> + (segno + 1 < sec_end_segno) ?
>>> + segno + 1 : NULL_SEGNO;
>>> skip:
>>> f2fs_put_page(sum_page, 0);
>>> }
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [f2fs-dev] [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC
2024-08-29 21:52 ` [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC Daeho Jeong
@ 2024-09-09 9:22 ` Chao Yu
0 siblings, 0 replies; 16+ messages in thread
From: Chao Yu @ 2024-09-09 9:22 UTC (permalink / raw)
To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team
Cc: chao, Daeho Jeong
On 2024/8/30 5:52, Daeho Jeong wrote:
> From: Daeho Jeong <daehojeong@google.com>
>
> We need to introduce a valid block ratio threshold not to trigger
> excessive GC for zoned deivces. The initial value of it is 95%. So, F2FS
> will stop the thread from intiating GC for sections having valid blocks
> exceeding the ratio.
>
> Signed-off-by: Daeho Jeong <daehojeong@google.com>
> ---
> Documentation/ABI/testing/sysfs-fs-f2fs | 8 ++++++++
> fs/f2fs/f2fs.h | 2 +-
> fs/f2fs/gc.c | 15 +++++++++++----
> fs/f2fs/gc.h | 2 ++
> fs/f2fs/segment.c | 6 ++++--
> fs/f2fs/segment.h | 1 +
> fs/f2fs/sysfs.c | 2 ++
> 7 files changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> index 265baec879fd..2d3e42af0e63 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -783,3 +783,11 @@ Contact: "Daeho Jeong" <daehojeong@google.com>
> Description: If the percentage of free sections over total sections is under this
> number, F2FS boosts garbage collection for zoned devices through the
> background GC thread. the default number is "25".
> +
> +What: /sys/fs/f2fs/<disk>/gc_valid_thresh_ratio
> +Date: August 2024
> +Contact: "Daeho Jeong" <daehojeong@google.com>
> +Description: It controls the valid block ratio threshold not to trigger excessive GC
> + for zoned deivces. The initial value of it is 95(%). F2FS will stop the
> + background GC thread from intiating GC for sections having valid blocks
> + exceeding the ratio.
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ee1fafc65e95..8220b3189780 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3918,7 +3918,7 @@ void f2fs_destroy_garbage_collection_cache(void);
> /* victim selection function for cleaning and SSR */
> int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
> int gc_type, int type, char alloc_mode,
> - unsigned long long age);
> + unsigned long long age, bool one_time);
>
> /*
> * recovery.c
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 6b79c43a57e3..feb80345aca3 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -196,6 +196,7 @@ 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->valid_thresh_ratio = DEF_GC_THREAD_VALID_THRESH_RATIO;
>
> if (f2fs_sb_has_blkzoned(sbi)) {
> gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME_ZONED;
> @@ -396,6 +397,10 @@ static inline unsigned int get_gc_cost(struct f2fs_sb_info *sbi,
> if (p->alloc_mode == SSR)
> return get_seg_entry(sbi, segno)->ckpt_valid_blocks;
>
> + if (p->one_time_gc && (get_valid_blocks(sbi, segno, true) >=
> + BLKS_PER_SEC(sbi) * sbi->gc_thread->valid_thresh_ratio / 100))
Use CAP_BLKS_PER_SEC() instead of BLKS_PER_SEC() ?
Thanks,
> + return UINT_MAX;
> +
> /* alloc_mode == LFS */
> if (p->gc_mode == GC_GREEDY)
> return get_valid_blocks(sbi, segno, true);
> @@ -770,7 +775,7 @@ static int f2fs_gc_pinned_control(struct inode *inode, int gc_type,
> */
> int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
> int gc_type, int type, char alloc_mode,
> - unsigned long long age)
> + unsigned long long age, bool one_time)
> {
> struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
> struct sit_info *sm = SIT_I(sbi);
> @@ -787,6 +792,7 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
> p.alloc_mode = alloc_mode;
> p.age = age;
> p.age_threshold = sbi->am.age_threshold;
> + p.one_time_gc = one_time;
>
> retry:
> select_policy(sbi, gc_type, type, &p);
> @@ -1698,13 +1704,14 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
> }
>
> static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,
> - int gc_type)
> + int gc_type, bool one_time)
> {
> struct sit_info *sit_i = SIT_I(sbi);
> int ret;
>
> down_write(&sit_i->sentry_lock);
> - ret = f2fs_get_victim(sbi, victim, gc_type, NO_CHECK_TYPE, LFS, 0);
> + ret = f2fs_get_victim(sbi, victim, gc_type, NO_CHECK_TYPE,
> + LFS, 0, one_time);
> up_write(&sit_i->sentry_lock);
> return ret;
> }
> @@ -1908,7 +1915,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
> goto stop;
> }
> retry:
> - ret = __get_victim(sbi, &segno, gc_type);
> + ret = __get_victim(sbi, &segno, gc_type, gc_control->one_time);
> if (ret) {
> /* allow to search victim from sections has pinned data */
> if (ret == -ENODATA && gc_type == FG_GC &&
> diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
> index e8195eb4ca6d..59872daf88ee 100644
> --- a/fs/f2fs/gc.h
> +++ b/fs/f2fs/gc.h
> @@ -25,6 +25,7 @@
> #define DEF_GC_THREAD_CANDIDATE_RATIO 20 /* select 20% oldest sections as candidates */
> #define DEF_GC_THREAD_MAX_CANDIDATE_COUNT 10 /* select at most 10 sections as candidates */
> #define DEF_GC_THREAD_AGE_WEIGHT 60 /* age weight */
> +#define DEF_GC_THREAD_VALID_THRESH_RATIO 95 /* do not GC over 95% valid block ratio for one time GC */
> #define DEFAULT_ACCURACY_CLASS 10000 /* accuracy class */
>
> #define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */
> @@ -65,6 +66,7 @@ struct f2fs_gc_kthread {
> /* for gc control for zoned devices */
> unsigned int no_zoned_gc_percent;
> unsigned int boost_zoned_gc_percent;
> + unsigned int valid_thresh_ratio;
> };
>
> struct gc_inode_list {
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 78c3198a6308..26f5abc62461 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3052,7 +3052,8 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
> sanity_check_seg_type(sbi, seg_type);
>
> /* f2fs_need_SSR() already forces to do this */
> - if (!f2fs_get_victim(sbi, &segno, BG_GC, seg_type, alloc_mode, age)) {
> + if (!f2fs_get_victim(sbi, &segno, BG_GC, seg_type,
> + alloc_mode, age, false)) {
> curseg->next_segno = segno;
> return 1;
> }
> @@ -3079,7 +3080,8 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
> for (; cnt-- > 0; reversed ? i-- : i++) {
> if (i == seg_type)
> continue;
> - if (!f2fs_get_victim(sbi, &segno, BG_GC, i, alloc_mode, age)) {
> + if (!f2fs_get_victim(sbi, &segno, BG_GC, i,
> + alloc_mode, age, false)) {
> curseg->next_segno = segno;
> return 1;
> }
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index bfc01a521cb9..43db2d3e8c85 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -188,6 +188,7 @@ struct victim_sel_policy {
> unsigned int min_segno; /* segment # having min. cost */
> unsigned long long age; /* mtime of GCed section*/
> unsigned long long age_threshold;/* age threshold */
> + bool one_time_gc; /* one time GC */
> };
>
> struct seg_entry {
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index 647f6660f4df..d9d47c0698d1 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -962,6 +962,7 @@ GC_THREAD_RW_ATTR(gc_max_sleep_time, max_sleep_time);
> GC_THREAD_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);
> GC_THREAD_RW_ATTR(gc_no_zoned_gc_percent, no_zoned_gc_percent);
> GC_THREAD_RW_ATTR(gc_boost_zoned_gc_percent, boost_zoned_gc_percent);
> +GC_THREAD_RW_ATTR(gc_valid_thresh_ratio, valid_thresh_ratio);
>
> /* SM_INFO ATTR */
> SM_INFO_RW_ATTR(reclaim_segments, rec_prefree_segments);
> @@ -1121,6 +1122,7 @@ static struct attribute *f2fs_attrs[] = {
> ATTR_LIST(gc_no_gc_sleep_time),
> ATTR_LIST(gc_no_zoned_gc_percent),
> ATTR_LIST(gc_boost_zoned_gc_percent),
> + ATTR_LIST(gc_valid_thresh_ratio),
> ATTR_LIST(gc_idle),
> ATTR_LIST(gc_urgent),
> ATTR_LIST(reclaim_segments),
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2024-09-09 9:22 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-29 21:52 [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Daeho Jeong
2024-08-29 21:52 ` [PATCH 2/7] f2fs: read summary blocks with the correct amount for migration_granularity Daeho Jeong
2024-09-06 2:56 ` [f2fs-dev] " Chao Yu
2024-09-06 20:23 ` Daeho Jeong
2024-09-09 8:18 ` Chao Yu
2024-08-29 21:52 ` [PATCH 3/7] f2fs: add reserved_segments sysfs node Daeho Jeong
2024-09-06 3:04 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 4/7] f2fs: increase BG GC migration granularity when boosted for zoned devices Daeho Jeong
2024-09-06 3:37 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 5/7] f2fs: do FG_GC when GC boosting is required " Daeho Jeong
2024-09-06 6:34 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 6/7] f2fs: create gc_no_zoned_gc_percent and gc_boost_zoned_gc_percent Daeho Jeong
2024-09-06 6:35 ` [f2fs-dev] " Chao Yu
2024-08-29 21:52 ` [PATCH 7/7] f2fs: add valid block ratio not to do excessive GC for one time GC Daeho Jeong
2024-09-09 9:22 ` [f2fs-dev] " Chao Yu
2024-09-06 2:21 ` [f2fs-dev] [PATCH 1/7] f2fs: make BG GC more aggressive for zoned devices Chao Yu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome