Commit 195cf453d2c3d789cbe80e3735755f860c2fb222

Authored by Bron Gondwana
Committed by Linus Torvalds
1 parent 3dfa5721f1

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>

Showing 5 changed files with 47 additions and 5 deletions Side-by-side Diff

Documentation/filesystems/proc.txt
... ... @@ -1315,6 +1315,21 @@
1315 1315 Data which has been dirty in-memory for longer than this interval will be
1316 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 1333 legacy_va_layout
1319 1334 ----------------
1320 1335  
Documentation/sysctl/vm.txt
... ... @@ -22,6 +22,7 @@
22 22 - dirty_background_ratio
23 23 - dirty_expire_centisecs
24 24 - dirty_writeback_centisecs
  25 +- highmem_is_dirtyable (only if CONFIG_HIGHMEM set)
25 26 - max_map_count
26 27 - min_free_kbytes
27 28 - laptop_mode
... ... @@ -40,9 +41,9 @@
40 41 ==============================================================
41 42  
42 43 dirty_ratio, dirty_background_ratio, dirty_expire_centisecs,
43   -dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode,
44   -block_dump, swap_token_timeout, drop-caches,
45   -hugepages_treat_as_movable:
  44 +dirty_writeback_centisecs, highmem_is_dirtyable,
  45 +vfs_cache_pressure, laptop_mode, block_dump, swap_token_timeout,
  46 +drop-caches, hugepages_treat_as_movable:
46 47  
47 48 See Documentation/filesystems/proc.txt
48 49  
include/linux/writeback.h
... ... @@ -100,6 +100,7 @@
100 100 extern int vm_dirty_ratio;
101 101 extern int dirty_writeback_interval;
102 102 extern int dirty_expire_interval;
  103 +extern int vm_highmem_is_dirtyable;
103 104 extern int block_dump;
104 105 extern int laptop_mode;
105 106  
... ... @@ -84,8 +84,11 @@
84 84 extern int latencytop_enabled;
85 85  
86 86 /* Constants used for minimum and maximum */
87   -#ifdef CONFIG_DETECT_SOFTLOCKUP
  87 +#if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM)
88 88 static int one = 1;
  89 +#endif
  90 +
  91 +#ifdef CONFIG_DETECT_SOFTLOCKUP
89 92 static int sixty = 60;
90 93 #endif
91 94  
... ... @@ -1148,6 +1151,19 @@
1148 1151 .proc_handler = &proc_dointvec,
1149 1152 .strategy = &sysctl_intvec,
1150 1153 .extra1 = &zero,
  1154 + },
  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,
1151 1167 },
1152 1168 #endif
1153 1169 /*
... ... @@ -69,6 +69,12 @@
69 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 78 * The generator of dirty data starts writeback at this percentage
73 79 */
74 80 int vm_dirty_ratio = 10;
... ... @@ -287,7 +293,10 @@
287 293 x = global_page_state(NR_FREE_PAGES)
288 294 + global_page_state(NR_INACTIVE)
289 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 300 return x + 1; /* Ensure that we never return 0 */
292 301 }
293 302