From 93d33a4885a483c708ccb7d24b56e0d5fef7bcab Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 11 Apr 2004 23:17:38 -0700 Subject: [PATCH] laptop mode From: Bart Samwel Adds /proc/sys/vm/laptop-mode: a special knob which says "this is a laptop". In this mode the kernel will attempt to avoid spinning disks up. Algorithm: the idea is to hold dirty data in memory for a long time, but to flush everything which has been accumulated if the disk happens to spin up for other reasons. - Whenever a disk request completes (read or write), schedule a timer a few seconds hence. If the timer was already pending, reset it to a few seconds hence. - When the timer expires, write back the whole world. We use sync_filesystems() for this because it will force ext3 journal commits as well. - In balance_dirty_pages(), kick off background writeback when we hit the high threshold (dirty_ratio), not when we hit the low threshold. This has the effect of causing "lumpy" writeback which is something I spent a year fixing, but in laptop mode, it is desirable. - In try_to_free_pages(), only kick pdflush if the VM is getting into distress: we want to keep scanning for clean pages, deferring writeback. - In page reclaim, avoid writing back the odd random dirty page off the LRU: only start I/O if the scanning is working harder. The effect is to perform a sync() a few seconds after all I/O has ceased. The value which was written into /proc/sys/vm/laptop-mode determines, in seconds, the delay between the final I/O and the flush. Additionally, the patch adds tools which help answer the question "why the heck does my disk spin up all the time?". The user may set /proc/sys/vm/block_dump to a non-zero value and the kernel will print out information which will identify the process which is performing disk reads or which is dirtying pagecache. The user should probably disable syslogd before setting block-dump. --- include/linux/sysctl.h | 2 ++ include/linux/writeback.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 3767428df94d..d2224f6617f9 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -159,6 +159,8 @@ enum VM_LOWER_ZONE_PROTECTION=20,/* Amount of protection of lower zones */ VM_MIN_FREE_KBYTES=21, /* Minimum free kilobytes to maintain */ VM_MAX_MAP_COUNT=22, /* int: Maximum number of mmaps/address-space */ + VM_LAPTOP_MODE=23, /* vm laptop mode */ + VM_BLOCK_DUMP=24, /* block dump mode */ }; diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 7380d2cefb16..f557b55e8b0a 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -72,12 +72,16 @@ static inline void wait_on_inode(struct inode *inode) * mm/page-writeback.c */ int wakeup_bdflush(long nr_pages); +void laptop_io_completion(void); +void laptop_sync_completion(void); -/* These 5 are exported to sysctl. */ +/* These are exported to sysctl. */ extern int dirty_background_ratio; extern int vm_dirty_ratio; extern int dirty_writeback_centisecs; extern int dirty_expire_centisecs; +extern int block_dump; +extern int laptop_mode; struct ctl_table; struct file; -- cgit v1.2.3