| Index: content/browser/gpu/gpu_process_host.cc
|
| diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
|
| index f123addefee525e1206fddb3d5822821e2b6a621..27496f526e00dd7e58d79ba12020f8cdf6cc877d 100644
|
| --- a/content/browser/gpu/gpu_process_host.cc
|
| +++ b/content/browser/gpu/gpu_process_host.cc
|
| @@ -68,6 +68,10 @@ namespace content {
|
|
|
| bool GpuProcessHost::gpu_enabled_ = true;
|
| bool GpuProcessHost::hardware_gpu_enabled_ = true;
|
| +int GpuProcessHost::gpu_crash_count_ = 0;
|
| +int GpuProcessHost::gpu_recent_crash_count_ = 0;
|
| +bool GpuProcessHost::crashed_before_ = false;
|
| +int GpuProcessHost::swiftshader_crash_count_ = 0;
|
|
|
| namespace {
|
|
|
| @@ -331,6 +335,7 @@ GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind)
|
| kind_(kind),
|
| process_launched_(false),
|
| initialized_(false),
|
| + gpu_crash_recorded_(false),
|
| uma_memory_stats_received_(false) {
|
| if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
|
| CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) {
|
| @@ -361,67 +366,7 @@ GpuProcessHost::~GpuProcessHost() {
|
|
|
| SendOutstandingReplies();
|
|
|
| - // Maximum number of times the gpu process is allowed to crash in a session.
|
| - // Once this limit is reached, any request to launch the gpu process will
|
| - // fail.
|
| - const int kGpuMaxCrashCount = 3;
|
| -
|
| - // Number of times the gpu process has crashed in the current browser session.
|
| - static int gpu_crash_count = 0;
|
| - static int gpu_recent_crash_count = 0;
|
| - static base::Time last_gpu_crash_time;
|
| - static bool crashed_before = false;
|
| - static int swiftshader_crash_count = 0;
|
| -
|
| - bool disable_crash_limit = CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kDisableGpuProcessCrashLimit);
|
| -
|
| - // Ending only acts as a failure if the GPU process was actually started and
|
| - // was intended for actual rendering (and not just checking caps or other
|
| - // options).
|
| - if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
|
| - if (swiftshader_rendering_) {
|
| - UMA_HISTOGRAM_ENUMERATION("GPU.SwiftShaderLifetimeEvents",
|
| - DIED_FIRST_TIME + swiftshader_crash_count,
|
| - GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| -
|
| - if (++swiftshader_crash_count >= kGpuMaxCrashCount &&
|
| - !disable_crash_limit) {
|
| - // SwiftShader is too unstable to use. Disable it for current session.
|
| - gpu_enabled_ = false;
|
| - }
|
| - } else {
|
| - ++gpu_crash_count;
|
| - UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
|
| - std::min(DIED_FIRST_TIME + gpu_crash_count,
|
| - GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
|
| - GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| -
|
| - // Allow about 1 GPU crash per hour to be removed from the crash count,
|
| - // so very occasional crashes won't eventually add up and prevent the
|
| - // GPU process from launching.
|
| - ++gpu_recent_crash_count;
|
| - base::Time current_time = base::Time::Now();
|
| - if (crashed_before) {
|
| - int hours_different = (current_time - last_gpu_crash_time).InHours();
|
| - gpu_recent_crash_count =
|
| - std::max(0, gpu_recent_crash_count - hours_different);
|
| - }
|
| -
|
| - crashed_before = true;
|
| - last_gpu_crash_time = current_time;
|
| -
|
| - if ((gpu_recent_crash_count >= kGpuMaxCrashCount && !disable_crash_limit)
|
| - || !initialized_) {
|
| -#if !defined(OS_CHROMEOS)
|
| - // The gpu process is too unstable to use. Disable it for current
|
| - // session.
|
| - hardware_gpu_enabled_ = false;
|
| - GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
|
| -#endif
|
| - }
|
| - }
|
| - }
|
| + RecordProcessCrash();
|
|
|
| // In case we never started, clean up.
|
| while (!queued_messages_.empty()) {
|
| @@ -861,6 +806,7 @@ void GpuProcessHost::OnProcessLaunched() {
|
|
|
| void GpuProcessHost::OnProcessCrashed(int exit_code) {
|
| SendOutstandingReplies();
|
| + RecordProcessCrash();
|
| GpuDataManagerImpl::GetInstance()->ProcessCrashed(
|
| process_->GetTerminationStatus(true /* known_dead */, NULL));
|
| }
|
| @@ -1023,6 +969,72 @@ void GpuProcessHost::BlockLiveOffscreenContexts() {
|
| }
|
| }
|
|
|
| +void GpuProcessHost::RecordProcessCrash() {
|
| + // Skip if a GPU process crash was already counted.
|
| + if (gpu_crash_recorded_)
|
| + return;
|
| +
|
| + // Maximum number of times the gpu process is allowed to crash in a session.
|
| + // Once this limit is reached, any request to launch the gpu process will
|
| + // fail.
|
| + const int kGpuMaxCrashCount = 3;
|
| +
|
| + // Last time the GPU process crashed.
|
| + static base::Time last_gpu_crash_time;
|
| +
|
| + bool disable_crash_limit = CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kDisableGpuProcessCrashLimit);
|
| +
|
| + // Ending only acts as a failure if the GPU process was actually started and
|
| + // was intended for actual rendering (and not just checking caps or other
|
| + // options).
|
| + if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
|
| + gpu_crash_recorded_ = true;
|
| + if (swiftshader_rendering_) {
|
| + UMA_HISTOGRAM_ENUMERATION("GPU.SwiftShaderLifetimeEvents",
|
| + DIED_FIRST_TIME + swiftshader_crash_count_,
|
| + GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| +
|
| + if (++swiftshader_crash_count_ >= kGpuMaxCrashCount &&
|
| + !disable_crash_limit) {
|
| + // SwiftShader is too unstable to use. Disable it for current session.
|
| + gpu_enabled_ = false;
|
| + }
|
| + } else {
|
| + ++gpu_crash_count_;
|
| + UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
|
| + std::min(DIED_FIRST_TIME + gpu_crash_count_,
|
| + GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
|
| + GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| +
|
| + // Allow about 1 GPU crash per hour to be removed from the crash count,
|
| + // so very occasional crashes won't eventually add up and prevent the
|
| + // GPU process from launching.
|
| + ++gpu_recent_crash_count_;
|
| + base::Time current_time = base::Time::Now();
|
| + if (crashed_before_) {
|
| + int hours_different = (current_time - last_gpu_crash_time).InHours();
|
| + gpu_recent_crash_count_ =
|
| + std::max(0, gpu_recent_crash_count_ - hours_different);
|
| + }
|
| +
|
| + crashed_before_ = true;
|
| + last_gpu_crash_time = current_time;
|
| +
|
| + if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount &&
|
| + !disable_crash_limit) ||
|
| + !initialized_) {
|
| +#if !defined(OS_CHROMEOS)
|
| + // The gpu process is too unstable to use. Disable it for current
|
| + // session.
|
| + hardware_gpu_enabled_ = false;
|
| + GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
|
| +#endif
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| std::string GpuProcessHost::GetShaderPrefixKey() {
|
| if (shader_prefix_key_.empty()) {
|
| gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
|
|
|