Bug 1729026 - Add support for GPU-process Glean metrics via FOG r=Dexter,nical

Differential Revision: https://phabricator.services.mozilla.com/D124840
This commit is contained in:
Chris H-C 2021-12-01 14:35:08 +00:00
Родитель a822ca45de
Коммит 217e25cfa5
9 изменённых файлов: 84 добавлений и 6 удалений

Просмотреть файл

@ -12,6 +12,7 @@
#include "gfxConfig.h"
#include "gfxPlatform.h"
#include "mozilla/Components.h"
#include "mozilla/FOGIPC.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryIPC.h"
@ -316,6 +317,11 @@ mozilla::ipc::IPCResult GPUChild::RecvUpdateMediaCodecsSupported(
return IPC_OK();
}
mozilla::ipc::IPCResult GPUChild::RecvFOGData(ByteBuf&& aBuf) {
glean::FOGData(std::move(aBuf));
return IPC_OK();
}
class DeferredDeleteGPUChild : public Runnable {
public:
explicit DeferredDeleteGPUChild(UniquePtr<GPUChild>&& aChild)

Просмотреть файл

@ -72,6 +72,7 @@ class GPUChild final : public ipc::CrashReporterHelper<GeckoProcessType_GPU>,
mozilla::ipc::IPCResult RecvBHRThreadHang(const HangDetails& aDetails);
mozilla::ipc::IPCResult RecvUpdateMediaCodecsSupported(
const PDMFactory::MediaCodecsSupported& aSupported);
mozilla::ipc::IPCResult RecvFOGData(ByteBuf&& aBuf);
bool SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,

Просмотреть файл

@ -25,6 +25,7 @@
#include "gfxPlatform.h"
#include "mozilla/Assertions.h"
#include "mozilla/Components.h"
#include "mozilla/FOGIPC.h"
#include "mozilla/HangDetails.h"
#include "mozilla/PerfStats.h"
#include "mozilla/Preferences.h"
@ -617,12 +618,22 @@ mozilla::ipc::IPCResult GPUParent::RecvCollectPerfStatsJSON(
return IPC_OK();
}
mozilla::ipc::IPCResult GPUParent::RecvFlushFOGData(
FlushFOGDataResolver&& aResolver) {
glean::FlushFOGData(std::move(aResolver));
return IPC_OK();
}
void GPUParent::ActorDestroy(ActorDestroyReason aWhy) {
if (AbnormalShutdown == aWhy) {
NS_WARNING("Shutting down GPU process early due to a crash!");
ProcessChild::QuickExit();
}
// Send the last bits of Glean data over to the main process.
glean::FlushFOGData(
[](ByteBuf&& aBuf) { glean::SendFOGData(std::move(aBuf)); });
#ifndef NS_FREE_PERMANENT_DATA
# ifdef XP_WIN
wmf::MFShutdown();

Просмотреть файл

@ -97,6 +97,8 @@ class GPUParent final : public PGPUParent {
Endpoint<PSandboxTestingChild>&& aEndpoint);
#endif
mozilla::ipc::IPCResult RecvFlushFOGData(FlushFOGDataResolver&& aResolver);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:

Просмотреть файл

@ -22,6 +22,7 @@ include protocol PRemoteDecoderManager;
include protocol PSandboxTesting;
#endif
include "mozilla/ipc/ByteBufUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
using base::ProcessId from "base/process.h";
@ -112,6 +113,11 @@ parent:
async InitSandboxTesting(Endpoint<PSandboxTestingChild> aEndpoint);
#endif
// Tells the gpu process to flush any pending telemetry.
// Used in tests and ping assembly. Buffer contains bincoded Rust structs.
// https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/ipc.html
async FlushFOGData() returns (ByteBuf buf);
child:
// Sent when the GPU process has initialized devices. This occurs once, after
// Init().
@ -158,6 +164,11 @@ child:
// Update the cached list of codec supported following a check in the
// GPU parent.
async UpdateMediaCodecsSupported(MediaCodecsSupported aSupported);
// Sent from time-to-time to limit the amount of telemetry vulnerable to loss
// Buffer contains bincoded Rust structs.
// https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/ipc.html
async FOGData(ByteBuf buf);
};
} // namespace gfx

Просмотреть файл

@ -97,6 +97,9 @@ fn register_process_shutdown(process_type: u32) {
FOG_RegisterContentChildShutdown();
};
}
nsIXULRuntime::PROCESS_TYPE_GPU => {
// GPU process shutdown is handled in GPUParent::ActorDestroy.
}
_ => {
// We don't yet support other process types.
log::error!("Process type {} tried to use FOG, but isn't supported! (Process type constants are in nsIXULRuntime.rs)", process_type);

Просмотреть файл

@ -127,6 +127,7 @@ Rust is then responsible for turning the pending data into
FOG supports messaging between the following types of child process and the parent process:
* content children (via `PContent`
(for now. See [bug 1641989](https://bugzilla.mozilla.org/show_bug.cgi?id=1641989))
* gpu children (via `PGPU`)
See
[the process model docs](../../../../dom/ipc/process_model.html)

Просмотреть файл

@ -9,12 +9,18 @@
#include "mozilla/glean/GleanMetrics.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/gfx/GPUChild.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/MozPromise.h"
#include "mozilla/ProcInfo.h"
#include "mozilla/Unused.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
using mozilla::dom::ContentParent;
using mozilla::gfx::GPUChild;
using mozilla::gfx::GPUProcessManager;
using mozilla::ipc::ByteBuf;
using FlushFOGDataPromise = mozilla::dom::ContentParent::FlushFOGDataPromise;
@ -81,19 +87,33 @@ void FlushFOGData(std::function<void(ipc::ByteBuf&&)>&& aResolver) {
*/
void FlushAllChildData(
std::function<void(nsTArray<ipc::ByteBuf>&&)>&& aResolver) {
auto timerId = fog_ipc::flush_durations.Start();
nsTArray<ContentParent*> parents;
ContentParent::GetAll(parents);
if (parents.Length() == 0) {
nsTArray<RefPtr<FlushFOGDataPromise>> promises;
for (auto* parent : parents) {
promises.EmplaceBack(parent->SendFlushFOGData());
}
GPUProcessManager* gpuManager = GPUProcessManager::Get();
GPUChild* gpuChild = nullptr;
if (gpuManager) {
gpuChild = gpuManager->GetGPUChild();
if (gpuChild) {
promises.EmplaceBack(gpuChild->SendFlushFOGData());
}
}
if (promises.Length() == 0) {
// No child processes at the moment. Resolve synchronously.
fog_ipc::flush_durations.Cancel(std::move(timerId));
nsTArray<ipc::ByteBuf> results;
aResolver(std::move(results));
return;
}
auto timerId = fog_ipc::flush_durations.Start();
nsTArray<RefPtr<FlushFOGDataPromise>> promises;
for (auto* parent : parents) {
promises.EmplaceBack(parent->SendFlushFOGData());
}
// If fog.ipc.flush_failures ever gets too high:
// TODO: Don't throw away resolved data if some of the promises reject.
// (not sure how, but it'll mean not using ::All... maybe a custom copy of
// AllPromiseHolder? Might be impossible outside MozPromise.h)
@ -106,6 +126,7 @@ void FlushAllChildData(
if (aValue.IsResolve()) {
aResolver(std::move(aValue.ResolveValue()));
} else {
fog_ipc::flush_failures.Add(1);
nsTArray<ipc::ByteBuf> results;
aResolver(std::move(results));
}
@ -130,6 +151,10 @@ void SendFOGData(ipc::ByteBuf&& buf) {
case GeckoProcessType_Content:
mozilla::dom::ContentChild::GetSingleton()->SendFOGData(std::move(buf));
break;
case GeckoProcessType_GPU:
Unused << mozilla::gfx::GPUParent::GetSingleton()->SendFOGData(
std::move(buf));
break;
default:
MOZ_ASSERT_UNREACHABLE("Unsuppored process type");
}

Просмотреть файл

@ -97,3 +97,21 @@ fog.ipc:
- chutten@mozilla.com
- glean-team@mozilla.com
expires: never
flush_failures:
type: counter
description: |
The number of times we failed to flush all non-parent-process data,
throwing even partial results into the trash.
If this number is high, we might consider writing custom `MozPromise`-
handling code instead of using `MozPromise::All`.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1729026
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1729026
data_sensitivity:
- technical
notification_emails:
- chutten@mozilla.com
- glean-team@mozilla.com
expires: never