[compiler-rt] d423509 - [scudo] Check if MADV_DONTNEED zeroes memory

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 22 10:40:46 PDT 2021


Author: Vitaly Buka
Date: 2021-04-22T10:40:18-07:00
New Revision: d423509b8036c29bbf94dab192d12097555ce0f8

URL: https://github.com/llvm/llvm-project/commit/d423509b8036c29bbf94dab192d12097555ce0f8
DIFF: https://github.com/llvm/llvm-project/commit/d423509b8036c29bbf94dab192d12097555ce0f8.diff

LOG: [scudo] Check if MADV_DONTNEED zeroes memory

QEMU just ignores MADV_DONTNEED
https://github.com/qemu/qemu/blob/b1cffefa1b163bce9aebc3416f562c1d3886eeaa/linux-user/syscall.c#L11941

Depends on D100998.

Differential Revision: https://reviews.llvm.org/D101031

Added: 
    

Modified: 
    compiler-rt/lib/scudo/standalone/linux.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/scudo/standalone/linux.cpp b/compiler-rt/lib/scudo/standalone/linux.cpp
index c2fdf211e22f5..9b5ed67c515d5 100644
--- a/compiler-rt/lib/scudo/standalone/linux.cpp
+++ b/compiler-rt/lib/scudo/standalone/linux.cpp
@@ -10,6 +10,7 @@
 
 #if SCUDO_LINUX
 
+#include "atomic_helpers.h"
 #include "common.h"
 #include "linux.h"
 #include "mutex.h"
@@ -89,9 +90,40 @@ void setMemoryPermission(uptr Addr, uptr Size, uptr Flags,
     dieOnMapUnmapError();
 }
 
+static bool madviseNeedsMemset() {
+  uptr Size = getPageSizeCached();
+  char *P = (char *)mmap(0, Size, PROT_READ | PROT_WRITE,
+                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (!P)
+    dieOnMapUnmapError(errno == ENOMEM);
+  *P = -1;
+  while (madvise(P, Size, MADV_DONTNEED) == -1 && errno == EAGAIN) {
+  }
+  bool R = (*P != 0);
+  if (munmap(P, Size) != 0)
+    dieOnMapUnmapError();
+  return R;
+}
+
+static bool madviseNeedsMemsetCached() {
+  static atomic_u8 Cache;
+  enum State : u8 { Unknown = 0, Yes = 1, No = 2 };
+  State NeedsMemset = static_cast<State>(atomic_load_relaxed(&Cache));
+  if (NeedsMemset == Unknown) {
+    NeedsMemset = madviseNeedsMemset() ? Yes : No;
+    atomic_store_relaxed(&Cache, NeedsMemset);
+  }
+  return NeedsMemset == Yes;
+}
+
 void releasePagesToOS(uptr BaseAddress, uptr Offset, uptr Size,
                       UNUSED MapPlatformData *Data) {
   void *Addr = reinterpret_cast<void *>(BaseAddress + Offset);
+  if (madviseNeedsMemsetCached()) {
+    // Workaround for QEMU-user ignoring MADV_DONTNEED.
+    // https://github.com/qemu/qemu/blob/b1cffefa1b163bce9aebc3416f562c1d3886eeaa/linux-user/syscall.c#L11941
+    memset(Addr, 0, Size);
+  }
   while (madvise(Addr, Size, MADV_DONTNEED) == -1 && errno == EAGAIN) {
   }
 }


        


More information about the llvm-commits mailing list