Date: Tue, 20 Dec 2011 11:10:26 +0100 From: Tijl Coosemans <tijl@coosemans.org> To: freebsd-stable@freebsd.org Cc: Ganael LAPLANCHE <ganael.laplanche@martymac.org> Subject: Re: Using mmap(2) with a hint address Message-ID: <201112201110.32559.tijl@coosemans.org> In-Reply-To: <20111220080437.M63044@martymac.org> References: <20111220080437.M63044@martymac.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--nextPart1645308.pnkqAZZbLn Content-Type: Text/Plain; charset="iso-8859-15" Content-Transfer-Encoding: quoted-printable On Tuesday 20 December 2011 09:08:18 Ganael LAPLANCHE wrote: > Hi folks, >=20 > I am trying to use mmap(2) with a hint address. Unfortunately, this addre= ss > seems to be ignored and I never manage to get the desired one, while it > seems to be free. >=20 > Here is my code (the same code on NetBSD and GNU/Linux returns the hint > address) : >=20 > 8< ----------- >8 > #include <stdio.h> > #include <string.h> > #include <errno.h> >=20 > /* mmap */ > #include <sys/mman.h> >=20 > /* getpagesize */ > #include <unistd.h> >=20 > /* round_page */ > #include <machine/param.h> >=20 > int main(void) > { > size_t map_size =3D getpagesize(); >=20 > /* first call, ask for one page, with hint */ > char *map_hint =3D (char*)round_page(512*1024*1024); > printf("=3D> calling mmap with hint =3D %p, size =3D %zu\n", map_hint, > map_size); > void *addr =3D mmap(map_hint, map_size, PROT_READ | PROT_WRITE | > PROT_EXEC, > MAP_ANON | MAP_PRIVATE, -1, 0); > if (addr =3D=3D MAP_FAILED) { > printf("mmap failed: %s\n", strerror(errno)); > } > else { > printf("mmap succeeded: addr =3D %p\n", addr); > #ifdef SLEEP > /* leave time to use 'procstat -v' */ > sleep(10); > #endif > if(munmap(addr, map_size) !=3D 0) { > printf("munmap failed: %s\n", strerror(errno)); > } > } >=20 > /* second call, one page, without hint */ > map_hint =3D 0; > printf("=3D> calling mmap without hint, size =3D %zu\n", map_size); > addr =3D mmap(map_hint, map_size, PROT_READ | PROT_WRITE | PROT_EXEC, > MAP_ANON | MAP_PRIVATE, -1, 0); > if (addr =3D=3D MAP_FAILED) { > printf("mmap failed: %s\n", strerror(errno)); > } > else { > printf("mmap succeeded: addr =3D %p\n", addr); > #ifdef SLEEP > /* leave time to use 'procstat -v' */ > sleep(10); > #endif > if(munmap(addr, map_size) !=3D 0) { > printf("munmap failed: %s\n", strerror(errno)); > } > } > return (0); > } > 8< ----------- >8 >=20 > and its output : >=20 > 1) On an i386 machine, FreeBSD 8.2-RELEASE : >=20 > $ ./test-mmap > =3D> calling mmap with hint =3D 0x20000000, size =3D 4096 > mmap succeeded: addr =3D 0x281a8000 > =3D> calling mmap without hint, size =3D 4096 > mmap succeeded: addr =3D 0x281a8000 >=20 > $ procstat -v 1685 > PID START END PRT RES PRES REF SHD FL TP PATH > 1685 0x8048000 0x8049000 r-x 1 0 1 0 CN vn /tmp/test-mmap > 1685 0x8049000 0x8100000 rw- 1 0 1 0 -- df > 1685 0x28049000 0x28078000 r-x 47 0 82 41 CN vn /libexec/ld-elf.s= o.1 > 1685 0x28078000 0x2807a000 rw- 2 0 1 0 C- vn /libexec/ld-elf.s= o.1 > 1685 0x2807a000 0x2808d000 rw- 12 0 1 0 -- df > 1685 0x2808d000 0x2818b000 r-x 134 0 82 41 CN vn /lib/libc.so.7 > 1685 0x2818b000 0x28191000 rw- 6 0 1 0 C- vn /lib/libc.so.7 > 1685 0x28191000 0x281a8000 rw- 5 0 1 0 -- df > 1685 0x281a8000 0x281a9000 rwx 0 0 0 0 -- -- > 1685 0x28200000 0x28300000 rw- 2 0 1 0 -- df > 1685 0xbfbe0000 0xbfc00000 rwx 3 0 1 0 -- df >=20 > 2) On an amd64 machine, FreeBSD 8.2-RELEASE : >=20 > $ ./test-mmap > =3D> calling mmap with hint =3D 0x20000000, size =3D 4096 > mmap succeeded: addr =3D 0x800538000 > =3D> calling mmap without hint, size =3D 4096 > mmap succeeded: addr =3D 0x800538000 >=20 > $ procstat -v 38899 > PID START END PRT RES PRES REF SHD FL TP P= ATH > 38899 0x400000 0x401000 r-x 1 0 1 0 CN vn > /tmp/test-mmap > 38899 0x500000 0x600000 rw- 2 0 1 0 -- df=20 > 38899 0x800500000 0x800530000 r-x 48 0 218 95 CN vn > /libexec/ld-elf.so.1 > 38899 0x800530000 0x800538000 rw- 7 0 2 0 -- df=20 > 38899 0x800538000 0x800539000 rwx 0 0 2 0 -- df=20 > 38899 0x80062f000 0x800637000 rw- 8 0 1 0 C- vn > /libexec/ld-elf.so.1 > 38899 0x800637000 0x800646000 rw- 5 0 1 0 -- df=20 > 38899 0x800646000 0x80074e000 r-x 146 0 218 95 CN vn > /lib/libc.so.7 > 38899 0x80074e000 0x80084e000 --- 0 0 2 0 -- df=20 > 38899 0x80084e000 0x80086d000 rw- 31 0 1 0 C- vn > /lib/libc.so.7 > 38899 0x80086d000 0x800888000 rw- 6 0 2 0 -- df=20 > 38899 0x800a00000 0x800c00000 rw- 5 0 1 0 -- df=20 > 38899 0x7ffffffe0000 0x800000000000 rwx 3 0 1 0 -- df=20 >=20 > Using MAP_FIXED, I can get the desired address, but it is overkill (it > replaces > any previous mappings and its use is discouraged, see mmap(2)) and > should not > be needed here. >=20 > Am I doing something wrong here ? =46reeBSD reserves quite a bit of space for brk(2) style heap. Your program will work if you use higher addresses. You can also shrink the reserved space either system wide by setting kern.maxdsiz sysctl in /boot/loader.conf, or in your program by setting the maximum RLIMIT_DATA with setrlimit(2). --nextPart1645308.pnkqAZZbLn Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (FreeBSD) iF4EABEIAAYFAk7wXxgACgkQfoCS2CCgtitxAAD9HlZklV0Miz9+MpymfgTXzaiL LKwb6vm72wfKDBbf5d8A/18OtAG0rnsth42dZPqKJE3VOgOvL74VFnpQ2GiIHX1F =H3rU -----END PGP SIGNATURE----- --nextPart1645308.pnkqAZZbLn--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112201110.32559.tijl>