summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/mm.h2
-rw-r--r--mm/internal.h6
-rw-r--r--mm/mmap.c2
-rw-r--r--mm/mremap.c4
-rw-r--r--mm/nommu.c2
-rw-r--r--mm/vma.c6
-rw-r--r--tools/testing/vma/include/custom.h3
-rw-r--r--tools/testing/vma/include/dup.h9
-rw-r--r--tools/testing/vma/main.c2
9 files changed, 24 insertions, 12 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index efb8be5d259c..25ba5816e02b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -207,8 +207,6 @@ static inline void __mm_zero_struct_page(struct page *page)
#define MAPCOUNT_ELF_CORE_MARGIN (5)
#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
-extern int sysctl_max_map_count;
-
extern unsigned long sysctl_user_reserve_kbytes;
extern unsigned long sysctl_admin_reserve_kbytes;
diff --git a/mm/internal.h b/mm/internal.h
index f50a0376b87e..62d80fd37ae1 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1863,4 +1863,10 @@ static inline int pmdp_test_and_clear_young_notify(struct vm_area_struct *vma,
#endif /* CONFIG_MMU_NOTIFIER */
+extern int sysctl_max_map_count;
+static inline int get_sysctl_max_map_count(void)
+{
+ return READ_ONCE(sysctl_max_map_count);
+}
+
#endif /* __MM_INTERNAL_H */
diff --git a/mm/mmap.c b/mm/mmap.c
index 843160946aa5..79544d893411 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -375,7 +375,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
return -EOVERFLOW;
/* Too many mappings? */
- if (mm->map_count > sysctl_max_map_count)
+ if (mm->map_count > get_sysctl_max_map_count())
return -ENOMEM;
/*
diff --git a/mm/mremap.c b/mm/mremap.c
index e8c3021dd841..ba6c690f6c1b 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -1045,7 +1045,7 @@ static unsigned long prep_move_vma(struct vma_remap_struct *vrm)
* which may not merge, then (if MREMAP_DONTUNMAP is not set) unmap the
* source, which may split, causing a net increase of 2 mappings.
*/
- if (current->mm->map_count + 2 > sysctl_max_map_count)
+ if (current->mm->map_count + 2 > get_sysctl_max_map_count())
return -ENOMEM;
if (vma->vm_ops && vma->vm_ops->may_split) {
@@ -1813,7 +1813,7 @@ static unsigned long check_mremap_params(struct vma_remap_struct *vrm)
* net increased map count of 2. In move_vma() we check for headroom of
* 2 additional mappings, so check early to avoid bailing out then.
*/
- if (current->mm->map_count + 4 > sysctl_max_map_count)
+ if (current->mm->map_count + 4 > get_sysctl_max_map_count())
return -ENOMEM;
return 0;
diff --git a/mm/nommu.c b/mm/nommu.c
index c3a23b082adb..ed3934bc2de4 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1317,7 +1317,7 @@ static int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
return -ENOMEM;
mm = vma->vm_mm;
- if (mm->map_count >= sysctl_max_map_count)
+ if (mm->map_count >= get_sysctl_max_map_count())
return -ENOMEM;
region = kmem_cache_alloc(vm_region_jar, GFP_KERNEL);
diff --git a/mm/vma.c b/mm/vma.c
index b7055c264b5d..4d21e7d8e93c 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -590,7 +590,7 @@ out_free_vma:
static int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
unsigned long addr, int new_below)
{
- if (vma->vm_mm->map_count >= sysctl_max_map_count)
+ if (vma->vm_mm->map_count >= get_sysctl_max_map_count())
return -ENOMEM;
return __split_vma(vmi, vma, addr, new_below);
@@ -1394,7 +1394,7 @@ static int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
* its limit temporarily, to help free resources as expected.
*/
if (vms->end < vms->vma->vm_end &&
- vms->vma->vm_mm->map_count >= sysctl_max_map_count) {
+ vms->vma->vm_mm->map_count >= get_sysctl_max_map_count()) {
error = -ENOMEM;
goto map_count_exceeded;
}
@@ -2868,7 +2868,7 @@ int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma,
if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT))
return -ENOMEM;
- if (mm->map_count > sysctl_max_map_count)
+ if (mm->map_count > get_sysctl_max_map_count())
return -ENOMEM;
if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT))
diff --git a/tools/testing/vma/include/custom.h b/tools/testing/vma/include/custom.h
index 7150e09122b2..6c62a38a2f6f 100644
--- a/tools/testing/vma/include/custom.h
+++ b/tools/testing/vma/include/custom.h
@@ -21,9 +21,6 @@ extern unsigned long dac_mmap_min_addr;
#define VM_BUG_ON(_expr) (BUG_ON(_expr))
#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr))
-/* We hardcode this for now. */
-#define sysctl_max_map_count 0x1000000UL
-
#define TASK_SIZE ((1ul << 47)-PAGE_SIZE)
/*
diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
index 5eb313beb43d..8865ffe046d8 100644
--- a/tools/testing/vma/include/dup.h
+++ b/tools/testing/vma/include/dup.h
@@ -419,6 +419,9 @@ struct vma_iterator {
#define EMPTY_VMA_FLAGS ((vma_flags_t){ })
+#define MAPCOUNT_ELF_CORE_MARGIN (5)
+#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
+
/* What action should be taken after an .mmap_prepare call is complete? */
enum mmap_action_type {
MMAP_NOTHING, /* Mapping is complete, no further action. */
@@ -1342,3 +1345,9 @@ static inline void vma_set_file(struct vm_area_struct *vma, struct file *file)
swap(vma->vm_file, file);
fput(file);
}
+
+extern int sysctl_max_map_count;
+static inline int get_sysctl_max_map_count(void)
+{
+ return READ_ONCE(sysctl_max_map_count);
+}
diff --git a/tools/testing/vma/main.c b/tools/testing/vma/main.c
index 49b09e97a51f..18338f5d29e0 100644
--- a/tools/testing/vma/main.c
+++ b/tools/testing/vma/main.c
@@ -14,6 +14,8 @@
#include "tests/mmap.c"
#include "tests/vma.c"
+int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
+
/* Helper functions which utilise static kernel functions. */
struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg)