All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net,
	linux-kernel@vger.kernel.org, Chao Yu <yuchao0@huawei.com>
Subject: Re: [PATCH 1/6] f2fs: support issuing/waiting discard in range
Date: Tue, 3 Oct 2017 13:52:27 -0700	[thread overview]
Message-ID: <20171003205227.GA48271@jaegeuk-macbookpro.roam.corp.google.com> (raw)
In-Reply-To: <20171003201657.GA35961@jaegeuk-macbookpro.roam.corp.google.com>

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.

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

  reply	other threads:[~2017-10-03 20:52 UTC|newest]

Thread overview: 16+ 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-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   ` 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-09-27  1:40     ` Chao Yu
2017-10-03 20:16 ` Jaegeuk Kim
2017-10-03 20:52   ` Jaegeuk Kim [this message]
2017-10-04  0:48     ` [f2fs-dev] " Chao Yu
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=20171003205227.GA48271@jaegeuk-macbookpro.roam.corp.google.com \
    --to=jaegeuk@kernel.org \
    --cc=chao@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=yuchao0@huawei.com \
    /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.