Subject: Re: Allow mmap(2) hint to be taken literally (patch)
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 06/20/2003 17:22:11
In article <Pine.NEB.4.53.0306201140400.7425@netbsd.int.duh.org>,
Todd Vierling <tv@pobox.com> wrote:
I like the patch...
christos
>While attempting to get CrossOver Office (http://www.codeweavers.com/)
>running under NetBSD 1.6.1, I hit upon the known mmap(2) incompatibility
>where NetBSD's mmap does not work the same as Linux's mmap when a hint is
>provided and MAP_FIXED is *not* set.
>
>This was originally described here:
>
> http://mail-index.netbsd.org/tech-kern/2001/11/18/0000.html
>
>but the patch there is very intrusive into NetBSD's native mmap(2) handling.
>
>One of the requirements here to get CrossOver running will be to provide
>this behavior (actually, an even looser form of the above), but specifically
>for Linux emulation mmap(2). This isn't such a big deal, as I could rip out
>the guts of sys_mmap() and plonk it into linux_sys_mmap() if need be.
>
>After thinking about it a bit, though, I thought it might be useful to offer
>this behavior even under NetBSD, provided a given flag was present to
>mmap(2). The patch below provides a new option to mmap(2), called
>MAP_TRYFIXED, which indicates that mmap(2) will *not* try to skip the heap
>space when attempting a mapping at the provided hint address. This was
>inspired by another message in the above thread:
>
>http://mail-index.netbsd.org/tech-kern/2001/11/21/0015.html
>
>The effect is that the caller can now try to mmap an absolute file location,
>but still get a non-absolute mapping if the asbolute address is "truly"
>unavailable (i.e. not in the vm_map). This flag could only be used by a
>process that understands what it is doing -- and in particular, is not using
>NetBSD's sbrk heap space.
>
>Comments? (Also, if you know that there is precedent here on some other
>*ix, please let me know.)
>
>=====
>
>Note that the compat/linux/common/linux_misc.c diff should still apply
>correctly (with fuzz and offset) if the diff from kern/21937 is committed.
>
>Index: compat/linux/common/linux_misc.c
>===================================================================
>RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc.c,v
>retrieving revision 1.109.4.2
>diff -u -r1.109.4.2 linux_misc.c
>--- compat/linux/common/linux_misc.c 2002/12/12 21:29:13 1.109.4.2
>+++ compat/linux/common/linux_misc.c 2003/06/20 16:00:50
>@@ -446,7 +446,7 @@
> struct sys_mmap_args cma;
> int flags, fl = SCARG(uap, flags);
>
>- flags = 0;
>+ flags = MAP_TRYFIXED;
> flags |= cvtto_bsd_mask(fl, LINUX_MAP_SHARED, MAP_SHARED);
> flags |= cvtto_bsd_mask(fl, LINUX_MAP_PRIVATE, MAP_PRIVATE);
> flags |= cvtto_bsd_mask(fl, LINUX_MAP_FIXED, MAP_FIXED);
>Index: uvm/uvm_mmap.c
>===================================================================
>RCS file: /cvsroot/src/sys/uvm/uvm_mmap.c,v
>retrieving revision 1.63
>diff -u -r1.63 uvm_mmap.c
>--- uvm/uvm_mmap.c 2002/03/22 11:06:33 1.63
>+++ uvm/uvm_mmap.c 2003/06/20 16:00:50
>@@ -346,7 +346,7 @@
> if (addr > addr + size)
> return (EOVERFLOW); /* no wrapping! */
>
>- } else {
>+ } else if (addr == NULL || !(flags & MAP_TRYFIXED)) {
>
> /*
> * not fixed: make sure we skip over the largest possible heap.
>Index: sys/mman.h
>===================================================================
>RCS file: /cvsroot/src/sys/sys/mman.h,v
>retrieving revision 1.28
>diff -u -r1.28 mman.h
>--- sys/mman.h 2000/10/18 01:43:18 1.28
>+++ sys/mman.h 2003/06/20 16:00:51
>@@ -92,6 +92,7 @@
> #define MAP_INHERIT 0x0080 /* region is retained after exec */
> #define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size */
> #define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */
>+#define MAP_TRYFIXED 0x0400 /* attempt hint address, even within break */
>
> /*
> * Mapping type
>
>--
>-- Todd Vierling <tv@pobox.com>