diff options
author | Konstantin Khlebnikov <koct9i@gmail.com> | 2016-05-20 19:57:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 20:58:30 -0400 |
commit | f4fcd55841fc9e46daac553b39361572453c2b88 (patch) | |
tree | 56d0e92a579868fe7074df81b177889969a5fade /mm | |
parent | d5957d2fc232a689543bdbed1a5ff8002f0e9843 (diff) |
mm: enable RLIMIT_DATA by default with workaround for valgrind
Since commit 84638335900f ("mm: rework virtual memory accounting")
RLIMIT_DATA limits both brk() and private mmap() but this's disabled by
default because of incompatibility with older versions of valgrind.
Valgrind always set limit to zero and fails if RLIMIT_DATA is enabled.
Fortunately it changes only rlim_cur and keeps rlim_max for reverting
limit back when needed.
This patch checks current usage also against rlim_max if rlim_cur is
zero. This is safe because task anyway can increase rlim_cur up to
rlim_max. Size of brk is still checked against rlim_cur, so this part
is completely compatible - zero rlim_cur forbids brk() but allows
private mmap().
Link: http://lkml.kernel.org/r/56A28613.5070104@de.ibm.com
Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mmap.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -66,7 +66,7 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; | |||
66 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; | 66 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | static bool ignore_rlimit_data = true; | 69 | static bool ignore_rlimit_data; |
70 | core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); | 70 | core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); |
71 | 71 | ||
72 | static void unmap_region(struct mm_struct *mm, | 72 | static void unmap_region(struct mm_struct *mm, |
@@ -2886,13 +2886,17 @@ bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages) | |||
2886 | 2886 | ||
2887 | if (is_data_mapping(flags) && | 2887 | if (is_data_mapping(flags) && |
2888 | mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) { | 2888 | mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) { |
2889 | if (ignore_rlimit_data) | 2889 | /* Workaround for Valgrind */ |
2890 | pr_warn_once("%s (%d): VmData %lu exceed data ulimit %lu. Will be forbidden soon.\n", | 2890 | if (rlimit(RLIMIT_DATA) == 0 && |
2891 | mm->data_vm + npages <= rlimit_max(RLIMIT_DATA) >> PAGE_SHIFT) | ||
2892 | return true; | ||
2893 | if (!ignore_rlimit_data) { | ||
2894 | pr_warn_once("%s (%d): VmData %lu exceed data ulimit %lu. Update limits or use boot option ignore_rlimit_data.\n", | ||
2891 | current->comm, current->pid, | 2895 | current->comm, current->pid, |
2892 | (mm->data_vm + npages) << PAGE_SHIFT, | 2896 | (mm->data_vm + npages) << PAGE_SHIFT, |
2893 | rlimit(RLIMIT_DATA)); | 2897 | rlimit(RLIMIT_DATA)); |
2894 | else | ||
2895 | return false; | 2898 | return false; |
2899 | } | ||
2896 | } | 2900 | } |
2897 | 2901 | ||
2898 | return true; | 2902 | return true; |