Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Introduce "top down" memory management for mmap()ed allocati...



details:   https://anonhg.NetBSD.org/src/rev/6fcee14cf035
branches:  trunk
changeset: 543254:6fcee14cf035
user:      atatat <atatat%NetBSD.org@localhost>
date:      Thu Feb 20 22:16:05 2003 +0000

description:
Introduce "top down" memory management for mmap()ed allocations.  This
means that the dynamic linker gets mapped in at the top of available
user virtual memory (typically just below the stack), shared libraries
get mapped downwards from that point, and calls to mmap() that don't
specify a preferred address will get mapped in below those.

This means that the heap and the mmap()ed allocations will grow
towards each other, allowing one or the other to grow larger than
before.  Previously, the heap was limited to MAXDSIZ by the placement
of the dynamic linker (and the process's rlimits) and the space
available to mmap was hobbled by this reservation.

This is currently only enabled via an *option* for the i386 platform
(though other platforms are expected to follow).  Add "options
USE_TOPDOWN_VM" to your kernel config file, rerun config, and rebuild
your kernel to take advantage of this.

Note that the pmap_prefer() interface has not yet been modified to
play nicely with this, so those platforms require a bit more work
(most notably the sparc) before they can use this new memory
arrangement.

This change also introduces a VM_DEFAULT_ADDRESS() macro that picks
the appropriate default address based on the size of the allocation or
the size of the process's text segment accordingly.  Several drivers
and the SYSV SHM address assignment were changed to use this instead
of each one picking their own "default".

diffstat:

 share/man/man4/options.4         |  23 +++++++++++++++++-
 sys/arch/hp300/dev/grf.c         |   6 ++--
 sys/arch/i386/include/vmparam.h  |  11 +++++++-
 sys/arch/mac68k/dev/grf_compat.c |   4 +-
 sys/arch/pmax/dev/px.c           |   6 ++--
 sys/arch/pmax/dev/qvss_compat.c  |   4 +-
 sys/arch/x68k/dev/grf.c          |   4 +-
 sys/conf/files                   |   3 +-
 sys/kern/exec_elf32.c            |  17 ++++++++----
 sys/kern/exec_subr.c             |  27 ++++++++++++++------
 sys/kern/sysv_shm.c              |   8 ++---
 sys/sys/exec.h                   |  21 ++++++++++++++--
 sys/uvm/uvm_map.c                |  51 ++++++++++++++++++++++++++++++++++-----
 sys/uvm/uvm_map.h                |  12 ++++++++-
 sys/uvm/uvm_mmap.c               |  19 ++++++++++----
 sys/uvm/uvm_param.h              |  43 ++++++++++++++++++++++++++++++++-
 16 files changed, 207 insertions(+), 52 deletions(-)

diffs (truncated from 693 to 300 lines):

diff -r f7e4eca5b8d3 -r 6fcee14cf035 share/man/man4/options.4
--- a/share/man/man4/options.4  Thu Feb 20 21:09:40 2003 +0000
+++ b/share/man/man4/options.4  Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: options.4,v 1.195 2003/02/10 15:30:52 wiz Exp $
+.\"    $NetBSD: options.4,v 1.196 2003/02/20 22:16:09 atatat Exp $
 .\"
 .\" Copyright (c) 1996
 .\"    Perry E. Metzger.  All rights reserved.
@@ -1719,6 +1719,27 @@
 variable which may be changed at run time -- see
 .Xr sysctl 8
 for details.
+.It Cd options USE_TOPDOWN_VM
+User space memory allocations (as made by
+.Xr mmap 2 )
+will be arranged in a
+.Dq top down
+fashion instead of the traditional
+.Dq upwards from MAXDSIZ \+ vm_daddr
+method.
+This includes the placement of
+.Xr ld.so 1 .
+Arranging memory in this manner allows either (or both of) the heap or
+.Xr mmap 2
+allocated space to grow larger than traditionally possible.
+This option is not available on all ports, but is instead expected to be
+offered on a port-by-port basis, after which some ports will commit to
+using it by default.
+See the files
+.Pa /usr/include/uvm/uvm_param.h
+for some implementation details, and
+.Pa /usr/include/machine/vmparam.h
+for port specific details including availability.
 .El
 .Ss amiga-specific Options
 .Bl -ohang
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/hp300/dev/grf.c
--- a/sys/arch/hp300/dev/grf.c  Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/hp300/dev/grf.c  Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: grf.c,v 1.49 2003/01/01 01:34:45 thorpej Exp $ */
+/*     $NetBSD: grf.c,v 1.50 2003/02/20 22:16:05 atatat Exp $  */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.49 2003/01/01 01:34:45 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.50 2003/02/20 22:16:05 atatat Exp $");
 
 #include "opt_compat_hpux.h"
 
@@ -628,7 +628,7 @@
        if (*addrp)
                flags |= MAP_FIXED;
        else
-               *addrp = (caddr_t)0x1000000;    /* XXX */
+               *addrp = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, len)
        vn.v_type = VCHR;                       /* XXX */
        vn.v_specinfo = &si;                    /* XXX */
        vn.v_rdev = dev;                        /* XXX */
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/i386/include/vmparam.h
--- a/sys/arch/i386/include/vmparam.h   Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/i386/include/vmparam.h   Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmparam.h,v 1.47 2003/01/29 14:12:36 drochner Exp $    */
+/*     $NetBSD: vmparam.h,v 1.48 2003/02/20 22:16:05 atatat Exp $      */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -102,6 +102,15 @@
 #define        VM_MIN_KERNEL_ADDRESS   ((vaddr_t)(PDSLOT_KERN << PDSHIFT))
 #define        VM_MAX_KERNEL_ADDRESS   ((vaddr_t)(PDSLOT_APTE << PDSHIFT))
 
+/*
+ * The address to which unspecified mapping requests default
+ */
+#define __HAVE_TOPDOWN_VM
+#ifdef USE_TOPDOWN_VM
+#define VM_DEFAULT_ADDRESS(da, sz) \
+       trunc_page(VM_MAXUSER_ADDRESS - MAXSSIZ - (sz))
+#endif
+
 /* XXX max. amount of KVM to be used by buffers. */
 #ifndef VM_MAX_KERNEL_BUF
 #define VM_MAX_KERNEL_BUF      (384 * 1024 * 1024)
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/mac68k/dev/grf_compat.c
--- a/sys/arch/mac68k/dev/grf_compat.c  Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/mac68k/dev/grf_compat.c  Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: grf_compat.c,v 1.10 2002/10/23 09:11:28 jdolecek Exp $ */
+/*     $NetBSD: grf_compat.c,v 1.11 2003/02/20 22:16:06 atatat Exp $   */
 
 /*
  * Copyright (C) 1999 Scott Reynolds
@@ -342,8 +342,8 @@
        u_long len;
        int error, flags;
 
-       *addrp = (caddr_t)sc->sc_dc->dc_paddr;
        len = m68k_round_page(sc->sc_dc->dc_offset + sc->sc_dc->dc_size);
+       *addrp = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, len);
        flags = MAP_SHARED | MAP_FIXED;
 
        vn.v_type = VCHR;               /* XXX */
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/pmax/dev/px.c
--- a/sys/arch/pmax/dev/px.c    Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/pmax/dev/px.c    Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: px.c,v 1.45 2003/01/20 05:30:01 simonb Exp $   */
+/*     $NetBSD: px.c,v 1.46 2003/02/20 22:16:06 atatat Exp $   */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: px.c,v 1.45 2003/01/20 05:30:01 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: px.c,v 1.46 2003/02/20 22:16:06 atatat Exp $");
 
 /*
  * px.c: driver for the DEC TURBOchannel 2D and 3D accelerated framebuffers
@@ -1997,7 +1997,7 @@
        size = sizeof(struct px_map);
        prot = VM_PROT_READ | VM_PROT_WRITE;
        flags = MAP_SHARED | MAP_FILE;
-       *va = round_page((vaddr_t)p->p_vmspace->vm_taddr + MAXTSIZ + MAXDSIZ);
+       *va = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, size);
        return uvm_mmap(&p->p_vmspace->vm_map, va, size, prot,
            VM_PROT_ALL, flags, &vn, 0, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
 }
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/pmax/dev/qvss_compat.c
--- a/sys/arch/pmax/dev/qvss_compat.c   Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/pmax/dev/qvss_compat.c   Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: qvss_compat.c,v 1.31 2002/10/23 09:11:51 jdolecek Exp $        */
+/*     $NetBSD: qvss_compat.c,v 1.32 2003/02/20 22:16:06 atatat Exp $  */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -457,7 +457,7 @@
        len = mips_round_page(((vaddr_t)fbu & PGOFSET) +
                              sizeof(struct fbuaccess)) +
                mips_round_page(fi->fi_type.fb_size);
-       addr = (vaddr_t)0x20000000;             /* XXX */
+       addr = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, len);
        vn.v_type = VCHR;                       /* XXX */
        vn.v_specinfo = &si;                    /* XXX */
        vn.v_rdev = dev;                        /* XXX */
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/arch/x68k/dev/grf.c
--- a/sys/arch/x68k/dev/grf.c   Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/arch/x68k/dev/grf.c   Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: grf.c,v 1.24 2002/10/23 09:12:44 jdolecek Exp $        */
+/*     $NetBSD: grf.c,v 1.25 2003/02/20 22:16:06 atatat Exp $  */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -555,7 +555,7 @@
        if (*addrp)
                flags |= MAP_FIXED;
        else
-               *addrp = (caddr_t)0x1000000;    /* XXX */
+               *addrp = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, len);
        vn.v_type = VCHR;                       /* XXX */
        vn.v_specinfo = &si;                    /* XXX */
        vn.v_rdev = dev;                        /* XXX */
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/conf/files
--- a/sys/conf/files    Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/conf/files    Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.600 2003/02/18 12:20:19 jdolecek Exp $
+#      $NetBSD: files,v 1.601 2003/02/20 22:16:06 atatat Exp $
 
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
@@ -120,6 +120,7 @@
 # UVM options
 #
 defflag        opt_uvmhist.h           UVMHIST UVMHIST_PRINT
+defflag        opt_uvm.h               USE_TOPDOWN_VM
 
 # file system options
 #
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/kern/exec_elf32.c
--- a/sys/kern/exec_elf32.c     Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/kern/exec_elf32.c     Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_elf32.c,v 1.79 2003/01/30 20:03:46 atatat Exp $   */
+/*     $NetBSD: exec_elf32.c,v 1.80 2003/02/20 22:16:07 atatat Exp $   */
 
 /*-
  * Copyright (c) 1994, 2000 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.79 2003/01/30 20:03:46 atatat Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.80 2003/02/20 22:16:07 atatat Exp $");
 
 /* If not included by exec_elf64.c, ELFSIZE won't be defined. */
 #ifndef ELFSIZE
@@ -280,6 +280,8 @@
                psize = *size;
        }
 
+       if ((flags & (VMCMD_TOPDOWN|VMCMD_RELATIVE)) == VMCMD_TOPDOWN)
+               *addr -= round_page(*size);
        if (psize > 0) {
                NEW_VMCMD2(vcset, ph->p_align < PAGE_SIZE ?
                    vmcmd_map_readvn : vmcmd_map_pagedvn, psize, *addr, vp,
@@ -288,7 +290,7 @@
        if (psize < *size) {
                NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize,
                    *addr + psize, vp, offset + psize, *prot, 
-                   psize > 0 ? flags & VMCMD_RELATIVE : flags);
+                   psize > 0 ? flags & (VMCMD_RELATIVE | VMCMD_TOPDOWN) : flags);
        }
 
        /*
@@ -299,7 +301,7 @@
 
        if (rm != rf) {
                NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
-                   0, *prot, flags & VMCMD_RELATIVE);
+                   0, *prot, flags & (VMCMD_RELATIVE | VMCMD_TOPDOWN));
                *size = msize;
        }
 }
@@ -317,6 +319,8 @@
     Elf_Addr *last)
 {
        int error, i;
+       const int topdown =
+           p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN ? VMCMD_TOPDOWN : 0;
        struct nameidata nd;
        struct vnode *vp;
        struct vattr attr;
@@ -403,7 +407,7 @@
                                flags = VMCMD_RELATIVE;
                        }
                        ELFNAME(load_psection)(vcset, vp, &ph[i], &addr,
-                           &size, &prot, flags);
+                           &size, &prot, flags|topdown);
                        /* If entry is within this section it must be text */
                        if (eh.e_entry >= ph[i].p_vaddr &&
                            eh.e_entry < (ph[i].p_vaddr + size)) {
@@ -596,7 +600,8 @@
         * would (i.e. something safely out of the way).
         */
        if (pos == ELFDEFNNAME(NO_ADDR))
-               pos = round_page(epp->ep_daddr + MAXDSIZ);
+               /* XXX size will be accounted for in load_psection */
+               pos = VM_DEFAULT_ADDRESS(epp->ep_daddr, 0);
 #endif /* !ELF_INTERP_NON_RELOCATABLE */
 
        /*
diff -r f7e4eca5b8d3 -r 6fcee14cf035 sys/kern/exec_subr.c
--- a/sys/kern/exec_subr.c      Thu Feb 20 21:09:40 2003 +0000
+++ b/sys/kern/exec_subr.c      Thu Feb 20 22:16:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_subr.c,v 1.33 2003/01/30 20:03:46 atatat Exp $    */
+/*     $NetBSD: exec_subr.c,v 1.34 2003/02/20 22:16:07 atatat Exp $    */
 
 /*
  * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.33 2003/01/30 20:03:46 atatat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.34 2003/02/20 22:16:07 atatat Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,6 +78,20 @@
        vcp->ev_offset = offset;
        vcp->ev_prot = prot;
        vcp->ev_flags = flags;
+       if ((flags & (VMCMD_TOPDOWN|VMCMD_RELATIVE)) ==
+           (VMCMD_TOPDOWN|VMCMD_RELATIVE)) {
+               int i = evsp->evs_used - 2;
+               while (i >= 0) {
+                       vcp = &evsp->evs_cmds[i--];
+                       if (vcp->ev_flags & VMCMD_BASE) {
+                               if ((vcp->ev_flags &
+                                   (VMCMD_TOPDOWN|VMCMD_FIXED)) ==
+                                   (VMCMD_TOPDOWN))
+                                       vcp->ev_addr -= round_page(len);
+                               break;
+                       }
+               }
+       }
 }
 #endif /* DEBUG */
 



Home | Main Index | Thread Index | Old Index