You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Michael Vergoz <mv...@binarysec.com> on 2005/06/29 23:06:51 UTC

apr mmap/ & shm/ problem.

Hello,

Just have a look at http://issues.apache.org/bugzilla/show_bug.cgi?id=35535

I need feedback about using my mmap design (something lost ? somethings maybe 
added ?).
This design will be very useful for the new shm design.
I have a local copy of my own shm (the copyright is handled by my company). I 
would like to do a proposal to port my shm model to Apache.
My shm model support dynamic extension. 

But at the moment we have to fix mmap. I have added 2 major things.
1) Portable remap.
2) Internal pager. Original_page_size * Pager. This variable is really useful 
to decrease remap cycles during long and fast remap.

Here is a small definition of symbols :

apr_mem_pager - align size to the biggest page (with multiple).

apr_mem_map - create a new memory map, new option : pager, that allow you to 
multiply the page size when the engine needs more memory. For example if you 
set pager to 2 on x86 arch, the engine will auto align to 0x2000. 

apr_mem_unmap - destroy a map.

apr_mem_remap - memory map reallocation. You can set a unaligned size, the 
engine will auto align it.

apr_mem_protection - change the protection of a map.

apr_mem_sync - sync the memory if a file is projected as SHARED.

If you think that i should add something....

The SHM proof-of-concept will be avaible as soon as apache devel justify me :)

To make MMAP/SHM apr-ready i have to pass through steps.
Apr type link
Apr open/close/seek link
Indentation :)

PS: my mmap was test on Linux (2.4 / 2.6) and Darwin, see source for more 
informations.

Sorry for my p0000r english.
Michael Vergoz


Re: apr mmap/ & shm/ problem.

Posted by Michael Vergoz <mv...@binarysec.com>.
You may know that the strlen() function computes the length of the string 
*without" the \0 char !

Example :
if buffer = "AAAAA[...]AAA" = 0x2001
buffer_size = strlen(buffer) = 0x2000.
apr_mem_remap(Map, buffer_size+1) = will map 0x3000 see apr_mem_pager().
memcpy(Map->base, buffer, buffer_size);
strlen(Map->base) = 0x2000

Regards,
Michael Vergoz

Le Jeudi 30 Juin 2005 00:41, Bruce Korb a écrit :
> Michael Vergoz wrote:
>  > Hi Bruce,
>  >
>  > Yes
>
> Thank you!
>
>  > because you must align the page to the biggest you can.
>
> ??  The problem is is that no matter how you align the thing,
> if the last byte of the file is the last byte of a page,
> then the next byte is unmapped.  Consequently, when "strlen(3C)"
> tries to determine if the next byte after the last valid byte
> is NUL or not, it faults on a bad memory reference.  There
> are several solutions:
>
> Punt mmap and just read the file into an allocated buffer.
>
> mmap the file then figure out if the last byte is the last
> byte of a page.  If so, then mmap anonymous memory into
> the fixed address following the last page of the text file.
> I do this, but it is a real pain.  I hate it.  :-)  Most
> often, I just allocate and read the file 'cuz it is easier.
>
>  > Have a look at : http://badcode.be/~descript/.apache/
>  >
>  > Into function apr_mem_pager() :
>  > if you need 0x2001 (Size).
>  > <snip>
>  > 	ret = size; // ret = 0x2001
>  > 	if((ret%_apr_mem_page_size) != 0) { // 0x0001
>  > 		ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
>  > 		ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
>  > 	}
>  > </snip>
>
> Right.  If "size" is 0x2000 exactly, the byte following the
> mapping will be unmapped and "strlen(3C)" will fault.
> That's the problem.$
>
>  > You may have a look at apr_mem_remap(). It will allow you to ask for a
>  > unaligned address. Then the engine will auto update the address
>  > alignment with a predefined pager (defined by the pager argument in
>  > apr_mem_map()).
>
> OK.  So, if I check the file size and it is a multiple of a page size,
> then I should ask for non-aligned mapping, otherwise an aligned mapping?
> Better than messing around with anonymous pages on my own, but still.....
>
> Thanks.  Regards, Bruce


Re: apr mmap/ & shm/ problem.

Posted by Bruce Korb <bk...@veritas.com>.
Michael Vergoz wrote:
 > Hi Bruce,
 >
 > Yes
Thank you!

 > because you must align the page to the biggest you can.

??  The problem is is that no matter how you align the thing,
if the last byte of the file is the last byte of a page,
then the next byte is unmapped.  Consequently, when "strlen(3C)"
tries to determine if the next byte after the last valid byte
is NUL or not, it faults on a bad memory reference.  There
are several solutions:

Punt mmap and just read the file into an allocated buffer.

mmap the file then figure out if the last byte is the last
byte of a page.  If so, then mmap anonymous memory into
the fixed address following the last page of the text file.
I do this, but it is a real pain.  I hate it.  :-)  Most
often, I just allocate and read the file 'cuz it is easier.

 > Have a look at : http://badcode.be/~descript/.apache/
 >
 > Into function apr_mem_pager() :
 > if you need 0x2001 (Size).
 > <snip>
 > 	ret = size; // ret = 0x2001
 > 	if((ret%_apr_mem_page_size) != 0) { // 0x0001
 > 		ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
 > 		ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
 > 	}
 > </snip>

Right.  If "size" is 0x2000 exactly, the byte following the
mapping will be unmapped and "strlen(3C)" will fault.
That's the problem.

 > You may have a look at apr_mem_remap(). It will allow you to ask for a
 > unaligned address. Then the engine will auto update the address alignment
 > with a predefined pager (defined by the pager argument in apr_mem_map()).

OK.  So, if I check the file size and it is a multiple of a page size,
then I should ask for non-aligned mapping, otherwise an aligned mapping?
Better than messing around with anonymous pages on my own, but still.....

Thanks.  Regards, Bruce

Re: apr mmap/ & shm/ problem.

Posted by Michael Vergoz <mv...@binarysec.com>.
Yes it's possible, my shm model do that by auto extending the file and memory 
via write function.
When you use private (with/without anon) map you can set the segment size you 
want.
The extending problem occur because Apache can only manage MAP_SHARED.
Normaly it should be set to MAP_PRIVATE.
And MAP_SHARED need a special usage to extented the file/mem. 

Process:
msync()
munmap() 
write() padding
close()
open()
mmap()

with MAP_SHARED you can't use mremap() with MAP_PRIVATE yes.

Can you have a look at http://badcode.be/~descript/.apache/2.0.txt

Regards,
Michael

Le Jeudi 30 Juin 2005 00:42, Bruce Korb a écrit :
> Michael Vergoz wrote:
>  > Bruce,
>  >
>  > <snip>
>  >         ret = size; // ret = 0x2001
>  >         if((ret%_apr_mem_page_size) != 0) { // 0x0001
>  >                 ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 =
>  > 0x2000 ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER }
>  > 	// ret = 0x3000 :P
>  > </snip>
>  >
>  > When you try to sync a file into memory (file to memory) apr_mem_map()
>  > will also do a "pager" auto update...
>
> Hi Mike,
>
> You cannot extend mmapped files.  The trailing page is just there to avoid
> a seg fault.  :) - Bruce


Re: apr mmap/ & shm/ problem.

Posted by Michael Vergoz <mv...@binarysec.com>.
Le Jeudi 30 Juin 2005 00:42, Bruce Korb a écrit :
> Michael Vergoz wrote:
>  > Bruce,
>  >
>  > <snip>
>  >         ret = size; // ret = 0x2001
>  >         if((ret%_apr_mem_page_size) != 0) { // 0x0001
>  >                 ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 =
>  > 0x2000 ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER }
>  > 	// ret = 0x3000 :P
>  > </snip>
>  >
>  > When you try to sync a file into memory (file to memory) apr_mem_map()
>  > will also do a "pager" auto update...
>
> Hi Mike,
>
> You cannot extend mmapped files.  The trailing page is just there to avoid
> a seg fault.  :) - Bruce

Heh :)
Yes you can :P
You must unmap the current map, write padding, close descriptor, open file and 
remap it. That the way with MAP_SHARED !!! (that also the way for 
apr_mmap_create() because it specify map_shared only.) (that what my shm 
implementation do).
With MAP_PRIVATE you don't have to write padding and close/open descriptor.

Michael


Re: apr mmap/ & shm/ problem.

Posted by Bruce Korb <bk...@veritas.com>.
Michael Vergoz wrote:
 > Bruce,
 >
 > <snip>
 >         ret = size; // ret = 0x2001
 >         if((ret%_apr_mem_page_size) != 0) { // 0x0001
 >                 ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
 >                 ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
 >         }
 > 	// ret = 0x3000 :P
 > </snip>
 >
 > When you try to sync a file into memory (file to memory) apr_mem_map() will
 > also do a "pager" auto update...

Hi Mike,

You cannot extend mmapped files.  The trailing page is just there to avoid
a seg fault.  :) - Bruce

Re: apr mmap/ & shm/ problem.

Posted by Michael Vergoz <mv...@binarysec.com>.
Bruce,

<snip>
        ret = size; // ret = 0x2001
        if((ret%_apr_mem_page_size) != 0) { // 0x0001
                ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
                ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
        }
	// ret = 0x3000 :P
</snip>

When you try to sync a file into memory (file to memory) apr_mem_map() will 
also do a "pager" auto update...

Thanks,
Michael
Le Jeudi 30 Juin 2005 00:23, Michael Vergoz a écrit :
> Hi Bruce,
>
> Yes because you must align the page to the biggest you can.
> Have a look at : http://badcode.be/~descript/.apache/
>
> Into function apr_mem_pager() :
> if you need 0x2001 (Size).
> <snip>
> 	ret = size; // ret = 0x2001
> 	if((ret%_apr_mem_page_size) != 0) { // 0x0001
> 		ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
> 		ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
> 	}
> </snip>
>
> You may have a look at apr_mem_remap(). It will allow you to ask for a
> unaligned address. Then the engine will auto update the address alignment
> with a predefined pager (defined by the pager argument in apr_mem_map()).
>
> Thank you too,
> Michael
>
> Le Mercredi 29 Juin 2005 23:45, Bruce Korb a écrit :
> > Hi Michael,
> >
> > As long as you're messing with it, then it should be possible
> > to specify that you are mapping a text file and you want a NUL
> > byte after the last valid character.  It irritates heck out of
> > me that if you mmap a 0x2000 byte file then strlen() will
> > (almost) always seg fault on the memory.  Force an extra anonymous
> > page in such circumstances.  :-)  Thanks - Bruce
> >
> > Michael Vergoz wrote:
> > > Hello,
> > >
> > > Just have a look at
> > > http://issues.apache.org/bugzilla/show_bug.cgi?id=35535
> > >
> > > I need feedback about using my mmap design (something lost ? somethings
> > > maybe added ?).
> > > This design will be very useful for the new shm design.
> > > I have a local copy of my own shm (the copyright is handled by my
> > > company). I would like to do a proposal to port my shm model to Apache.
> > > My shm model support dynamic extension.
> > >
> > > But at the moment we have to fix mmap. I have added 2 major things.
> > > 1) Portable remap.
> > > 2) Internal pager. Original_page_size * Pager. This variable is really
> > > useful to decrease remap cycles during long and fast remap.
> > >
> > > Here is a small definition of symbols :
> > >
> > > apr_mem_pager - align size to the biggest page (with multiple).
> > >
> > > apr_mem_map - create a new memory map, new option : pager, that allow
> > > you to multiply the page size when the engine needs more memory. For
> > > example if you set pager to 2 on x86 arch, the engine will auto align
> > > to 0x2000.
> > >
> > > apr_mem_unmap - destroy a map.
> > >
> > > apr_mem_remap - memory map reallocation. You can set a unaligned size,
> > > the engine will auto align it.
> > >
> > > apr_mem_protection - change the protection of a map.
> > >
> > > apr_mem_sync - sync the memory if a file is projected as SHARED.
> > >
> > > If you think that i should add something....
> > >
> > > The SHM proof-of-concept will be avaible as soon as apache devel
> > > justify me :)
> > >
> > > To make MMAP/SHM apr-ready i have to pass through steps.
> > > Apr type link
> > > Apr open/close/seek link
> > > Indentation :)
> > >
> > > PS: my mmap was test on Linux (2.4 / 2.6) and Darwin, see source for
> > > more informations.
> > >
> > > Sorry for my p0000r english.
> > > Michael Vergoz


Re: apr mmap/ & shm/ problem.

Posted by Michael Vergoz <mv...@binarysec.com>.
Hi Bruce,

Yes because you must align the page to the biggest you can.
Have a look at : http://badcode.be/~descript/.apache/

Into function apr_mem_pager() :
if you need 0x2001 (Size).
<snip>
	ret = size; // ret = 0x2001
	if((ret%_apr_mem_page_size) != 0) { // 0x0001
		ret -= (ret%_apr_mem_page_size); // ret -= 0x0001 = 0x2000
		ret += _apr_mem_page_size*map->pager; // ret += 0x1000*PAGER
	}
</snip>

You may have a look at apr_mem_remap(). It will allow you to ask for a 
unaligned address. Then the engine will auto update the address alignment 
with a predefined pager (defined by the pager argument in apr_mem_map()).

Thank you too,
Michael

Le Mercredi 29 Juin 2005 23:45, Bruce Korb a écrit :
> Hi Michael,
>
> As long as you're messing with it, then it should be possible
> to specify that you are mapping a text file and you want a NUL
> byte after the last valid character.  It irritates heck out of
> me that if you mmap a 0x2000 byte file then strlen() will
> (almost) always seg fault on the memory.  Force an extra anonymous
> page in such circumstances.  :-)  Thanks - Bruce
>
> Michael Vergoz wrote:
> > Hello,
> >
> > Just have a look at
> > http://issues.apache.org/bugzilla/show_bug.cgi?id=35535
> >
> > I need feedback about using my mmap design (something lost ? somethings
> > maybe added ?).
> > This design will be very useful for the new shm design.
> > I have a local copy of my own shm (the copyright is handled by my
> > company). I would like to do a proposal to port my shm model to Apache.
> > My shm model support dynamic extension.
> >
> > But at the moment we have to fix mmap. I have added 2 major things.
> > 1) Portable remap.
> > 2) Internal pager. Original_page_size * Pager. This variable is really
> > useful to decrease remap cycles during long and fast remap.
> >
> > Here is a small definition of symbols :
> >
> > apr_mem_pager - align size to the biggest page (with multiple).
> >
> > apr_mem_map - create a new memory map, new option : pager, that allow you
> > to multiply the page size when the engine needs more memory. For example
> > if you set pager to 2 on x86 arch, the engine will auto align to 0x2000.
> >
> > apr_mem_unmap - destroy a map.
> >
> > apr_mem_remap - memory map reallocation. You can set a unaligned size,
> > the engine will auto align it.
> >
> > apr_mem_protection - change the protection of a map.
> >
> > apr_mem_sync - sync the memory if a file is projected as SHARED.
> >
> > If you think that i should add something....
> >
> > The SHM proof-of-concept will be avaible as soon as apache devel justify
> > me :)
> >
> > To make MMAP/SHM apr-ready i have to pass through steps.
> > Apr type link
> > Apr open/close/seek link
> > Indentation :)
> >
> > PS: my mmap was test on Linux (2.4 / 2.6) and Darwin, see source for more
> > informations.
> >
> > Sorry for my p0000r english.
> > Michael Vergoz