Commit 9c07e8ca authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Force atomic shutdown on the info-collection GPU process.

After completing DxDiag, DX12/Vulkan and DevicePerfInfo requests,
the info-collection GPU process will shut down atomically.

Before this CL, the info-collection GPU process always goes through the
slow non-atomic shutdown procedure, which causes a crash when an
exception is raised during shutdown.

Bug: 1045920
Change-Id: I4dc3041fc940301735e248a52184749be0ef2e91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151829Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759755}
parent 44a7a003
......@@ -722,11 +722,6 @@ void GpuServiceImpl::GetGpuSupportedRuntimeVersionAndDevicePerfInfo(
DCHECK(device_perf_info_.has_value());
std::move(callback).Run(gpu_info_.dx12_vulkan_version_info,
device_perf_info_.value());
// The unsandboxed GPU info collection process fulfilled its duty and Dxdiag
// task is not running. Bye bye.
if (number_of_long_dx_tasks_in_progress_ == 0)
MaybeExit(false);
}
void GpuServiceImpl::RequestCompleteGpuInfo(
......@@ -746,11 +741,6 @@ void GpuServiceImpl::RequestCompleteGpuInfo(
[](GpuServiceImpl* gpu_service,
RequestCompleteGpuInfoCallback callback) {
std::move(callback).Run(gpu_service->gpu_info_.dx_diagnostics);
// The unsandboxed GPU info collection process fulfilled its duty.
gpu_service->number_of_long_dx_tasks_in_progress_--;
if (gpu_service->number_of_long_dx_tasks_in_progress_ == 0)
gpu_service->MaybeExit(false);
},
this, std::move(callback))));
}
......@@ -785,7 +775,6 @@ void GpuServiceImpl::UpdateGpuInfoPlatform(
// We can continue on shutdown here because we're not writing any critical
// state in this task.
number_of_long_dx_tasks_in_progress_++;
base::PostTaskAndReplyWithResult(
base::ThreadPool::CreateCOMSTATaskRunner(
{base::TaskPriority::USER_VISIBLE,
......
......@@ -415,12 +415,6 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
// Should only be accessed on the IO thread after creation.
mojo::Receiver<mojom::GpuService> receiver_{this};
#if defined(OS_WIN)
// Used to track if the Dx Diag task on a different thread is still running.
// The status is checked before exiting the unsandboxed GPU process.
int number_of_long_dx_tasks_in_progress_ = 0;
#endif
#if defined(OS_CHROMEOS)
scoped_refptr<arc::ProtectedBufferManager> protected_buffer_manager_;
#endif // defined(OS_CHROMEOS)
......
......@@ -165,6 +165,11 @@ void GpuDataManagerImpl::OnBrowserThreadsStarted() {
base::AutoLock auto_lock(lock_);
private_->OnBrowserThreadsStarted();
}
void GpuDataManagerImpl::TerminateInfoCollectionGpuProcess() {
base::AutoLock auto_lock(lock_);
private_->TerminateInfoCollectionGpuProcess();
}
#endif
void GpuDataManagerImpl::UpdateGpuFeatureInfo(
......
......@@ -92,6 +92,7 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager,
bool Dx12VulkanRequested() const;
// Called from BrowserMainLoop::BrowserThreadsStarted().
void OnBrowserThreadsStarted();
void TerminateInfoCollectionGpuProcess();
#endif
// Update the GPU feature info. This updates the blacklist and enabled status
// of GPU rasterization. In the future this will be used for more features.
......
......@@ -644,7 +644,9 @@ void GpuDataManagerImplPrivate::RequestDxDiagNodeData() {
manager->UpdateDxDiagNodeRequestStatus(true);
host->gpu_service()->RequestCompleteGpuInfo(
base::BindOnce([](const gpu::DxDiagNode& dx_diagnostics) {
GpuDataManagerImpl::GetInstance()->UpdateDxDiagNode(dx_diagnostics);
GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
manager->UpdateDxDiagNode(dx_diagnostics);
manager->TerminateInfoCollectionGpuProcess();
}));
});
......@@ -708,6 +710,7 @@ void GpuDataManagerImplPrivate::RequestGpuSupportedRuntimeVersion(
// UpdateDevicePerfInfo() because only the latter calls
// NotifyGpuInfoUpdate().
manager->UpdateDevicePerfInfo(device_perf_info);
manager->TerminateInfoCollectionGpuProcess();
}));
},
delta);
......@@ -896,6 +899,30 @@ void GpuDataManagerImplPrivate::OnBrowserThreadsStarted() {
display::Screen::GetScreen()->AddObserver(owner_);
}
void GpuDataManagerImplPrivate::TerminateInfoCollectionGpuProcess() {
// Wait until DxDiag, DX12/Vulkan and DevicePerfInfo requests are all
// complete.
if (gpu_info_dx_diag_requested_ && !gpu_info_dx_diag_request_failed_ &&
gpu_info_.dx_diagnostics.IsEmpty())
return;
// gpu_info_dx12_vulkan_valid_ is always updated before device_perf_info
if (gpu_info_dx12_vulkan_requested_ &&
!gpu_info_dx12_vulkan_request_failed_ &&
!gpu::GetDevicePerfInfo().has_value())
return;
// GpuProcessHost::Get() calls GpuDataManagerImpl functions and causes a
// re-entry of lock.
base::AutoUnlock unlock(owner_->lock_);
// GpuProcessHost::Get() only runs on the IO thread. Get() can be called
// directly here from TerminateInfoCollectionGpuProcess(), which also runs on
// the IO thread.
GpuProcessHost* host = GpuProcessHost::Get(GPU_PROCESS_KIND_INFO_COLLECTION,
false /* force_create */);
if (host)
host->ForceShutdown();
}
#endif
void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo(
......
......@@ -71,6 +71,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void UpdateDxDiagNodeRequestStatus(bool request_continues);
bool Dx12VulkanRequested() const;
void OnBrowserThreadsStarted();
void TerminateInfoCollectionGpuProcess();
#endif
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info,
const base::Optional<gpu::GpuFeatureInfo>&
......
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