[compiler-rt] 70758b8 - [scudo] Calling getStats requires holding lock
Chia-hung Duan via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 13 15:11:20 PST 2023
Author: Chia-hung Duan
Date: 2023-02-13T23:09:47Z
New Revision: 70758b801df9b76b8200ae6f22cab44554545693
URL: https://github.com/llvm/llvm-project/commit/70758b801df9b76b8200ae6f22cab44554545693
DIFF: https://github.com/llvm/llvm-project/commit/70758b801df9b76b8200ae6f22cab44554545693.diff
LOG: [scudo] Calling getStats requires holding lock
We didn't acquire the mutex while accessing those lock protected data,
this CL fixes it and now we don't need to disable the allocator while
reading its states.
Differential Revision: https://reviews.llvm.org/D142149
Added:
Modified:
compiler-rt/lib/scudo/standalone/combined.h
compiler-rt/lib/scudo/standalone/primary32.h
compiler-rt/lib/scudo/standalone/primary64.h
compiler-rt/lib/scudo/standalone/quarantine.h
compiler-rt/lib/scudo/standalone/secondary.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index b6d74ab451b6c..826e2a0806e00 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -726,9 +726,7 @@ class Allocator {
// sizing purposes.
uptr getStats(char *Buffer, uptr Size) {
ScopedString Str;
- disable();
const uptr Length = getStats(&Str) + 1;
- enable();
if (Length < Size)
Size = Length;
if (Buffer && Size) {
@@ -740,9 +738,7 @@ class Allocator {
void printStats() {
ScopedString Str;
- disable();
getStats(&Str);
- enable();
Str.output();
}
diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h
index a3d908cee9e52..c9e6c6a01e530 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -230,6 +230,7 @@ template <typename Config> class SizeClassAllocator32 {
uptr PushedBlocks = 0;
for (uptr I = 0; I < NumClasses; I++) {
SizeClassInfo *Sci = getSizeClassInfo(I);
+ ScopedLock L(Sci->Mutex);
TotalMapped += Sci->AllocatedUser;
PoppedBlocks += Sci->Stats.PoppedBlocks;
PushedBlocks += Sci->Stats.PushedBlocks;
@@ -237,8 +238,11 @@ template <typename Config> class SizeClassAllocator32 {
Str->append("Stats: SizeClassAllocator32: %zuM mapped in %zu allocations; "
"remains %zu\n",
TotalMapped >> 20, PoppedBlocks, PoppedBlocks - PushedBlocks);
- for (uptr I = 0; I < NumClasses; I++)
+ for (uptr I = 0; I < NumClasses; I++) {
+ SizeClassInfo *Sci = getSizeClassInfo(I);
+ ScopedLock L(Sci->Mutex);
getStats(Str, I, 0);
+ }
}
bool setOption(Option O, sptr Value) {
diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h
index b653bc802022f..68bf229364438 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -199,6 +199,7 @@ template <typename Config> class SizeClassAllocator64 {
uptr PushedBlocks = 0;
for (uptr I = 0; I < NumClasses; I++) {
RegionInfo *Region = getRegionInfo(I);
+ ScopedLock L(Region->Mutex);
if (Region->MappedUser)
TotalMapped += Region->MappedUser;
PoppedBlocks += Region->Stats.PoppedBlocks;
@@ -209,8 +210,11 @@ template <typename Config> class SizeClassAllocator64 {
TotalMapped >> 20, 0U, PoppedBlocks,
PoppedBlocks - PushedBlocks);
- for (uptr I = 0; I < NumClasses; I++)
+ for (uptr I = 0; I < NumClasses; I++) {
+ RegionInfo *Region = getRegionInfo(I);
+ ScopedLock L(Region->Mutex);
getStats(Str, I, 0);
+ }
}
bool setOption(Option O, sptr Value) {
@@ -577,7 +581,11 @@ template <typename Config> class SizeClassAllocator64 {
if (!Region->Exhausted) {
Region->Exhausted = true;
ScopedString Str;
- getStats(&Str);
+ // FIXME: getStats() needs to go over all the regions and
+ // will take the locks of them. Which means we will try to recursively
+ // acquire the `Region->Mutex` which is not supported. It will be
+ // better to log this somewhere else.
+ // getStats(&Str);
Str.append(
"Scudo OOM: The process has exhausted %zuM for size class %zu.\n",
RegionSize >> 20, Size);
diff --git a/compiler-rt/lib/scudo/standalone/quarantine.h b/compiler-rt/lib/scudo/standalone/quarantine.h
index 2d231c3a28dbb..2d240d279c3ff 100644
--- a/compiler-rt/lib/scudo/standalone/quarantine.h
+++ b/compiler-rt/lib/scudo/standalone/quarantine.h
@@ -215,7 +215,8 @@ template <typename Callback, typename Node> class GlobalQuarantine {
recycle(0, Cb);
}
- void getStats(ScopedString *Str) const {
+ void getStats(ScopedString *Str) {
+ ScopedLock L(CacheMutex);
// It assumes that the world is stopped, just as the allocator's printStats.
Cache.getStats(Str);
Str->append("Quarantine limits: global: %zuK; thread local: %zuK\n",
diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h
index 2d17757625886..1c4d0effe603a 100644
--- a/compiler-rt/lib/scudo/standalone/secondary.h
+++ b/compiler-rt/lib/scudo/standalone/secondary.h
@@ -438,7 +438,7 @@ template <typename Config> class MapAllocator {
return getBlockEnd(Ptr) - reinterpret_cast<uptr>(Ptr);
}
- void getStats(ScopedString *Str) const;
+ void getStats(ScopedString *Str);
void disable() {
Mutex.lock();
@@ -615,7 +615,8 @@ void MapAllocator<Config>::deallocate(Options Options, void *Ptr) {
}
template <typename Config>
-void MapAllocator<Config>::getStats(ScopedString *Str) const {
+void MapAllocator<Config>::getStats(ScopedString *Str) {
+ ScopedLock L(Mutex);
Str->append("Stats: MapAllocator: allocated %u times (%zuK), freed %u times "
"(%zuK), remains %u (%zuK) max %zuM\n",
NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees,
More information about the llvm-commits
mailing list