What follows is a somewhat older mail I had forgotten about. It's suddenly become more interesting to be because I was playing around with jruby which requires a big heap size. It pisses me off to own a 3GB laptop and only be able to use 1GB of that memory.
This does 2.5 things. 1. If uvm_mmap fails to find memory in the normal mmap area, go back again and look for memory somewhere else (brk). We only do this after failure, to preserve the brk space as long as possible. 2. Distinguish the two meanings of MAXDSIZ. Use BRKSIZ in more places (I think this technically fixes a bug on vax) and add it to i386. 2.5. Up i386 MAXDSIZ to 2G. End effect: You can fsck a much larger filesystem now. This doesn't change memory layout or allocation policy for any existing program, but will let you throw more memory at programs that don't currently run. Index: arch/i386/include/vmparam.h =================================================================== RCS file: /cvs/src/sys/arch/i386/include/vmparam.h,v retrieving revision 1.43 diff -u -r1.43 vmparam.h --- arch/i386/include/vmparam.h 16 Jun 2009 16:42:41 -0000 1.43 +++ arch/i386/include/vmparam.h 30 Jun 2010 02:17:34 -0000 @@ -63,7 +63,10 @@ #define DFLDSIZ (64*1024*1024) /* initial data size limit */ #endif #ifndef MAXDSIZ -#define MAXDSIZ (1024*1024*1024) /* max data size */ +#define MAXDSIZ (2U*1024*1024*1024 - 4096) /* max data size */ +#endif +#ifndef BRKSIZ +#define BRKSIZ (1024*1024*1024) #endif #ifndef DFLSSIZ #define DFLSSIZ (4*1024*1024) /* initial stack size limit */ Index: compat/svr4/svr4_misc.c =================================================================== RCS file: /cvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.54 diff -u -r1.54 svr4_misc.c --- compat/svr4/svr4_misc.c 25 May 2010 16:39:15 -0000 1.54 +++ compat/svr4/svr4_misc.c 30 Jun 2010 02:17:35 -0000 @@ -370,7 +370,7 @@ SCARG(&mm, addr) = SCARG(uap, addr); SCARG(&mm, pos) = SCARG(uap, pos); - rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ); + rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ); if ((SCARG(&mm, flags) & MAP_FIXED) == 0 && SCARG(&mm, addr) != 0 && SCARG(&mm, addr) < rp) SCARG(&mm, addr) = rp; @@ -404,7 +404,7 @@ SCARG(&mm, addr) = SCARG(uap, addr); SCARG(&mm, pos) = SCARG(uap, pos); - rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ); + rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ); if ((SCARG(&mm, flags) & MAP_FIXED) == 0 && SCARG(&mm, addr) != 0 && SCARG(&mm, addr) < rp) SCARG(&mm, addr) = rp; Index: dev/pci/drm/i915_drv.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/i915_drv.c,v retrieving revision 1.86 diff -u -r1.86 i915_drv.c --- dev/pci/drm/i915_drv.c 12 Jun 2010 16:51:36 -0000 1.86 +++ dev/pci/drm/i915_drv.c 30 Jun 2010 02:17:35 -0000 @@ -1307,7 +1307,7 @@ * We give our reference from object_lookup to the mmap, so only * must free it in the case that the map fails. */ - addr = uvm_map_hint(curproc, VM_PROT_READ | VM_PROT_WRITE); + addr = uvm_map_hint(curproc, VM_PROT_READ | VM_PROT_WRITE, 0); ret = uvm_map_p(&curproc->p_vmspace->vm_map, &addr, nsize, &obj->uobj, offset, 0, UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_SHARE, UVM_ADV_RANDOM, 0), curproc); Index: kern/exec_elf.c =================================================================== RCS file: /cvs/src/sys/kern/exec_elf.c,v retrieving revision 1.74 diff -u -r1.74 exec_elf.c --- kern/exec_elf.c 29 Jun 2010 00:28:14 -0000 1.74 +++ kern/exec_elf.c 30 Jun 2010 02:17:35 -0000 @@ -391,7 +391,7 @@ * would (i.e. something safely out of the way). */ if (pos == ELFDEFNNAME(NO_ADDR)) { - pos = uvm_map_hint(p, VM_PROT_EXECUTE); + pos = uvm_map_hint(p, VM_PROT_EXECUTE, 0); } pos = ELF_ROUND(pos, file_align); Index: kern/kern_exec.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exec.c,v retrieving revision 1.112 diff -u -r1.112 kern_exec.c --- kern/kern_exec.c 18 May 2010 22:26:10 -0000 1.112 +++ kern/kern_exec.c 30 Jun 2010 02:17:35 -0000 @@ -804,7 +804,7 @@ } /* Just a hint to uvm_mmap where to put it. */ - p->p_sigcode = uvm_map_hint(p, VM_PROT_READ|VM_PROT_EXECUTE); + p->p_sigcode = uvm_map_hint(p, VM_PROT_READ|VM_PROT_EXECUTE, 0); uao_reference(e->e_sigobject); if (uvm_map(&p->p_vmspace->vm_map, &p->p_sigcode, round_page(sz), e->e_sigobject, 0, 0, UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX, Index: kern/sysv_shm.c =================================================================== RCS file: /cvs/src/sys/kern/sysv_shm.c,v retrieving revision 1.50 diff -u -r1.50 sysv_shm.c --- kern/sysv_shm.c 2 Jun 2009 12:11:16 -0000 1.50 +++ kern/sysv_shm.c 30 Jun 2010 02:17:35 -0000 @@ -266,7 +266,7 @@ return (EINVAL); } else { /* This is just a hint to uvm_map() about where to put it. */ - attach_va = uvm_map_hint(p, prot); + attach_va = uvm_map_hint(p, prot, 0); } shm_handle = shmseg->shm_internal; uao_reference(shm_handle->shm_object); Index: uvm/uvm_map.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_map.c,v retrieving revision 1.127 diff -u -r1.127 uvm_map.c --- uvm/uvm_map.c 17 Jun 2010 16:11:20 -0000 1.127 +++ uvm/uvm_map.c 30 Jun 2010 02:17:35 -0000 @@ -1226,7 +1226,7 @@ * creating a new mapping with "prot" protection. */ vaddr_t -uvm_map_hint(struct proc *p, vm_prot_t prot) +uvm_map_hint(struct proc *p, vm_prot_t prot, int invadeheap) { vaddr_t addr; @@ -1242,9 +1242,11 @@ return (round_page(addr)); } #endif - addr = (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ; + addr = (vaddr_t)p->p_vmspace->vm_daddr; + if (!invadeheap) + addr += BRKSIZ; #if !defined(__vax__) - addr += arc4random() & (MIN((256 * 1024 * 1024), MAXDSIZ) - 1); + addr += arc4random() & (MIN((256 * 1024 * 1024), BRKSIZ) - 1); #else /* start malloc/mmap after the brk */ addr = (vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ; Index: uvm/uvm_map.h =================================================================== RCS file: /cvs/src/sys/uvm/uvm_map.h,v retrieving revision 1.43 diff -u -r1.43 uvm_map.h --- uvm/uvm_map.h 20 Apr 2010 22:05:44 -0000 1.43 +++ uvm/uvm_map.h 30 Jun 2010 02:17:35 -0000 @@ -287,7 +287,7 @@ vm_map_entry_t uvm_map_findspace(vm_map_t, vaddr_t, vsize_t, vaddr_t *, struct uvm_object *, voff_t, vsize_t, int); vaddr_t uvm_map_pie(vaddr_t); -vaddr_t uvm_map_hint(struct proc *, vm_prot_t); +vaddr_t uvm_map_hint(struct proc *, vm_prot_t, int); int uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t); int uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int); void uvm_map_init(void); Index: uvm/uvm_mmap.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_mmap.c,v retrieving revision 1.80 diff -u -r1.80 uvm_mmap.c --- uvm/uvm_mmap.c 21 May 2010 23:22:33 -0000 1.80 +++ uvm/uvm_mmap.c 30 Jun 2010 02:17:35 -0000 @@ -185,16 +185,16 @@ } if (vaddr == 0) - vaddr = uvm_map_hint(p, prot); + vaddr = uvm_map_hint(p, prot, 0); /* prevent a user requested address from falling in heap space */ if ((vaddr + size > (vaddr_t)p->p_vmspace->vm_daddr) && - (vaddr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ)) { + (vaddr < (vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ)) { if (flags & UVM_FLAG_FIXED) { error = EINVAL; goto done; } - vaddr = round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ); + vaddr = round_page((vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ); } vm_map_lock(&p->p_vmspace->vm_map); @@ -208,9 +208,9 @@ } else { /* prevent a returned address from falling in heap space */ if ((vaddr + size > (vaddr_t)p->p_vmspace->vm_daddr) - && (vaddr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ)) { + && (vaddr < (vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ)) { vaddr = round_page((vaddr_t)p->p_vmspace->vm_daddr + - MAXDSIZ); + BRKSIZ); goto again; } error = 0; @@ -458,10 +458,10 @@ * we will refine our guess later (e.g. to account for VAC, etc) */ if (addr == 0) - addr = uvm_map_hint(p, prot); + addr = uvm_map_hint(p, prot, 0); else if (!(flags & MAP_TRYFIXED) && addr < (vaddr_t)p->p_vmspace->vm_daddr) - addr = uvm_map_hint(p, prot); + addr = uvm_map_hint(p, prot, 0); } /* @@ -604,6 +604,12 @@ error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot, flags, handle, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p); + if (error == ENOMEM && !(flags & (MAP_FIXED | MAP_TRYFIXED))) { + addr = uvm_map_hint(p, prot, 1); + error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, + maxprot, flags, handle, pos, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p); + } if (error == 0) /* remember to add offset */ Index: uvm/uvm_param.h =================================================================== RCS file: /cvs/src/sys/uvm/uvm_param.h,v retrieving revision 1.14 diff -u -r1.14 uvm_param.h --- uvm/uvm_param.h 17 Feb 2008 20:33:47 -0000 1.14 +++ uvm/uvm_param.h 30 Jun 2010 02:17:35 -0000 @@ -70,6 +70,10 @@ #include <machine/vmparam.h> +#ifndef BRKSIZ +#define BRKSIZ MAXDSIZ +#endif + /* * This belongs in types.h, but breaks too many existing programs. */