diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
-rw-r--r-- | mm/internal.h | 16 | ||||
-rw-r--r-- | mm/mmap.c | 23 |
3 files changed, 38 insertions, 6 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 87d40a72f6a1..551ecf09c8dd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1496,6 +1496,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1496 | could change it dynamically, usually by | 1496 | could change it dynamically, usually by |
1497 | /sys/module/printk/parameters/ignore_loglevel. | 1497 | /sys/module/printk/parameters/ignore_loglevel. |
1498 | 1498 | ||
1499 | ignore_rlimit_data | ||
1500 | Ignore RLIMIT_DATA setting for data mappings, | ||
1501 | print warning at first misuse. Can be changed via | ||
1502 | /sys/module/kernel/parameters/ignore_rlimit_data. | ||
1503 | |||
1499 | ihash_entries= [KNL] | 1504 | ihash_entries= [KNL] |
1500 | Set number of hash buckets for inode cache. | 1505 | Set number of hash buckets for inode cache. |
1501 | 1506 | ||
diff --git a/mm/internal.h b/mm/internal.h index ed8b5ffcf9b1..6e976302ddd8 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -216,6 +216,22 @@ static inline bool is_cow_mapping(vm_flags_t flags) | |||
216 | return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; | 216 | return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; |
217 | } | 217 | } |
218 | 218 | ||
219 | static inline bool is_exec_mapping(vm_flags_t flags) | ||
220 | { | ||
221 | return (flags & (VM_EXEC | VM_WRITE)) == VM_EXEC; | ||
222 | } | ||
223 | |||
224 | static inline bool is_stack_mapping(vm_flags_t flags) | ||
225 | { | ||
226 | return (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) != 0; | ||
227 | } | ||
228 | |||
229 | static inline bool is_data_mapping(vm_flags_t flags) | ||
230 | { | ||
231 | return (flags & ((VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN)) | | ||
232 | VM_WRITE | VM_SHARED)) == VM_WRITE; | ||
233 | } | ||
234 | |||
219 | /* mm/util.c */ | 235 | /* mm/util.c */ |
220 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, | 236 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, |
221 | struct vm_area_struct *prev, struct rb_node *rb_parent); | 237 | struct vm_area_struct *prev, struct rb_node *rb_parent); |
@@ -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; | |||
69 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; | 70 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; |
70 | #endif | 71 | #endif |
71 | 72 | ||
73 | static bool ignore_rlimit_data = true; | ||
74 | core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); | ||
72 | 75 | ||
73 | static void unmap_region(struct mm_struct *mm, | 76 | static 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, |
@@ -2982,9 +2985,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) | 2985 | if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT) |
2983 | return false; | 2986 | return false; |
2984 | 2987 | ||
2985 | if ((flags & (VM_WRITE | VM_SHARED | (VM_STACK_FLAGS & | 2988 | if (is_data_mapping(flags) && |
2986 | (VM_GROWSUP | VM_GROWSDOWN)))) == VM_WRITE) | 2989 | mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) { |
2987 | return mm->data_vm + npages <= rlimit(RLIMIT_DATA); | 2990 | if (ignore_rlimit_data) |
2991 | pr_warn_once("%s (%d): VmData %lu exceed data ulimit " | ||
2992 | "%lu. Will be forbidden soon.\n", | ||
2993 | current->comm, current->pid, | ||
2994 | (mm->data_vm + npages) << PAGE_SHIFT, | ||
2995 | rlimit(RLIMIT_DATA)); | ||
2996 | else | ||
2997 | return false; | ||
2998 | } | ||
2988 | 2999 | ||
2989 | return true; | 3000 | return true; |
2990 | } | 3001 | } |
@@ -2993,11 +3004,11 @@ void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, long npages) | |||
2993 | { | 3004 | { |
2994 | mm->total_vm += npages; | 3005 | mm->total_vm += npages; |
2995 | 3006 | ||
2996 | if ((flags & (VM_EXEC | VM_WRITE)) == VM_EXEC) | 3007 | if (is_exec_mapping(flags)) |
2997 | mm->exec_vm += npages; | 3008 | mm->exec_vm += npages; |
2998 | else if (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) | 3009 | else if (is_stack_mapping(flags)) |
2999 | mm->stack_vm += npages; | 3010 | mm->stack_vm += npages; |
3000 | else if ((flags & (VM_WRITE | VM_SHARED)) == VM_WRITE) | 3011 | else if (is_data_mapping(flags)) |
3001 | mm->data_vm += npages; | 3012 | mm->data_vm += npages; |
3002 | } | 3013 | } |
3003 | 3014 | ||