linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Chao Yu <chao@kernel.org>
To: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] [PATCH 1/6] f2fs: support issuing/waiting discard in range
Date: Wed, 4 Oct 2017 08:48:40 +0800	[thread overview]
Message-ID: <c2a64487-d031-d2bf-db1c-ff4ba7641245@kernel.org> (raw)
In-Reply-To: <20171003205227.GA48271@jaegeuk-macbookpro.roam.corp.google.com>

Hi Jaegeuk,

On 2017/10/4 4:52, Jaegeuk Kim wrote:
> Hi Chao,
> 
> Could you please rebase the following patches on top of dev-test?
> 
> f2fs-support-issuing-waiting-discard-in-range
> f2fs-wrap-discard-policy
> f2fs-split-discard-policy
> f2fs-reduce-cmd_lock-coverage-in-__issue_discard_cmd
> f2fs-trace-f2fs_remove_discard
> f2fs-give-up-CP_TRIMMED_FLAG-if-it-drops-discards
> 
> It seems we need to rearrange some of patches for better review.

No problem, let me rebase them. :)

Thanks,

> 
> Thanks,
> 
> On 10/03, Jaegeuk Kim wrote:
>> On 09/19, Chao Yu wrote:
>>> From: Chao Yu <yuchao0@huawei.com>
>>>
>>> Fstrim intends to trim invalid blocks of filesystem only with specified
>>> range and granularity, but actually, it will issue all previous cached
>>> discard commands which may be out-of-range and be with unmatched
>>> granularity, it's unneeded.
>>>
>>> In order to fix above issues, this patch introduces new helps to support
>>> to issue and wait discard in range and adds a new fstrim_list for tracking
>>> in-flight discard from ->fstrim.
>>>
>>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>>> ---
>>>  fs/f2fs/f2fs.h    |   1 +
>>>  fs/f2fs/segment.c | 125 +++++++++++++++++++++++++++++++++++++++++++++---------
>>>  2 files changed, 106 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>> index 89b4927dcd79..cb13c7df6971 100644
>>> --- a/fs/f2fs/f2fs.h
>>> +++ b/fs/f2fs/f2fs.h
>>> @@ -249,6 +249,7 @@ struct discard_cmd_control {
>>>  	struct list_head pend_list[MAX_PLIST_NUM];/* store pending entries */
>>>  	unsigned char pend_list_tag[MAX_PLIST_NUM];/* tag for pending entries */
>>>  	struct list_head wait_list;		/* store on-flushing entries */
>>> +	struct list_head fstrim_list;		/* in-flight discard from fstrim */
>>>  	wait_queue_head_t discard_wait_queue;	/* waiting queue for wake-up */
>>>  	unsigned int discard_wake;		/* to wake up discard thread */
>>>  	struct mutex cmd_lock;
>>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>>> index dedf0209d820..088936c61905 100644
>>> --- a/fs/f2fs/segment.c
>>> +++ b/fs/f2fs/segment.c
>>> @@ -845,9 +845,11 @@ void __check_sit_bitmap(struct f2fs_sb_info *sbi,
>>>  
>>>  /* this function is copied from blkdev_issue_discard from block/blk-lib.c */
>>>  static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
>>> -				struct discard_cmd *dc)
>>> +				struct discard_cmd *dc, bool fstrim)
>>>  {
>>>  	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>>> +	struct list_head *wait_list = fstrim ? &(dcc->fstrim_list) :
>>> +							&(dcc->wait_list);
>>>  	struct bio *bio = NULL;
>>>  
>>>  	if (dc->state != D_PREP)
>>> @@ -869,7 +871,7 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
>>>  			bio->bi_end_io = f2fs_submit_discard_endio;
>>>  			bio->bi_opf |= REQ_SYNC;
>>>  			submit_bio(bio);
>>> -			list_move_tail(&dc->list, &dcc->wait_list);
>>> +			list_move_tail(&dc->list, wait_list);
>>>  			__check_sit_bitmap(sbi, dc->start, dc->start + dc->len);
>>>  
>>>  			f2fs_update_iostat(sbi, FS_DISCARD, 1);
>>> @@ -1054,6 +1056,68 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
>>>  	return 0;
>>>  }
>>>  
>>> +static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
>>> +					unsigned int start, unsigned int end,
>>> +					unsigned int granularity)
>>> +{
>>> +	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>>> +	struct discard_cmd *prev_dc = NULL, *next_dc = NULL;
>>> +	struct rb_node **insert_p = NULL, *insert_parent = NULL;
>>> +	struct discard_cmd *dc;
>>> +	struct blk_plug plug;
>>> +	int issued;
>>> +
>>> +next:
>>> +	issued = 0;
>>> +
>>> +	mutex_lock(&dcc->cmd_lock);
>>> +	f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
>>> +
>>> +	dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
>>> +					NULL, start,
>>> +					(struct rb_entry **)&prev_dc,
>>> +					(struct rb_entry **)&next_dc,
>>> +					&insert_p, &insert_parent, true);
>>> +	if (!dc)
>>> +		dc = next_dc;
>>> +
>>> +	blk_start_plug(&plug);
>>> +
>>> +	while (dc && dc->lstart <= end) {
>>> +		struct rb_node *node;
>>> +
>>> +		if (dc->len < granularity)
>>> +			goto skip;
>>> +
>>> +		if (dc->state != D_PREP) {
>>> +			list_move_tail(&dc->list, &dcc->fstrim_list);
>>> +			goto skip;
>>> +		}
>>> +
>>> +		__submit_discard_cmd(sbi, dc, true);
>>> +
>>> +		if (++issued >= DISCARD_ISSUE_RATE) {
>>> +			start = dc->lstart + dc->len;
>>> +
>>> +			blk_finish_plug(&plug);
>>> +			mutex_unlock(&dcc->cmd_lock);
>>> +
>>> +			schedule();
>>> +
>>> +			goto next;
>>> +		}
>>> +skip:
>>> +		node = rb_next(&dc->rb_node);
>>> +		dc = rb_entry_safe(node, struct discard_cmd, rb_node);
>>> +
>>> +		if (fatal_signal_pending(current))
>>> +			break;
>>> +	}
>>> +
>>> +	blk_finish_plug(&plug);
>>> +	mutex_unlock(&dcc->cmd_lock);
>>> +}
>>> +
>>>  static int __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond)
>>>  {
>>>  	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>>> @@ -1076,22 +1140,19 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond)
>>>  
>>>  			/* Hurry up to finish fstrim */
>>>  			if (dcc->pend_list_tag[i] & P_TRIM) {
>>> -				__submit_discard_cmd(sbi, dc);
>>> +				__submit_discard_cmd(sbi, dc, false);
>>>  				issued++;
>>> -
>>> -				if (fatal_signal_pending(current))
>>> -					break;
>>>  				continue;
>>>  			}
>>>  
>>>  			if (!issue_cond) {
>>> -				__submit_discard_cmd(sbi, dc);
>>> +				__submit_discard_cmd(sbi, dc, false);
>>>  				issued++;
>>>  				continue;
>>>  			}
>>>  
>>>  			if (is_idle(sbi)) {
>>> -				__submit_discard_cmd(sbi, dc);
>>> +				__submit_discard_cmd(sbi, dc, false);
>>>  				issued++;
>>>  			} else {
>>>  				io_interrupted = true;
>>> @@ -1145,10 +1206,14 @@ static void __wait_one_discard_bio(struct f2fs_sb_info *sbi,
>>>  	mutex_unlock(&dcc->cmd_lock);
>>>  }
>>>  
>>> -static void __wait_discard_cmd(struct f2fs_sb_info *sbi, bool wait_cond)
>>> +static void __wait_discard_cmd_range(struct f2fs_sb_info *sbi, bool wait_cond,
>>> +						block_t start, block_t end,
>>> +						unsigned int granularity,
>>> +						bool fstrim)
>>>  {
>>>  	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>>> -	struct list_head *wait_list = &(dcc->wait_list);
>>> +	struct list_head *wait_list = fstrim ? &(dcc->fstrim_list) :
>>> +							&(dcc->wait_list);
>>>  	struct discard_cmd *dc, *tmp;
>>>  	bool need_wait;
>>>  
>>> @@ -1157,6 +1222,10 @@ static void __wait_discard_cmd(struct f2fs_sb_info *sbi, bool wait_cond)
>>>  
>>>  	mutex_lock(&dcc->cmd_lock);
>>>  	list_for_each_entry_safe(dc, tmp, wait_list, list) {
>>> +		if (dc->lstart + dc->len <= start || end <= dc->lstart)
>>> +			continue;
>>> +		if (dc->len < granularity)
>>> +			continue;
>>>  		if (!wait_cond || (dc->state == D_DONE && !dc->ref)) {
>>>  			wait_for_completion_io(&dc->wait);
>>>  			__remove_discard_cmd(sbi, dc);
>>
>> So, we need to add this on top of the patch that fixes the bug reported
>> by Juhyung, right?
>>
>> 		if (fstrim)
>> 			need_wait = true;
>>
>> Thanks,
>>
>>> @@ -1174,6 +1243,11 @@ static void __wait_discard_cmd(struct f2fs_sb_info *sbi, bool wait_cond)
>>>  	}
>>>  }
>>>  
>>> +static void __wait_all_discard_cmd(struct f2fs_sb_info *sbi, bool wait_cond)
>>> +{
>>> +	__wait_discard_cmd_range(sbi, wait_cond, 0, UINT_MAX, 1, false);
>>> +}
>>> +
>>>  /* This should be covered by global mutex, &sit_i->sentry_lock */
>>>  void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
>>>  {
>>> @@ -1209,12 +1283,12 @@ void stop_discard_thread(struct f2fs_sb_info *sbi)
>>>  	}
>>>  }
>>>  
>>> -/* This comes from f2fs_put_super and f2fs_trim_fs */
>>> +/* This comes from f2fs_put_super */
>>>  void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
>>>  {
>>>  	__issue_discard_cmd(sbi, false);
>>>  	__drop_discard_cmd(sbi);
>>> -	__wait_discard_cmd(sbi, false);
>>> +	__wait_all_discard_cmd(sbi, false);
>>>  }
>>>  
>>>  static void mark_discard_range_all(struct f2fs_sb_info *sbi)
>>> @@ -1258,7 +1332,7 @@ static int issue_discard_thread(void *data)
>>>  
>>>  		issued = __issue_discard_cmd(sbi, true);
>>>  		if (issued) {
>>> -			__wait_discard_cmd(sbi, true);
>>> +			__wait_all_discard_cmd(sbi, true);
>>>  			wait_ms = DEF_MIN_DISCARD_ISSUE_TIME;
>>>  		} else {
>>>  			wait_ms = DEF_MAX_DISCARD_ISSUE_TIME;
>>> @@ -1569,6 +1643,7 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
>>>  			dcc->pend_list_tag[i] |= P_ACTIVE;
>>>  	}
>>>  	INIT_LIST_HEAD(&dcc->wait_list);
>>> +	INIT_LIST_HEAD(&dcc->fstrim_list);
>>>  	mutex_init(&dcc->cmd_lock);
>>>  	atomic_set(&dcc->issued_discard, 0);
>>>  	atomic_set(&dcc->issing_discard, 0);
>>> @@ -2196,7 +2271,8 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
>>>  {
>>>  	__u64 start = F2FS_BYTES_TO_BLK(range->start);
>>>  	__u64 end = start + F2FS_BYTES_TO_BLK(range->len) - 1;
>>> -	unsigned int start_segno, end_segno;
>>> +	unsigned int start_segno, end_segno, cur_segno;
>>> +	block_t start_block, end_block;
>>>  	struct cp_control cpc;
>>>  	int err = 0;
>>>  
>>> @@ -2217,12 +2293,17 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
>>>  	start_segno = (start <= MAIN_BLKADDR(sbi)) ? 0 : GET_SEGNO(sbi, start);
>>>  	end_segno = (end >= MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 :
>>>  						GET_SEGNO(sbi, end);
>>> +
>>> +	start_block = START_BLOCK(sbi, start_segno);
>>> +	end_block = START_BLOCK(sbi, end_segno + 1);
>>> +
>>>  	cpc.reason = CP_DISCARD;
>>>  	cpc.trim_minlen = max_t(__u64, 1, F2FS_BYTES_TO_BLK(range->minlen));
>>>  
>>>  	/* do checkpoint to issue discard commands safely */
>>> -	for (; start_segno <= end_segno; start_segno = cpc.trim_end + 1) {
>>> -		cpc.trim_start = start_segno;
>>> +	for (cur_segno = start_segno; cur_segno <= end_segno;
>>> +					cur_segno = cpc.trim_end + 1) {
>>> +		cpc.trim_start = cur_segno;
>>>  
>>>  		if (sbi->discard_blks == 0)
>>>  			break;
>>> @@ -2230,7 +2311,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
>>>  			cpc.trim_end = end_segno;
>>>  		else
>>>  			cpc.trim_end = min_t(unsigned int,
>>> -				rounddown(start_segno +
>>> +				rounddown(cur_segno +
>>>  				BATCHED_TRIM_SEGMENTS(sbi),
>>>  				sbi->segs_per_sec) - 1, end_segno);
>>>  
>>> @@ -2242,9 +2323,13 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
>>>  
>>>  		schedule();
>>>  	}
>>> -	/* It's time to issue all the filed discards */
>>> -	mark_discard_range_all(sbi);
>>> -	f2fs_wait_discard_bios(sbi);
>>> +
>>> +	start_block = START_BLOCK(sbi, start_segno);
>>> +	end_block = START_BLOCK(sbi, min(cur_segno, end_segno) + 1);
>>> +
>>> +	__issue_discard_cmd_range(sbi, start_block, end_block, cpc.trim_minlen);
>>> +	__wait_discard_cmd_range(sbi, false, start_block, end_block,
>>> +						cpc.trim_minlen, true);
>>>  out:
>>>  	range->len = F2FS_BLK_TO_BYTES(cpc.trimmed);
>>>  	return err;
>>> -- 
>>> 2.14.1.145.gb3622a4ee
> 
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
> 

  reply	other threads:[~2017-10-04  0:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-19 15:30 [PATCH 1/6] f2fs: support issuing/waiting discard in range Chao Yu
2017-09-19 15:30 ` [PATCH 2/6] f2fs: wrap discard policy Chao Yu
2017-09-27  9:57   ` Chao Yu
2017-09-19 15:30 ` [PATCH 3/6] f2fs: split " Chao Yu
2017-09-19 15:30 ` [PATCH 4/6] f2fs: reduce cmd_lock coverage in __issue_discard_cmd Chao Yu
2017-09-19 15:30 ` [PATCH 5/6] f2fs: trace f2fs_remove_discard Chao Yu
2017-09-19 15:30 ` [PATCH 6/6] f2fs: give up CP_TRIMMED_FLAG if it drops discards Chao Yu
2017-09-26 17:00 ` [PATCH 1/6] f2fs: support issuing/waiting discard in range Jaegeuk Kim
2017-09-27  1:40   ` Chao Yu
2017-10-03 20:16 ` Jaegeuk Kim
2017-10-03 20:52   ` Jaegeuk Kim
2017-10-04  0:48     ` Chao Yu [this message]
2017-10-04  0:43   ` 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=c2a64487-d031-d2bf-db1c-ff4ba7641245@kernel.org \
    --to=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).