mm: Fix atomic_t overflow in vm
Subsystems (3)
PATCH 1/1 mm: Fix atomic_t overflow in vm
From: Alan Cox <[email protected]>
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
---
fs/proc/proc_misc.c | 2 +- include/linux/mman.h | 4 ++-- mm/mmap.c | 4 ++-- mm/nommu.c | 4 ++-- mm/swap.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-)
fs/proc/proc_misc.c +1 -1
@@ -139,7 +139,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,#define K (x) ((x) << (PAGE_SHIFT - 10))si_meminfo (&i);si_swapinfo (&i); - committed =atomic_read (&vm_committed_space); + committed =atomic_long_read (&vm_committed_space); allowed = ((totalram_pages -hugetlb_total_pages ()) * sysctl_overcommit_ratio /100 ) + total_swap_pages;
include/linux/mman.h +2 -2
@@ -17,14 +17,14 @@extern int sysctl_overcommit_memory;extern int sysctl_overcommit_ratio; -extern atomic_t vm_committed_space; +extern atomic_long_t vm_committed_space;#ifdef CONFIG_SMP extern void vm_acct_memory (long pages);#else static inline void vm_acct_memory (long pages) { -atomic_add (pages, &vm_committed_space); +atomic_long_add (pages, &vm_committed_space); }#endif
mm/mmap.c +2 -2
@@ -80,7 +80,7 @@ EXPORT_SYMBOL(vm_get_page_prot);int sysctl_overcommit_memory =OVERCOMMIT_GUESS ;/* heuristic overcommit */ int sysctl_overcommit_ratio =50 ;/* default is 50% */ int sysctl_max_map_count__read_mostly =DEFAULT_MAX_MAP_COUNT ; -atomic_t vm_committed_space =ATOMIC_INIT (0 ); +atomic_long_t vm_committed_space =ATOMIC_LONG_INIT (0 );/* * Check that a process has enough memory to allocate a new virtual
@@ -177,7 +177,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)* cast `allowed' as a signed long because vm_committed_space * sometimes has a negative value */ -if (atomic_read (&vm_committed_space) < (long )allowed) +if (atomic_long_read (&vm_committed_space) < (long )allowed)return 0 ; error:vm_unacct_memory (pages);
mm/nommu.c +2 -2
@@ -39,7 +39,7 @@ struct page *mem_map;unsigned long max_mapnr;unsigned long num_physpages;unsigned long askedalloc, realalloc; -atomic_t vm_committed_space =ATOMIC_INIT (0 ); +atomic_long_t vm_committed_space =ATOMIC_LONG_INIT (0 );int sysctl_overcommit_memory =OVERCOMMIT_GUESS ;/* heuristic overcommit */ int sysctl_overcommit_ratio =50 ;/* default is 50% */ int sysctl_max_map_count =DEFAULT_MAX_MAP_COUNT ;
@@ -1410,7 +1410,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)* cast `allowed' as a signed long because vm_committed_space * sometimes has a negative value */ -if (atomic_read (&vm_committed_space) < (long )allowed) +if (atomic_long_read (&vm_committed_space) < (long )allowed)return 0 ; error:vm_unacct_memory (pages);
mm/swap.c +2 -2
@@ -503,7 +503,7 @@ void vm_acct_memory(long pages) local = &__get_cpu_var (committed_space); *local += pages;if (*local >ACCT_THRESHOLD || *local < -ACCT_THRESHOLD ) { -atomic_add (*local, &vm_committed_space); +atomic_long_add (*local, &vm_committed_space); *local =0 ; }preempt_enable ();
@@ -520,7 +520,7 @@ static int cpu_swap_callback(struct notifier_block *nfb, committed = &per_cpu (committed_space, (long )hcpu);if (action ==CPU_DEAD || action ==CPU_DEAD_FROZEN ) { -atomic_add (*committed, &vm_committed_space); +atomic_long_add (*committed, &vm_committed_space); *committed =0 ;drain_cpu_pagevecs ((long )hcpu); }
Quoted 6 lines · On Wed, 14 May 2008 22:33:03 +0100 Alan Cox <[email protected]> wrote:
From: Alan Cox <[email protected]>
The
atomic_ttype 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
---
Umm need to adjust the template: Add
Signed-off-by Alan Cox <[email protected]>