This speeds up process startup and teardown and also reduces lock contention when running multiple ASanified/TSanified processes simultaneously. Should greatly improve lit testing time.
Details
- Reviewers
dvyukov george.karpenkov delcypher kcc eugenis - Commits
- rGc4b8eb53c4cd: [sanitizer] Use "fast mmap" kernel flag for shadow memory on macOS 10.13.4+
rL346262: [sanitizer] Use "fast mmap" kernel flag for shadow memory on macOS 10.13.4+
rCRT346262: [sanitizer] Use "fast mmap" kernel flag for shadow memory on macOS 10.13.4+
Diff Detail
Event Timeline
lib/sanitizer_common/sanitizer_mac.cc | ||
---|---|---|
764 | Would you like to resolve this by moving into your new function? |
lib/sanitizer_common/sanitizer_mac.cc | ||
---|---|---|
764 | Yes, nice catch! Will send another patch after this one. |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
331 ↗ | (On Diff #152344) | Is there a reason the use_xnu_fast_mmap isn't pushed into the Darwin implementation of internal_mmap()? Wouldn't it make more sense to be there given that xnu_fast_mmap is Darwin specific? |
391 ↗ | (On Diff #152344) | Again can't we move this into the Darwin implementation of internal_mmap(). This will also mean we avoid duplicating code. |
lib/tsan/rtl/tsan_rtl.cc | ||
362–364 | __sanitizer::InitializePlatformEarly() is different from InitializePlatformEarly() that's called immediately afterwards? |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
331 ↗ | (On Diff #152344) | We don't want to use this flag in internal_mmap, that would apply to all mmap calls. We really only want this flag for the shadow memory. I can add another argument to internal_mmap, but that looks to me like it would complicate things more than clarify them. |
lib/tsan/rtl/tsan_rtl.cc | ||
362–364 | Yes. Tsan has __tsan::InitializePlatformEarly. |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
331 ↗ | (On Diff #152344) | Why wouldn't you want to take the fast path for all mmap calls? I suppose it's the fast path for large allocations but not necessarily smaller ones? If we're going with this approach there should probably be a comment or note in the commit message explaining why the decision to use fast_mmap has to belong in these locations and not in internal_mmap. I'd kind of feel that the fast mmap option really should be a flag because that would allow us to pass that flag and then handle it in internal_mmap() (i.e. on non Darwin platforms, strip out the flag and use it appropriately on Darwin). That would avoid having to change all call sites to internal_mmap(). The problem is mmap flag values are likely reserved and adding our own special value makes me feel uneasy because if another platform (or even Darwin) ever uses that flag value to mean something else, then semantics of internal_mmap will be broken. So I guess we have to do something else. |
lib/tsan/rtl/tsan_rtl.cc | ||
362–364 | Ah. Personally I'd rather it read as __sanitizer::InitializePlatformEarly(); __tsan::InitializePlatformEarly(); for clarity but I won't insist on this if you really want to write it how it is now. |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
331 ↗ | (On Diff #152344) | I'll add the comment with a bit of explanation, but I think you won't be fully satisfied because I don't understand what exactly the behavior of this flag is either. It was added into xnu specifically for the sanitizers and it's supposed to only be used for the shadow memory (giant region sizes), and not for other memory allocations. I don't know why. The interface of internal_mmap is exactly the same as mmap, so I don't think we want to change it, or pass "fd" into "flags". |
lib/tsan/rtl/tsan_rtl.cc | ||
362–364 | Sure, I'll change it. |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
338 ↗ | (On Diff #152344) | Side note. This implementation will prevent the VM tag being set (see https://reviews.llvm.org/D49603 ) with fast mmap is being used. This needs to be fixed. |
391 ↗ | (On Diff #152344) | Side note. This implementation will prevent the VM tag being set (see https://reviews.llvm.org/D49603 ) with fast mmap is being used. This needs to be fixed. |
lib/sanitizer_common/sanitizer_mac.cc | ||
---|---|---|
138 | Thanks for fixing the VM tag issue! | |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
337 ↗ | (On Diff #157177) | The name internal_mmap_shadow(...) implies that this function is only for use in allocating shadow regions. However the name MmapFixedNoReserve() doesn't imply that. However, looking at the uses |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
337 ↗ | (On Diff #157177) | “large” to me doesn’t imply what I mean here. A 10 MB mmap is “large”. But “shadow” regions imply they are proportional in size to the entire VM address space. |
lib/sanitizer_common/sanitizer_posix_libcdep.cc | ||
---|---|---|
337 ↗ | (On Diff #157177) | Ok. By "large" I mean extremely "large" but I guess that could also be confusing. I guess the remaining thing to address is MmapFixedNoReserve() calling internal_mmap_shadow(). I don't like MmapFixedNoReserve() (which has a name that does not imply it is for shadow memory) calling a function whose name implies it is for use for shadow memory. A comment on MmapFixedNoReserve() saying it is meant for allocating shadow memory might be sufficient. |
Ok. By "large" I mean extremely "large" but I guess that could also be confusing. I guess the remaining thing to address is MmapFixedNoReserve() calling internal_mmap_shadow(). I don't like MmapFixedNoReserve() (which has a name that does not imply it is for shadow memory) calling a function whose name implies it is for use for shadow memory.
I've updated the patch to now split out MmapFixedNoReserve into MmapFixedNoReserveShadow. The latter is used when allocating shadow regions.
Other than the kXnuFastMmapFd declaration. LGTM.
lib/sanitizer_common/sanitizer_mac.cc | ||
---|---|---|
131 | Any particular reason to use a macro rather than static const int kXnuFastMmapFd = 0x4;? The later style seems used more in the sanitizer code base (at least the bits I've seen). This is a very minor issue though so I'll leave changing this to your discretion. |
I don't like the new Mmap*Shadow functions. The number of different Mmap* functions is growing exponentially with any new feature, let's use flags and/or arguments instead.
It is also not clear from the user side what this Shadow suffix means exactly. If that's an optimization for huge mappings, can't we define a size threshold when it is more efficient than the alternative, and use it under the hood in common Mmap* calls?
lib/sanitizer_common/sanitizer_mac.cc | ||
---|---|---|
119 | Leftover debug? More of the same below. |
Okay, simplifying this patch back, and only applying the "fast mmap" flag based on a size threshold.
r346264 | d0k | 2018-11-06 12:42:19 -0800 (Tue, 06 Nov 2018) | 11 lines [dfsan] Fix build after r346262 compiler-rt/lib/dfsan/dfsan.cc:426:3: error: call to 'InitializePlatformEarly' is ambiguous InitializePlatformEarly(); ^~~~~~~~~~~~~~~~~~~~~~~ compiler-rt/lib/dfsan/../sanitizer_common/sanitizer_common.h:901:6: note: candidate function void InitializePlatformEarly(); ^ compiler-rt/lib/dfsan/dfsan.cc:391:13: note: candidate function static void InitializePlatformEarly() { ^
Thanks and sorry about this! Please let me know if the failure is still there!
Leftover debug? More of the same below.