-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Use mmap(MAP_STACK|...) for fibre stacks on OpenBSD #10875
Conversation
Personal communication with @ctk21 indicates that we can calculate the stack length at free point by the Stack_end value -- I'll simplify this patch later on |
My thinking for the size, is that you could back it out from: Lines 68 to 87 in 1546e1f
using Stack_high and Stack_base .
However there is an alignment adjustment to ensure the stack is 16-byte aligned: Lines 124 to 128 in 1546e1f
and unfortunately it doesn't look simple to know the exact boundary of the area from Stack_high as things stand.
|
I like the clarity of tracking
After re-reading the relevant man pages, I agree that I'll report back if I encounter any problems while running on this PR. |
I've been running this PR with some local (admittedly light) workloads. No problems so far beyond the domain-parallel-burn test. I manually merge this branch each morning when I rebuild trunk on my laptop, so I'd personally enjoy seeing it merged. Is it possible to disable the domain-parallel-burn test on OpenBSD? I don't know enough about OpenBSD's scheduler to send a patch upstream. |
This would need a review before we can consider merging. I just merged #10872, on which the present PR is based (it may be possible to rebase now?) thanks to @kayceesrk's review there. |
Is it possible first to try rebasing the PR to include the performance fix in #10880? I'm wanting to flush out if the domain-parallel-burn test is just slow or if there is a livelock/deadlock bug in the runtime that the test on OpenBSD is picking up. |
I merged this PR into trunk (as of commit 488a28a, which includes the fix from #10880) then ran the domain parallel spawn burn test on OpenBSD. It passes for bytecode but ends with a timeout for native. Here's |
a038c3d
to
90e4885
Compare
I pushed a Oddly enough, in a rare "OpenBSD feature speeds up Linux" situation, the use of mmaped stacks on Linux seems to be faster than the existing malloc strategy. A very rough benchmark was running Linux 'make tests' a few times with the option on/off and without this patch:
I think we need to run this on Sandmark to see if it really is faster or not without the variance. Another thing to track down is that FreeBSD crashes with mmap(MAP_STACK). This is due to its very different semantics, where it allocates a guard page to automatically grow the stack as it heads downward in memory. I suspect that on FreeBSD we'll need to have an extra page as the guard page never disappears. However, MAP_STACK just isn't that much use on FreeBSD either since we do our own manual management. |
Note: the non-mmap path uses I think that this not an issue for this PR that implements OpenBSD support ("eventually leaking some memory in corner cases" is way better than "being killed instantly"), but we think a bit harder about it before using the feature much beyond that. (I think that having a configure option is a good idea.) I guess that a "proper" way to handle this would be to add a different kind of blocks to our stat_alloc pool for mmapped memory, to call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks very reasonable to me, and I understand that it has been tested on OpenBSD.
(You still need a Changes entry and also check-typo complains)
./configure.ac:1928.81: [long-line] line is over 80 columns
I agree @gasche -- I looked into adding the tracking support into the caml_stat functions, but wanted to figure out this FreeBSD situation first. @shubhamkumar13 is going to run some Sandmark tests this week with this PR to get some more systematic results, and then I'll tidy up the Changes and check-typo and mark the PR as ready. |
90e4885
to
95de85e
Compare
No appreciable difference vs trunk or with mmap on/off on Linux, so this looks safe to merge. Thanks to @shubhamkumar13 for the Sandmark run. |
This exposes a --enable-mmap-map-stack configure option that switch stack allocation from malloc to use mmap(MAP_STACK). This is always enabled on OpenBSD, and optionally available when explicitly specified on at least Linux. FreeBSD's mmap with MAP_STACK has different semantics and is not supported.
95de85e
to
9960757
Compare
Thanks for all the reviews and the benchmarking efforts. |
OpenBSD 6.4 and higher (circa 2018ish) has a feature known as stack-register checking that requires that all memory used as a stack is allocated using
mmap(MAP_STACK)
. The kernel checks upon syscall entry if the stack pointer is aimed at such memory, and kills the process otherwise. There is no mprotect or other post-allocation way to mark a piece of memory as intended for the stack, to avoid ROP widgets.For OCaml, this means that we can't use the
caml_stat_alloc
allocator for fibre stacks, as that usesmalloc
behind the scenes and causes the native code compiler to be killed almost immediately when executed on OpenBSD 6.4+. This draft PR hides the OpenBSD-specific changes behind a #define to illustrate the changes required to pass the full OCaml test suite (apart from the domain parallel burn test, which seems to take hours and is killed with a timeout).__OpenBSD__
checks into aUSE_MMAP_MAP_STACK
config.h option, and turn that on automatically if OpenBSD is detected.With this, the test suite and the fix from #10872, OpenBSD passes the test suite with the exception of domain-parallel-burn which looks like a fairness issue in the pthread implementation in OpenBSD itself.