Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit feb1b25b authored by Sahitya Tummala's avatar Sahitya Tummala Committed by Jaegeuk Kim
Browse files

f2fs: add new idle interval timing for discard and gc paths



This helps to control the frequency of submission of discard and
GC requests independently, based on the need.

Suggested-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 40292b97
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -121,7 +121,22 @@ What: /sys/fs/f2fs/<disk>/idle_interval
Date:		January 2016
Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
Description:
		 Controls the idle timing.
		 Controls the idle timing for all paths other than
		 discard and gc path.

What:		/sys/fs/f2fs/<disk>/discard_idle_interval
Date:		September 2018
Contact:	"Chao Yu" <yuchao0@huawei.com>
Contact:	"Sahitya Tummala" <stummala@codeaurora.org>
Description:
		 Controls the idle timing for discard path.

What:		/sys/fs/f2fs/<disk>/gc_idle_interval
Date:		September 2018
Contact:	"Chao Yu" <yuchao0@huawei.com>
Contact:	"Sahitya Tummala" <stummala@codeaurora.org>
Description:
		 Controls the idle timing for gc path.

What:		/sys/fs/f2fs/<disk>/iostat_enable
Date:		August 2017
+27 −3
Original line number Diff line number Diff line
@@ -1092,6 +1092,8 @@ enum {
enum {
	CP_TIME,
	REQ_TIME,
	DISCARD_TIME,
	GC_TIME,
	MAX_TIME,
};

@@ -1343,7 +1345,15 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)

static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
{
	sbi->last_time[type] = jiffies;
	unsigned long now = jiffies;

	sbi->last_time[type] = now;

	/* DISCARD_TIME and GC_TIME are based on REQ_TIME */
	if (type == REQ_TIME) {
		sbi->last_time[DISCARD_TIME] = now;
		sbi->last_time[GC_TIME] = now;
	}
}

static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
@@ -1353,7 +1363,21 @@ static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
	return time_after(jiffies, sbi->last_time[type] + interval);
}

static inline bool is_idle(struct f2fs_sb_info *sbi)
static inline unsigned int f2fs_time_to_wait(struct f2fs_sb_info *sbi,
						int type)
{
	unsigned long interval = sbi->interval_time[type] * HZ;
	unsigned int wait_ms = 0;
	long delta;

	delta = (sbi->last_time[type] + interval) - jiffies;
	if (delta > 0)
		wait_ms = jiffies_to_msecs(delta);

	return wait_ms;
}

static inline bool is_idle(struct f2fs_sb_info *sbi, int type)
{
	struct block_device *bdev = sbi->sb->s_bdev;
	struct request_queue *q = bdev_get_queue(bdev);
@@ -1362,7 +1386,7 @@ static inline bool is_idle(struct f2fs_sb_info *sbi)
	if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
		return false;

	return f2fs_time_over(sbi, REQ_TIME);
	return f2fs_time_over(sbi, type);
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static int gc_thread_func(void *data)
		if (!mutex_trylock(&sbi->gc_mutex))
			goto next;

		if (!is_idle(sbi)) {
		if (!is_idle(sbi, GC_TIME)) {
			increase_sleep_time(gc_th, &wait_ms);
			mutex_unlock(&sbi->gc_mutex);
			goto next;
+5 −9
Original line number Diff line number Diff line
@@ -508,7 +508,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
	else
		f2fs_build_free_nids(sbi, false, false);

	if (!is_idle(sbi) &&
	if (!is_idle(sbi, REQ_TIME) &&
		(!excess_dirty_nats(sbi) && !excess_dirty_nodes(sbi)))
		return;

@@ -1308,7 +1308,7 @@ static unsigned int __issue_discard_cmd_orderly(struct f2fs_sb_info *sbi,
		if (dc->state != D_PREP)
			goto next;

		if (dpolicy->io_aware && !is_idle(sbi)) {
		if (dpolicy->io_aware && !is_idle(sbi, DISCARD_TIME)) {
			io_interrupted = true;
			break;
		}
@@ -1368,7 +1368,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
			f2fs_bug_on(sbi, dc->state != D_PREP);

			if (dpolicy->io_aware && i < dpolicy->io_aware_gran &&
								!is_idle(sbi)) {
						!is_idle(sbi, DISCARD_TIME)) {
				io_interrupted = true;
				break;
			}
@@ -1561,8 +1561,6 @@ static int issue_discard_thread(void *data)
	struct discard_policy dpolicy;
	unsigned int wait_ms = DEF_MIN_DISCARD_ISSUE_TIME;
	int issued;
	unsigned long interval = sbi->interval_time[REQ_TIME] * HZ;
	long delta;

	set_freezable();

@@ -1599,10 +1597,8 @@ static int issue_discard_thread(void *data)
			__wait_all_discard_cmd(sbi, &dpolicy);
			wait_ms = dpolicy.min_interval;
		} else if (issued == -1){
			delta = (sbi->last_time[REQ_TIME] + interval) - jiffies;
			if (delta > 0)
				wait_ms = jiffies_to_msecs(delta);
			else
			wait_ms = f2fs_time_to_wait(sbi, DISCARD_TIME);
			if (!wait_ms)
				wait_ms = dpolicy.mid_interval;
		} else {
			wait_ms = dpolicy.max_interval;
+2 −0
Original line number Diff line number Diff line
@@ -2461,6 +2461,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
	sbi->dir_level = DEF_DIR_LEVEL;
	sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL;
	sbi->interval_time[REQ_TIME] = DEF_IDLE_INTERVAL;
	sbi->interval_time[DISCARD_TIME] = DEF_IDLE_INTERVAL;
	sbi->interval_time[GC_TIME] = DEF_IDLE_INTERVAL;
	clear_sbi_flag(sbi, SBI_NEED_FSCK);

	for (i = 0; i < NR_COUNT_TYPE; i++)
Loading