Bug 1629064 - pt 10. Add telemetry r=smaug

We'd like to know if there are any problems with starving content processes
of cleaning up memory in a timely way.  Add some telemetry to get a sense of
this.

Differential Revision: https://phabricator.services.mozilla.com/D113275
This commit is contained in:
Paul Bone 2021-05-12 06:46:11 +00:00
parent 831e9abe44
commit 1aec99356d
4 changed files with 54 additions and 1 deletions

View File

@ -9,6 +9,7 @@
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/Atomics.h"
#include "mozilla/IdlePeriodState.h"
#include "mozilla/Telemetry.h"
#include "BackgroundChild.h"
namespace mozilla {
@ -77,13 +78,17 @@ RefPtr<IdleSchedulerChild::MayGCPromise> IdleSchedulerChild::MayGCNow() {
if (mIsRequestingGC || mIsDoingGC) {
return nullptr;
}
TimeStamp wait_since = TimeStamp::Now();
mIsRequestingGC = true;
return SendRequestGC()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr(this)](bool aIgnored) {
[self = RefPtr(this), wait_since](bool aIgnored) {
MOZ_ASSERT(self->mIsRequestingGC && !self->mIsDoingGC);
// The parent process always says yes, sometimes after a delay.
Telemetry::AccumulateTimeDelta(Telemetry::GC_WAIT_FOR_IDLE_MS,
wait_since);
self->mIsRequestingGC = false;
self->mIsDoingGC = true;
return MayGCPromise::CreateAndResolve(true, __func__);

View File

@ -8,6 +8,7 @@
#include "mozilla/StaticPrefs_javascript.h"
#include "mozilla/Unused.h"
#include "mozilla/ipc/IdleSchedulerParent.h"
#include "mozilla/Telemetry.h"
#include "nsSystemInfo.h"
#include "nsThreadUtils.h"
#include "nsITimer.h"
@ -23,6 +24,8 @@ LinkedList<IdleSchedulerParent> IdleSchedulerParent::sIdleAndGCRequests;
int32_t IdleSchedulerParent::sMaxConcurrentIdleTasksInChildProcesses = 1;
uint32_t IdleSchedulerParent::sMaxConcurrentGCs = 1;
uint32_t IdleSchedulerParent::sActiveGCs = 0;
bool IdleSchedulerParent::sRecordGCTelemetry = false;
uint32_t IdleSchedulerParent::sNumWaitingGC = 0;
uint32_t IdleSchedulerParent::sChildProcessesRunningPrioritizedOperation = 0;
uint32_t IdleSchedulerParent::sChildProcessesAlive = 0;
nsITimer* IdleSchedulerParent::sStarvationPreventer = nullptr;
@ -280,6 +283,8 @@ IPCResult IdleSchedulerParent::RecvRequestGC(RequestGCResolver&& aResolver) {
sIdleAndGCRequests.insertBack(this);
}
sRecordGCTelemetry = true;
sNumWaitingGC++;
Schedule(nullptr);
return IPC_OK();
}
@ -295,12 +300,15 @@ IPCResult IdleSchedulerParent::RecvDoneGC() {
if (mRequestingGC) {
mRequestingGC.value()(false);
mRequestingGC = Nothing();
MOZ_ASSERT(sNumWaitingGC > 0);
sNumWaitingGC--;
} else {
// mDoingGC is true.
sActiveGCs--;
mDoingGC = false;
}
sRecordGCTelemetry = true;
Schedule(nullptr);
return IPC_OK();
}
@ -345,6 +353,9 @@ void IdleSchedulerParent::SendMayGC() {
mRequestingGC = Nothing();
mDoingGC = true;
sActiveGCs++;
sRecordGCTelemetry = true;
MOZ_ASSERT(sNumWaitingGC > 0);
sNumWaitingGC--;
}
void IdleSchedulerParent::Schedule(IdleSchedulerParent* aRequester) {
@ -401,6 +412,11 @@ void IdleSchedulerParent::Schedule(IdleSchedulerParent* aRequester) {
if (!sIdleAndGCRequests.isEmpty() && HasSpareCycles(activeCount)) {
EnsureStarvationTimer();
}
if (sRecordGCTelemetry) {
sRecordGCTelemetry = false;
Telemetry::Accumulate(Telemetry::GC_WAIT_FOR_IDLE_COUNT, sNumWaitingGC);
}
}
void IdleSchedulerParent::EnsureStarvationTimer() {

View File

@ -110,6 +110,12 @@ class IdleSchedulerParent final
static uint32_t sMaxConcurrentGCs;
static uint32_t sActiveGCs;
// True if we should record some telemetry for GCs in the next Schedule().
// This is set to true by either requesting a GC job or scheduling a GC job.
static bool sRecordGCTelemetry;
// The current number of waiting GCs.
static uint32_t sNumWaitingGC;
// Counting all the child processes which have at least one prioritized
// operation.
static uint32_t sChildProcessesRunningPrioritizedOperation;

View File

@ -1026,6 +1026,32 @@
"bug_numbers": [1580227],
"description": "GC 'effectiveness', the amount of memory freed divided by main-thread collection time (MB/s)"
},
"GC_WAIT_FOR_IDLE_MS": {
"record_in_processes": ["content"],
"products": ["firefox", "fennec"],
"alert_emails": ["dev-telemetry-gc-alerts@mozilla.org", "pbone@mozilla.com"],
"expires_in_version": "98",
"kind": "exponential",
"releaseChannelCollection": "opt-out",
"low": 1,
"high": 120000,
"n_buckets": 60,
"bug_numbers": [1629064],
"description": "The time a content process waits before the parent process said that it may begin a GC"
},
"GC_WAIT_FOR_IDLE_COUNT": {
"record_in_processes": ["main"],
"products": ["firefox", "fennec"],
"alert_emails": ["dev-telemetry-gc-alerts@mozilla.org", "pbone@mozilla.com"],
"expires_in_version": "98",
"kind": "exponential",
"releaseChannelCollection": "opt-out",
"low": 1,
"high": 120,
"n_buckets": 25,
"bug_numbers": [1629064],
"description": "The number of queued GCs, collected each time GCs are (de)queued)"
},
"GEOLOCATION_ACCURACY_EXPONENTIAL": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec"],