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>