Re: Using mmap(2) with a hint address
Hi Artem, Tijl, On Tue, 20 Dec 2011 09:27:43 -0800, Artem Belevich wrote Something like that. [...] These days malloc() by default uses mmap, so if you don't force it to use sbrk() you can probably lower MAXDSIZE and let kernel use most of address space for hinted mmaps. [...] On Tue, 20 Dec 2011 18:45:08 +0100, Tijl Coosemans wrote I don't know about NetBSD but Linux maps from the stack downwards when there's no hint and FreeBSD maps from the program upwards. [...] malloc(3) used to be implemented on top of brk(2) so the size was increased on amd64 so you could malloc more memory. Nowadays malloc can use mmap(2) so a large datasize isn't really needed anymore. I will use setrlimit(2) to lower datasize then. Thanks a lot for your time and explanations, Best regards, -- Ganael LAPLANCHE ganael.laplan...@martymac.org http://www.martymac.org | http://contribs.martymac.org FreeBSD: martymac marty...@freebsd.org, http://www.FreeBSD.org ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to freebsd-stable-unsubscr...@freebsd.org
Using mmap(2) with a hint address
Hi folks, I am trying to use mmap(2) with a hint address. Unfortunately, this address seems to be ignored and I never manage to get the desired one, while it seems to be free. Here is my code (the same code on NetBSD and GNU/Linux returns the hint address) : 8 --- 8 #include stdio.h #include string.h #include errno.h /* mmap */ #include sys/mman.h /* getpagesize */ #include unistd.h /* round_page */ #include machine/param.h int main(void) { size_t map_size = getpagesize(); /* first call, ask for one page, with hint */ char *map_hint = (char*)round_page(512*1024*1024); printf(= calling mmap with hint = %p, size = %zu\n, map_hint, map_size); void *addr = mmap(map_hint, map_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); if (addr == MAP_FAILED) { printf(mmap failed: %s\n, strerror(errno)); } else { printf(mmap succeeded: addr = %p\n, addr); #ifdef SLEEP /* leave time to use 'procstat -v' */ sleep(10); #endif if(munmap(addr, map_size) != 0) { printf(munmap failed: %s\n, strerror(errno)); } } /* second call, one page, without hint */ map_hint = 0; printf(= calling mmap without hint, size = %zu\n, map_size); addr = mmap(map_hint, map_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); if (addr == MAP_FAILED) { printf(mmap failed: %s\n, strerror(errno)); } else { printf(mmap succeeded: addr = %p\n, addr); #ifdef SLEEP /* leave time to use 'procstat -v' */ sleep(10); #endif if(munmap(addr, map_size) != 0) { printf(munmap failed: %s\n, strerror(errno)); } } return (0); } 8 --- 8 and its output : 1) On an i386 machine, FreeBSD 8.2-RELEASE : $ ./test-mmap = calling mmap with hint = 0x2000, size = 4096 mmap succeeded: addr = 0x281a8000 = calling mmap without hint, size = 4096 mmap succeeded: addr = 0x281a8000 $ procstat -v 1685 PID STARTEND PRT RES PRES REF SHD FL TP PATH 1685 0x8048000 0x8049000 r-x10 1 0 CN vn /tmp/test-mmap 1685 0x8049000 0x810 rw-10 1 0 -- df 1685 0x28049000 0x28078000 r-x 470 82 41 CN vn /libexec/ld-elf.so.1 1685 0x28078000 0x2807a000 rw-20 1 0 C- vn /libexec/ld-elf.so.1 1685 0x2807a000 0x2808d000 rw- 120 1 0 -- df 1685 0x2808d000 0x2818b000 r-x 1340 82 41 CN vn /lib/libc.so.7 1685 0x2818b000 0x28191000 rw-60 1 0 C- vn /lib/libc.so.7 1685 0x28191000 0x281a8000 rw-50 1 0 -- df 1685 0x281a8000 0x281a9000 rwx00 0 0 -- -- 1685 0x2820 0x2830 rw-20 1 0 -- df 1685 0xbfbe 0xbfc0 rwx30 1 0 -- df 2) On an amd64 machine, FreeBSD 8.2-RELEASE : $ ./test-mmap = calling mmap with hint = 0x2000, size = 4096 mmap succeeded: addr = 0x800538000 = calling mmap without hint, size = 4096 mmap succeeded: addr = 0x800538000 $ procstat -v 38899 PID STARTEND PRT RES PRES REF SHD FL TP PATH 38899 0x40 0x401000 r-x10 1 0 CN vn /tmp/test-mmap 38899 0x50 0x60 rw-20 1 0 -- df 388990x800500x80053 r-x 480 218 95 CN vn /libexec/ld-elf.so.1 388990x800530x800538000 rw-70 2 0 -- df 388990x8005380000x800539000 rwx00 2 0 -- df 388990x80062f0000x800637000 rw-80 1 0 C- vn /libexec/ld-elf.so.1 388990x8006370000x800646000 rw-50 1 0 -- df 388990x8006460000x80074e000 r-x 1460 218 95 CN vn /lib/libc.so.7 388990x80074e0000x80084e000 ---00 2 0 -- df 388990x80084e0000x80086d000 rw- 310 1 0 C- vn /lib/libc.so.7 388990x80086d0000x800888000 rw-60 2 0 -- df 388990x800a00x800c0 rw-50 1 0 -- df 38899 0x7ffe 0x8000 rwx30 1 0 -- df 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. Am I doing something wrong here ? -- Ganael LAPLANCHE ganael.laplan...@martymac.org http://www.martymac.org | http://contribs.martymac.org FreeBSD: martymac marty...@freebsd.org, http://www.FreeBSD.org ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to freebsd-stable-unsubscr...@freebsd.org
Re: Using mmap(2) with a hint address
Hi Andriy, Hi Tijl, On Tue, 20 Dec 2011 12:10:47 +0200, Andriy Gapon wrote Can the following code explain what you are seeing? [...] Yes, for sure. I had seen this part of the code but, to be honest, had not understood the meaning of this computation. On Tue, 20 Dec 2011 11:10:26 +0100, Tijl Coosemans wrote FreeBSD 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). Thanks for the explanation! Reducing reserved space for data segment seems to work. But there is still something I don't understand : on the Linux machine where I ran my test program, the current RLIMIT_DATA is set to 0x/0x and I can manage to mmap at address 0x2000. If I set the same limit on FreeBSD, I won't get the mapping at 0x2000. So, there *is* a difference of behaviour between the two systems, but I don't understand why. Thanks to both of you, Best regards, -- Ganael LAPLANCHE ganael.laplan...@martymac.org http://www.martymac.org | http://contribs.martymac.org FreeBSD: martymac marty...@freebsd.org, http://www.FreeBSD.org ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to freebsd-stable-unsubscr...@freebsd.org
Re: Using mmap(2) with a hint address
On Tue, 20 Dec 2011 15:02:01 +0100 (CET), Ganael LAPLANCHE wrote But there is still something I don't understand : on the Linux machine where I ran my test program, the current RLIMIT_DATA is set to 0x/0x and I can manage to mmap at address 0x2000. If I set the same limit on FreeBSD, I won't get the mapping at 0x2000. So, there *is* a difference of behaviour between the two systems, but I don't understand why. Well, in fact, two things remain not very clear for me : - Why are mmap()s performed *after* data segment ? = It seems they can go within, on GNU/Linux and NetBSD. - Why do we have such a default value for datasize (8.2, amd64) : $ limits Resource limits (current): cputime infinity secs filesize infinity kB datasize 33554432 kB this is HUGE ! -- Ganael LAPLANCHE ganael.laplan...@martymac.org http://www.martymac.org | http://contribs.martymac.org FreeBSD: martymac marty...@freebsd.org, http://www.FreeBSD.org ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to freebsd-stable-unsubscr...@freebsd.org
Re: Using mmap(2) with a hint address
On Tue, 20 Dec 2011 17:03:03 +0200, Andriy Gapon wrote Just a guess - this might be some sort of optimization to keep virtual address range of dynamic allocations untouched by unrelated mmap calls. Not sure if that's so and how useful could that be. svn log / svn annotate of the file may reveal more details. Mmmhh It seems that this part of the code is quite old and was already present in the BSD 4.4 Lite kernel (not exactly in the same shape, but with the same idea). Quite confusing... -- Ganael LAPLANCHE ganael.laplan...@martymac.org http://www.martymac.org | http://contribs.martymac.org FreeBSD: martymac marty...@freebsd.org, http://www.FreeBSD.org ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to freebsd-stable-unsubscr...@freebsd.org