-
Notifications
You must be signed in to change notification settings - Fork 16
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
Mimalloc download #54
base: master
Are you sure you want to change the base?
Conversation
b65f6f3
to
5dc728a
Compare
Thanks, @andronat. I haven't looked at the details, but I think the TLS switching should be separate from adding support for mimalloc. In other words, SaBRe should work the same with mimalloc as it does now for our plugins, even w/o switching the TLS. Furthermore, because it's expensive, I would make that configurable. |
Going even further down the rabbit hole, when the But why do we need these vars to be |
@ccadar I'm afraid the TLS mechanism is fundamental to the correctness of SaBRe and thus we can't add mimalloc without fixing the TLS first. In addition, I don't think we can make this mechanism optional as:
It is a mere coincidence that until now we didn't see a crash in SaBRe's plugins. For example, in my VM all the tests are passing, while in Travis things are failing (this is why I asked for ssh access to travis-ci.com because I couldn't reproduce the issues in my machine), I was lucky enough for the silent memory corruption to not disturb the output of the tests. Something that can be done is merge the TLS fixes first (when properly done, because I see travis failing again) and then the memory allocator. But for now mimalloc is a good test that surfaces important issues. |
@andronat I agree that to be able to support a more diverse set of plugins, we need to swap the TLS. But at the same time, I think it's important to allow plugins like Varan -- which perform their own synchronization, etc. -- to be as fast as they are now. So I think the right solution is to add that fix, but make it configurable at compile time (or maybe even at runtime if the extra check doesn't add much overhead, not sure). And yes, I would make that change in a different PR. |
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 mimalloc
introduction and patch look good to me.
However, the TLS runtime switch poses a couple of problems. Other than the ones already mentioned by @ccadar , I'm worried about the clone
syscall. When a new thread is created, pthread and libc set up one new TLS. But here we have two TLS. Leaving one of those two TLS uninitialised is fraught with errors.
Unfortunately, I don't have a solution to that yet. This issue is actually what prevented me from implementing runtime TLS switch, limiting to load-time switch only.
To throw another wrench in the mix, TLS stores its variables (i.e. As an example, you can verify this by From test
From SaBRe:
It should be obvious that those two will always clash if the But is the The answer is yes most of the time, but no during the TLS swapping... In functions Further explanation can be found here. Bottomline: Switching TLS is much much harder than expected to do it properly. What can we do?: I'm not sure to be honest. This is a chicken-and-egg problem. I could potentially mmap some random page in memory and keep the TLS pointers there manually. |
Before the TLS switch you can take a pointer to the address of the thread local variable and access it through there as mentioned in GCC’s documentation: |
Hmm, I don't see how this could work. I would still need to store the address to some thread-local variable for later use.
Yea, this is exactly what I wanted to avoid to implement 😞 |
You can store the pointers as local variables in proxy_plugin_sc_handler. Just get the addresses before the switch there and explicitly pass them in to the TLS switching routines. |
c264bd3
to
249754e
Compare
249754e
to
6b101e5
Compare
82dbdec
to
deccce3
Compare
An update on my side:
Issues:
|
Hi @andronat thanks! I would still remove the commit that switches to Mimalloc to a follow-up PR. I think it's orthogonal to the TLS issue, and it would be good to see that the regression tests pass before the switch (they should, right?). |
deccce3
to
c19ab74
Compare
Just another update on my side, I was able to run zboxfs as a new plugin with the current PR. To make it run though I had to solve another tricky issue, see commit here: 34df09d. Whenever a new thread is created a new stack is also allocated for the new thread. In the beginning of this newly created stack, Unfortunately I'm not sure how can I use some more robust way to measure the size of these structs as This strategy is very risky as I don't know if any of these "after-TLS" information need to be carefully derived from the parent SaBRe process. I think at this point we are reaching the limits of this architecture and we should be moving forward with re-architecting the plugins. |
@andronat Thanks for your great endeavour trying to make this TLS scheme work. Unfortunately you're now running into the kind of intricacies that I absolutely wanted to avoid. All of this is completely undocumented and private to a specific libc implementation. It may even change between two minor revisions of glibc. Therefore, unless you have a clear idea of how to make this scheme robust, I'm not sure it is worth your time trying to go further into this direction. |
One clean solution that I can contemplate would be to call |
Yea, my point exactly. We are at the limit of this approach. Re-architecting how the plugins are working might be an one-way.
I've thought about about this but only briefly. If I understand correctly, what you mention is that we have one idle thread on the side, created by SaBRe, that we can use as a template to copy the required stack and TLS information to the newly created client thread, right? In this case, I'm still concerned about the Another idea I had that I though only briefly, was to actually double call |
This is more or less what I have in mind.
|
My concern is there will be 1 In any case, I would like to explore a little bit adding the plugin as a dependency to the client before I go deeper on the current approach. I'll be opening a PR soon to compare. |
RIght. Then, we could go one step further in this direction and completely run the plugin inside the |
This PR contains the following changes that are required to be bundled together in order for tests to pass:
libmimalloc.so
library should be placed. Having one binary that you can move anywhere you want is much more flexible.mmap
to handle its heap. This creates a natural separation between SaBRe+plugins and the client. mimalloc is also relatively small and usescmake
that makes it "easy" to integrate its build with SaBRe.jemalloc
butjemalloc
by default usesbrk()
so we end up having the same issue aslibc
.tcmalloc
.LD_PRELOAD=./libmimalloc.so.1.6 cat /proc/self/maps | less
). These maps are created withmmap
when SaBRe starts (as SaBRe now uses mimalloc). Now when we load a client that usestsan
,tsan
scans the memory to check what is there already. We had issues with this scanning process before, this is why we have this SaBRe code here.tsan
doesn't recognize these mimalloc-heap memory areas as "standard" and throws an error when scans the process memory maps. You can find thetsan
allowed ranges here, whatever is outside of these ranges, will maketsan
fail. In the beginning I though of patching the SaBRe code to hide the mimalloc-heap area but I think this will create more issues rather than solve anything. So the easiest way is to disable the mimalloc hint, and delegate themmap
area to the kernel. This is absolutely fine from mimalloc's perspective.MI_LOCAL_DYNAMIC_TLS=ON
: Read here.cmake
made my life extremely hard and at some point I just quit. If anyone has an opinion regarding.a
vs.o
static linking, I would also like to know more.