mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
f2fs: introduce f2fs_get_section_mtime
When segs_per_sec is larger than 1, section may contain invalid segments, mtime should be the average value of each valid blocks, so introduce f2fs_get_section_mtime to record the average mtime of all valid blocks in a section. Signed-off-by: liuderong <liuderong@oppo.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
eca631b8fe
commit
b19ee72722
4 changed files with 38 additions and 18 deletions
|
@ -3783,6 +3783,8 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
|
||||||
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi);
|
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi);
|
||||||
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
|
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
|
||||||
unsigned int segno);
|
unsigned int segno);
|
||||||
|
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
|
||||||
|
unsigned int segno);
|
||||||
|
|
||||||
#define DEF_FRAGMENT_SIZE 4
|
#define DEF_FRAGMENT_SIZE 4
|
||||||
#define MIN_FRAGMENT_SIZE 1
|
#define MIN_FRAGMENT_SIZE 1
|
||||||
|
|
17
fs/f2fs/gc.c
17
fs/f2fs/gc.c
|
@ -361,20 +361,15 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
|
||||||
static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
|
static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
|
||||||
{
|
{
|
||||||
struct sit_info *sit_i = SIT_I(sbi);
|
struct sit_info *sit_i = SIT_I(sbi);
|
||||||
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
|
|
||||||
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
|
|
||||||
unsigned long long mtime = 0;
|
unsigned long long mtime = 0;
|
||||||
unsigned int vblocks;
|
unsigned int vblocks;
|
||||||
unsigned char age = 0;
|
unsigned char age = 0;
|
||||||
unsigned char u;
|
unsigned char u;
|
||||||
unsigned int i;
|
|
||||||
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
|
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
|
||||||
|
|
||||||
for (i = 0; i < usable_segs_per_sec; i++)
|
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||||
mtime += get_seg_entry(sbi, start + i)->mtime;
|
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
|
||||||
vblocks = get_valid_blocks(sbi, segno, true);
|
vblocks = get_valid_blocks(sbi, segno, true);
|
||||||
|
|
||||||
mtime = div_u64(mtime, usable_segs_per_sec);
|
|
||||||
vblocks = div_u64(vblocks, usable_segs_per_sec);
|
vblocks = div_u64(vblocks, usable_segs_per_sec);
|
||||||
|
|
||||||
u = BLKS_TO_SEGS(sbi, vblocks * 100);
|
u = BLKS_TO_SEGS(sbi, vblocks * 100);
|
||||||
|
@ -519,10 +514,7 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
|
||||||
struct victim_sel_policy *p, unsigned int segno)
|
struct victim_sel_policy *p, unsigned int segno)
|
||||||
{
|
{
|
||||||
struct sit_info *sit_i = SIT_I(sbi);
|
struct sit_info *sit_i = SIT_I(sbi);
|
||||||
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
|
|
||||||
unsigned int start = GET_SEG_FROM_SEC(sbi, secno);
|
|
||||||
unsigned long long mtime = 0;
|
unsigned long long mtime = 0;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
|
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
|
||||||
if (p->gc_mode == GC_AT &&
|
if (p->gc_mode == GC_AT &&
|
||||||
|
@ -530,9 +522,8 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
|
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||||
mtime += get_seg_entry(sbi, start + i)->mtime;
|
f2fs_bug_on(sbi, mtime == INVALID_MTIME);
|
||||||
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
|
|
||||||
|
|
||||||
/* Handle if the system time has changed by the user */
|
/* Handle if the system time has changed by the user */
|
||||||
if (mtime < sit_i->min_mtime)
|
if (mtime < sit_i->min_mtime)
|
||||||
|
|
|
@ -5430,6 +5430,35 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi)
|
||||||
return SEGS_PER_SEC(sbi);
|
return SEGS_PER_SEC(sbi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long long f2fs_get_section_mtime(struct f2fs_sb_info *sbi,
|
||||||
|
unsigned int segno)
|
||||||
|
{
|
||||||
|
unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi);
|
||||||
|
unsigned int secno = 0, start = 0;
|
||||||
|
unsigned int total_valid_blocks = 0;
|
||||||
|
unsigned long long mtime = 0;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
secno = GET_SEC_FROM_SEG(sbi, segno);
|
||||||
|
start = GET_SEG_FROM_SEC(sbi, secno);
|
||||||
|
|
||||||
|
if (!__is_large_section(sbi))
|
||||||
|
return get_seg_entry(sbi, start + i)->mtime;
|
||||||
|
|
||||||
|
for (i = 0; i < usable_segs_per_sec; i++) {
|
||||||
|
/* for large section, only check the mtime of valid segments */
|
||||||
|
struct seg_entry *se = get_seg_entry(sbi, start+i);
|
||||||
|
|
||||||
|
mtime += se->mtime * se->valid_blocks;
|
||||||
|
total_valid_blocks += se->valid_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_valid_blocks == 0)
|
||||||
|
return INVALID_MTIME;
|
||||||
|
|
||||||
|
return div_u64(mtime, total_valid_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update min, max modified time for cost-benefit GC algorithm
|
* Update min, max modified time for cost-benefit GC algorithm
|
||||||
*/
|
*/
|
||||||
|
@ -5443,13 +5472,9 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi)
|
||||||
sit_i->min_mtime = ULLONG_MAX;
|
sit_i->min_mtime = ULLONG_MAX;
|
||||||
|
|
||||||
for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
|
for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
|
||||||
unsigned int i;
|
|
||||||
unsigned long long mtime = 0;
|
unsigned long long mtime = 0;
|
||||||
|
|
||||||
for (i = 0; i < SEGS_PER_SEC(sbi); i++)
|
mtime = f2fs_get_section_mtime(sbi, segno);
|
||||||
mtime += get_seg_entry(sbi, segno + i)->mtime;
|
|
||||||
|
|
||||||
mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
|
|
||||||
|
|
||||||
if (sit_i->min_mtime > mtime)
|
if (sit_i->min_mtime > mtime)
|
||||||
sit_i->min_mtime = mtime;
|
sit_i->min_mtime = mtime;
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#define F2FS_MIN_SEGMENTS 9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
|
#define F2FS_MIN_SEGMENTS 9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
|
||||||
#define F2FS_MIN_META_SEGMENTS 8 /* SB + 2 (CP + SIT + NAT) + SSA */
|
#define F2FS_MIN_META_SEGMENTS 8 /* SB + 2 (CP + SIT + NAT) + SSA */
|
||||||
|
|
||||||
|
#define INVALID_MTIME ULLONG_MAX /* no valid blocks in a segment/section */
|
||||||
|
|
||||||
/* L: Logical segment # in volume, R: Relative segment # in main area */
|
/* L: Logical segment # in volume, R: Relative segment # in main area */
|
||||||
#define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
|
#define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
|
||||||
#define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno)
|
#define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno)
|
||||||
|
|
Loading…
Add table
Reference in a new issue