Well, Mark Hahn mailed me and brought up the point that there might be some
security issue for having the MAX_MAP_COUNT set lower than the full address
space (Although I don't see how you can do anything with more mappings if
RLIMIT_AS is set tight). He suggested something like this might be better
suited to /proc, like vm.overcommit_memory. So I went ahead and moved it to
/proc. I've attached a patch against 2.2.17 and 2.4.0test8. The default is
back to 65536.

-- 
Mike Perry
http://so.fscked.org
diff -ur linux-2.2.17/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.2.17/include/linux/sched.h  Sun Oct  1 00:05:42 2000
+++ linux/include/linux/sched.h Sun Oct  1 18:47:12 2000
@@ -166,9 +166,6 @@
        NULL, NULL \
 }
 
-/* Maximum number of active map areas. This is the number of pages that fit in
- * the address space */
-#define MAX_MAP_COUNT   (ULONG_MAX >> PAGE_SHIFT)
 
 /* Number of map areas at which the AVL tree is activated. This is arbitrary. */
 #define AVL_MIN_MAP_COUNT      32
diff -ur linux-2.2.17/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux-2.2.17/include/linux/sysctl.h Wed Jun  7 16:26:44 2000
+++ linux/include/linux/sysctl.h        Sun Oct  1 18:50:31 2000
@@ -121,7 +121,8 @@
        VM_PAGECACHE=7,         /* struct: Set cache memory thresholds */
        VM_PAGERDAEMON=8,       /* struct: Control kswapd behaviour */
        VM_PGT_CACHE=9,         /* struct: Set page table cache parameters */
-       VM_PAGE_CLUSTER=10      /* int: set number of pages to swap together */
+       VM_PAGE_CLUSTER=10,     /* int: set number of pages to swap together */
+       VM_MAX_MAP_COUNT=11     /* int: max number mappings per process */
 };
 
 
diff -ur linux-2.2.17/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.2.17/kernel/sysctl.c        Wed Jun  7 16:26:44 2000
+++ linux/kernel/sysctl.c       Sun Oct  1 18:46:50 2000
@@ -37,6 +37,7 @@
 extern int bdf_prm[], bdflush_min[], bdflush_max[];
 extern char binfmt_java_interpreter[], binfmt_java_appletviewer[];
 extern int sysctl_overcommit_memory;
+extern int sysctl_max_map_count;
 extern int nr_queued_signals, max_queued_signals;
 
 #ifdef CONFIG_KMOD
@@ -252,6 +253,8 @@
         &pgt_cache_water, 2*sizeof(int), 0600, NULL, &proc_dointvec},
        {VM_PAGE_CLUSTER, "page-cluster", 
         &page_cluster, sizeof(int), 0600, NULL, &proc_dointvec},
+       {VM_MAX_MAP_COUNT, "max_map_count", 
+        &sysctl_max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
        {0}
 };
 
diff -ur linux-2.2.17/mm/mmap.c linux/mm/mmap.c
--- linux-2.2.17/mm/mmap.c      Wed Jun  7 16:26:44 2000
+++ linux/mm/mmap.c     Sun Oct  1 18:51:23 2000
@@ -40,6 +40,7 @@
 kmem_cache_t *vm_area_cachep;
 
 int sysctl_overcommit_memory;
+int sysctl_max_map_count = 65536;
 
 /* Check that a process has enough memory to allocate a
  * new virtual mapping.
@@ -190,7 +191,7 @@
                return -EINVAL;
 
        /* Too many mappings? */
-       if (mm->map_count > MAX_MAP_COUNT)
+       if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
        /* mlock MCL_FUTURE? */
@@ -632,7 +633,7 @@
 
        /* If we'll make "hole", check the vm areas limit */
        if ((mpnt->vm_start < addr && mpnt->vm_end > addr+len)
-           && mm->map_count >= MAX_MAP_COUNT)
+           && mm->map_count >= sysctl_max_map_count)
                return -ENOMEM;
 
        /*
diff -ur linux-2.4.0test8/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.4.0test8/include/linux/sched.h      Sun Oct  1 22:28:08 2000
+++ linux/include/linux/sched.h Sun Oct  1 22:50:33 2000
@@ -187,9 +187,6 @@
        { NULL, } \
 }
 
-/* Maximum number of active map areas.. This is a random (large) number */
-#define MAX_MAP_COUNT  (65536)
-
 /* Number of map areas at which the AVL tree is activated. This is arbitrary. */
 #define AVL_MIN_MAP_COUNT      32
 
diff -ur linux-2.4.0test8/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux-2.4.0test8/include/linux/sysctl.h     Sun Oct  1 22:28:00 2000
+++ linux/include/linux/sysctl.h        Sun Oct  1 20:44:58 2000
@@ -128,7 +128,8 @@
        VM_PAGECACHE=7,         /* struct: Set cache memory thresholds */
        VM_PAGERDAEMON=8,       /* struct: Control kswapd behaviour */
        VM_PGT_CACHE=9,         /* struct: Set page table cache parameters */
-       VM_PAGE_CLUSTER=10      /* int: set number of pages to swap together */
+       VM_PAGE_CLUSTER=10,     /* int: set number of pages to swap together */
+       VM_MAX_MAP_COUNT=11     /* int: max number mappings per process  */
 };
 
 
diff -ur linux-2.4.0test8/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.4.0test8/kernel/sysctl.c    Sun Oct  1 22:27:43 2000
+++ linux/kernel/sysctl.c       Sun Oct  1 20:33:51 2000
@@ -43,6 +43,7 @@
 extern int panic_timeout;
 extern int console_loglevel, C_A_D;
 extern int bdf_prm[], bdflush_min[], bdflush_max[];
+extern int sysctl_max_map_count;
 extern int sysctl_overcommit_memory;
 extern int max_threads;
 extern int nr_queued_signals, max_queued_signals;
@@ -251,7 +252,9 @@
         &pgt_cache_water, 2*sizeof(int), 0644, NULL, &proc_dointvec},
        {VM_PAGE_CLUSTER, "page-cluster", 
         &page_cluster, sizeof(int), 0644, NULL, &proc_dointvec},
-       {0}
+       {VM_MAX_MAP_COUNT, "max_map_count", &sysctl_max_map_count,
+        sizeof(sysctl_max_map_count), 0644, NULL, &proc_dointvec},
+        {0}
 };
 
 static ctl_table proc_table[] = {
diff -ur linux-2.4.0test8/mm/filemap.c linux/mm/filemap.c
--- linux-2.4.0test8/mm/filemap.c       Sun Oct  1 22:28:09 2000
+++ linux/mm/filemap.c  Sun Oct  1 20:51:13 2000
@@ -29,6 +29,8 @@
 
 #include <linux/highmem.h>
 
+extern int sysctl_max_map_count;
+
 /*
  * Shared mappings implemented 30.11.1994. It's not fully working yet,
  * though.
@@ -1920,7 +1922,7 @@
        int error = 0;
 
        /* This caps the number of vma's this process can own */
-       if (vma->vm_mm->map_count > MAX_MAP_COUNT)
+       if (vma->vm_mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
        if (start == vma->vm_start) {
diff -ur linux-2.4.0test8/mm/mmap.c linux/mm/mmap.c
--- linux-2.4.0test8/mm/mmap.c  Sun Oct  1 22:28:09 2000
+++ linux/mm/mmap.c     Sun Oct  1 20:48:39 2000
@@ -37,6 +37,7 @@
 };
 
 int sysctl_overcommit_memory;
+int sysctl_max_map_count = 65536;
 
 /* Check that a process has enough memory to allocate a
  * new virtual mapping.
@@ -180,7 +181,8 @@
                return -EINVAL;
 
        /* Too many mappings? */
-       if (mm->map_count > MAX_MAP_COUNT)
+
+       if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
        /* mlock MCL_FUTURE? */
@@ -657,7 +659,7 @@
 
        /* If we'll make "hole", check the vm areas limit */
        if ((mpnt->vm_start < addr && mpnt->vm_end > addr+len)
-           && mm->map_count >= MAX_MAP_COUNT)
+           && mm->map_count >= sysctl_max_map_count)
                return -ENOMEM;
 
        /*
@@ -778,7 +780,7 @@
            > 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 (!vm_enough_memory(len >> PAGE_SHIFT))

Reply via email to