mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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> Conflicts: Documentation/ABI/testing/sysfs-fs-f2fs
This commit is contained in:
parent
b074a0de9c
commit
389d2eece6
10 changed files with 138 additions and 10 deletions
100
Documentation/ABI/testing/sysfs-fs-f2fs
Normal file
100
Documentation/ABI/testing/sysfs-fs-f2fs
Normal file
|
@ -0,0 +1,100 @@
|
|||
What: /sys/fs/f2fs/<disk>/gc_max_sleep_time
|
||||
Date: July 2013
|
||||
Contact: "Namjae Jeon" <namjae.jeon@samsung.com>
|
||||
Description:
|
||||
Controls the maximun sleep time for gc_thread. Time
|
||||
is in milliseconds.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/gc_min_sleep_time
|
||||
Date: July 2013
|
||||
Contact: "Namjae Jeon" <namjae.jeon@samsung.com>
|
||||
Description:
|
||||
Controls the minimum sleep time for gc_thread. Time
|
||||
is in milliseconds.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/gc_no_gc_sleep_time
|
||||
Date: July 2013
|
||||
Contact: "Namjae Jeon" <namjae.jeon@samsung.com>
|
||||
Description:
|
||||
Controls the default sleep time for gc_thread. Time
|
||||
is in milliseconds.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/gc_idle
|
||||
Date: July 2013
|
||||
Contact: "Namjae Jeon" <namjae.jeon@samsung.com>
|
||||
Description:
|
||||
Controls the victim selection policy for garbage collection.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/reclaim_segments
|
||||
Date: October 2013
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the issue rate of segment discard commands.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/ipu_policy
|
||||
Date: November 2013
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the in-place-update policy.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/min_ipu_util
|
||||
Date: November 2013
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the FS utilization condition for the in-place-update
|
||||
policies.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/min_fsync_blocks
|
||||
Date: September 2014
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Controls the dirty page count condition for the in-place-update
|
||||
policies.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/max_small_discards
|
||||
Date: November 2013
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the issue rate of small discard commands.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/max_victim_search
|
||||
Date: January 2014
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the number of trials to find a victim segment.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/dir_level
|
||||
Date: March 2014
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the directory level for large directory.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/ram_thresh
|
||||
Date: March 2014
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
Description:
|
||||
Controls the memory footprint used by f2fs.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/trim_sections
|
||||
Date: February 2015
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Controls the trimming rate in batch mode.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/cp_interval
|
||||
Date: October 2015
|
||||
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>
|
||||
Description:
|
||||
Controls the count of nid pages to be readaheaded.
|
|
@ -1597,6 +1597,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -127,6 +128,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;
|
||||
|
@ -725,6 +727,7 @@ enum {
|
|||
|
||||
enum {
|
||||
CP_TIME,
|
||||
REQ_TIME,
|
||||
MAX_TIME,
|
||||
};
|
||||
|
||||
|
@ -858,6 +861,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->rq;
|
||||
|
||||
if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
|
||||
return 0;
|
||||
|
||||
return f2fs_time_over(sbi, REQ_TIME);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline functions
|
||||
*/
|
||||
|
|
|
@ -95,6 +95,7 @@ mapped:
|
|||
/* if gced page is attached, don't write to cold segment */
|
||||
clear_cold_data(page);
|
||||
out:
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
return block_page_mkwrite_return(err);
|
||||
}
|
||||
|
||||
|
@ -278,6 +279,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);
|
||||
|
@ -502,6 +504,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;
|
||||
|
@ -1256,6 +1259,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:
|
||||
|
@ -1371,6 +1375,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;
|
||||
}
|
||||
|
||||
|
@ -1418,6 +1424,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;
|
||||
}
|
||||
|
||||
|
@ -1459,6 +1466,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;
|
||||
}
|
||||
|
||||
|
@ -1498,6 +1506,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1528,6 +1537,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;
|
||||
}
|
||||
|
||||
|
@ -1551,6 +1561,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;
|
||||
|
@ -1827,6 +1838,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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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->rq;
|
||||
return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]);
|
||||
}
|
||||
|
|
|
@ -352,7 +352,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);
|
||||
|
|
|
@ -218,6 +218,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[] = {
|
||||
|
@ -236,6 +237,7 @@ static struct attribute *f2fs_attrs[] = {
|
|||
ATTR_LIST(ram_thresh),
|
||||
ATTR_LIST(ra_nid_pages),
|
||||
ATTR_LIST(cp_interval),
|
||||
ATTR_LIST(idle_interval),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -1116,6 +1118,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);
|
||||
|
@ -1461,6 +1464,7 @@ try_onemore:
|
|||
}
|
||||
|
||||
f2fs_update_time(sbi, CP_TIME);
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
return 0;
|
||||
|
||||
free_kobj:
|
||||
|
|
|
@ -619,5 +619,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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue