[scudo] Add the record of number of attempted page release (#120497)

This also removes the `RangesReleased` which doesn't give much insight
to whether we should adjust the heuristic of doing page release.
This commit is contained in:
ChiaHungDuan
2024-12-19 10:47:44 -08:00
committed by GitHub
parent 21684e38ee
commit b71c44b9be
3 changed files with 19 additions and 24 deletions

View File

@@ -387,7 +387,7 @@ private:
struct ReleaseToOsInfo {
uptr BytesInFreeListAtLastCheckpoint;
uptr RangesReleased;
uptr NumReleasesAttempted;
uptr LastReleasedBytes;
u64 LastReleaseAtNs;
};
@@ -880,14 +880,14 @@ private:
BytesInFreeList - Sci->ReleaseInfo.BytesInFreeListAtLastCheckpoint;
}
const uptr AvailableChunks = Sci->AllocatedUser / BlockSize;
Str->append(" %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu "
"inuse: %6zu avail: %6zu releases: %6zu last released: %6zuK "
"latest pushed bytes: %6zuK\n",
ClassId, getSizeByClassId(ClassId), Sci->AllocatedUser >> 10,
Sci->FreeListInfo.PoppedBlocks, Sci->FreeListInfo.PushedBlocks,
InUse, AvailableChunks, Sci->ReleaseInfo.RangesReleased,
Sci->ReleaseInfo.LastReleasedBytes >> 10,
PushedBytesDelta >> 10);
Str->append(
" %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu "
"inuse: %6zu avail: %6zu releases attempted: %6zu last released: %6zuK "
"latest pushed bytes: %6zuK\n",
ClassId, getSizeByClassId(ClassId), Sci->AllocatedUser >> 10,
Sci->FreeListInfo.PoppedBlocks, Sci->FreeListInfo.PushedBlocks, InUse,
AvailableChunks, Sci->ReleaseInfo.NumReleasesAttempted,
Sci->ReleaseInfo.LastReleasedBytes >> 10, PushedBytesDelta >> 10);
}
void getSizeClassFragmentationInfo(SizeClassInfo *Sci, uptr ClassId,
@@ -972,6 +972,10 @@ private:
const uptr Base = First * RegionSize;
const uptr NumberOfRegions = Last - First + 1U;
// The following steps contribute to the majority time spent in page
// releasing thus we increment the counter here.
++Sci->ReleaseInfo.NumReleasesAttempted;
// ==================================================================== //
// 2. Mark the free blocks and we can tell which pages are in-use by
// querying `PageReleaseContext`.
@@ -991,9 +995,8 @@ private:
};
releaseFreeMemoryToOS(Context, Recorder, SkipRegion);
if (Recorder.getReleasedRangesCount() > 0) {
if (Recorder.getReleasedBytes() > 0) {
Sci->ReleaseInfo.BytesInFreeListAtLastCheckpoint = BytesInFreeList;
Sci->ReleaseInfo.RangesReleased += Recorder.getReleasedRangesCount();
Sci->ReleaseInfo.LastReleasedBytes = Recorder.getReleasedBytes();
TotalReleasedBytes += Sci->ReleaseInfo.LastReleasedBytes;
}

View File

@@ -530,7 +530,7 @@ private:
struct ReleaseToOsInfo {
uptr BytesInFreeListAtLastCheckpoint;
uptr RangesReleased;
uptr NumReleasesAttempted;
uptr LastReleasedBytes;
// The minimum size of pushed blocks to trigger page release.
uptr TryReleaseThreshold;
@@ -1144,11 +1144,12 @@ private:
Str->append(
"%s %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu "
"inuse: %6zu total: %6zu releases: %6zu last "
"released: %6zuK latest pushed bytes: %6zuK region: 0x%zx (0x%zx)\n",
"releases attempted: %6zuK latest pushed bytes: %6zuK region: 0x%zx "
"(0x%zx)\n",
Region->Exhausted ? "E" : " ", ClassId, getSizeByClassId(ClassId),
Region->MemMapInfo.MappedUser >> 10, Region->FreeListInfo.PoppedBlocks,
Region->FreeListInfo.PushedBlocks, InUseBlocks, TotalChunks,
Region->ReleaseInfo.RangesReleased,
Region->ReleaseInfo.NumReleasesAttempted,
Region->ReleaseInfo.LastReleasedBytes >> 10,
RegionPushedBytesDelta >> 10, Region->RegionBeg,
getRegionBaseByClassId(ClassId));
@@ -1322,7 +1323,7 @@ private:
Context.getReleaseOffset());
auto SkipRegion = [](UNUSED uptr RegionIndex) { return false; };
releaseFreeMemoryToOS(Context, Recorder, SkipRegion);
if (Recorder.getReleasedRangesCount() > 0) {
if (Recorder.getReleasedBytes() > 0) {
// This is the case that we didn't hit the release threshold but it has
// been past a certain period of time. Thus we try to release some pages
// and if it does release some additional pages, it's hint that we are
@@ -1342,7 +1343,6 @@ private:
}
Region->ReleaseInfo.BytesInFreeListAtLastCheckpoint = BytesInFreeList;
Region->ReleaseInfo.RangesReleased += Recorder.getReleasedRangesCount();
Region->ReleaseInfo.LastReleasedBytes = Recorder.getReleasedBytes();
}
Region->ReleaseInfo.LastReleaseAtNs = getMonotonicTimeFast();

View File

@@ -22,8 +22,6 @@ public:
RegionReleaseRecorder(MemMapT *RegionMemMap, uptr Base, uptr Offset = 0)
: RegionMemMap(RegionMemMap), Base(Base), Offset(Offset) {}
uptr getReleasedRangesCount() const { return ReleasedRangesCount; }
uptr getReleasedBytes() const { return ReleasedBytes; }
uptr getBase() const { return Base; }
@@ -33,12 +31,10 @@ public:
void releasePageRangeToOS(uptr From, uptr To) {
const uptr Size = To - From;
RegionMemMap->releasePagesToOS(getBase() + Offset + From, Size);
ReleasedRangesCount++;
ReleasedBytes += Size;
}
private:
uptr ReleasedRangesCount = 0;
uptr ReleasedBytes = 0;
MemMapT *RegionMemMap = nullptr;
uptr Base = 0;
@@ -52,8 +48,6 @@ public:
ReleaseRecorder(uptr Base, uptr Offset = 0, MapPlatformData *Data = nullptr)
: Base(Base), Offset(Offset), Data(Data) {}
uptr getReleasedRangesCount() const { return ReleasedRangesCount; }
uptr getReleasedBytes() const { return ReleasedBytes; }
uptr getBase() const { return Base; }
@@ -62,12 +56,10 @@ public:
void releasePageRangeToOS(uptr From, uptr To) {
const uptr Size = To - From;
releasePagesToOS(Base, From + Offset, Size, Data);
ReleasedRangesCount++;
ReleasedBytes += Size;
}
private:
uptr ReleasedRangesCount = 0;
uptr ReleasedBytes = 0;
// The starting address to release. Note that we may want to combine (Base +
// Offset) as a new Base. However, the Base is retrieved from