linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] f2fs: introduce time and interval facility
@ 2016-01-09  1:29 Jaegeuk Kim
  2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-01-09  1:29 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds time and interval arrays to store some timing variables.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c |  2 +-
 fs/f2fs/f2fs.h       | 21 ++++++++++++++++++++-
 fs/f2fs/segment.c    |  2 +-
 fs/f2fs/super.c      |  7 +++----
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5dbafd5..3842af9 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1139,7 +1139,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 			"checkpoint: version = %llx", ckpt_ver);
 
 	/* do checkpoint periodically */
-	sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval);
+	f2fs_update_time(sbi, CP_TIME);
 	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
 out:
 	mutex_unlock(&sbi->cp_mutex);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ae0007d..603266c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -721,6 +721,11 @@ enum {
 	SBI_POR_DOING,				/* recovery is doing or not */
 };
 
+enum {
+	CP_TIME,
+	MAX_TIME,
+};
+
 struct f2fs_sb_info {
 	struct super_block *sb;			/* pointer to VFS super block */
 	struct proc_dir_entry *s_proc;		/* proc entry */
@@ -747,7 +752,8 @@ struct f2fs_sb_info {
 	struct rw_semaphore node_write;		/* locking node writes */
 	struct mutex writepages;		/* mutex for writepages() */
 	wait_queue_head_t cp_wait;
-	long cp_expires, cp_interval;		/* next expected periodic cp */
+	unsigned long last_time[MAX_TIME];	/* to store time in jiffies */
+	long interval_time[MAX_TIME];		/* to store thresholds */
 
 	struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
 
@@ -837,6 +843,19 @@ struct f2fs_sb_info {
 	unsigned int shrinker_run_no;
 };
 
+static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
+{
+	sbi->last_time[type] = jiffies;
+}
+
+static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
+{
+	struct timespec ts = {sbi->interval_time[type], 0};
+	unsigned long interval = timespec_to_jiffies(&ts);
+
+	return jiffies > sbi->last_time[type] + interval;
+}
+
 /*
  * Inline functions
  */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c7bbc91..fed23d5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
 	if (!available_free_memory(sbi, NAT_ENTRIES) ||
 			excess_prefree_segs(sbi) ||
 			!available_free_memory(sbi, INO_ENTRIES) ||
-			jiffies > sbi->cp_expires) {
+			f2fs_time_over(sbi, CP_TIME)) {
 		if (test_opt(sbi, DATA_FLUSH))
 			sync_dirty_inodes(sbi, FILE_INODE);
 		f2fs_sync_fs(sbi->sb, true);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f5cc790..787047f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -218,7 +218,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -1122,7 +1122,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 		atomic_set(&sbi->nr_pages[i], 0);
 
 	sbi->dir_level = DEF_DIR_LEVEL;
-	sbi->cp_interval = DEF_CP_INTERVAL;
+	sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL;
 	clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
 	INIT_LIST_HEAD(&sbi->s_list);
@@ -1467,8 +1467,7 @@ try_onemore:
 		f2fs_commit_super(sbi, true);
 	}
 
-	sbi->cp_expires = round_jiffies_up(jiffies);
-
+	f2fs_update_time(sbi, CP_TIME);
 	return 0;
 
 free_kobj:
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] f2fs: detect idle time depending on user behavior
  2016-01-09  1:29 [PATCH 1/2] f2fs: introduce time and interval facility Jaegeuk Kim
@ 2016-01-09  1:29 ` Jaegeuk Kim
  2016-01-11  7:15   ` [f2fs-dev] " Chao Yu
  2016-01-11 23:59   ` Jaegeuk Kim
  2016-01-11  7:12 ` [f2fs-dev] [PATCH 1/2] f2fs: introduce time and interval facility Chao Yu
  2016-01-11 23:47 ` Jaegeuk Kim
  2 siblings, 2 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-01-09  1:29 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds last time that user requested filesystem operations.
This information is used to detect whether system is idle or not later.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++++++
 fs/f2fs/data.c                          |  1 +
 fs/f2fs/dir.c                           |  3 +++
 fs/f2fs/f2fs.h                          | 15 +++++++++++++++
 fs/f2fs/file.c                          |  4 ++++
 fs/f2fs/gc.c                            |  1 -
 fs/f2fs/gc.h                            |  8 --------
 fs/f2fs/segment.c                       |  2 +-
 fs/f2fs/super.c                         |  4 ++++
 9 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 0345f2d..e5200f3 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -87,6 +87,12 @@ Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
 Description:
 		 Controls the checkpoint timing.
 
+What:		/sys/fs/f2fs/<disk>/idle_interval
+Date:		January 2016
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Controls the idle timing.
+
 What:		/sys/fs/f2fs/<disk>/ra_nid_pages
 Date:		October 2015
 Contact:	"Chao Yu" <chao2.yu@samsung.com>
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index a3bce12..ac9e7c6 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1596,6 +1596,7 @@ static int f2fs_write_end(struct file *file,
 	}
 
 	f2fs_put_page(page, 1);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return copied;
 }
 
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 29bb8dd..216dd87 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -636,6 +636,7 @@ fail:
 	f2fs_put_page(dentry_page, 1);
 out:
 	f2fs_fname_free_filename(&fname);
+	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
 	return err;
 }
 
@@ -701,6 +702,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 	int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
 	int i;
 
+	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
+
 	if (f2fs_has_inline_dentry(dir))
 		return f2fs_delete_inline_entry(dentry, page, dir, inode);
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 603266c..ef6e666 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 #include <linux/bio.h>
+#include <linux/blkdev.h>
 
 #ifdef CONFIG_F2FS_CHECK_FS
 #define f2fs_bug_on(sbi, condition)	BUG_ON(condition)
@@ -126,6 +127,7 @@ enum {
 #define BATCHED_TRIM_BLOCKS(sbi)	\
 		(BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
 #define DEF_CP_INTERVAL			60	/* 60 secs */
+#define DEF_IDLE_INTERVAL		120	/* 2 mins */
 
 struct cp_control {
 	int reason;
@@ -723,6 +725,7 @@ enum {
 
 enum {
 	CP_TIME,
+	REQ_TIME,
 	MAX_TIME,
 };
 
@@ -856,6 +859,18 @@ static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
 	return jiffies > sbi->last_time[type] + interval;
 }
 
+static inline bool is_idle(struct f2fs_sb_info *sbi)
+{
+	struct block_device *bdev = sbi->sb->s_bdev;
+	struct request_queue *q = bdev_get_queue(bdev);
+	struct request_list *rl = &q->root_rl;
+
+	if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
+		return 0;
+
+	return f2fs_time_over(sbi, REQ_TIME);
+}
+
 /*
  * Inline functions
  */
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index ff06827..dfaed51 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -96,6 +96,7 @@ mapped:
 	clear_cold_data(page);
 out:
 	sb_end_pagefault(inode->i_sb);
+	f2fs_update_time(sbi, REQ_TIME);
 	return block_page_mkwrite_return(err);
 }
 
@@ -280,6 +281,7 @@ flush_out:
 	remove_ino_entry(sbi, ino, UPDATE_INO);
 	clear_inode_flag(fi, FI_UPDATE_WRITE);
 	ret = f2fs_issue_flush(sbi);
+	f2fs_update_time(sbi, REQ_TIME);
 out:
 	trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
 	f2fs_trace_ios(NULL, 1);
@@ -485,6 +487,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
 	}
 	dn->ofs_in_node = ofs;
 
+	f2fs_update_time(sbi, REQ_TIME);
 	trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid,
 					 dn->ofs_in_node, nr_free);
 	return nr_free;
@@ -1236,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode,
 	if (!ret) {
 		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		mark_inode_dirty(inode);
+		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	}
 
 out:
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index c09be33..f610c2a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -16,7 +16,6 @@
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
-#include <linux/blkdev.h>
 
 #include "f2fs.h"
 #include "node.h"
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index b4a65be..a993967 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -100,11 +100,3 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
 		return true;
 	return false;
 }
-
-static inline int is_idle(struct f2fs_sb_info *sbi)
-{
-	struct block_device *bdev = sbi->sb->s_bdev;
-	struct request_queue *q = bdev_get_queue(bdev);
-	struct request_list *rl = &q->root_rl;
-	return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]);
-}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index fed23d5..d8ad1ab 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
 	if (!available_free_memory(sbi, NAT_ENTRIES) ||
 			excess_prefree_segs(sbi) ||
 			!available_free_memory(sbi, INO_ENTRIES) ||
-			f2fs_time_over(sbi, CP_TIME)) {
+			(is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) {
 		if (test_opt(sbi, DATA_FLUSH))
 			sync_dirty_inodes(sbi, FILE_INODE);
 		f2fs_sync_fs(sbi->sb, true);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 787047f..3bf990b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -219,6 +219,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -237,6 +238,7 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(ram_thresh),
 	ATTR_LIST(ra_nid_pages),
 	ATTR_LIST(cp_interval),
+	ATTR_LIST(idle_interval),
 	NULL,
 };
 
@@ -1123,6 +1125,7 @@ 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;
 	clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
 	INIT_LIST_HEAD(&sbi->s_list);
@@ -1468,6 +1471,7 @@ try_onemore:
 	}
 
 	f2fs_update_time(sbi, CP_TIME);
+	f2fs_update_time(sbi, REQ_TIME);
 	return 0;
 
 free_kobj:
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [f2fs-dev] [PATCH 1/2] f2fs: introduce time and interval facility
  2016-01-09  1:29 [PATCH 1/2] f2fs: introduce time and interval facility Jaegeuk Kim
  2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
@ 2016-01-11  7:12 ` Chao Yu
  2016-01-11 23:47 ` Jaegeuk Kim
  2 siblings, 0 replies; 7+ messages in thread
From: Chao Yu @ 2016-01-11  7:12 UTC (permalink / raw)
  To: 'Jaegeuk Kim'; +Cc: linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Jaegeuk,

> -----Original Message-----
> From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> Sent: Saturday, January 09, 2016 9:29 AM
> To: linux-kernel@vger.kernel.org; linux-fsdevel@vger.kernel.org;
> linux-f2fs-devel@lists.sourceforge.net
> Cc: Jaegeuk Kim
> Subject: [f2fs-dev] [PATCH 1/2] f2fs: introduce time and interval facility
> 
> This patch adds time and interval arrays to store some timing variables.
> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
>  fs/f2fs/checkpoint.c |  2 +-
>  fs/f2fs/f2fs.h       | 21 ++++++++++++++++++++-
>  fs/f2fs/segment.c    |  2 +-
>  fs/f2fs/super.c      |  7 +++----
>  4 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index 5dbafd5..3842af9 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -1139,7 +1139,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
>  			"checkpoint: version = %llx", ckpt_ver);
> 
>  	/* do checkpoint periodically */
> -	sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval);
> +	f2fs_update_time(sbi, CP_TIME);
>  	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
>  out:
>  	mutex_unlock(&sbi->cp_mutex);
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ae0007d..603266c 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -721,6 +721,11 @@ enum {
>  	SBI_POR_DOING,				/* recovery is doing or not */
>  };
> 
> +enum {
> +	CP_TIME,
> +	MAX_TIME,
> +};
> +
>  struct f2fs_sb_info {
>  	struct super_block *sb;			/* pointer to VFS super block */
>  	struct proc_dir_entry *s_proc;		/* proc entry */
> @@ -747,7 +752,8 @@ struct f2fs_sb_info {
>  	struct rw_semaphore node_write;		/* locking node writes */
>  	struct mutex writepages;		/* mutex for writepages() */
>  	wait_queue_head_t cp_wait;
> -	long cp_expires, cp_interval;		/* next expected periodic cp */
> +	unsigned long last_time[MAX_TIME];	/* to store time in jiffies */
> +	long interval_time[MAX_TIME];		/* to store thresholds */
> 
>  	struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
> 
> @@ -837,6 +843,19 @@ struct f2fs_sb_info {
>  	unsigned int shrinker_run_no;
>  };
> 
> +static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
> +{
> +	sbi->last_time[type] = jiffies;
> +}
> +
> +static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
> +{
> +	struct timespec ts = {sbi->interval_time[type], 0};
> +	unsigned long interval = timespec_to_jiffies(&ts);
> +
> +	return jiffies > sbi->last_time[type] + interval;

How about using time_after like checkpatch.pl recommended?

WARNING: Comparing jiffies is almost always wrong; prefer time_after, time_before and friends
#70: FILE: fs/f2fs/f2fs.h:856:
+       return jiffies > sbi->last_time[type] + interval;

Thanks,

> +}
> +
>  /*
>   * Inline functions
>   */
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index c7bbc91..fed23d5 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
>  	if (!available_free_memory(sbi, NAT_ENTRIES) ||
>  			excess_prefree_segs(sbi) ||
>  			!available_free_memory(sbi, INO_ENTRIES) ||
> -			jiffies > sbi->cp_expires) {
> +			f2fs_time_over(sbi, CP_TIME)) {
>  		if (test_opt(sbi, DATA_FLUSH))
>  			sync_dirty_inodes(sbi, FILE_INODE);
>  		f2fs_sync_fs(sbi->sb, true);
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index f5cc790..787047f 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -218,7 +218,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
>  F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
>  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
>  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
> -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval);
> +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
> 
>  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
>  static struct attribute *f2fs_attrs[] = {
> @@ -1122,7 +1122,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
>  		atomic_set(&sbi->nr_pages[i], 0);
> 
>  	sbi->dir_level = DEF_DIR_LEVEL;
> -	sbi->cp_interval = DEF_CP_INTERVAL;
> +	sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL;
>  	clear_sbi_flag(sbi, SBI_NEED_FSCK);
> 
>  	INIT_LIST_HEAD(&sbi->s_list);
> @@ -1467,8 +1467,7 @@ try_onemore:
>  		f2fs_commit_super(sbi, true);
>  	}
> 
> -	sbi->cp_expires = round_jiffies_up(jiffies);
> -
> +	f2fs_update_time(sbi, CP_TIME);
>  	return 0;
> 
>  free_kobj:
> --
> 2.6.3
> 
> 
> ------------------------------------------------------------------------------
> Site24x7 APM Insight: Get Deep Visibility into Application Performance
> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
> Monitor end-to-end web transactions and take corrective actions now
> Troubleshoot faster and improve end-user experience. Signup Now!
> http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [f2fs-dev] [PATCH 2/2] f2fs: detect idle time depending on user behavior
  2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
@ 2016-01-11  7:15   ` Chao Yu
  2016-01-11 23:45     ` Jaegeuk Kim
  2016-01-11 23:59   ` Jaegeuk Kim
  1 sibling, 1 reply; 7+ messages in thread
From: Chao Yu @ 2016-01-11  7:15 UTC (permalink / raw)
  To: 'Jaegeuk Kim'; +Cc: linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Jaegeuk,

> -----Original Message-----
> From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> Sent: Saturday, January 09, 2016 9:29 AM
> To: linux-kernel@vger.kernel.org; linux-fsdevel@vger.kernel.org;
> linux-f2fs-devel@lists.sourceforge.net
> Cc: Jaegeuk Kim
> Subject: [f2fs-dev] [PATCH 2/2] f2fs: detect idle time depending on user behavior
> 
> This patch adds last time that user requested filesystem operations.
> This information is used to detect whether system is idle or not later.

Seems there are some missing cases:
- xattr
- tmpfile
- ioctl

Thanks,

> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
>  Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++++++
>  fs/f2fs/data.c                          |  1 +
>  fs/f2fs/dir.c                           |  3 +++
>  fs/f2fs/f2fs.h                          | 15 +++++++++++++++
>  fs/f2fs/file.c                          |  4 ++++
>  fs/f2fs/gc.c                            |  1 -
>  fs/f2fs/gc.h                            |  8 --------
>  fs/f2fs/segment.c                       |  2 +-
>  fs/f2fs/super.c                         |  4 ++++
>  9 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs
> b/Documentation/ABI/testing/sysfs-fs-f2fs
> index 0345f2d..e5200f3 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -87,6 +87,12 @@ Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
>  Description:
>  		 Controls the checkpoint timing.
> 
> +What:		/sys/fs/f2fs/<disk>/idle_interval
> +Date:		January 2016
> +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> +Description:
> +		 Controls the idle timing.
> +
>  What:		/sys/fs/f2fs/<disk>/ra_nid_pages
>  Date:		October 2015
>  Contact:	"Chao Yu" <chao2.yu@samsung.com>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index a3bce12..ac9e7c6 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1596,6 +1596,7 @@ static int f2fs_write_end(struct file *file,
>  	}
> 
>  	f2fs_put_page(page, 1);
> +	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
>  	return copied;
>  }
> 
> diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
> index 29bb8dd..216dd87 100644
> --- a/fs/f2fs/dir.c
> +++ b/fs/f2fs/dir.c
> @@ -636,6 +636,7 @@ fail:
>  	f2fs_put_page(dentry_page, 1);
>  out:
>  	f2fs_fname_free_filename(&fname);
> +	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
>  	return err;
>  }
> 
> @@ -701,6 +702,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
>  	int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
>  	int i;
> 
> +	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
> +
>  	if (f2fs_has_inline_dentry(dir))
>  		return f2fs_delete_inline_entry(dentry, page, dir, inode);
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 603266c..ef6e666 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -21,6 +21,7 @@
>  #include <linux/sched.h>
>  #include <linux/vmalloc.h>
>  #include <linux/bio.h>
> +#include <linux/blkdev.h>
> 
>  #ifdef CONFIG_F2FS_CHECK_FS
>  #define f2fs_bug_on(sbi, condition)	BUG_ON(condition)
> @@ -126,6 +127,7 @@ enum {
>  #define BATCHED_TRIM_BLOCKS(sbi)	\
>  		(BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
>  #define DEF_CP_INTERVAL			60	/* 60 secs */
> +#define DEF_IDLE_INTERVAL		120	/* 2 mins */
> 
>  struct cp_control {
>  	int reason;
> @@ -723,6 +725,7 @@ enum {
> 
>  enum {
>  	CP_TIME,
> +	REQ_TIME,
>  	MAX_TIME,
>  };
> 
> @@ -856,6 +859,18 @@ static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
>  	return jiffies > sbi->last_time[type] + interval;
>  }
> 
> +static inline bool is_idle(struct f2fs_sb_info *sbi)
> +{
> +	struct block_device *bdev = sbi->sb->s_bdev;
> +	struct request_queue *q = bdev_get_queue(bdev);
> +	struct request_list *rl = &q->root_rl;
> +
> +	if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
> +		return 0;
> +
> +	return f2fs_time_over(sbi, REQ_TIME);
> +}
> +
>  /*
>   * Inline functions
>   */
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index ff06827..dfaed51 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -96,6 +96,7 @@ mapped:
>  	clear_cold_data(page);
>  out:
>  	sb_end_pagefault(inode->i_sb);
> +	f2fs_update_time(sbi, REQ_TIME);
>  	return block_page_mkwrite_return(err);
>  }
> 
> @@ -280,6 +281,7 @@ flush_out:
>  	remove_ino_entry(sbi, ino, UPDATE_INO);
>  	clear_inode_flag(fi, FI_UPDATE_WRITE);
>  	ret = f2fs_issue_flush(sbi);
> +	f2fs_update_time(sbi, REQ_TIME);
>  out:
>  	trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
>  	f2fs_trace_ios(NULL, 1);
> @@ -485,6 +487,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
>  	}
>  	dn->ofs_in_node = ofs;
> 
> +	f2fs_update_time(sbi, REQ_TIME);
>  	trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid,
>  					 dn->ofs_in_node, nr_free);
>  	return nr_free;
> @@ -1236,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode,
>  	if (!ret) {
>  		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
>  		mark_inode_dirty(inode);
> +		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
>  	}
> 
>  out:
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index c09be33..f610c2a 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -16,7 +16,6 @@
>  #include <linux/kthread.h>
>  #include <linux/delay.h>
>  #include <linux/freezer.h>
> -#include <linux/blkdev.h>
> 
>  #include "f2fs.h"
>  #include "node.h"
> diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
> index b4a65be..a993967 100644
> --- a/fs/f2fs/gc.h
> +++ b/fs/f2fs/gc.h
> @@ -100,11 +100,3 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
>  		return true;
>  	return false;
>  }
> -
> -static inline int is_idle(struct f2fs_sb_info *sbi)
> -{
> -	struct block_device *bdev = sbi->sb->s_bdev;
> -	struct request_queue *q = bdev_get_queue(bdev);
> -	struct request_list *rl = &q->root_rl;
> -	return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]);
> -}
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index fed23d5..d8ad1ab 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
>  	if (!available_free_memory(sbi, NAT_ENTRIES) ||
>  			excess_prefree_segs(sbi) ||
>  			!available_free_memory(sbi, INO_ENTRIES) ||
> -			f2fs_time_over(sbi, CP_TIME)) {
> +			(is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) {
>  		if (test_opt(sbi, DATA_FLUSH))
>  			sync_dirty_inodes(sbi, FILE_INODE);
>  		f2fs_sync_fs(sbi->sb, true);
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 787047f..3bf990b 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -219,6 +219,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
>  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
>  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
>  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
> +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
> 
>  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
>  static struct attribute *f2fs_attrs[] = {
> @@ -237,6 +238,7 @@ static struct attribute *f2fs_attrs[] = {
>  	ATTR_LIST(ram_thresh),
>  	ATTR_LIST(ra_nid_pages),
>  	ATTR_LIST(cp_interval),
> +	ATTR_LIST(idle_interval),
>  	NULL,
>  };
> 
> @@ -1123,6 +1125,7 @@ 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;
>  	clear_sbi_flag(sbi, SBI_NEED_FSCK);
> 
>  	INIT_LIST_HEAD(&sbi->s_list);
> @@ -1468,6 +1471,7 @@ try_onemore:
>  	}
> 
>  	f2fs_update_time(sbi, CP_TIME);
> +	f2fs_update_time(sbi, REQ_TIME);
>  	return 0;
> 
>  free_kobj:
> --
> 2.6.3
> 
> 
> ------------------------------------------------------------------------------
> Site24x7 APM Insight: Get Deep Visibility into Application Performance
> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
> Monitor end-to-end web transactions and take corrective actions now
> Troubleshoot faster and improve end-user experience. Signup Now!
> http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [f2fs-dev] [PATCH 2/2] f2fs: detect idle time depending on user behavior
  2016-01-11  7:15   ` [f2fs-dev] " Chao Yu
@ 2016-01-11 23:45     ` Jaegeuk Kim
  0 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-01-11 23:45 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Chao,

On Mon, Jan 11, 2016 at 03:15:36PM +0800, Chao Yu wrote:
> Hi Jaegeuk,
> 
> > -----Original Message-----
> > From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> > Sent: Saturday, January 09, 2016 9:29 AM
> > To: linux-kernel@vger.kernel.org; linux-fsdevel@vger.kernel.org;
> > linux-f2fs-devel@lists.sourceforge.net
> > Cc: Jaegeuk Kim
> > Subject: [f2fs-dev] [PATCH 2/2] f2fs: detect idle time depending on user behavior
> > 
> > This patch adds last time that user requested filesystem operations.
> > This information is used to detect whether system is idle or not later.
> 
> Seems there are some missing cases:
> - xattr
> - tmpfile
> - ioctl

Agreed.
Thanks,

> 
> Thanks,
> 
> > 
> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> > ---
> >  Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++++++
> >  fs/f2fs/data.c                          |  1 +
> >  fs/f2fs/dir.c                           |  3 +++
> >  fs/f2fs/f2fs.h                          | 15 +++++++++++++++
> >  fs/f2fs/file.c                          |  4 ++++
> >  fs/f2fs/gc.c                            |  1 -
> >  fs/f2fs/gc.h                            |  8 --------
> >  fs/f2fs/segment.c                       |  2 +-
> >  fs/f2fs/super.c                         |  4 ++++
> >  9 files changed, 34 insertions(+), 10 deletions(-)
> > 
> > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs
> > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > index 0345f2d..e5200f3 100644
> > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > @@ -87,6 +87,12 @@ Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> >  Description:
> >  		 Controls the checkpoint timing.
> > 
> > +What:		/sys/fs/f2fs/<disk>/idle_interval
> > +Date:		January 2016
> > +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> > +Description:
> > +		 Controls the idle timing.
> > +
> >  What:		/sys/fs/f2fs/<disk>/ra_nid_pages
> >  Date:		October 2015
> >  Contact:	"Chao Yu" <chao2.yu@samsung.com>
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index a3bce12..ac9e7c6 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -1596,6 +1596,7 @@ static int f2fs_write_end(struct file *file,
> >  	}
> > 
> >  	f2fs_put_page(page, 1);
> > +	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
> >  	return copied;
> >  }
> > 
> > diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
> > index 29bb8dd..216dd87 100644
> > --- a/fs/f2fs/dir.c
> > +++ b/fs/f2fs/dir.c
> > @@ -636,6 +636,7 @@ fail:
> >  	f2fs_put_page(dentry_page, 1);
> >  out:
> >  	f2fs_fname_free_filename(&fname);
> > +	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
> >  	return err;
> >  }
> > 
> > @@ -701,6 +702,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
> >  	int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
> >  	int i;
> > 
> > +	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
> > +
> >  	if (f2fs_has_inline_dentry(dir))
> >  		return f2fs_delete_inline_entry(dentry, page, dir, inode);
> > 
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 603266c..ef6e666 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -21,6 +21,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/vmalloc.h>
> >  #include <linux/bio.h>
> > +#include <linux/blkdev.h>
> > 
> >  #ifdef CONFIG_F2FS_CHECK_FS
> >  #define f2fs_bug_on(sbi, condition)	BUG_ON(condition)
> > @@ -126,6 +127,7 @@ enum {
> >  #define BATCHED_TRIM_BLOCKS(sbi)	\
> >  		(BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
> >  #define DEF_CP_INTERVAL			60	/* 60 secs */
> > +#define DEF_IDLE_INTERVAL		120	/* 2 mins */
> > 
> >  struct cp_control {
> >  	int reason;
> > @@ -723,6 +725,7 @@ enum {
> > 
> >  enum {
> >  	CP_TIME,
> > +	REQ_TIME,
> >  	MAX_TIME,
> >  };
> > 
> > @@ -856,6 +859,18 @@ static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
> >  	return jiffies > sbi->last_time[type] + interval;
> >  }
> > 
> > +static inline bool is_idle(struct f2fs_sb_info *sbi)
> > +{
> > +	struct block_device *bdev = sbi->sb->s_bdev;
> > +	struct request_queue *q = bdev_get_queue(bdev);
> > +	struct request_list *rl = &q->root_rl;
> > +
> > +	if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
> > +		return 0;
> > +
> > +	return f2fs_time_over(sbi, REQ_TIME);
> > +}
> > +
> >  /*
> >   * Inline functions
> >   */
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index ff06827..dfaed51 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -96,6 +96,7 @@ mapped:
> >  	clear_cold_data(page);
> >  out:
> >  	sb_end_pagefault(inode->i_sb);
> > +	f2fs_update_time(sbi, REQ_TIME);
> >  	return block_page_mkwrite_return(err);
> >  }
> > 
> > @@ -280,6 +281,7 @@ flush_out:
> >  	remove_ino_entry(sbi, ino, UPDATE_INO);
> >  	clear_inode_flag(fi, FI_UPDATE_WRITE);
> >  	ret = f2fs_issue_flush(sbi);
> > +	f2fs_update_time(sbi, REQ_TIME);
> >  out:
> >  	trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
> >  	f2fs_trace_ios(NULL, 1);
> > @@ -485,6 +487,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
> >  	}
> >  	dn->ofs_in_node = ofs;
> > 
> > +	f2fs_update_time(sbi, REQ_TIME);
> >  	trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid,
> >  					 dn->ofs_in_node, nr_free);
> >  	return nr_free;
> > @@ -1236,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode,
> >  	if (!ret) {
> >  		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
> >  		mark_inode_dirty(inode);
> > +		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
> >  	}
> > 
> >  out:
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index c09be33..f610c2a 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -16,7 +16,6 @@
> >  #include <linux/kthread.h>
> >  #include <linux/delay.h>
> >  #include <linux/freezer.h>
> > -#include <linux/blkdev.h>
> > 
> >  #include "f2fs.h"
> >  #include "node.h"
> > diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
> > index b4a65be..a993967 100644
> > --- a/fs/f2fs/gc.h
> > +++ b/fs/f2fs/gc.h
> > @@ -100,11 +100,3 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
> >  		return true;
> >  	return false;
> >  }
> > -
> > -static inline int is_idle(struct f2fs_sb_info *sbi)
> > -{
> > -	struct block_device *bdev = sbi->sb->s_bdev;
> > -	struct request_queue *q = bdev_get_queue(bdev);
> > -	struct request_list *rl = &q->root_rl;
> > -	return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]);
> > -}
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index fed23d5..d8ad1ab 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
> >  	if (!available_free_memory(sbi, NAT_ENTRIES) ||
> >  			excess_prefree_segs(sbi) ||
> >  			!available_free_memory(sbi, INO_ENTRIES) ||
> > -			f2fs_time_over(sbi, CP_TIME)) {
> > +			(is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) {
> >  		if (test_opt(sbi, DATA_FLUSH))
> >  			sync_dirty_inodes(sbi, FILE_INODE);
> >  		f2fs_sync_fs(sbi->sb, true);
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index 787047f..3bf990b 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -219,6 +219,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
> >  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
> >  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
> >  F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
> > +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
> > 
> >  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
> >  static struct attribute *f2fs_attrs[] = {
> > @@ -237,6 +238,7 @@ static struct attribute *f2fs_attrs[] = {
> >  	ATTR_LIST(ram_thresh),
> >  	ATTR_LIST(ra_nid_pages),
> >  	ATTR_LIST(cp_interval),
> > +	ATTR_LIST(idle_interval),
> >  	NULL,
> >  };
> > 
> > @@ -1123,6 +1125,7 @@ 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;
> >  	clear_sbi_flag(sbi, SBI_NEED_FSCK);
> > 
> >  	INIT_LIST_HEAD(&sbi->s_list);
> > @@ -1468,6 +1471,7 @@ try_onemore:
> >  	}
> > 
> >  	f2fs_update_time(sbi, CP_TIME);
> > +	f2fs_update_time(sbi, REQ_TIME);
> >  	return 0;
> > 
> >  free_kobj:
> > --
> > 2.6.3
> > 
> > 
> > ------------------------------------------------------------------------------
> > Site24x7 APM Insight: Get Deep Visibility into Application Performance
> > APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
> > Monitor end-to-end web transactions and take corrective actions now
> > Troubleshoot faster and improve end-user experience. Signup Now!
> > http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
> > _______________________________________________
> > Linux-f2fs-devel mailing list
> > Linux-f2fs-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] f2fs: introduce time and interval facility
  2016-01-09  1:29 [PATCH 1/2] f2fs: introduce time and interval facility Jaegeuk Kim
  2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
  2016-01-11  7:12 ` [f2fs-dev] [PATCH 1/2] f2fs: introduce time and interval facility Chao Yu
@ 2016-01-11 23:47 ` Jaegeuk Kim
  2 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-01-11 23:47 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel

Change log from v1:
 - use time_after

>From 6beceb5427aa8731f958d2484e0fd8ff21d604dc Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <jaegeuk@kernel.org>
Date: Fri, 8 Jan 2016 15:51:50 -0800
Subject: [PATCH] f2fs: introduce time and interval facility

This patch adds time and interval arrays to store some timing variables.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c |  2 +-
 fs/f2fs/f2fs.h       | 21 ++++++++++++++++++++-
 fs/f2fs/segment.c    |  2 +-
 fs/f2fs/super.c      |  7 +++----
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5dbafd5..3842af9 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1139,7 +1139,7 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 			"checkpoint: version = %llx", ckpt_ver);
 
 	/* do checkpoint periodically */
-	sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval);
+	f2fs_update_time(sbi, CP_TIME);
 	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
 out:
 	mutex_unlock(&sbi->cp_mutex);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ae0007d..5bbb6a4 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -721,6 +721,11 @@ enum {
 	SBI_POR_DOING,				/* recovery is doing or not */
 };
 
+enum {
+	CP_TIME,
+	MAX_TIME,
+};
+
 struct f2fs_sb_info {
 	struct super_block *sb;			/* pointer to VFS super block */
 	struct proc_dir_entry *s_proc;		/* proc entry */
@@ -747,7 +752,8 @@ struct f2fs_sb_info {
 	struct rw_semaphore node_write;		/* locking node writes */
 	struct mutex writepages;		/* mutex for writepages() */
 	wait_queue_head_t cp_wait;
-	long cp_expires, cp_interval;		/* next expected periodic cp */
+	unsigned long last_time[MAX_TIME];	/* to store time in jiffies */
+	long interval_time[MAX_TIME];		/* to store thresholds */
 
 	struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
 
@@ -837,6 +843,19 @@ struct f2fs_sb_info {
 	unsigned int shrinker_run_no;
 };
 
+static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
+{
+	sbi->last_time[type] = jiffies;
+}
+
+static inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
+{
+	struct timespec ts = {sbi->interval_time[type], 0};
+	unsigned long interval = timespec_to_jiffies(&ts);
+
+	return time_after(jiffies, sbi->last_time[type] + interval);
+}
+
 /*
  * Inline functions
  */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c7bbc91..fed23d5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
 	if (!available_free_memory(sbi, NAT_ENTRIES) ||
 			excess_prefree_segs(sbi) ||
 			!available_free_memory(sbi, INO_ENTRIES) ||
-			jiffies > sbi->cp_expires) {
+			f2fs_time_over(sbi, CP_TIME)) {
 		if (test_opt(sbi, DATA_FLUSH))
 			sync_dirty_inodes(sbi, FILE_INODE);
 		f2fs_sync_fs(sbi->sb, true);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f5cc790..787047f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -218,7 +218,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -1122,7 +1122,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 		atomic_set(&sbi->nr_pages[i], 0);
 
 	sbi->dir_level = DEF_DIR_LEVEL;
-	sbi->cp_interval = DEF_CP_INTERVAL;
+	sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL;
 	clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
 	INIT_LIST_HEAD(&sbi->s_list);
@@ -1467,8 +1467,7 @@ try_onemore:
 		f2fs_commit_super(sbi, true);
 	}
 
-	sbi->cp_expires = round_jiffies_up(jiffies);
-
+	f2fs_update_time(sbi, CP_TIME);
 	return 0;
 
 free_kobj:
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] f2fs: detect idle time depending on user behavior
  2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
  2016-01-11  7:15   ` [f2fs-dev] " Chao Yu
@ 2016-01-11 23:59   ` Jaegeuk Kim
  1 sibling, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-01-11 23:59 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel

Change log from v1:
 - add more cases

>From d0239e1bf5204d602281f93c01d46bcf3531098d Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <jaegeuk@kernel.org>
Date: Fri, 8 Jan 2016 16:57:48 -0800
Subject: [PATCH] f2fs: detect idle time depending on user behavior

This patch adds last time that user requested filesystem operations.
This information is used to detect whether system is idle or not later.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++++++
 fs/f2fs/data.c                          |  1 +
 fs/f2fs/dir.c                           |  4 ++++
 fs/f2fs/f2fs.h                          | 15 +++++++++++++++
 fs/f2fs/file.c                          | 12 ++++++++++++
 fs/f2fs/gc.c                            |  1 -
 fs/f2fs/gc.h                            |  8 --------
 fs/f2fs/segment.c                       |  2 +-
 fs/f2fs/super.c                         |  4 ++++
 fs/f2fs/xattr.c                         |  1 +
 10 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 0345f2d..e5200f3 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -87,6 +87,12 @@ Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
 Description:
 		 Controls the checkpoint timing.
 
+What:		/sys/fs/f2fs/<disk>/idle_interval
+Date:		January 2016
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Controls the idle timing.
+
 What:		/sys/fs/f2fs/<disk>/ra_nid_pages
 Date:		October 2015
 Contact:	"Chao Yu" <chao2.yu@samsung.com>
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index a3bce12..ac9e7c6 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1596,6 +1596,7 @@ static int f2fs_write_end(struct file *file,
 	}
 
 	f2fs_put_page(page, 1);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return copied;
 }
 
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 29bb8dd..faa7495 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -636,6 +636,7 @@ fail:
 	f2fs_put_page(dentry_page, 1);
 out:
 	f2fs_fname_free_filename(&fname);
+	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
 	return err;
 }
 
@@ -657,6 +658,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir)
 	clear_inode_flag(F2FS_I(inode), FI_NEW_INODE);
 fail:
 	up_write(&F2FS_I(inode)->i_sem);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return err;
 }
 
@@ -701,6 +703,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 	int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
 	int i;
 
+	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
+
 	if (f2fs_has_inline_dentry(dir))
 		return f2fs_delete_inline_entry(dentry, page, dir, inode);
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 5bbb6a4..4331b9f 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 #include <linux/bio.h>
+#include <linux/blkdev.h>
 
 #ifdef CONFIG_F2FS_CHECK_FS
 #define f2fs_bug_on(sbi, condition)	BUG_ON(condition)
@@ -126,6 +127,7 @@ enum {
 #define BATCHED_TRIM_BLOCKS(sbi)	\
 		(BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
 #define DEF_CP_INTERVAL			60	/* 60 secs */
+#define DEF_IDLE_INTERVAL		120	/* 2 mins */
 
 struct cp_control {
 	int reason;
@@ -723,6 +725,7 @@ enum {
 
 enum {
 	CP_TIME,
+	REQ_TIME,
 	MAX_TIME,
 };
 
@@ -856,6 +859,18 @@ 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)
+{
+	struct block_device *bdev = sbi->sb->s_bdev;
+	struct request_queue *q = bdev_get_queue(bdev);
+	struct request_list *rl = &q->root_rl;
+
+	if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
+		return 0;
+
+	return f2fs_time_over(sbi, REQ_TIME);
+}
+
 /*
  * Inline functions
  */
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index ff06827..3d43857 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -96,6 +96,7 @@ mapped:
 	clear_cold_data(page);
 out:
 	sb_end_pagefault(inode->i_sb);
+	f2fs_update_time(sbi, REQ_TIME);
 	return block_page_mkwrite_return(err);
 }
 
@@ -280,6 +281,7 @@ flush_out:
 	remove_ino_entry(sbi, ino, UPDATE_INO);
 	clear_inode_flag(fi, FI_UPDATE_WRITE);
 	ret = f2fs_issue_flush(sbi);
+	f2fs_update_time(sbi, REQ_TIME);
 out:
 	trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
 	f2fs_trace_ios(NULL, 1);
@@ -485,6 +487,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
 	}
 	dn->ofs_in_node = ofs;
 
+	f2fs_update_time(sbi, REQ_TIME);
 	trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid,
 					 dn->ofs_in_node, nr_free);
 	return nr_free;
@@ -1236,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode,
 	if (!ret) {
 		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		mark_inode_dirty(inode);
+		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	}
 
 out:
@@ -1351,6 +1355,8 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
 		return ret;
 
 	set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+
 	return 0;
 }
 
@@ -1398,6 +1404,7 @@ static int f2fs_ioc_start_volatile_write(struct file *filp)
 		return ret;
 
 	set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return 0;
 }
 
@@ -1439,6 +1446,7 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
 	}
 
 	mnt_drop_write_file(filp);
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return ret;
 }
 
@@ -1478,6 +1486,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
 	default:
 		return -EINVAL;
 	}
+	f2fs_update_time(sbi, REQ_TIME);
 	return 0;
 }
 
@@ -1508,6 +1517,7 @@ static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
 	if (copy_to_user((struct fstrim_range __user *)arg, &range,
 				sizeof(range)))
 		return -EFAULT;
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return 0;
 }
 
@@ -1531,6 +1541,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 				sizeof(policy)))
 		return -EFAULT;
 
+	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 	return f2fs_process_policy(&policy, inode);
 #else
 	return -EOPNOTSUPP;
@@ -1807,6 +1818,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
 	}
 
 	err = f2fs_defragment_range(sbi, filp, &range);
+	f2fs_update_time(sbi, REQ_TIME);
 	if (err < 0)
 		goto out;
 
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index c09be33..f610c2a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -16,7 +16,6 @@
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
-#include <linux/blkdev.h>
 
 #include "f2fs.h"
 #include "node.h"
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index b4a65be..a993967 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -100,11 +100,3 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
 		return true;
 	return false;
 }
-
-static inline int is_idle(struct f2fs_sb_info *sbi)
-{
-	struct block_device *bdev = sbi->sb->s_bdev;
-	struct request_queue *q = bdev_get_queue(bdev);
-	struct request_list *rl = &q->root_rl;
-	return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]);
-}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index fed23d5..d8ad1ab 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -293,7 +293,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
 	if (!available_free_memory(sbi, NAT_ENTRIES) ||
 			excess_prefree_segs(sbi) ||
 			!available_free_memory(sbi, INO_ENTRIES) ||
-			f2fs_time_over(sbi, CP_TIME)) {
+			(is_idle(sbi) && f2fs_time_over(sbi, CP_TIME))) {
 		if (test_opt(sbi, DATA_FLUSH))
 			sync_dirty_inodes(sbi, FILE_INODE);
 		f2fs_sync_fs(sbi->sb, true);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 787047f..3bf990b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -219,6 +219,7 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -237,6 +238,7 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(ram_thresh),
 	ATTR_LIST(ra_nid_pages),
 	ATTR_LIST(cp_interval),
+	ATTR_LIST(idle_interval),
 	NULL,
 };
 
@@ -1123,6 +1125,7 @@ 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;
 	clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
 	INIT_LIST_HEAD(&sbi->s_list);
@@ -1468,6 +1471,7 @@ try_onemore:
 	}
 
 	f2fs_update_time(sbi, CP_TIME);
+	f2fs_update_time(sbi, REQ_TIME);
 	return 0;
 
 free_kobj:
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 822a8af..0108f48 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -618,5 +618,6 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name,
 	up_write(&F2FS_I(inode)->i_sem);
 	f2fs_unlock_op(sbi);
 
+	f2fs_update_time(sbi, REQ_TIME);
 	return err;
 }
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-01-11 23:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-09  1:29 [PATCH 1/2] f2fs: introduce time and interval facility Jaegeuk Kim
2016-01-09  1:29 ` [PATCH 2/2] f2fs: detect idle time depending on user behavior Jaegeuk Kim
2016-01-11  7:15   ` [f2fs-dev] " Chao Yu
2016-01-11 23:45     ` Jaegeuk Kim
2016-01-11 23:59   ` Jaegeuk Kim
2016-01-11  7:12 ` [f2fs-dev] [PATCH 1/2] f2fs: introduce time and interval facility Chao Yu
2016-01-11 23:47 ` Jaegeuk Kim

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).