Commit e2c5558b authored by Kai Ninomiya's avatar Kai Ninomiya Committed by Commit Bot

On Mac, gracefully exit GPU process on GPU disconnect/disconnect request

Using the "SafeEjectGPU" tool, we can see that when the "responsible"
process (the browser process) has a GPUEjectPolicy of 'wait', any
subordinates using the GPU (i.e. the GPU process) get the 'rwait'
GPUEjectPolicy: "Eject actions apply to the responsible process, who in
turn deals with subordinates to eliminate their ejecting eGPU
references." [man 8 SafeEjectGPU]

Empirically, the browser does not relaunch. Once the GPU process exits,
it appears that the browser process is no longer considered to be using
the GPU, so it "succeeds" the "wait".

Documentation:
https://developer.apple.com/documentation/metal/gpu_selection_in_macos/handling_external_gpu_additions_and_removals

Change-Id: Ia44c2ed864d1bdbb52d82ad72e14cbfcb4e32108
Bug: 1035619
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1974856Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726602}
parent db4d6dca
......@@ -357,5 +357,7 @@
<string>banner</string>
<key>NSRequiresAquaSystemAppearance</key>
<false/>
<key>GPUEjectPolicy</key>
<string>wait</string>
</dict>
</plist>
......@@ -12,6 +12,8 @@ component("metal_util") {
sources = [
"device.h",
"device.mm",
"device_removal.h",
"device_removal.mm",
"metal_util_export.h",
"test_shader.h",
"test_shader.mm",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_METAL_UTIL_DEVICE_REMOVAL_H_
#define COMPONENTS_METAL_UTIL_DEVICE_REMOVAL_H_
#include "components/metal_util/metal_util_export.h"
namespace metal {
void METAL_UTIL_EXPORT RegisterGracefulExitOnDeviceRemoval();
} // namespace metal
#endif // COMPONENTS_METAL_UTIL_DEVICE_REMOVAL_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/metal_util/device_removal.h"
#include "base/process/process.h"
#import <Metal/Metal.h>
namespace metal {
void RegisterGracefulExitOnDeviceRemoval() {
if (@available(macOS 10.13, *)) {
id<NSObject> deviceObserver = nil;
MTLCopyAllDevicesWithObserver(
&deviceObserver,
^(id<MTLDevice> device, MTLDeviceNotificationName name) {
if (name == MTLDeviceRemovalRequestedNotification ||
name == MTLDeviceWasRemovedNotification) {
// Exit the GPU process without error. The browser process sees
// this error code as a graceful shutdown, so relaunches the GPU
// process without incrementing the crash count.
//
// Note this wouldn't work nicely with in-process-gpu (it would
// exit the browser), but we don't support that on macOS anyway.
base::Process::TerminateCurrentProcessImmediately(0);
}
});
}
}
} // namespace metal
......@@ -91,6 +91,7 @@
#if defined(OS_MACOSX)
#include "base/message_loop/message_pump_mac.h"
#include "components/metal_util/device_removal.h"
#include "components/metal_util/test_shader.h"
#include "content/public/common/content_features.h"
#include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
......@@ -385,6 +386,22 @@ int GpuMain(const MainFunctionParams& parameters) {
tracing::TracingSamplerProfiler::CreateOnMainThread();
#if defined(OS_MACOSX)
// A GPUEjectPolicy of 'wait' is set in the Info.plist of the browser
// process, meaning it is "responsible" for making sure it and its
// subordinate processes (i.e. the GPU process) drop references to the
// external GPU. Despite this, the system still sends the device removal
// notifications to the GPU process, so the GPU process handles its own
// graceful shutdown without help from the browser process.
//
// Using the "SafeEjectGPU" tool, we can see that when the browser process
// has a policy of 'wait', the GPU process gets the 'rwait' policy: "Eject
// actions apply to the responsible process, who in turn deals with
// subordinates to eliminate their ejecting eGPU references" [man 8
// SafeEjectGPU]. Empirically, the browser does not relaunch. Once the GPU
// process exits, it appears that the browser process is no longer considered
// to be using the GPU, so it "succeeds" the 'wait'.
metal::RegisterGracefulExitOnDeviceRemoval();
// Launch a test metal shader compile to see how long it takes to complete (if
// it ever completes).
// https://crbug.com/974219
......
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