From becb5e70d374a1f29cdacb04605c55dda066b4a9 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Tue, 14 May 2024 12:58:36 +0000 Subject: [PATCH] Bug 1880503 - Handle sync IPC timeout in UiCompositorControllerChild. r=aosmond Extend the sync IPC timeout mechanism in CompositorManagerChild to additionally cover UiCompositorControllerChild. As UiCompositorControllerChild runs on the Android UI thread, we ensure GPUProcessManager::KillProcess dispatches to the gecko main thread. Along with the previous patch in this series this should provide us with crash reports when the Android UI thread is hung waiting for the GPU process to reply. Differential Revision: https://phabricator.services.mozilla.com/D202167 --- gfx/ipc/GPUProcessHost.cpp | 2 ++ gfx/ipc/GPUProcessManager.cpp | 7 +++++++ gfx/layers/ipc/UiCompositorControllerChild.cpp | 18 ++++++++++++++++++ gfx/layers/ipc/UiCompositorControllerChild.h | 3 +++ 4 files changed, 30 insertions(+) diff --git a/gfx/ipc/GPUProcessHost.cpp b/gfx/ipc/GPUProcessHost.cpp index 75f68f04740c..e7f6ac1be278 100644 --- a/gfx/ipc/GPUProcessHost.cpp +++ b/gfx/ipc/GPUProcessHost.cpp @@ -212,6 +212,8 @@ void GPUProcessHost::OnChannelClosed() { } void GPUProcessHost::KillHard(bool aGenerateMinidump) { + MOZ_ASSERT(NS_IsMainThread()); + if (mGPUChild && aGenerateMinidump) { mGPUChild->GeneratePairedMinidump(); } diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp index 21ea6f39c24e..5f22b4980d49 100644 --- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -1122,6 +1122,13 @@ void GPUProcessManager::CleanShutdown() { } void GPUProcessManager::KillProcess(bool aGenerateMinidump) { + if (!NS_IsMainThread()) { + RefPtr task = mTaskFactory.NewRunnableMethod( + &GPUProcessManager::KillProcess, aGenerateMinidump); + NS_DispatchToMainThread(task.forget()); + return; + } + if (!mProcess) { return; } diff --git a/gfx/layers/ipc/UiCompositorControllerChild.cpp b/gfx/layers/ipc/UiCompositorControllerChild.cpp index c1bf49bc27c8..a359c4bc9e31 100644 --- a/gfx/layers/ipc/UiCompositorControllerChild.cpp +++ b/gfx/layers/ipc/UiCompositorControllerChild.cpp @@ -13,6 +13,7 @@ #include "mozilla/layers/UiCompositorControllerParent.h" #include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/ipc/Endpoint.h" +#include "mozilla/StaticPrefs_layers.h" #include "mozilla/StaticPtr.h" #include "nsBaseWidget.h" #include "nsProxyRelease.h" @@ -287,6 +288,8 @@ void UiCompositorControllerChild::OpenForGPUProcess( return; } + SetReplyTimeout(); + SendCachedValues(); // Let Ui thread know the connection is open; RecvToolbarAnimatorMessageFromCompositor(COMPOSITOR_CONTROLLER_OPEN); @@ -346,5 +349,20 @@ void UiCompositorControllerChild::OnCompositorSurfaceChanged( } #endif +void UiCompositorControllerChild::SetReplyTimeout() { +#ifndef DEBUG + // Add a timeout for release builds to kill GPU process when it hangs. + const int32_t timeout = + StaticPrefs::layers_gpu_process_ipc_reply_timeout_ms_AtStartup(); + SetReplyTimeoutMs(timeout); +#endif +} + +bool UiCompositorControllerChild::ShouldContinueFromReplyTimeout() { + gfxCriticalNote << "Killing GPU process due to IPC reply timeout"; + gfx::GPUProcessManager::Get()->KillProcess(/* aGenerateMinidump */ true); + return false; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/UiCompositorControllerChild.h b/gfx/layers/ipc/UiCompositorControllerChild.h index bf543ee6a30f..cf986c5c3aa4 100644 --- a/gfx/layers/ipc/UiCompositorControllerChild.h +++ b/gfx/layers/ipc/UiCompositorControllerChild.h @@ -94,6 +94,9 @@ class UiCompositorControllerChild final void OpenForGPUProcess(Endpoint&& aEndpoint); void SendCachedValues(); + void SetReplyTimeout(); + bool ShouldContinueFromReplyTimeout() override; + bool mIsOpen; uint64_t mProcessToken; Maybe mResize;