Re: Using mmap(2) with a hint address

2011-12-22 Thread Ganael LAPLANCHE
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

2011-12-20 Thread Ganael LAPLANCHE
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

2011-12-20 Thread Ganael LAPLANCHE
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

2011-12-20 Thread Ganael LAPLANCHE
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

2011-12-20 Thread Ganael LAPLANCHE
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