aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 081e6da8e1a4..80a965f35251 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -84,6 +84,7 @@ EXPORT_SYMBOL(vm_get_page_prot);
84int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic overcommit */ 84int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic overcommit */
85int sysctl_overcommit_ratio __read_mostly = 50; /* default is 50% */ 85int sysctl_overcommit_ratio __read_mostly = 50; /* default is 50% */
86int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; 86int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
87unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
87/* 88/*
88 * Make sure vm_committed_as in one cacheline and not cacheline shared with 89 * Make sure vm_committed_as in one cacheline and not cacheline shared with
89 * other variables. It can be updated by several CPUs frequently. 90 * other variables. It can be updated by several CPUs frequently.
@@ -122,7 +123,7 @@ EXPORT_SYMBOL_GPL(vm_memory_committed);
122 */ 123 */
123int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) 124int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
124{ 125{
125 unsigned long free, allowed; 126 unsigned long free, allowed, reserve;
126 127
127 vm_acct_memory(pages); 128 vm_acct_memory(pages);
128 129
@@ -183,10 +184,13 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
183 allowed -= allowed / 32; 184 allowed -= allowed / 32;
184 allowed += total_swap_pages; 185 allowed += total_swap_pages;
185 186
186 /* Don't let a single process grow too big: 187 /*
187 leave 3% of the size of this process for other processes */ 188 * Don't let a single process grow so big a user can't recover
188 if (mm) 189 */
189 allowed -= mm->total_vm / 32; 190 if (mm) {
191 reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10);
192 allowed -= min(mm->total_vm / 32, reserve);
193 }
190 194
191 if (percpu_counter_read_positive(&vm_committed_as) < allowed) 195 if (percpu_counter_read_positive(&vm_committed_as) < allowed)
192 return 0; 196 return 0;
@@ -3094,3 +3098,24 @@ void __init mmap_init(void)
3094 ret = percpu_counter_init(&vm_committed_as, 0); 3098 ret = percpu_counter_init(&vm_committed_as, 0);
3095 VM_BUG_ON(ret); 3099 VM_BUG_ON(ret);
3096} 3100}
3101
3102/*
3103 * Initialise sysctl_user_reserve_kbytes.
3104 *
3105 * This is intended to prevent a user from starting a single memory hogging
3106 * process, such that they cannot recover (kill the hog) in OVERCOMMIT_NEVER
3107 * mode.
3108 *
3109 * The default value is min(3% of free memory, 128MB)
3110 * 128MB is enough to recover with sshd/login, bash, and top/kill.
3111 */
3112static int __meminit init_user_reserve(void)
3113{
3114 unsigned long free_kbytes;
3115
3116 free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10);
3117
3118 sysctl_user_reserve_kbytes = min(free_kbytes / 32, 1UL << 17);
3119 return 0;
3120}
3121module_init(init_user_reserve)