[compiler-rt] 5a1525c - [scudo][standalone] Precommit pages

Chia-hung Duan via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 20 09:40:42 PST 2022


Author: Yaneury Fermin
Date: 2022-12-20T17:37:49Z
New Revision: 5a1525c57635f3633e069c23f20ca12fe92ecced

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

LOG: [scudo][standalone] Precommit pages

On Fuchsia, this CL changes garbage collection
to precommit all pages if the |Buffer| doesn't
fit into the static buffer size.

A test program (scudotest) was used that deliberately
grows a size class high water mark to the point where
the pre-allocated static buffer is no longer used for
garbage collection.

Traces showed that precommiting the Vmar removes ~30 page faults
and ~.22ms of wall time.*

Before: https://ui.perfetto.dev/#!/?s=7da19fc3f59448eef51fd6fd03283bb87b702cf1a565bcbe6c9c28371671
After: https://ui.perfetto.dev/#!/?s=97707cd99b2c9efd1e6569b2deb97e3d16f8be532c59a0cc12463c37fbb1d8

*: Use the added `zx_vmar_op_range` as a reference point to observe
the differences.

For more context, see https://fxbug.dev/115594.

Reviewed By: Chia-hungDuan

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

Added: 
    

Modified: 
    compiler-rt/lib/scudo/standalone/common.h
    compiler-rt/lib/scudo/standalone/fuchsia.cpp
    compiler-rt/lib/scudo/standalone/release.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h
index d03ffd8d4fede..601481671d71d 100644
--- a/compiler-rt/lib/scudo/standalone/common.h
+++ b/compiler-rt/lib/scudo/standalone/common.h
@@ -149,6 +149,7 @@ bool getRandom(void *Buffer, uptr Length, bool Blocking = false);
 #define MAP_NOACCESS (1U << 1)
 #define MAP_RESIZABLE (1U << 2)
 #define MAP_MEMTAG (1U << 3)
+#define MAP_PRECOMMIT (1U << 4)
 
 // Our platform memory mapping use is restricted to 3 scenarios:
 // - reserve memory at a random address (MAP_NOACCESS);

diff  --git a/compiler-rt/lib/scudo/standalone/fuchsia.cpp b/compiler-rt/lib/scudo/standalone/fuchsia.cpp
index 4ce3b4ce6d181..70e4e714f2cb9 100644
--- a/compiler-rt/lib/scudo/standalone/fuchsia.cpp
+++ b/compiler-rt/lib/scudo/standalone/fuchsia.cpp
@@ -97,6 +97,17 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
   if (Offset)
     MapFlags |= ZX_VM_SPECIFIC;
   Status = _zx_vmar_map(Vmar, MapFlags, Offset, Vmo, VmoSize, Size, &P);
+  if (UNLIKELY(Status != ZX_OK)) {
+    if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
+      dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0);
+    return nullptr;
+  }
+
+  if (Flags & MAP_PRECOMMIT) {
+    Status = _zx_vmar_op_range(Vmar, ZX_VMAR_OP_COMMIT, P, Size,
+                               /*buffer=*/nullptr, /*buffer_size=*/0);
+  }
+
   // No need to track the Vmo if we don't intend on resizing it. Close it.
   if (Flags & MAP_RESIZABLE) {
     DCHECK(Data);
@@ -112,6 +123,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
       dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0);
     return nullptr;
   }
+
   if (Data)
     Data->VmoSize += Size;
 

diff  --git a/compiler-rt/lib/scudo/standalone/release.h b/compiler-rt/lib/scudo/standalone/release.h
index ef5f23208dff4..6de3b15534d0c 100644
--- a/compiler-rt/lib/scudo/standalone/release.h
+++ b/compiler-rt/lib/scudo/standalone/release.h
@@ -107,9 +107,15 @@ class RegionPageMap {
       Buffer = &StaticBuffer[0];
       memset(Buffer, 0, BufferSize);
     } else {
+      // When using a heap-based buffer, precommit the pages backing the
+      // Vmar by passing |MAP_PRECOMMIT| flag. This allows an optimization
+      // where page fault exceptions are skipped as the allocated memory
+      // is accessed.
+      const uptr MmapFlags =
+          MAP_ALLOWNOMEM | (SCUDO_FUCHSIA ? MAP_PRECOMMIT : 0);
       Buffer = reinterpret_cast<uptr *>(
           map(nullptr, roundUpTo(BufferSize, getPageSizeCached()),
-              "scudo:counters", MAP_ALLOWNOMEM, &MapData));
+              "scudo:counters", MmapFlags, &MapData));
     }
   }
 


        


More information about the llvm-commits mailing list