Commit 83090290 authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Arm the GPU watchdog during GPU process shutdown.

The GPU process is now armed to detect hangs during shutdown. This also fixes
a problem that ReportProgress() is called without Arm() first and a DCHECK is
triggered due to the wrong Arm/InProgress/Disarm order. Calling Arm() when the
GPU starts to shut down fix this order issue.

Bug:949839, 674475

Change-Id: I5f8ec78787945a09ad6cf519506175386e24a646
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1775214
Commit-Queue: Maggie Chen <magchen@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691945}
parent a1b5aec5
...@@ -220,6 +220,9 @@ GpuServiceImpl::~GpuServiceImpl() { ...@@ -220,6 +220,9 @@ GpuServiceImpl::~GpuServiceImpl() {
wait.Wait(); wait.Wait();
} }
if (watchdog_thread_)
watchdog_thread_->OnGpuProcessTearDown();
media_gpu_channel_manager_.reset(); media_gpu_channel_manager_.reset();
gpu_channel_manager_.reset(); gpu_channel_manager_.reset();
......
...@@ -281,6 +281,8 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate, ...@@ -281,6 +281,8 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
scoped_refptr<base::SingleThreadTaskRunner> main_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
// Do not change the class member order here. watchdog_thread_ should be the
// last one to be destroyed before main_runner_ and io_runner_.
std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread_; std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread_;
const gpu::GpuPreferences gpu_preferences_; const gpu::GpuPreferences gpu_preferences_;
......
...@@ -59,6 +59,11 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread : public base::Thread, ...@@ -59,6 +59,11 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread : public base::Thread,
// once init is complete, before executing tasks. // once init is complete, before executing tasks.
virtual void OnInitComplete() = 0; virtual void OnInitComplete() = 0;
// Notifies the watchdog when the GPU child process is being destroyed.
// This function is called directly from
// viz::GpuServiceImpl::~GpuServiceImpl()
virtual void OnGpuProcessTearDown() = 0;
virtual void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) = 0; virtual void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) = 0;
// For gpu testing only. Return status for the watchdog tests // For gpu testing only. Return status for the watchdog tests
...@@ -86,6 +91,7 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThreadImplV1 ...@@ -86,6 +91,7 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThreadImplV1
void OnBackgrounded() override; void OnBackgrounded() override;
void OnForegrounded() override; void OnForegrounded() override;
void OnInitComplete() override {} void OnInitComplete() override {}
void OnGpuProcessTearDown() override {}
void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) override; void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) override;
bool IsGpuHangDetectedForTesting() override; bool IsGpuHangDetectedForTesting() override;
......
...@@ -86,12 +86,22 @@ void GpuWatchdogThreadImplV2::OnForegrounded() { ...@@ -86,12 +86,22 @@ void GpuWatchdogThreadImplV2::OnForegrounded() {
base::Unretained(this))); base::Unretained(this)));
} }
// Called from the gpu thread when gpu init has completed // Called from the gpu thread when gpu init has completed.
void GpuWatchdogThreadImplV2::OnInitComplete() { void GpuWatchdogThreadImplV2::OnInitComplete() {
DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread()); DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread());
Disarm(); Disarm();
} }
// Called from the gpu thread in viz::GpuServiceImpl::~GpuServiceImpl().
// After this, no Disarm() will be called before the watchdog thread is
// destroyed. If this destruction takes too long, the watchdog timeout
// will be triggered.
void GpuWatchdogThreadImplV2::OnGpuProcessTearDown() {
DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread());
Arm();
}
// Running on the watchdog thread. // Running on the watchdog thread.
// On Linux, Init() will be called twice for Sandbox Initialization. The // On Linux, Init() will be called twice for Sandbox Initialization. The
// watchdog is stopped and then restarted in StartSandboxLinux(). Everything // watchdog is stopped and then restarted in StartSandboxLinux(). Everything
...@@ -200,6 +210,9 @@ void GpuWatchdogThreadImplV2::RestartWatchdogTimeoutTask() { ...@@ -200,6 +210,9 @@ void GpuWatchdogThreadImplV2::RestartWatchdogTimeoutTask() {
} }
} }
// Called from the gpu main thread.
// The watchdog is armed only in these three functions -
// GpuWatchdogThreadImplV2(), WillProcessTask(), and OnGpuProcessTearDown()
void GpuWatchdogThreadImplV2::Arm() { void GpuWatchdogThreadImplV2::Arm() {
DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread()); DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread());
......
...@@ -26,6 +26,7 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThreadImplV2 ...@@ -26,6 +26,7 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThreadImplV2
void OnBackgrounded() override; void OnBackgrounded() override;
void OnForegrounded() override; void OnForegrounded() override;
void OnInitComplete() override; void OnInitComplete() override;
void OnGpuProcessTearDown() override;
void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) override; void GpuWatchdogHistogram(GpuWatchdogThreadEvent thread_event) override;
bool IsGpuHangDetectedForTesting() override; bool IsGpuHangDetectedForTesting() override;
void WaitForPowerObserverAddedForTesting() override; void WaitForPowerObserverAddedForTesting() override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment