[tracing] Use trace thread for gpu process to initialize tracing
For non-zygote child gpu thread, start the trace thread in ContentMainRunnerImpl() directly. For zygote child gpu thread, start the trace thread in RunZygote after zygote fork and featurelist init. For Linux & ChromeOS, stop and restart the trace thread when entering sandbox. Restarting trace thread has a caveat that delayed tasks would will be lost unless we save them. This is [3/?] CL of enabling tracing prior to sandboxing. Bug: 380411640 Change-Id: I89fa94f63a709de0e3da4f8759098c9fff813bee Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6180639 Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org> Commit-Queue: Kramer Ge <fangzhoug@chromium.org> Cr-Commit-Position: refs/heads/main@{#1428704}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
9a1b229f41
commit
44d8036a9d
content
services/tracing/public/cpp
ui/gl
@ -658,7 +658,18 @@ NO_STACK_PROTECTOR int RunZygote(ContentMainDelegate* delegate) {
|
|||||||
|
|
||||||
MainFunctionParams main_params(command_line);
|
MainFunctionParams main_params(command_line);
|
||||||
main_params.zygote_child = true;
|
main_params.zygote_child = true;
|
||||||
main_params.needs_startup_tracing_after_mojo_init = true;
|
|
||||||
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
// Once Zygote forks and feature list initializes we can start a thread to
|
||||||
|
// begin tracing immediately.
|
||||||
|
// TODO(https://crbug.com/380411640): Enable for more processes other than
|
||||||
|
// GPU process.
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/true);
|
||||||
|
tracing::InitTracingPostFeatureList(/*enable_consumer=*/false);
|
||||||
|
main_params.needs_startup_tracing_after_mojo_init = false;
|
||||||
|
} else {
|
||||||
|
main_params.needs_startup_tracing_after_mojo_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
// The hang watcher needs to be created once the feature list is available
|
// The hang watcher needs to be created once the feature list is available
|
||||||
// but before the IO thread is started.
|
// but before the IO thread is started.
|
||||||
@ -888,15 +899,27 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
|
|||||||
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
||||||
// A sandboxed process won't be able to allocate the SMB needed for startup
|
// A sandboxed process won't be able to allocate the SMB needed for startup
|
||||||
// tracing until Mojo IPC support is brought up, at which point the Mojo
|
// tracing until Mojo IPC support is brought up, at which point the Mojo
|
||||||
// broker will transparently broker the SMB creation.
|
// broker will transparently broker the SMB creation. Unless the sandboxed
|
||||||
if (!sandbox::policy::IsUnsandboxedSandboxType(
|
// process stops the trace threads when entering sandbox.
|
||||||
|
// TODO(https://crbug.com/380411640): Implement for other processes other than
|
||||||
|
// GPU process.
|
||||||
|
if (process_type != switches::kGpuProcess &&
|
||||||
|
!sandbox::policy::IsUnsandboxedSandboxType(
|
||||||
sandbox::policy::SandboxTypeFromCommandLine(command_line))) {
|
sandbox::policy::SandboxTypeFromCommandLine(command_line))) {
|
||||||
enable_startup_tracing = false;
|
enable_startup_tracing = false;
|
||||||
needs_startup_tracing_after_mojo_init_ = true;
|
needs_startup_tracing_after_mojo_init_ = true;
|
||||||
}
|
}
|
||||||
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
||||||
if (enable_startup_tracing) {
|
if (enable_startup_tracing) {
|
||||||
tracing::EnableStartupTracingIfNeeded();
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
// Without Zygote and posix sandbox we can start a thread to begin tracing
|
||||||
|
// immediately.
|
||||||
|
// TODO(https://crbug.com/380411640): Enable for more processes other than
|
||||||
|
// GPU process.
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/true);
|
||||||
|
} else {
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
|
TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
|
||||||
|
|
||||||
@ -1112,6 +1135,9 @@ NO_STACK_PROTECTOR int ContentMainRunnerImpl::Run() {
|
|||||||
ContentMainDelegate::InvokedInChildProcess())) {
|
ContentMainDelegate::InvokedInChildProcess())) {
|
||||||
InitializeFieldTrialAndFeatureList();
|
InitializeFieldTrialAndFeatureList();
|
||||||
}
|
}
|
||||||
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
tracing::InitTracingPostFeatureList(/*enable_consumer=*/false);
|
||||||
|
}
|
||||||
if (delegate_->ShouldInitializeMojo(
|
if (delegate_->ShouldInitializeMojo(
|
||||||
ContentMainDelegate::InvokedInChildProcess())) {
|
ContentMainDelegate::InvokedInChildProcess())) {
|
||||||
InitializeMojoCore();
|
InitializeMojoCore();
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "base/task/single_thread_task_executor.h"
|
#include "base/task/single_thread_task_executor.h"
|
||||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||||
#include "base/threading/platform_thread.h"
|
#include "base/threading/platform_thread.h"
|
||||||
|
#include "base/threading/thread.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/timer/hi_res_timer_manager.h"
|
#include "base/timer/hi_res_timer_manager.h"
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
@ -44,6 +45,7 @@
|
|||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "content/public/common/main_function_params.h"
|
#include "content/public/common/main_function_params.h"
|
||||||
#include "content/public/common/result_codes.h"
|
#include "content/public/common/result_codes.h"
|
||||||
|
#include "content/public/common/zygote/zygote_buildflags.h"
|
||||||
#include "content/public/gpu/content_gpu_client.h"
|
#include "content/public/gpu/content_gpu_client.h"
|
||||||
#include "gpu/command_buffer/service/gpu_switches.h"
|
#include "gpu/command_buffer/service/gpu_switches.h"
|
||||||
#include "gpu/config/gpu_driver_bug_list.h"
|
#include "gpu/config/gpu_driver_bug_list.h"
|
||||||
@ -59,6 +61,7 @@
|
|||||||
#include "media/gpu/buildflags.h"
|
#include "media/gpu/buildflags.h"
|
||||||
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
||||||
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||||
|
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
|
||||||
#include "services/tracing/public/cpp/trace_startup.h"
|
#include "services/tracing/public/cpp/trace_startup.h"
|
||||||
#include "services/tracing/public/cpp/trace_startup_config.h"
|
#include "services/tracing/public/cpp/trace_startup_config.h"
|
||||||
#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
|
#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
|
||||||
@ -206,11 +209,8 @@ void LoadMetalShaderCacheIfNecessary() {
|
|||||||
|
|
||||||
// Main function for starting the Gpu process.
|
// Main function for starting the Gpu process.
|
||||||
int GpuMain(MainFunctionParams parameters) {
|
int GpuMain(MainFunctionParams parameters) {
|
||||||
if (tracing::TraceStartupConfig::GetInstance().IsEnabled()) {
|
TRACE_EVENT("gpu,startup", "GpuMain");
|
||||||
gl::StartupTrace::Startup();
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE_EVENT0("gpu", "GpuMain");
|
|
||||||
base::CurrentProcess::GetInstance().SetProcessType(
|
base::CurrentProcess::GetInstance().SetProcessType(
|
||||||
base::CurrentProcessType::PROCESS_GPU);
|
base::CurrentProcessType::PROCESS_GPU);
|
||||||
|
|
||||||
@ -324,7 +324,6 @@ int GpuMain(MainFunctionParams parameters) {
|
|||||||
base::MessagePumpType::DEFAULT);
|
base::MessagePumpType::DEFAULT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
gl::StartupTrace::GetInstance()->BindToCurrentThread();
|
|
||||||
|
|
||||||
base::PlatformThread::SetName("CrGpuMain");
|
base::PlatformThread::SetName("CrGpuMain");
|
||||||
mojo::InterfaceEndpointClient::SetThreadNameSuffixForMetrics("GpuMain");
|
mojo::InterfaceEndpointClient::SetThreadNameSuffixForMetrics("GpuMain");
|
||||||
@ -450,7 +449,6 @@ int GpuMain(MainFunctionParams parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DCHECK(tracing::IsTracingInitialized());
|
DCHECK(tracing::IsTracingInitialized());
|
||||||
gl::StartupTrace::StarupDone();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
TRACE_EVENT0("gpu", "Run Message Loop");
|
TRACE_EVENT0("gpu", "Run Message Loop");
|
||||||
@ -474,6 +472,14 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
|
|||||||
sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
|
sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::Thread* trace_thread =
|
||||||
|
tracing::IsTracingInitialized()
|
||||||
|
? tracing::PerfettoTracedProcess::GetTraceThread()
|
||||||
|
: nullptr;
|
||||||
|
if (trace_thread) {
|
||||||
|
sandbox::policy::SandboxLinux::GetInstance()->StopThread(trace_thread);
|
||||||
|
}
|
||||||
|
|
||||||
// SandboxLinux::InitializeSandbox() must always be called
|
// SandboxLinux::InitializeSandbox() must always be called
|
||||||
// with only one thread.
|
// with only one thread.
|
||||||
sandbox::policy::SandboxLinux::Options sandbox_options;
|
sandbox::policy::SandboxLinux::Options sandbox_options;
|
||||||
@ -523,6 +529,10 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
|
|||||||
watchdog_thread->Start();
|
watchdog_thread->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trace_thread) {
|
||||||
|
tracing::PerfettoTracedProcess::RestartThreadInSandbox();
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||||
|
@ -47,17 +47,15 @@ using base::trace_event::TraceLog;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool g_tracing_initialized_after_featurelist = false;
|
bool g_tracing_initialized_after_featurelist = false;
|
||||||
|
bool g_tracing_with_thread = false;
|
||||||
|
|
||||||
bool IsTracingInitialized() {
|
bool IsTracingInitialized() {
|
||||||
return g_tracing_initialized_after_featurelist;
|
return g_tracing_initialized_after_featurelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnableStartupTracingIfNeeded() {
|
void EnableStartupTracingIfNeeded(bool with_thread) {
|
||||||
RegisterTracedValueProtoWriter();
|
RegisterTracedValueProtoWriter();
|
||||||
|
|
||||||
// Create the PerfettoTracedProcess.
|
|
||||||
PerfettoTracedProcess::MaybeCreateInstance();
|
|
||||||
|
|
||||||
// Initialize the client library's TrackRegistry to support trace points
|
// Initialize the client library's TrackRegistry to support trace points
|
||||||
// during startup tracing. We don't setup the client library completely here
|
// during startup tracing. We don't setup the client library completely here
|
||||||
// yet, because we don't have field trials loaded yet (which influence which
|
// yet, because we don't have field trials loaded yet (which influence which
|
||||||
@ -66,6 +64,14 @@ void EnableStartupTracingIfNeeded() {
|
|||||||
// setting up the client library?
|
// setting up the client library?
|
||||||
perfetto::internal::TrackRegistry::InitializeInstance();
|
perfetto::internal::TrackRegistry::InitializeInstance();
|
||||||
|
|
||||||
|
// Create the PerfettoTracedProcess.
|
||||||
|
if (with_thread) {
|
||||||
|
g_tracing_with_thread = true;
|
||||||
|
PerfettoTracedProcess::MaybeCreateInstanceWithThread();
|
||||||
|
} else {
|
||||||
|
PerfettoTracedProcess::MaybeCreateInstance();
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure TraceLog is initialized first.
|
// Ensure TraceLog is initialized first.
|
||||||
// https://crbug.com/764357
|
// https://crbug.com/764357
|
||||||
TraceLog::GetInstance();
|
TraceLog::GetInstance();
|
||||||
@ -106,7 +112,9 @@ void InitTracingPostFeatureList(bool enable_consumer) {
|
|||||||
DCHECK(base::FeatureList::GetInstance());
|
DCHECK(base::FeatureList::GetInstance());
|
||||||
|
|
||||||
// Create the PerfettoTracedProcess.
|
// Create the PerfettoTracedProcess.
|
||||||
PerfettoTracedProcess::MaybeCreateInstance();
|
if (!g_tracing_with_thread) {
|
||||||
|
PerfettoTracedProcess::MaybeCreateInstance();
|
||||||
|
}
|
||||||
PerfettoTracedProcess::Get().OnThreadPoolAvailable(enable_consumer);
|
PerfettoTracedProcess::Get().OnThreadPoolAvailable(enable_consumer);
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
tracing::EnableETWExport();
|
tracing::EnableETWExport();
|
||||||
|
@ -35,7 +35,8 @@ bool COMPONENT_EXPORT(TRACING_CPP) IsTracingInitialized();
|
|||||||
// TODO(eseckler): Consider allocating the SMB in parent processes outside the
|
// TODO(eseckler): Consider allocating the SMB in parent processes outside the
|
||||||
// sandbox and supply it via the command line. Then, we can revert to call this
|
// sandbox and supply it via the command line. Then, we can revert to call this
|
||||||
// earlier and from fewer places again.
|
// earlier and from fewer places again.
|
||||||
void COMPONENT_EXPORT(TRACING_CPP) EnableStartupTracingIfNeeded();
|
void COMPONENT_EXPORT(TRACING_CPP)
|
||||||
|
EnableStartupTracingIfNeeded(bool with_thread = false);
|
||||||
|
|
||||||
// Enable startup tracing for the current process with the provided config. Sets
|
// Enable startup tracing for the current process with the provided config. Sets
|
||||||
// up ProducerClient and trace event and/or sampler profiler data sources, and
|
// up ProducerClient and trace event and/or sampler profiler data sources, and
|
||||||
|
@ -77,20 +77,6 @@ class GL_EXPORT StartupTrace {
|
|||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
||||||
// Generate a unique variable name with a given prefix.
|
#define GPU_STARTUP_TRACE_EVENT(name) TRACE_EVENT("gpu,startup", name);
|
||||||
#define GPU_STARTUP_TRACE_INTERNAL_CONCAT2(a, b) a##b
|
|
||||||
#define GPU_STARTUP_TRACE_INTERNAL_CONCAT(a, b) \
|
|
||||||
GPU_STARTUP_TRACE_INTERNAL_CONCAT2(a, b)
|
|
||||||
#define GPU_STARTUP_TRACE_UID(prefix) \
|
|
||||||
GPU_STARTUP_TRACE_INTERNAL_CONCAT(prefix, __LINE__)
|
|
||||||
|
|
||||||
#define GPU_STARTUP_TRACE_EVENT(name) \
|
|
||||||
gl::StartupTrace::ScopedStage GPU_STARTUP_TRACE_UID(scoped_gpu_trace){0}; \
|
|
||||||
if (gl::StartupTrace::IsEnabled()) { \
|
|
||||||
GPU_STARTUP_TRACE_UID(scoped_gpu_trace) = \
|
|
||||||
gl::StartupTrace::GetInstance()->AddStage(name); \
|
|
||||||
} else { \
|
|
||||||
TRACE_EVENT0("gpu,startup", name); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // UI_GL_STARTUP_TRACE_H_
|
#endif // UI_GL_STARTUP_TRACE_H_
|
||||||
|
Reference in New Issue
Block a user