Commit 80119ef5c8153e0a6cc5edf00c083dc98a9bd348

Authored by Alan Cox
Committed by Linus Torvalds
1 parent 6c7c6afbb8

mm: fix atomic_t overflow in vm

The atomic_t type is 32bit but a 64bit system can have more than 2^32
pages of virtual address space available.  Without this we overflow on
ludicrously large mappings

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

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

... ... @@ -139,7 +139,7 @@
139 139 #define K(x) ((x) << (PAGE_SHIFT - 10))
140 140 si_meminfo(&i);
141 141 si_swapinfo(&i);
142   - committed = atomic_read(&vm_committed_space);
  142 + committed = atomic_long_read(&vm_committed_space);
143 143 allowed = ((totalram_pages - hugetlb_total_pages())
144 144 * sysctl_overcommit_ratio / 100) + total_swap_pages;
145 145  
include/linux/mman.h
... ... @@ -17,14 +17,14 @@
17 17  
18 18 extern int sysctl_overcommit_memory;
19 19 extern int sysctl_overcommit_ratio;
20   -extern atomic_t vm_committed_space;
  20 +extern atomic_long_t vm_committed_space;
21 21  
22 22 #ifdef CONFIG_SMP
23 23 extern void vm_acct_memory(long pages);
24 24 #else
25 25 static inline void vm_acct_memory(long pages)
26 26 {
27   - atomic_add(pages, &vm_committed_space);
  27 + atomic_long_add(pages, &vm_committed_space);
28 28 }
29 29 #endif
30 30  
... ... @@ -80,7 +80,7 @@
80 80 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
81 81 int sysctl_overcommit_ratio = 50; /* default is 50% */
82 82 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
83   -atomic_t vm_committed_space = ATOMIC_INIT(0);
  83 +atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0);
84 84  
85 85 /*
86 86 * Check that a process has enough memory to allocate a new virtual
... ... @@ -177,7 +177,7 @@
177 177 * cast `allowed' as a signed long because vm_committed_space
178 178 * sometimes has a negative value
179 179 */
180   - if (atomic_read(&vm_committed_space) < (long)allowed)
  180 + if (atomic_long_read(&vm_committed_space) < (long)allowed)
181 181 return 0;
182 182 error:
183 183 vm_unacct_memory(pages);
... ... @@ -39,7 +39,7 @@
39 39 unsigned long max_mapnr;
40 40 unsigned long num_physpages;
41 41 unsigned long askedalloc, realalloc;
42   -atomic_t vm_committed_space = ATOMIC_INIT(0);
  42 +atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0);
43 43 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
44 44 int sysctl_overcommit_ratio = 50; /* default is 50% */
45 45 int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
... ... @@ -1410,7 +1410,7 @@
1410 1410 * cast `allowed' as a signed long because vm_committed_space
1411 1411 * sometimes has a negative value
1412 1412 */
1413   - if (atomic_read(&vm_committed_space) < (long)allowed)
  1413 + if (atomic_long_read(&vm_committed_space) < (long)allowed)
1414 1414 return 0;
1415 1415 error:
1416 1416 vm_unacct_memory(pages);
... ... @@ -503,7 +503,7 @@
503 503 local = &__get_cpu_var(committed_space);
504 504 *local += pages;
505 505 if (*local > ACCT_THRESHOLD || *local < -ACCT_THRESHOLD) {
506   - atomic_add(*local, &vm_committed_space);
  506 + atomic_long_add(*local, &vm_committed_space);
507 507 *local = 0;
508 508 }
509 509 preempt_enable();
... ... @@ -520,7 +520,7 @@
520 520  
521 521 committed = &per_cpu(committed_space, (long)hcpu);
522 522 if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
523   - atomic_add(*committed, &vm_committed_space);
  523 + atomic_long_add(*committed, &vm_committed_space);
524 524 *committed = 0;
525 525 drain_cpu_pagevecs((long)hcpu);
526 526 }