]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Replace MAX_MAP_COUNT with /proc/sys/vm/max_map_count
authorAndrew Morton <akpm@osdl.org>
Thu, 1 Apr 2004 05:51:54 +0000 (21:51 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 1 Apr 2004 05:51:54 +0000 (21:51 -0800)
From: David Mosberger <davidm@napali.hpl.hp.com>

Below is a warmed up version of a patch originally done by Werner Almesberger
(see http://tinyurl.com/25zra) to replace the MAX_MAP_COUNT limit with a
sysctl variable.  I thought this had gone into the tree a long time ago but
alas it has not and as luck would have it, the hard limit bit someone today
once again with a large app on a large machine.

Here is a small test app:

Documentation/sysctl/vm.txt
include/linux/sched.h
include/linux/sysctl.h
kernel/sysctl.c
mm/mmap.c

index 05f627955391ae76ce069690280ab5047e95676b..fc3e413c37210f74d314bf71b93deb638a0dcc25 100644 (file)
@@ -22,6 +22,7 @@ Currently, these files are in /proc/sys/vm:
 - dirty_background_ratio
 - dirty_expire_centisecs
 - dirty_writeback_centisecs
+- max_map_count
 - min_free_kbytes
 
 ==============================================================
@@ -77,6 +78,21 @@ for swap because we only cluster swap data in 32-page groups.
 
 ==============================================================
 
+max_map_count:
+
+This file contains the maximum number of memory map areas a process
+may have. Memory map areas are used as a side-effect of calling
+malloc, directly by mmap and mprotect, and also when loading shared
+libraries.
+
+While most applications need less than a thousand maps, certain
+programs, particularly malloc debuggers, may consume lots of them,
+e.g., up to one or two maps per allocation.
+
+The default value is 65536.
+
+==============================================================
+
 min_free_kbytes:
 
 This is used to force the Linux VM to keep a minimum number 
index eb5bc2f127885c4b4d8e9077a7ccd468bacc8683..f5fa0c07a7f84cb46b51024f65857128083b0467 100644 (file)
@@ -179,7 +179,9 @@ asmlinkage void schedule(void);
 struct namespace;
 
 /* Maximum number of active map areas.. This is a random (large) number */
-#define MAX_MAP_COUNT  (65536)
+#define DEFAULT_MAX_MAP_COUNT  65536
+
+extern int sysctl_max_map_count;
 
 #include <linux/aio.h>
 
index dbd57168ac61c7cb2b0cc24b0fcebf87128e74fc..3767428df94d9268692f3b83197591aa52dd7fa3 100644 (file)
@@ -158,6 +158,7 @@ enum
        VM_SWAPPINESS=19,       /* Tendency to steal mapped memory */
        VM_LOWER_ZONE_PROTECTION=20,/* Amount of protection of lower zones */
        VM_MIN_FREE_KBYTES=21,  /* Minimum free kilobytes to maintain */
+       VM_MAX_MAP_COUNT=22,    /* int: Maximum number of mmaps/address-space */
 };
 
 
index b790c5ecf37f652ab1c5a10d572826ffd85ef918..f5f3123b05225ca3f769c1c8b90ab3de2d544042 100644 (file)
@@ -736,6 +736,14 @@ static ctl_table vm_table[] = {
                .strategy       = &sysctl_intvec,
                .extra1         = &zero,
        },
+       {
+               .ctl_name       = VM_MAX_MAP_COUNT,
+               .procname       = "max_map_count",
+               .data           = &sysctl_max_map_count,
+               .maxlen         = sizeof(sysctl_max_map_count),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
        { .ctl_name = 0 }
 };
 
index 143a27ef28a2e85eb4951b7019369cb42b3899af..000e377d4888b6711da52e636ecf95460ad4057d 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -54,10 +54,12 @@ pgprot_t protection_map[16] = {
 
 int sysctl_overcommit_memory = 0;      /* default is heuristic overcommit */
 int sysctl_overcommit_ratio = 50;      /* default is 50% */
+int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
 atomic_t vm_committed_space = ATOMIC_INIT(0);
 
 EXPORT_SYMBOL(sysctl_overcommit_memory);
 EXPORT_SYMBOL(sysctl_overcommit_ratio);
+EXPORT_SYMBOL(sysctl_max_map_count);
 EXPORT_SYMBOL(vm_committed_space);
 
 /*
@@ -516,7 +518,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                return -EINVAL;
 
        /* Too many mappings? */
-       if (mm->map_count > MAX_MAP_COUNT)
+       if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
        /* Obtain the address to map to. we verify (or select) it and ensure
@@ -1203,7 +1205,7 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
        struct vm_area_struct *new;
        struct address_space *mapping = NULL;
 
-       if (mm->map_count >= MAX_MAP_COUNT)
+       if (mm->map_count >= sysctl_max_map_count)
                return -ENOMEM;
 
        new = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
@@ -1381,7 +1383,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
            > current->rlim[RLIMIT_AS].rlim_cur)
                return -ENOMEM;
 
-       if (mm->map_count > MAX_MAP_COUNT)
+       if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
        if (security_vm_enough_memory(len >> PAGE_SHIFT))