diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-03-31 21:51:54 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-31 21:51:54 -0800 |
| commit | 56d93842e4840f371cb9acc8e5a628496b615a96 (patch) | |
| tree | 84aa2bab1dc46823c9d913b9872d52e627da3b44 | |
| parent | bc5c1743cddcca31200f4a201fe9a70a87737ef8 (diff) | |
[PATCH] Replace MAX_MAP_COUNT with /proc/sys/vm/max_map_count
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:
| -rw-r--r-- | Documentation/sysctl/vm.txt | 16 | ||||
| -rw-r--r-- | include/linux/sched.h | 4 | ||||
| -rw-r--r-- | include/linux/sysctl.h | 1 | ||||
| -rw-r--r-- | kernel/sysctl.c | 8 | ||||
| -rw-r--r-- | mm/mmap.c | 8 |
5 files changed, 33 insertions, 4 deletions
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 05f627955391..fc3e413c3721 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -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 diff --git a/include/linux/sched.h b/include/linux/sched.h index eb5bc2f12788..f5fa0c07a7f8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -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> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index dbd57168ac61..3767428df94d 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -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 */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b790c5ecf37f..f5f3123b0522 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -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 } }; diff --git a/mm/mmap.c b/mm/mmap.c index 143a27ef28a2..000e377d4888 100644 --- 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)) |
