Bug 1829127 - Add telemetry for PHC utilisation r=glandium

Differential Revision: https://phabricator.services.mozilla.com/D192303
This commit is contained in:
Paul Bone 2023-11-06 04:59:33 +00:00
parent c473d4c7a0
commit 62f879e4b6
4 changed files with 70 additions and 17 deletions

View file

@ -841,23 +841,20 @@ class GMut {
void IncPageAllocMisses(GMutLock) {} void IncPageAllocMisses(GMutLock) {}
#endif #endif
#if PHC_LOGGING phc::PHCStats GetPageStats(GMutLock) {
struct PageStats { phc::PHCStats stats;
size_t mNumAlloced = 0;
size_t mNumFreed = 0;
};
PageStats GetPageStats(GMutLock) {
PageStats stats;
for (const auto& page : mAllocPages) { for (const auto& page : mAllocPages) {
stats.mNumAlloced += page.mState == AllocPageState::InUse ? 1 : 0; stats.mSlotsAllocated += page.mState == AllocPageState::InUse ? 1 : 0;
stats.mNumFreed += page.mState == AllocPageState::Freed ? 1 : 0; stats.mSlotsFreed += page.mState == AllocPageState::Freed ? 1 : 0;
} }
stats.mSlotsUnused =
kNumAllocPages - stats.mSlotsAllocated - stats.mSlotsFreed;
return stats; return stats;
} }
#if PHC_LOGGING
size_t PageAllocHits(GMutLock) { return mPageAllocHits; } size_t PageAllocHits(GMutLock) { return mPageAllocHits; }
size_t PageAllocAttempts(GMutLock) { size_t PageAllocAttempts(GMutLock) {
return mPageAllocHits + mPageAllocMisses; return mPageAllocHits + mPageAllocMisses;
@ -1244,12 +1241,12 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
gMut->IncPageAllocHits(lock); gMut->IncPageAllocHits(lock);
#if PHC_LOGGING #if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock); phc::PHCStats stats = gMut->GetPageStats(lock);
#endif #endif
LOG("PageAlloc(%zu, %zu) -> %p[%zu]/%p (%zu) (z%zu), sAllocDelay <- %zu, " LOG("PageAlloc(%zu, %zu) -> %p[%zu]/%p (%zu) (z%zu), sAllocDelay <- %zu, "
"fullness %zu/%zu/%zu, hits %zu/%zu (%zu%%), lifetime %zu\n", "fullness %zu/%zu/%zu, hits %zu/%zu (%zu%%), lifetime %zu\n",
aReqSize, aAlignment, pagePtr, i, ptr, usableSize, size_t(aZero), aReqSize, aAlignment, pagePtr, i, ptr, usableSize, size_t(aZero),
size_t(newAllocDelay), stats.mNumAlloced, stats.mNumFreed, size_t(newAllocDelay), stats.mSlotsAllocated, stats.mSlotsFreed,
kNumAllocPages, gMut->PageAllocHits(lock), kNumAllocPages, gMut->PageAllocHits(lock),
gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock), lifetime); gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock), lifetime);
break; break;
@ -1259,12 +1256,12 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
// No pages are available, or VirtualAlloc/mprotect failed. // No pages are available, or VirtualAlloc/mprotect failed.
gMut->IncPageAllocMisses(lock); gMut->IncPageAllocMisses(lock);
#if PHC_LOGGING #if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock); phc::PHCStats stats = gMut->GetPageStats(lock);
#endif #endif
LOG("No PageAlloc(%zu, %zu), sAllocDelay <- %zu, fullness %zu/%zu/%zu, " LOG("No PageAlloc(%zu, %zu), sAllocDelay <- %zu, fullness %zu/%zu/%zu, "
"hits %zu/%zu (%zu%%)\n", "hits %zu/%zu (%zu%%)\n",
aReqSize, aAlignment, size_t(newAllocDelay), stats.mNumAlloced, aReqSize, aAlignment, size_t(newAllocDelay), stats.mSlotsAllocated,
stats.mNumFreed, kNumAllocPages, gMut->PageAllocHits(lock), stats.mSlotsFreed, kNumAllocPages, gMut->PageAllocHits(lock),
gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock)); gMut->PageAllocAttempts(lock), gMut->PageAllocHitRate(lock));
} }
@ -1509,11 +1506,11 @@ MOZ_ALWAYS_INLINE static bool MaybePageFree(const Maybe<arena_id_t>& aArenaId,
FreePage(lock, index, aArenaId, freeStack, reuseDelay); FreePage(lock, index, aArenaId, freeStack, reuseDelay);
#if PHC_LOGGING #if PHC_LOGGING
GMut::PageStats stats = gMut->GetPageStats(lock); phc::PHCStats stats = gMut->GetPageStats(lock);
#endif #endif
LOG("PageFree(%p[%zu]), %zu delay, reuse at ~%zu, fullness %zu/%zu/%zu\n", LOG("PageFree(%p[%zu]), %zu delay, reuse at ~%zu, fullness %zu/%zu/%zu\n",
aPtr, index, size_t(reuseDelay), size_t(GAtomic::Now()) + reuseDelay, aPtr, index, size_t(reuseDelay), size_t(GAtomic::Now()) + reuseDelay,
stats.mNumAlloced, stats.mNumFreed, kNumAllocPages); stats.mSlotsAllocated, stats.mSlotsFreed, kNumAllocPages);
return true; return true;
} }
@ -1772,6 +1769,14 @@ void PHCMemoryUsage(MemoryUsage& aMemoryUsage) {
} }
} }
void GetPHCStats(PHCStats& aStats) {
if (gMut) {
MutexAutoLock lock(GMut::sMutex);
aStats = gMut->GetPageStats(lock);
}
}
// Enable or Disable PHC at runtime. If PHC is disabled it will still trap // Enable or Disable PHC at runtime. If PHC is disabled it will still trap
// bad uses of previous allocations, but won't track any new allocations. // bad uses of previous allocations, but won't track any new allocations.
void SetPHCState(PHCState aState) { gMut->SetState(aState); } void SetPHCState(PHCState aState) { gMut->SetState(aState); }

View file

@ -141,6 +141,15 @@ struct MemoryUsage {
MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage); MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage);
struct PHCStats {
size_t mSlotsAllocated = 0;
size_t mSlotsFreed = 0;
size_t mSlotsUnused = 0;
};
// Return PHC memory usage information by filling in the supplied structure.
MOZ_JEMALLOC_API void GetPHCStats(PHCStats& aStats);
} // namespace phc } // namespace phc
} // namespace mozilla } // namespace mozilla

View file

@ -1751,6 +1751,37 @@
"description": "Over-allocation due to PHC's rounding (aka internal fragmentation). Measured in bytes.", "description": "Over-allocation due to PHC's rounding (aka internal fragmentation). Measured in bytes.",
"releaseChannelCollection": "opt-out" "releaseChannelCollection": "opt-out"
}, },
"MEMORY_PHC_SLOTS_ALLOCATED": {
"record_in_processes": ["main", "content"],
"products": ["firefox"],
"alert_emails": [
"memshrink-telemetry-alerts@mozilla.com",
"pbone@mozilla.com"
],
"bug_numbers": [1829127],
"expires_in_version": "128",
"kind": "exponential",
"high": 16384,
"n_buckets": 64,
"description": "Number of PHC slots currently allocated",
"releaseChannelCollection": "opt-out"
},
"MEMORY_PHC_SLOTS_FREED": {
"record_in_processes": ["main", "content"],
"products": ["firefox"],
"alert_emails": [
"memshrink-telemetry-alerts@mozilla.com",
"pbone@mozilla.com"
],
"bug_numbers": [1829127],
"expires_in_version": "128",
"kind": "exponential",
"high": 16384,
"n_buckets": 64,
"description": "Number of PHC slots allocated-then-freed",
"releaseChannelCollection": "opt-out"
},
"FONTLIST_INITOTHERFAMILYNAMES": { "FONTLIST_INITOTHERFAMILYNAMES": {
"record_in_processes": ["main", "content"], "record_in_processes": ["main", "content"],
"products": ["firefox", "fennec"], "products": ["firefox", "fennec"],

View file

@ -38,6 +38,14 @@ void ReportPHCTelemetry() {
PHCMemoryUsage(usage); PHCMemoryUsage(usage);
Accumulate(Telemetry::MEMORY_PHC_SLOP, usage.mFragmentationBytes); Accumulate(Telemetry::MEMORY_PHC_SLOP, usage.mFragmentationBytes);
PHCStats stats;
GetPHCStats(stats);
Accumulate(Telemetry::MEMORY_PHC_SLOTS_ALLOCATED, stats.mSlotsAllocated);
Accumulate(Telemetry::MEMORY_PHC_SLOTS_FREED, stats.mSlotsFreed);
// There are also slots that are unused (neither free nor allocated) they
// can be calculated by knowing the total number of slots.
} }
}; // namespace mozilla }; // namespace mozilla