All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Yu <yuchao0@huawei.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: <linux-f2fs-devel@lists.sourceforge.net>,
	<linux-kernel@vger.kernel.org>, <chao@kernel.org>
Subject: Re: [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator
Date: Fri, 19 Mar 2021 10:31:09 +0800	[thread overview]
Message-ID: <ec5cda53-d3f4-450c-7567-7bfc68e224f9@huawei.com> (raw)
In-Reply-To: <YFOLNGo+/8sKQ7si@google.com>

On 2021/3/19 1:17, Jaegeuk Kim wrote:
> On 02/20, Chao Yu wrote:
>> In cp disabling mode, there could be a condition
>> - target segment has 128 ckpt valid blocks
>> - GC migrates 128 valid blocks to other segment (segment is still in
>> dirty list)
>> - GC migrates 384 blocks to target segment (segment has 128 cp_vblocks
>> and 384 vblocks)
>> - If GC selects target segment via {AT,}SSR allocator, however there is
>> no free space in targe segment.
>>
>> Fixes: 4354994f097d ("f2fs: checkpoint disabling")
>> Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>> ---
>>   fs/f2fs/f2fs.h    |  1 +
>>   fs/f2fs/gc.c      | 17 +++++++++++++----
>>   fs/f2fs/segment.c | 20 ++++++++++++++++++++
>>   3 files changed, 34 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index ed7807103c8e..9c753eff0814 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -3376,6 +3376,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
>>   int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
>>   void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>>   int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>> +bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
>>   void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
>>   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
>>   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>> index 86ba8ed0b8a7..a1d8062cdace 100644
>> --- a/fs/f2fs/gc.c
>> +++ b/fs/f2fs/gc.c
>> @@ -392,10 +392,6 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
>>   		if (p->gc_mode == GC_AT &&
>>   			get_valid_blocks(sbi, segno, true) == 0)
>>   			return;
>> -
>> -		if (p->alloc_mode == AT_SSR &&
>> -			get_seg_entry(sbi, segno)->ckpt_valid_blocks == 0)
>> -			return;
>>   	}
>>   
>>   	for (i = 0; i < sbi->segs_per_sec; i++)
>> @@ -736,6 +732,19 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
>>   		if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
>>   			goto next;
>>   
>> +		if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
>> +			/*
>> +			 * to avoid selecting candidate which has below valid
>> +			 * block distribution:
>> +			 * partial blocks are valid and all left ones are valid
>> +			 * in previous checkpoint.
>> +			 */
>> +			if (p.alloc_mode == SSR || p.alloc_mode == AT_SSR) {
>> +				if (!segment_has_free_slot(sbi, segno))
>> +					goto next;
> 
> Do we need to change this to check free_slot instead of get_ckpt_valid_blocks()?

Jaegeuk,

LFS was assigned only for GC case, in this case we are trying to select source
section, rather than target segment for SSR/AT_SSR case, so we don't need to
check free_slot.

- f2fs_gc
  - __get_victim
   - get_victim(sbi, victim, gc_type, NO_CHECK_TYPE, LFS, 0);

> 
>   732                 if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
>   733                                         get_ckpt_valid_blocks(sbi, segno) &&
>   734                                         p.alloc_mode == LFS))

BTW, in LFS mode, GC wants to find source section rather than segment, so we
should change to check valid ckpt blocks in every segment of targe section here?

Thanks,

> 
> 
>> +			}
>> +		}
>> +
>>   		if (is_atgc) {
>>   			add_victim_entry(sbi, &p, segno);
>>   			goto next;
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 2d5a82c4ca15..deaf57e13125 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -2650,6 +2650,26 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi,
>>   		seg->next_blkoff++;
>>   }
>>   
>> +bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno)
>> +{
>> +	struct sit_info *sit = SIT_I(sbi);
>> +	struct seg_entry *se = get_seg_entry(sbi, segno);
>> +	int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
>> +	unsigned long *target_map = SIT_I(sbi)->tmp_map;
>> +	unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
>> +	unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
>> +	int i, pos;
>> +
>> +	down_write(&sit->sentry_lock);
>> +	for (i = 0; i < entries; i++)
>> +		target_map[i] = ckpt_map[i] | cur_map[i];
>> +
>> +	pos = __find_rev_next_zero_bit(target_map, sbi->blocks_per_seg, 0);
>> +	up_write(&sit->sentry_lock);
>> +
>> +	return pos < sbi->blocks_per_seg;
>> +}
>> +
>>   /*
>>    * This function always allocates a used segment(from dirty seglist) by SSR
>>    * manner, so it should recover the existing segment information of valid blocks
>> -- 
>> 2.29.2
> .
> 

WARNING: multiple messages have this Message-ID (diff)
From: Chao Yu <yuchao0@huawei.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator
Date: Fri, 19 Mar 2021 10:31:09 +0800	[thread overview]
Message-ID: <ec5cda53-d3f4-450c-7567-7bfc68e224f9@huawei.com> (raw)
In-Reply-To: <YFOLNGo+/8sKQ7si@google.com>

On 2021/3/19 1:17, Jaegeuk Kim wrote:
> On 02/20, Chao Yu wrote:
>> In cp disabling mode, there could be a condition
>> - target segment has 128 ckpt valid blocks
>> - GC migrates 128 valid blocks to other segment (segment is still in
>> dirty list)
>> - GC migrates 384 blocks to target segment (segment has 128 cp_vblocks
>> and 384 vblocks)
>> - If GC selects target segment via {AT,}SSR allocator, however there is
>> no free space in targe segment.
>>
>> Fixes: 4354994f097d ("f2fs: checkpoint disabling")
>> Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>> ---
>>   fs/f2fs/f2fs.h    |  1 +
>>   fs/f2fs/gc.c      | 17 +++++++++++++----
>>   fs/f2fs/segment.c | 20 ++++++++++++++++++++
>>   3 files changed, 34 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index ed7807103c8e..9c753eff0814 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -3376,6 +3376,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
>>   int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
>>   void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>>   int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>> +bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
>>   void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
>>   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
>>   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>> index 86ba8ed0b8a7..a1d8062cdace 100644
>> --- a/fs/f2fs/gc.c
>> +++ b/fs/f2fs/gc.c
>> @@ -392,10 +392,6 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
>>   		if (p->gc_mode == GC_AT &&
>>   			get_valid_blocks(sbi, segno, true) == 0)
>>   			return;
>> -
>> -		if (p->alloc_mode == AT_SSR &&
>> -			get_seg_entry(sbi, segno)->ckpt_valid_blocks == 0)
>> -			return;
>>   	}
>>   
>>   	for (i = 0; i < sbi->segs_per_sec; i++)
>> @@ -736,6 +732,19 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
>>   		if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
>>   			goto next;
>>   
>> +		if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
>> +			/*
>> +			 * to avoid selecting candidate which has below valid
>> +			 * block distribution:
>> +			 * partial blocks are valid and all left ones are valid
>> +			 * in previous checkpoint.
>> +			 */
>> +			if (p.alloc_mode == SSR || p.alloc_mode == AT_SSR) {
>> +				if (!segment_has_free_slot(sbi, segno))
>> +					goto next;
> 
> Do we need to change this to check free_slot instead of get_ckpt_valid_blocks()?

Jaegeuk,

LFS was assigned only for GC case, in this case we are trying to select source
section, rather than target segment for SSR/AT_SSR case, so we don't need to
check free_slot.

- f2fs_gc
  - __get_victim
   - get_victim(sbi, victim, gc_type, NO_CHECK_TYPE, LFS, 0);

> 
>   732                 if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
>   733                                         get_ckpt_valid_blocks(sbi, segno) &&
>   734                                         p.alloc_mode == LFS))

BTW, in LFS mode, GC wants to find source section rather than segment, so we
should change to check valid ckpt blocks in every segment of targe section here?

Thanks,

> 
> 
>> +			}
>> +		}
>> +
>>   		if (is_atgc) {
>>   			add_victim_entry(sbi, &p, segno);
>>   			goto next;
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 2d5a82c4ca15..deaf57e13125 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -2650,6 +2650,26 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi,
>>   		seg->next_blkoff++;
>>   }
>>   
>> +bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno)
>> +{
>> +	struct sit_info *sit = SIT_I(sbi);
>> +	struct seg_entry *se = get_seg_entry(sbi, segno);
>> +	int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
>> +	unsigned long *target_map = SIT_I(sbi)->tmp_map;
>> +	unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
>> +	unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
>> +	int i, pos;
>> +
>> +	down_write(&sit->sentry_lock);
>> +	for (i = 0; i < entries; i++)
>> +		target_map[i] = ckpt_map[i] | cur_map[i];
>> +
>> +	pos = __find_rev_next_zero_bit(target_map, sbi->blocks_per_seg, 0);
>> +	up_write(&sit->sentry_lock);
>> +
>> +	return pos < sbi->blocks_per_seg;
>> +}
>> +
>>   /*
>>    * This function always allocates a used segment(from dirty seglist) by SSR
>>    * manner, so it should recover the existing segment information of valid blocks
>> -- 
>> 2.29.2
> .
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2021-03-19  2:31 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-20  9:40 [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Chao Yu
2021-02-20  9:40 ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Chao Yu
2021-02-22 13:43 ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Chao Yu
2021-02-22 13:43   ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Chao Yu
2021-02-23 12:26   ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Chao Yu
2021-02-23 12:26     ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Chao Yu
2021-02-28  5:10     ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Jaegeuk Kim
2021-02-28  5:10       ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Jaegeuk Kim
2021-03-18 17:17 ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Jaegeuk Kim
2021-03-18 17:17   ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Jaegeuk Kim
2021-03-19  2:31   ` Chao Yu [this message]
2021-03-19  2:31     ` Chao Yu
2021-03-23 22:59     ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Jaegeuk Kim
2021-03-23 22:59       ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Jaegeuk Kim
2021-03-24  3:28       ` [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator Chao Yu
2021-03-24  3:28         ` [f2fs-dev] [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT, }SSR allocator Chao Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ec5cda53-d3f4-450c-7567-7bfc68e224f9@huawei.com \
    --to=yuchao0@huawei.com \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.