Merge "Vulkan: unload builtin driver to reload updated driver if needed"

This commit is contained in:
TreeHugger Robot 2020-08-03 17:01:44 +00:00 committed by Android (Google) Code Review
commit f4785c6db2
3 changed files with 53 additions and 18 deletions

View file

@ -54,8 +54,9 @@ typedef union {
/* A hwvulkan_device_t corresponds to an ICD on other systems. Currently there /* A hwvulkan_device_t corresponds to an ICD on other systems. Currently there
* can only be one on a system (HWVULKAN_DEVICE_0). It is opened once per * can only be one on a system (HWVULKAN_DEVICE_0). It is opened once per
* process when the Vulkan API is first used; the hw_device_t::close() function * process when the Vulkan API is first used; the hw_device_t::close() function
* is never called. Any non-trivial resource allocation should be done when * is called upon driver unloading. Any non-trivial resource allocation should
* the VkInstance is created rather than when the hwvulkan_device_t is opened. * be done when the VkInstance is created rather than when the hwvulkan_device_t
* is opened.
*/ */
typedef struct hwvulkan_device_t { typedef struct hwvulkan_device_t {
struct hw_device_t common; struct hw_device_t common;

View file

@ -1174,23 +1174,18 @@ const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool EnsureInitialized() { bool EnsureInitialized() {
static std::once_flag once_flag; static bool initialized = false;
static bool initialized; static pid_t init_attempted_for_pid = 0;
static std::mutex init_lock;
std::call_once(once_flag, []() { std::lock_guard<std::mutex> lock(init_lock);
if (driver::OpenHAL()) { if (init_attempted_for_pid == getpid())
initialized = true; return initialized;
}
});
{ init_attempted_for_pid = getpid();
static pid_t pid = getpid() + 1; if (driver::OpenHAL()) {
static std::mutex layer_lock; DiscoverLayers();
std::lock_guard<std::mutex> lock(layer_lock); initialized = true;
if (pid != getpid()) {
pid = getpid();
DiscoverLayers();
}
} }
return initialized; return initialized;

View file

@ -84,6 +84,8 @@ class Hal {
Hal(const Hal&) = delete; Hal(const Hal&) = delete;
Hal& operator=(const Hal&) = delete; Hal& operator=(const Hal&) = delete;
bool ShouldUnloadBuiltinDriver();
void UnloadBuiltinDriver();
bool InitDebugReportIndex(); bool InitDebugReportIndex();
static Hal hal_; static Hal hal_;
@ -243,7 +245,12 @@ bool Hal::Open() {
const nsecs_t openTime = systemTime(); const nsecs_t openTime = systemTime();
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once"); if (hal_.ShouldUnloadBuiltinDriver()) {
hal_.UnloadBuiltinDriver();
}
if (hal_.dev_)
return true;
// Use a stub device unless we successfully open a real HAL device. // Use a stub device unless we successfully open a real HAL device.
hal_.dev_ = &stubhal::kDevice; hal_.dev_ = &stubhal::kDevice;
@ -288,6 +295,38 @@ bool Hal::Open() {
return true; return true;
} }
bool Hal::ShouldUnloadBuiltinDriver() {
// Should not unload since the driver was not loaded
if (!hal_.dev_)
return false;
// Should not unload if stubhal is used on the device
if (hal_.dev_ == &stubhal::kDevice)
return false;
// Unload the driver if updated driver is chosen
if (android::GraphicsEnv::getInstance().getDriverNamespace())
return true;
return false;
}
void Hal::UnloadBuiltinDriver() {
ATRACE_CALL();
ALOGD("Unload builtin Vulkan driver.");
// Close the opened device
ALOG_ASSERT(!hal_.dev_->common.close(hal_.dev_->common),
"hw_device_t::close() failed.");
// Close the opened shared library in the hw_module_t
dlclose(hal_.dev_->common.module->dso);
hal_.dev_ = nullptr;
hal_.debug_report_index_ = -1;
}
bool Hal::InitDebugReportIndex() { bool Hal::InitDebugReportIndex() {
ATRACE_CALL(); ATRACE_CALL();