From: Bart Samwel Add laptop mode support for XFS. * Add /proc/sys/fs/xfs/lm_age_buffer and .../lm_flush_interval, values that are used instead of age_buffer and flush_interval when laptop mode is active. * Make the macros xfs_age_buffer and xfs_flush_interval refer to lm_flush_age and lm_flush_interval when laptop mode is active. * Switch from keeping track of "flush time" to keeping track of "creation time" for a pagebuf, so that changes in xfs_age_buffer can take effect immediately instead of only for pagebufs whose flush time is set anew. * Export "laptop_mode" variable, so that XFS can be compiled as a module. --- 25-akpm/fs/xfs/linux/xfs_buf.c | 6 ++++-- 25-akpm/fs/xfs/linux/xfs_buf.h | 2 +- 25-akpm/fs/xfs/linux/xfs_globals.c | 3 +++ 25-akpm/fs/xfs/linux/xfs_linux.h | 4 ++-- 25-akpm/fs/xfs/linux/xfs_super.c | 1 + 25-akpm/fs/xfs/linux/xfs_sysctl.c | 10 ++++++++++ 25-akpm/fs/xfs/linux/xfs_sysctl.h | 6 ++++++ 25-akpm/mm/page-writeback.c | 1 + 8 files changed, 28 insertions(+), 5 deletions(-) diff -puN fs/xfs/linux/xfs_buf.c~xfs-laptop-mode fs/xfs/linux/xfs_buf.c --- 25/fs/xfs/linux/xfs_buf.c~xfs-laptop-mode 2004-03-31 23:15:36.468592416 -0800 +++ 25-akpm/fs/xfs/linux/xfs_buf.c 2004-03-31 23:15:36.483590136 -0800 @@ -58,6 +58,8 @@ #include #include #include +#include +#include #include "xfs_linux.h" @@ -1574,7 +1576,7 @@ pagebuf_delwri_queue( } list_add_tail(&pb->pb_list, &pbd_delwrite_queue); - pb->pb_flushtime = jiffies + xfs_age_buffer; + pb->pb_creation_time = jiffies; spin_unlock(&pbd_delwrite_lock); if (unlock) @@ -1647,7 +1649,7 @@ pagebuf_daemon( if ((pb->pb_flags & PBF_DELWRI) && !pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { if (!force_flush && - time_before(jiffies, pb->pb_flushtime)) { + time_before(jiffies, pb->pb_creation_time + xfs_age_buffer)) { pagebuf_unlock(pb); break; } diff -puN fs/xfs/linux/xfs_buf.h~xfs-laptop-mode fs/xfs/linux/xfs_buf.h --- 25/fs/xfs/linux/xfs_buf.h~xfs-laptop-mode 2004-03-31 23:15:36.469592264 -0800 +++ 25-akpm/fs/xfs/linux/xfs_buf.h 2004-03-31 23:15:36.484589984 -0800 @@ -139,7 +139,7 @@ typedef int (*page_buf_bdstrat_t)(struct typedef struct page_buf_s { struct semaphore pb_sema; /* semaphore for lockables */ - unsigned long pb_flushtime; /* time to flush pagebuf */ + unsigned long pb_creation_time; /* time pagebuf was created */ atomic_t pb_pin_count; /* pin count */ wait_queue_head_t pb_waiters; /* unpin waiters */ struct list_head pb_list; diff -puN fs/xfs/linux/xfs_globals.c~xfs-laptop-mode fs/xfs/linux/xfs_globals.c --- 25/fs/xfs/linux/xfs_globals.c~xfs-laptop-mode 2004-03-31 23:15:36.470592112 -0800 +++ 25-akpm/fs/xfs/linux/xfs_globals.c 2004-03-31 23:15:36.484589984 -0800 @@ -57,12 +57,15 @@ xfs_param_t xfs_params = { .panic_mask = { 0, 0, 127 }, .error_level = { 0, 3, 11 }, .sync_interval = { HZ, 30*HZ, 60*HZ }, + .lm_sync_interval + = { HZ, 600*HZ, INT_MAX }, .stats_clear = { 0, 0, 1 }, .inherit_sync = { 0, 1, 1 }, .inherit_nodump = { 0, 1, 1 }, .inherit_noatim = { 0, 1, 1 }, .flush_interval = { HZ/2, HZ, 30*HZ }, .age_buffer = { 1*HZ, 15*HZ, 300*HZ }, + .lm_age_buffer = { 1*HZ, 600*HZ, INT_MAX }, }; /* diff -puN fs/xfs/linux/xfs_linux.h~xfs-laptop-mode fs/xfs/linux/xfs_linux.h --- 25/fs/xfs/linux/xfs_linux.h~xfs-laptop-mode 2004-03-31 23:15:36.472591808 -0800 +++ 25-akpm/fs/xfs/linux/xfs_linux.h 2004-03-31 23:15:36.485589832 -0800 @@ -134,13 +134,13 @@ static inline void set_buffer_unwritten_ #define irix_symlink_mode xfs_params.symlink_mode.val #define xfs_panic_mask xfs_params.panic_mask.val #define xfs_error_level xfs_params.error_level.val -#define xfs_syncd_interval xfs_params.sync_interval.val +#define xfs_syncd_interval (unlikely(laptop_mode) ? xfs_params.lm_sync_interval.val : xfs_params.sync_interval.val) #define xfs_stats_clear xfs_params.stats_clear.val #define xfs_inherit_sync xfs_params.inherit_sync.val #define xfs_inherit_nodump xfs_params.inherit_nodump.val #define xfs_inherit_noatime xfs_params.inherit_noatim.val #define xfs_flush_interval xfs_params.flush_interval.val -#define xfs_age_buffer xfs_params.age_buffer.val +#define xfs_age_buffer (unlikely(laptop_mode) ? xfs_params.lm_age_buffer.val : xfs_params.age_buffer.val) #define current_cpu() smp_processor_id() #define current_pid() (current->pid) diff -puN fs/xfs/linux/xfs_super.c~xfs-laptop-mode fs/xfs/linux/xfs_super.c --- 25/fs/xfs/linux/xfs_super.c~xfs-laptop-mode 2004-03-31 23:15:36.474591504 -0800 +++ 25-akpm/fs/xfs/linux/xfs_super.c 2004-03-31 23:15:36.486589680 -0800 @@ -72,6 +72,7 @@ #include #include #include +#include STATIC struct quotactl_ops linvfs_qops; STATIC struct super_operations linvfs_sops; diff -puN fs/xfs/linux/xfs_sysctl.c~xfs-laptop-mode fs/xfs/linux/xfs_sysctl.c --- 25/fs/xfs/linux/xfs_sysctl.c~xfs-laptop-mode 2004-03-31 23:15:36.476591200 -0800 +++ 25-akpm/fs/xfs/linux/xfs_sysctl.c 2004-03-31 23:15:36.486589680 -0800 @@ -103,6 +103,11 @@ STATIC ctl_table xfs_table[] = { &sysctl_intvec, NULL, &xfs_params.sync_interval.min, &xfs_params.sync_interval.max}, + {XFS_LM_SYNC_INTERVAL, "lm_sync_interval", &xfs_params.lm_sync_interval.val, + sizeof(int), 0644, NULL, &proc_dointvec_minmax, + &sysctl_intvec, NULL, + &xfs_params.lm_sync_interval.min, &xfs_params.lm_sync_interval.max}, + {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val, sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, @@ -128,6 +133,11 @@ STATIC ctl_table xfs_table[] = { &sysctl_intvec, NULL, &xfs_params.age_buffer.min, &xfs_params.age_buffer.max}, + {XFS_LM_AGE_BUFFER, "lm_age_buffer", &xfs_params.lm_age_buffer.val, + sizeof(int), 0644, NULL, &proc_dointvec_minmax, + &sysctl_intvec, NULL, + &xfs_params.lm_age_buffer.min, &xfs_params.lm_age_buffer.max}, + /* please keep this the last entry */ #ifdef CONFIG_PROC_FS {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, diff -puN fs/xfs/linux/xfs_sysctl.h~xfs-laptop-mode fs/xfs/linux/xfs_sysctl.h --- 25/fs/xfs/linux/xfs_sysctl.h~xfs-laptop-mode 2004-03-31 23:15:36.477591048 -0800 +++ 25-akpm/fs/xfs/linux/xfs_sysctl.h 2004-03-31 23:15:36.487589528 -0800 @@ -54,6 +54,7 @@ typedef struct xfs_param { xfs_sysctl_val_t panic_mask; /* bitmask to cause panic on errors. */ xfs_sysctl_val_t error_level; /* Degree of reporting for problems */ xfs_sysctl_val_t sync_interval; /* time between sync calls */ + xfs_sysctl_val_t lm_sync_interval; /* same, in laptop mode */ xfs_sysctl_val_t stats_clear; /* Reset all XFS statistics to zero. */ xfs_sysctl_val_t inherit_sync; /* Inherit the "sync" inode flag. */ xfs_sysctl_val_t inherit_nodump;/* Inherit the "nodump" inode flag. */ @@ -62,6 +63,9 @@ typedef struct xfs_param { * delwri flush daemon. */ xfs_sysctl_val_t age_buffer; /* time for buffer to age before * we flush it. */ + xfs_sysctl_val_t lm_age_buffer; /* time for buffer to age before + * we flush it when laptop mode is + * active. */ } xfs_param_t; /* @@ -86,12 +90,14 @@ enum { XFS_PANIC_MASK = 6, XFS_ERRLEVEL = 7, XFS_SYNC_INTERVAL = 8, + XFS_LM_SYNC_INTERVAL = 9, XFS_STATS_CLEAR = 12, XFS_INHERIT_SYNC = 13, XFS_INHERIT_NODUMP = 14, XFS_INHERIT_NOATIME = 15, XFS_FLUSH_INTERVAL = 16, XFS_AGE_BUFFER = 17, + XFS_LM_AGE_BUFFER = 3, }; extern xfs_param_t xfs_params; diff -puN mm/page-writeback.c~xfs-laptop-mode mm/page-writeback.c --- 25/mm/page-writeback.c~xfs-laptop-mode 2004-03-31 23:15:36.479590744 -0800 +++ 25-akpm/mm/page-writeback.c 2004-03-31 23:15:36.487589528 -0800 @@ -91,6 +91,7 @@ int block_dump; * Flag that puts the machine in "laptop mode". */ int laptop_mode; +EXPORT_SYMBOL(laptop_mode); /* End of sysctl-exported parameters */ _