aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c85
1 files changed, 47 insertions, 38 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 84b12624ceb0..2f2415a7a688 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -42,6 +42,7 @@
42#include <linux/memory.h> 42#include <linux/memory.h>
43#include <linux/printk.h> 43#include <linux/printk.h>
44#include <linux/userfaultfd_k.h> 44#include <linux/userfaultfd_k.h>
45#include <linux/moduleparam.h>
45 46
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47#include <asm/cacheflush.h> 48#include <asm/cacheflush.h>
@@ -69,6 +70,8 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX;
69int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; 70int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS;
70#endif 71#endif
71 72
73static bool ignore_rlimit_data = true;
74core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);
72 75
73static void unmap_region(struct mm_struct *mm, 76static void unmap_region(struct mm_struct *mm,
74 struct vm_area_struct *vma, struct vm_area_struct *prev, 77 struct vm_area_struct *vma, struct vm_area_struct *prev,
@@ -387,8 +390,9 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)
387} 390}
388 391
389#ifdef CONFIG_DEBUG_VM_RB 392#ifdef CONFIG_DEBUG_VM_RB
390static int browse_rb(struct rb_root *root) 393static int browse_rb(struct mm_struct *mm)
391{ 394{
395 struct rb_root *root = &mm->mm_rb;
392 int i = 0, j, bug = 0; 396 int i = 0, j, bug = 0;
393 struct rb_node *nd, *pn = NULL; 397 struct rb_node *nd, *pn = NULL;
394 unsigned long prev = 0, pend = 0; 398 unsigned long prev = 0, pend = 0;
@@ -411,12 +415,14 @@ static int browse_rb(struct rb_root *root)
411 vma->vm_start, vma->vm_end); 415 vma->vm_start, vma->vm_end);
412 bug = 1; 416 bug = 1;
413 } 417 }
418 spin_lock(&mm->page_table_lock);
414 if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) { 419 if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
415 pr_emerg("free gap %lx, correct %lx\n", 420 pr_emerg("free gap %lx, correct %lx\n",
416 vma->rb_subtree_gap, 421 vma->rb_subtree_gap,
417 vma_compute_subtree_gap(vma)); 422 vma_compute_subtree_gap(vma));
418 bug = 1; 423 bug = 1;
419 } 424 }
425 spin_unlock(&mm->page_table_lock);
420 i++; 426 i++;
421 pn = nd; 427 pn = nd;
422 prev = vma->vm_start; 428 prev = vma->vm_start;
@@ -453,12 +459,16 @@ static void validate_mm(struct mm_struct *mm)
453 struct vm_area_struct *vma = mm->mmap; 459 struct vm_area_struct *vma = mm->mmap;
454 460
455 while (vma) { 461 while (vma) {
462 struct anon_vma *anon_vma = vma->anon_vma;
456 struct anon_vma_chain *avc; 463 struct anon_vma_chain *avc;
457 464
458 vma_lock_anon_vma(vma); 465 if (anon_vma) {
459 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) 466 anon_vma_lock_read(anon_vma);
460 anon_vma_interval_tree_verify(avc); 467 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
461 vma_unlock_anon_vma(vma); 468 anon_vma_interval_tree_verify(avc);
469 anon_vma_unlock_read(anon_vma);
470 }
471
462 highest_address = vma->vm_end; 472 highest_address = vma->vm_end;
463 vma = vma->vm_next; 473 vma = vma->vm_next;
464 i++; 474 i++;
@@ -472,7 +482,7 @@ static void validate_mm(struct mm_struct *mm)
472 mm->highest_vm_end, highest_address); 482 mm->highest_vm_end, highest_address);
473 bug = 1; 483 bug = 1;
474 } 484 }
475 i = browse_rb(&mm->mm_rb); 485 i = browse_rb(mm);
476 if (i != mm->map_count) { 486 if (i != mm->map_count) {
477 if (i != -1) 487 if (i != -1)
478 pr_emerg("map_count %d rb %d\n", mm->map_count, i); 488 pr_emerg("map_count %d rb %d\n", mm->map_count, i);
@@ -2139,32 +2149,27 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
2139int expand_upwards(struct vm_area_struct *vma, unsigned long address) 2149int expand_upwards(struct vm_area_struct *vma, unsigned long address)
2140{ 2150{
2141 struct mm_struct *mm = vma->vm_mm; 2151 struct mm_struct *mm = vma->vm_mm;
2142 int error; 2152 int error = 0;
2143 2153
2144 if (!(vma->vm_flags & VM_GROWSUP)) 2154 if (!(vma->vm_flags & VM_GROWSUP))
2145 return -EFAULT; 2155 return -EFAULT;
2146 2156
2147 /* 2157 /* Guard against wrapping around to address 0. */
2148 * We must make sure the anon_vma is allocated 2158 if (address < PAGE_ALIGN(address+4))
2149 * so that the anon_vma locking is not a noop. 2159 address = PAGE_ALIGN(address+4);
2150 */ 2160 else
2161 return -ENOMEM;
2162
2163 /* We must make sure the anon_vma is allocated. */
2151 if (unlikely(anon_vma_prepare(vma))) 2164 if (unlikely(anon_vma_prepare(vma)))
2152 return -ENOMEM; 2165 return -ENOMEM;
2153 vma_lock_anon_vma(vma);
2154 2166
2155 /* 2167 /*
2156 * vma->vm_start/vm_end cannot change under us because the caller 2168 * vma->vm_start/vm_end cannot change under us because the caller
2157 * is required to hold the mmap_sem in read mode. We need the 2169 * is required to hold the mmap_sem in read mode. We need the
2158 * anon_vma lock to serialize against concurrent expand_stacks. 2170 * anon_vma lock to serialize against concurrent expand_stacks.
2159 * Also guard against wrapping around to address 0.
2160 */ 2171 */
2161 if (address < PAGE_ALIGN(address+4)) 2172 anon_vma_lock_write(vma->anon_vma);
2162 address = PAGE_ALIGN(address+4);
2163 else {
2164 vma_unlock_anon_vma(vma);
2165 return -ENOMEM;
2166 }
2167 error = 0;
2168 2173
2169 /* Somebody else might have raced and expanded it already */ 2174 /* Somebody else might have raced and expanded it already */
2170 if (address > vma->vm_end) { 2175 if (address > vma->vm_end) {
@@ -2182,7 +2187,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
2182 * updates, but we only hold a shared mmap_sem 2187 * updates, but we only hold a shared mmap_sem
2183 * lock here, so we need to protect against 2188 * lock here, so we need to protect against
2184 * concurrent vma expansions. 2189 * concurrent vma expansions.
2185 * vma_lock_anon_vma() doesn't help here, as 2190 * anon_vma_lock_write() doesn't help here, as
2186 * we don't guarantee that all growable vmas 2191 * we don't guarantee that all growable vmas
2187 * in a mm share the same root anon vma. 2192 * in a mm share the same root anon vma.
2188 * So, we reuse mm->page_table_lock to guard 2193 * So, we reuse mm->page_table_lock to guard
@@ -2205,7 +2210,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
2205 } 2210 }
2206 } 2211 }
2207 } 2212 }
2208 vma_unlock_anon_vma(vma); 2213 anon_vma_unlock_write(vma->anon_vma);
2209 khugepaged_enter_vma_merge(vma, vma->vm_flags); 2214 khugepaged_enter_vma_merge(vma, vma->vm_flags);
2210 validate_mm(mm); 2215 validate_mm(mm);
2211 return error; 2216 return error;
@@ -2221,25 +2226,21 @@ int expand_downwards(struct vm_area_struct *vma,
2221 struct mm_struct *mm = vma->vm_mm; 2226 struct mm_struct *mm = vma->vm_mm;
2222 int error; 2227 int error;
2223 2228
2224 /*
2225 * We must make sure the anon_vma is allocated
2226 * so that the anon_vma locking is not a noop.
2227 */
2228 if (unlikely(anon_vma_prepare(vma)))
2229 return -ENOMEM;
2230
2231 address &= PAGE_MASK; 2229 address &= PAGE_MASK;
2232 error = security_mmap_addr(address); 2230 error = security_mmap_addr(address);
2233 if (error) 2231 if (error)
2234 return error; 2232 return error;
2235 2233
2236 vma_lock_anon_vma(vma); 2234 /* We must make sure the anon_vma is allocated. */
2235 if (unlikely(anon_vma_prepare(vma)))
2236 return -ENOMEM;
2237 2237
2238 /* 2238 /*
2239 * vma->vm_start/vm_end cannot change under us because the caller 2239 * vma->vm_start/vm_end cannot change under us because the caller
2240 * is required to hold the mmap_sem in read mode. We need the 2240 * is required to hold the mmap_sem in read mode. We need the
2241 * anon_vma lock to serialize against concurrent expand_stacks. 2241 * anon_vma lock to serialize against concurrent expand_stacks.
2242 */ 2242 */
2243 anon_vma_lock_write(vma->anon_vma);
2243 2244
2244 /* Somebody else might have raced and expanded it already */ 2245 /* Somebody else might have raced and expanded it already */
2245 if (address < vma->vm_start) { 2246 if (address < vma->vm_start) {
@@ -2257,7 +2258,7 @@ int expand_downwards(struct vm_area_struct *vma,
2257 * updates, but we only hold a shared mmap_sem 2258 * updates, but we only hold a shared mmap_sem
2258 * lock here, so we need to protect against 2259 * lock here, so we need to protect against
2259 * concurrent vma expansions. 2260 * concurrent vma expansions.
2260 * vma_lock_anon_vma() doesn't help here, as 2261 * anon_vma_lock_write() doesn't help here, as
2261 * we don't guarantee that all growable vmas 2262 * we don't guarantee that all growable vmas
2262 * in a mm share the same root anon vma. 2263 * in a mm share the same root anon vma.
2263 * So, we reuse mm->page_table_lock to guard 2264 * So, we reuse mm->page_table_lock to guard
@@ -2278,7 +2279,7 @@ int expand_downwards(struct vm_area_struct *vma,
2278 } 2279 }
2279 } 2280 }
2280 } 2281 }
2281 vma_unlock_anon_vma(vma); 2282 anon_vma_unlock_write(vma->anon_vma);
2282 khugepaged_enter_vma_merge(vma, vma->vm_flags); 2283 khugepaged_enter_vma_merge(vma, vma->vm_flags);
2283 validate_mm(mm); 2284 validate_mm(mm);
2284 return error; 2285 return error;
@@ -2982,9 +2983,17 @@ bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages)
2982 if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT) 2983 if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT)
2983 return false; 2984 return false;
2984 2985
2985 if ((flags & (VM_WRITE | VM_SHARED | (VM_STACK_FLAGS & 2986 if (is_data_mapping(flags) &&
2986 (VM_GROWSUP | VM_GROWSDOWN)))) == VM_WRITE) 2987 mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) {
2987 return mm->data_vm + npages <= rlimit(RLIMIT_DATA); 2988 if (ignore_rlimit_data)
2989 pr_warn_once("%s (%d): VmData %lu exceed data ulimit "
2990 "%lu. Will be forbidden soon.\n",
2991 current->comm, current->pid,
2992 (mm->data_vm + npages) << PAGE_SHIFT,
2993 rlimit(RLIMIT_DATA));
2994 else
2995 return false;
2996 }
2988 2997
2989 return true; 2998 return true;
2990} 2999}
@@ -2993,11 +3002,11 @@ void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, long npages)
2993{ 3002{
2994 mm->total_vm += npages; 3003 mm->total_vm += npages;
2995 3004
2996 if ((flags & (VM_EXEC | VM_WRITE)) == VM_EXEC) 3005 if (is_exec_mapping(flags))
2997 mm->exec_vm += npages; 3006 mm->exec_vm += npages;
2998 else if (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) 3007 else if (is_stack_mapping(flags))
2999 mm->stack_vm += npages; 3008 mm->stack_vm += npages;
3000 else if ((flags & (VM_WRITE | VM_SHARED)) == VM_WRITE) 3009 else if (is_data_mapping(flags))
3001 mm->data_vm += npages; 3010 mm->data_vm += npages;
3002} 3011}
3003 3012