Skip to content

Commit

Permalink
Bug 1729026 - Add support for GPU-process Glean metrics via FOG r=Dex…
Browse files Browse the repository at this point in the history
…ter,nical

Differential Revision: https://phabricator.services.mozilla.com/D124840
  • Loading branch information
chutten committed Dec 1, 2021
1 parent 508066c commit 76b90dc
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 6 deletions.
6 changes: 6 additions & 0 deletions gfx/ipc/GPUChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions gfx/ipc/GPUChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions gfx/ipc/GPUParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions gfx/ipc/GPUParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
11 changes: 11 additions & 0 deletions gfx/ipc/PGPU.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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().
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions toolkit/components/glean/api/src/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions toolkit/components/glean/docs/dev/ipc.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 31 additions & 6 deletions toolkit/components/glean/ipc/FOGIPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand All @@ -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));
}
Expand All @@ -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");
}
Expand Down
18 changes: 18 additions & 0 deletions toolkit/components/glean/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 76b90dc

Please sign in to comment.