Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: content/browser/gpu/gpu_process_host.cc

Issue 418733002: Prevent duplicate navigation to debug URLs from Telemetry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix comment. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/gpu/gpu_process_host.h ('k') | content/common/gpu/gpu_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gpu/gpu_process_host.h" 5 #include "content/browser/gpu/gpu_process_host.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/base_switches.h" 8 #include "base/base_switches.h"
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #endif 61 #endif
62 62
63 #if defined(USE_X11) && !defined(OS_CHROMEOS) 63 #if defined(USE_X11) && !defined(OS_CHROMEOS)
64 #include "ui/gfx/x/x11_switches.h" 64 #include "ui/gfx/x/x11_switches.h"
65 #endif 65 #endif
66 66
67 namespace content { 67 namespace content {
68 68
69 bool GpuProcessHost::gpu_enabled_ = true; 69 bool GpuProcessHost::gpu_enabled_ = true;
70 bool GpuProcessHost::hardware_gpu_enabled_ = true; 70 bool GpuProcessHost::hardware_gpu_enabled_ = true;
71 int GpuProcessHost::gpu_crash_count_ = 0;
72 int GpuProcessHost::gpu_recent_crash_count_ = 0;
73 bool GpuProcessHost::crashed_before_ = false;
74 int GpuProcessHost::swiftshader_crash_count_ = 0;
71 75
72 namespace { 76 namespace {
73 77
74 enum GPUProcessLifetimeEvent { 78 enum GPUProcessLifetimeEvent {
75 LAUNCHED, 79 LAUNCHED,
76 DIED_FIRST_TIME, 80 DIED_FIRST_TIME,
77 DIED_SECOND_TIME, 81 DIED_SECOND_TIME,
78 DIED_THIRD_TIME, 82 DIED_THIRD_TIME,
79 DIED_FOURTH_TIME, 83 DIED_FOURTH_TIME,
80 GPU_PROCESS_LIFETIME_EVENT_MAX = 100 84 GPU_PROCESS_LIFETIME_EVENT_MAX = 100
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 328 }
325 329
326 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) 330 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind)
327 : host_id_(host_id), 331 : host_id_(host_id),
328 valid_(true), 332 valid_(true),
329 in_process_(false), 333 in_process_(false),
330 swiftshader_rendering_(false), 334 swiftshader_rendering_(false),
331 kind_(kind), 335 kind_(kind),
332 process_launched_(false), 336 process_launched_(false),
333 initialized_(false), 337 initialized_(false),
338 gpu_crash_recorded_(false),
334 uma_memory_stats_received_(false) { 339 uma_memory_stats_received_(false) {
335 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || 340 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
336 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) { 341 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) {
337 in_process_ = true; 342 in_process_ = true;
338 } 343 }
339 344
340 // If the 'single GPU process' policy ever changes, we still want to maintain 345 // If the 'single GPU process' policy ever changes, we still want to maintain
341 // it for 'gpu thread' mode and only create one instance of host and thread. 346 // it for 'gpu thread' mode and only create one instance of host and thread.
342 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); 347 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL);
343 348
(...skipping 10 matching lines...) Expand all
354 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); 359 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id));
355 360
356 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this)); 361 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this));
357 } 362 }
358 363
359 GpuProcessHost::~GpuProcessHost() { 364 GpuProcessHost::~GpuProcessHost() {
360 DCHECK(CalledOnValidThread()); 365 DCHECK(CalledOnValidThread());
361 366
362 SendOutstandingReplies(); 367 SendOutstandingReplies();
363 368
364 // Maximum number of times the gpu process is allowed to crash in a session. 369 RecordProcessCrash();
365 // Once this limit is reached, any request to launch the gpu process will
366 // fail.
367 const int kGpuMaxCrashCount = 3;
368
369 // Number of times the gpu process has crashed in the current browser session.
370 static int gpu_crash_count = 0;
371 static int gpu_recent_crash_count = 0;
372 static base::Time last_gpu_crash_time;
373 static bool crashed_before = false;
374 static int swiftshader_crash_count = 0;
375
376 bool disable_crash_limit = CommandLine::ForCurrentProcess()->HasSwitch(
377 switches::kDisableGpuProcessCrashLimit);
378
379 // Ending only acts as a failure if the GPU process was actually started and
380 // was intended for actual rendering (and not just checking caps or other
381 // options).
382 if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
383 if (swiftshader_rendering_) {
384 UMA_HISTOGRAM_ENUMERATION("GPU.SwiftShaderLifetimeEvents",
385 DIED_FIRST_TIME + swiftshader_crash_count,
386 GPU_PROCESS_LIFETIME_EVENT_MAX);
387
388 if (++swiftshader_crash_count >= kGpuMaxCrashCount &&
389 !disable_crash_limit) {
390 // SwiftShader is too unstable to use. Disable it for current session.
391 gpu_enabled_ = false;
392 }
393 } else {
394 ++gpu_crash_count;
395 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
396 std::min(DIED_FIRST_TIME + gpu_crash_count,
397 GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
398 GPU_PROCESS_LIFETIME_EVENT_MAX);
399
400 // Allow about 1 GPU crash per hour to be removed from the crash count,
401 // so very occasional crashes won't eventually add up and prevent the
402 // GPU process from launching.
403 ++gpu_recent_crash_count;
404 base::Time current_time = base::Time::Now();
405 if (crashed_before) {
406 int hours_different = (current_time - last_gpu_crash_time).InHours();
407 gpu_recent_crash_count =
408 std::max(0, gpu_recent_crash_count - hours_different);
409 }
410
411 crashed_before = true;
412 last_gpu_crash_time = current_time;
413
414 if ((gpu_recent_crash_count >= kGpuMaxCrashCount && !disable_crash_limit)
415 || !initialized_) {
416 #if !defined(OS_CHROMEOS)
417 // The gpu process is too unstable to use. Disable it for current
418 // session.
419 hardware_gpu_enabled_ = false;
420 GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
421 #endif
422 }
423 }
424 }
425 370
426 // In case we never started, clean up. 371 // In case we never started, clean up.
427 while (!queued_messages_.empty()) { 372 while (!queued_messages_.empty()) {
428 delete queued_messages_.front(); 373 delete queued_messages_.front();
429 queued_messages_.pop(); 374 queued_messages_.pop();
430 } 375 }
431 376
432 // This is only called on the IO thread so no race against the constructor 377 // This is only called on the IO thread so no race against the constructor
433 // for another GpuProcessHost. 378 // for another GpuProcessHost.
434 if (g_gpu_process_hosts[kind_] == this) 379 if (g_gpu_process_hosts[kind_] == this)
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 } 799 }
855 #endif 800 #endif
856 801
857 void GpuProcessHost::OnProcessLaunched() { 802 void GpuProcessHost::OnProcessLaunched() {
858 UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime", 803 UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime",
859 base::TimeTicks::Now() - init_start_time_); 804 base::TimeTicks::Now() - init_start_time_);
860 } 805 }
861 806
862 void GpuProcessHost::OnProcessCrashed(int exit_code) { 807 void GpuProcessHost::OnProcessCrashed(int exit_code) {
863 SendOutstandingReplies(); 808 SendOutstandingReplies();
809 RecordProcessCrash();
864 GpuDataManagerImpl::GetInstance()->ProcessCrashed( 810 GpuDataManagerImpl::GetInstance()->ProcessCrashed(
865 process_->GetTerminationStatus(true /* known_dead */, NULL)); 811 process_->GetTerminationStatus(true /* known_dead */, NULL));
866 } 812 }
867 813
868 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { 814 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() {
869 return kind_; 815 return kind_;
870 } 816 }
871 817
872 void GpuProcessHost::ForceShutdown() { 818 void GpuProcessHost::ForceShutdown() {
873 // This is only called on the IO thread so no race against the constructor 819 // This is only called on the IO thread so no race against the constructor
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 962
1017 void GpuProcessHost::BlockLiveOffscreenContexts() { 963 void GpuProcessHost::BlockLiveOffscreenContexts() {
1018 for (std::multiset<GURL>::iterator iter = 964 for (std::multiset<GURL>::iterator iter =
1019 urls_with_live_offscreen_contexts_.begin(); 965 urls_with_live_offscreen_contexts_.begin();
1020 iter != urls_with_live_offscreen_contexts_.end(); ++iter) { 966 iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
1021 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs( 967 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(
1022 *iter, GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN); 968 *iter, GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN);
1023 } 969 }
1024 } 970 }
1025 971
972 void GpuProcessHost::RecordProcessCrash() {
973 // Skip if a GPU process crash was already counted.
974 if (gpu_crash_recorded_)
975 return;
976
977 // Maximum number of times the gpu process is allowed to crash in a session.
978 // Once this limit is reached, any request to launch the gpu process will
979 // fail.
980 const int kGpuMaxCrashCount = 3;
981
982 // Last time the GPU process crashed.
983 static base::Time last_gpu_crash_time;
984
985 bool disable_crash_limit = CommandLine::ForCurrentProcess()->HasSwitch(
986 switches::kDisableGpuProcessCrashLimit);
987
988 // Ending only acts as a failure if the GPU process was actually started and
989 // was intended for actual rendering (and not just checking caps or other
990 // options).
991 if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
992 gpu_crash_recorded_ = true;
993 if (swiftshader_rendering_) {
994 UMA_HISTOGRAM_ENUMERATION("GPU.SwiftShaderLifetimeEvents",
995 DIED_FIRST_TIME + swiftshader_crash_count_,
996 GPU_PROCESS_LIFETIME_EVENT_MAX);
997
998 if (++swiftshader_crash_count_ >= kGpuMaxCrashCount &&
999 !disable_crash_limit) {
1000 // SwiftShader is too unstable to use. Disable it for current session.
1001 gpu_enabled_ = false;
1002 }
1003 } else {
1004 ++gpu_crash_count_;
1005 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
1006 std::min(DIED_FIRST_TIME + gpu_crash_count_,
1007 GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
1008 GPU_PROCESS_LIFETIME_EVENT_MAX);
1009
1010 // Allow about 1 GPU crash per hour to be removed from the crash count,
1011 // so very occasional crashes won't eventually add up and prevent the
1012 // GPU process from launching.
1013 ++gpu_recent_crash_count_;
1014 base::Time current_time = base::Time::Now();
1015 if (crashed_before_) {
1016 int hours_different = (current_time - last_gpu_crash_time).InHours();
1017 gpu_recent_crash_count_ =
1018 std::max(0, gpu_recent_crash_count_ - hours_different);
1019 }
1020
1021 crashed_before_ = true;
1022 last_gpu_crash_time = current_time;
1023
1024 if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount &&
1025 !disable_crash_limit) ||
1026 !initialized_) {
1027 #if !defined(OS_CHROMEOS)
1028 // The gpu process is too unstable to use. Disable it for current
1029 // session.
1030 hardware_gpu_enabled_ = false;
1031 GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
1032 #endif
1033 }
1034 }
1035 }
1036 }
1037
1026 std::string GpuProcessHost::GetShaderPrefixKey() { 1038 std::string GpuProcessHost::GetShaderPrefixKey() {
1027 if (shader_prefix_key_.empty()) { 1039 if (shader_prefix_key_.empty()) {
1028 gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); 1040 gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
1029 1041
1030 std::string in_str = GetContentClient()->GetProduct() + "-" + 1042 std::string in_str = GetContentClient()->GetProduct() + "-" +
1031 info.gl_vendor + "-" + info.gl_renderer + "-" + 1043 info.gl_vendor + "-" + info.gl_renderer + "-" +
1032 info.driver_version + "-" + info.driver_vendor; 1044 info.driver_version + "-" + info.driver_vendor;
1033 1045
1034 base::Base64Encode(base::SHA1HashString(in_str), &shader_prefix_key_); 1046 base::Base64Encode(base::SHA1HashString(in_str), &shader_prefix_key_);
1035 } 1047 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); 1080 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader");
1069 ClientIdToShaderCacheMap::iterator iter = 1081 ClientIdToShaderCacheMap::iterator iter =
1070 client_id_to_shader_cache_.find(client_id); 1082 client_id_to_shader_cache_.find(client_id);
1071 // If the cache doesn't exist then this is an off the record profile. 1083 // If the cache doesn't exist then this is an off the record profile.
1072 if (iter == client_id_to_shader_cache_.end()) 1084 if (iter == client_id_to_shader_cache_.end())
1073 return; 1085 return;
1074 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); 1086 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader);
1075 } 1087 }
1076 1088
1077 } // namespace content 1089 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/gpu_process_host.h ('k') | content/common/gpu/gpu_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698