From 91dc545bf24daa60c21c93039408061194dd0ab3 Mon Sep 17 00:00:00 2001 From: Jianzhou Zhao Date: Sun, 18 Oct 2020 04:39:31 +0000 Subject: [PATCH] Set Huge Page mode on shadow regions based on no_huge_pages_for_shadow It turned out that at dynamic shared library mode, the memory access pattern can increase memory footprint significantly on OS when transparent hugepages (THP) are enabled. This could cause >70x memory overhead than running a static linked binary. For example, a static binary with RSS overhead 300M can use > 23G RSS if it is built dynamically. /proc/../smaps shows in 6204552 kB RSS 6141952 kB relates to AnonHugePages. Also such a high RSS happens in some rate: around 25% runs may use > 23G RSS, the rest uses in between 6-23G. I guess this may relate to how user memory is allocated and distributted across huge pages. THP is a trade-off between time and space. We have a flag no_huge_pages_for_shadow for sanitizer. It is true by default but DFSan did not follow this. Depending on if a target is built statically or dynamically, maybe Clang can set no_huge_pages_for_shadow accordingly after this change. But it still seems fine to follow the default setting of no_huge_pages_for_shadow. If time is an issue, and users are fine with high RSS, this flag can be set to false selectively. --- compiler-rt/lib/dfsan/dfsan.cpp | 4 +++- compiler-rt/test/dfsan/release_shadow_space.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp index 767c49b..5da2138 100644 --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -475,8 +475,10 @@ static void dfsan_init(int argc, char **argv, char **envp) { ::InitializePlatformEarly(); - if (!MmapFixedNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr())) + if (!MmapFixedSuperNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr())) Die(); + if (common_flags()->use_madv_dontdump) + DontDumpShadowMemory(ShadowAddr(), UnusedAddr() - ShadowAddr()); // Protect the region of memory we don't use, to preserve the one-to-one // mapping from application to shadow memory. But if ASLR is disabled, Linux diff --git a/compiler-rt/test/dfsan/release_shadow_space.c b/compiler-rt/test/dfsan/release_shadow_space.c index 40c0f38..40326a9 100644 --- a/compiler-rt/test/dfsan/release_shadow_space.c +++ b/compiler-rt/test/dfsan/release_shadow_space.c @@ -1,4 +1,5 @@ -// RUN: %clang_dfsan %s -o %t && %run %t +// DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -o %t && %run %t +// DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -o %t && %run %t #include #include -- 2.7.4