-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MAP_FIXED #162
Comments
I will have to double-check Stevens & etc. on this, but I'm pretty sure this can lead to portability problems. It may be free of edge cases on common platforms; whether this is a problem in practice and not just in theory is your call. |
We could use mremap when available (Linux only, AFAIK), but the most portable solution is to just copy to a larger chunk of mmap'd pooled memory. We want the same semantics as realloc, but for mmap'd memory. On OSX (Mountain Lion), overlapping MAP_FIXED mmaps will clobber each other with zeroed out memory pages, as expected: git://gist.github.com/3889656.git |
Do you mean the solution suggested on StackOverflow or something else? |
I think silently clobbering existing mappings, the expected behavior, is bad for this use case. If some platform(s) give an error instead, that's helpful, but can't be depended upon. |
Checked both 32-bit Gentoo and OSX. |
Removing (The test case to show how this fails is to map two objects contiguously in memory and then attempt to expand the first. Expected: With Advised: restore Options:
What are the timings for each? The best choice is probably the fastest. StackOverflow commenters suggest The previous idea to reserve large chunks of memory beforehand seems not as good. |
I think the above is the correct solution. (Speculation: After implementing the above, to be perfectly correct we may need to use All of this is to get around not having a portable mremap. |
Is there any benefit in using mremap for Linux (and maybe for Cygwin), and an alternate solution for OSX? |
Potentially, but it needs to be balanced against added portability issues. Scott On Thu, Mar 28, 2013 at 9:30 AM, Tom Szczesny notifications@github.comwrote:
|
It's a neutral change. NB. The full list of systems we claim to support is: OS X/Linux/BSD/Cygwin. |
FYI: Looks like Cygwin does not have mremap either. |
Suppose we use mincore(). Suppose the original k-structure uses m bytes, and we want to increase the size by an additional n bytes. We want to check that the additional n bytes do not contain an already-mapped area. (In other words, the additional n bytes needs to be completely unmapped.) |
Do you mean "contains some mapped memory"? If so, I think that gives us flag 2, and we are OK. If not, then you'll have to explain more since I don't understand. |
I did mean "contains some unmapped memory". |
OK, I see. You're saying this could give flag 3: some of the n bytes are mincore-unmapped. This is sufficient if we add a single page at a time. For multiple pages the flag is not sufficient to know whether or not we can proceed, unless we check each page. |
If flag 3 is indeed the case, we can call What is the timing like for calls to |
Z K kapn_(K _a,V *v,I n) { This comment simply documents my understanding as I go through the code: |
That looks right to me. We can further assume that |
(For specifics: I think the amount we can add is in [1, 8] bytes inclusive & tight, and that page sizes are essentially guaranteed to be much larger than that on all systems we currently support or intend to support in the future. Off the top of my head on Linux and OSX the page size is 4096. However, I think the discussion is moot since supporting kapn correctly means supporting arbitrary-count page additions.) |
The page size on Cygwin is 65536 = 2^16 (which is probably the page size on Windows). |
Just to document the latest wrinkle on this issue: In preparation for using mincore to pre-verify that each page added is not already mapped, I checked to see whether the following lines (placed in kexpander in km.c) print "map_OK" in 32-bit-Linux, OSX and Cygwin: if(MAP_FAILED!=mmap(a+e,f,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON|MAP_FIXED,-1,0)) {O("map-OK\n");R 1;}//Add pages to end I get "map-OK" in OSX and Cygwin. I get "map-failed" in 32-bit-Linux. Since I have not updated my version of 32-bit-Gentoo for over 6 months, I will attempt that and see if the problem disappears. |
That's strange. I'm not sure why the next block would already be mapped. Is it bad luck? Or does Linux automatically map the block after for some reason? Maybe a bad interaction with MAP_ANON? Perhaps good justification on Linux to use |
On 32-bit-Linux:
|
Latest wrinkle: mincore is not available in Cygwin. |
Hrm, I suppose since Cygwin is based on top of the memory manager for Windows. The Cygwin team seems to have successfully ported |
msync is present in Cygwin. |
The above commit 3137f17 demonstrates that for OSX using mincore with mmap and MAP_FIXED is not a successful replacement for mremap. If the extra space is unmapped, we are counting on mincore to fail with a return code of -1, and an errno set to ENOMEM. In fact, mincore does not fail, it has a return code of 0, and therefore errno is not set to ENOMEM. |
posix_mem_offset does not appear to be implemented in Linux, Cygwin or OSX. |
As written, a bug?
https://github.com/kevinlawler/kona/blob/master/km.c
The problem is that mapping MAP_FIXED over an existing address space won't fail, it will just destroy the other mapping if it was close enough. The bug is if another mapping is close enough behind the expanding mapping.
(I am not sure how I missed this the first time around: maybe there is some other consideration that prevents this bug. It seems like the kind of thing I would've been wary of. Maybe I thought MAP_FIXED would fail on such allocations. Does it really always succeed? It would be nice to verify via test case on OS X, Linux.) ((Another explanation is that StackOverflow didn't exist when I did this, or didn't have much on the subject, and so my understanding was based on a flawed interpretation of the POSIX documentation.))
One potential fix:
http://stackoverflow.com/questions/6446101/how-do-i-choose-a-fixed-address-for-mmap#comment7573599_6446215
"An aside: MAP_FIXED can be used safely if you first make a single mapping without MAP_FIXED, then use MAP_FIXED to create various mappings at fixed addresses relative to one another over top of the original throw-away mapping that was at a kernel-assigned location. With a sufficiently large mapping size, this might solve OP's problem."
If this lets us map "anonymous memory" without ever actual allocating real RAM, then we could always reserve something very large for any mapped structure.
The text was updated successfully, but these errors were encountered: