diff options
author | Bron Gondwana <brong@fastmail.fm> | 2008-02-05 01:29:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-05 12:44:18 -0500 |
commit | 195cf453d2c3d789cbe80e3735755f860c2fb222 (patch) | |
tree | fad48a8167744b6c091c8ca499bc78b859af8957 | |
parent | 3dfa5721f12c3d5a441448086bee156887daa961 (diff) |
mm/page-writeback: highmem_is_dirtyable option
Add vm.highmem_is_dirtyable toggle
A 32 bit machine with HIGHMEM64 enabled running DCC has an MMAPed file of
approximately 2Gb size which contains a hash format that is written
randomly by the dbclean process. On 2.6.16 this process took a few
minutes. With lowmem only accounting of dirty ratios, this takes about 12
hours of 100% disk IO, all random writes.
Include a toggle in /proc/sys/vm/highmem_is_dirtyable which can be set to 1 to
add the highmem back to the total available memory count.
[akpm@linux-foundation.org: Fix the CONFIG_DETECT_SOFTLOCKUP=y build]
Signed-off-by: Bron Gondwana <brong@fastmail.fm>
Cc: Ethan Solomita <solo@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: WU Fengguang <wfg@mail.ustc.edu.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/filesystems/proc.txt | 15 | ||||
-rw-r--r-- | Documentation/sysctl/vm.txt | 7 | ||||
-rw-r--r-- | include/linux/writeback.h | 1 | ||||
-rw-r--r-- | kernel/sysctl.c | 18 | ||||
-rw-r--r-- | mm/page-writeback.c | 11 |
5 files changed, 47 insertions, 5 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 0b1b0c008613..07231afca72d 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -1315,6 +1315,21 @@ for writeout by the pdflush daemons. It is expressed in 100'ths of a second. | |||
1315 | Data which has been dirty in-memory for longer than this interval will be | 1315 | Data which has been dirty in-memory for longer than this interval will be |
1316 | written out next time a pdflush daemon wakes up. | 1316 | written out next time a pdflush daemon wakes up. |
1317 | 1317 | ||
1318 | highmem_is_dirtyable | ||
1319 | -------------------- | ||
1320 | |||
1321 | Only present if CONFIG_HIGHMEM is set. | ||
1322 | |||
1323 | This defaults to 0 (false), meaning that the ratios set above are calculated | ||
1324 | as a percentage of lowmem only. This protects against excessive scanning | ||
1325 | in page reclaim, swapping and general VM distress. | ||
1326 | |||
1327 | Setting this to 1 can be useful on 32 bit machines where you want to make | ||
1328 | random changes within an MMAPed file that is larger than your available | ||
1329 | lowmem without causing large quantities of random IO. Is is safe if the | ||
1330 | behavior of all programs running on the machine is known and memory will | ||
1331 | not be otherwise stressed. | ||
1332 | |||
1318 | legacy_va_layout | 1333 | legacy_va_layout |
1319 | ---------------- | 1334 | ---------------- |
1320 | 1335 | ||
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 6f31f0a247d0..24eac1bc735d 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -22,6 +22,7 @@ Currently, these files are in /proc/sys/vm: | |||
22 | - dirty_background_ratio | 22 | - dirty_background_ratio |
23 | - dirty_expire_centisecs | 23 | - dirty_expire_centisecs |
24 | - dirty_writeback_centisecs | 24 | - dirty_writeback_centisecs |
25 | - highmem_is_dirtyable (only if CONFIG_HIGHMEM set) | ||
25 | - max_map_count | 26 | - max_map_count |
26 | - min_free_kbytes | 27 | - min_free_kbytes |
27 | - laptop_mode | 28 | - laptop_mode |
@@ -40,9 +41,9 @@ Currently, these files are in /proc/sys/vm: | |||
40 | ============================================================== | 41 | ============================================================== |
41 | 42 | ||
42 | dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, | 43 | dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, |
43 | dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode, | 44 | dirty_writeback_centisecs, highmem_is_dirtyable, |
44 | block_dump, swap_token_timeout, drop-caches, | 45 | vfs_cache_pressure, laptop_mode, block_dump, swap_token_timeout, |
45 | hugepages_treat_as_movable: | 46 | drop-caches, hugepages_treat_as_movable: |
46 | 47 | ||
47 | See Documentation/filesystems/proc.txt | 48 | See Documentation/filesystems/proc.txt |
48 | 49 | ||
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index c6148bbf1250..b2cd826a8c90 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -100,6 +100,7 @@ extern int dirty_background_ratio; | |||
100 | extern int vm_dirty_ratio; | 100 | extern int vm_dirty_ratio; |
101 | extern int dirty_writeback_interval; | 101 | extern int dirty_writeback_interval; |
102 | extern int dirty_expire_interval; | 102 | extern int dirty_expire_interval; |
103 | extern int vm_highmem_is_dirtyable; | ||
103 | extern int block_dump; | 104 | extern int block_dump; |
104 | extern int laptop_mode; | 105 | extern int laptop_mode; |
105 | 106 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 7cb1ac3e6fff..d0b47b859067 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -84,8 +84,11 @@ extern int sysctl_stat_interval; | |||
84 | extern int latencytop_enabled; | 84 | extern int latencytop_enabled; |
85 | 85 | ||
86 | /* Constants used for minimum and maximum */ | 86 | /* Constants used for minimum and maximum */ |
87 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 87 | #if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM) |
88 | static int one = 1; | 88 | static int one = 1; |
89 | #endif | ||
90 | |||
91 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
89 | static int sixty = 60; | 92 | static int sixty = 60; |
90 | #endif | 93 | #endif |
91 | 94 | ||
@@ -1150,6 +1153,19 @@ static struct ctl_table vm_table[] = { | |||
1150 | .extra1 = &zero, | 1153 | .extra1 = &zero, |
1151 | }, | 1154 | }, |
1152 | #endif | 1155 | #endif |
1156 | #ifdef CONFIG_HIGHMEM | ||
1157 | { | ||
1158 | .ctl_name = CTL_UNNUMBERED, | ||
1159 | .procname = "highmem_is_dirtyable", | ||
1160 | .data = &vm_highmem_is_dirtyable, | ||
1161 | .maxlen = sizeof(vm_highmem_is_dirtyable), | ||
1162 | .mode = 0644, | ||
1163 | .proc_handler = &proc_dointvec_minmax, | ||
1164 | .strategy = &sysctl_intvec, | ||
1165 | .extra1 = &zero, | ||
1166 | .extra2 = &one, | ||
1167 | }, | ||
1168 | #endif | ||
1153 | /* | 1169 | /* |
1154 | * NOTE: do not add new entries to this table unless you have read | 1170 | * NOTE: do not add new entries to this table unless you have read |
1155 | * Documentation/sysctl/ctl_unnumbered.txt | 1171 | * Documentation/sysctl/ctl_unnumbered.txt |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 8137482abd6e..c689b60af000 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -69,6 +69,12 @@ static inline long sync_writeback_pages(void) | |||
69 | int dirty_background_ratio = 5; | 69 | int dirty_background_ratio = 5; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * free highmem will not be subtracted from the total free memory | ||
73 | * for calculating free ratios if vm_highmem_is_dirtyable is true | ||
74 | */ | ||
75 | int vm_highmem_is_dirtyable; | ||
76 | |||
77 | /* | ||
72 | * The generator of dirty data starts writeback at this percentage | 78 | * The generator of dirty data starts writeback at this percentage |
73 | */ | 79 | */ |
74 | int vm_dirty_ratio = 10; | 80 | int vm_dirty_ratio = 10; |
@@ -287,7 +293,10 @@ static unsigned long determine_dirtyable_memory(void) | |||
287 | x = global_page_state(NR_FREE_PAGES) | 293 | x = global_page_state(NR_FREE_PAGES) |
288 | + global_page_state(NR_INACTIVE) | 294 | + global_page_state(NR_INACTIVE) |
289 | + global_page_state(NR_ACTIVE); | 295 | + global_page_state(NR_ACTIVE); |
290 | x -= highmem_dirtyable_memory(x); | 296 | |
297 | if (!vm_highmem_is_dirtyable) | ||
298 | x -= highmem_dirtyable_memory(x); | ||
299 | |||
291 | return x + 1; /* Ensure that we never return 0 */ | 300 | return x + 1; /* Ensure that we never return 0 */ |
292 | } | 301 | } |
293 | 302 | ||