mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-28 16:48:45 +08:00
fix: move gtpin initialization to first zeDriverGet call
Currently gtpin is intialized during zeInit call. However, it is not correct as gtpin is calling other L0 API functions, like zeDriverGet which should not be called until zeInit function finishes. With this commit gtpin initialization is performed during first zeDriverGet function call. In case of initialization failure ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE will be returned every zeDriverGet call. Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
c9457bb5eb
commit
b7cedb99a4
@@ -85,18 +85,14 @@ void DriverImp::initialize(ze_result_t *result) {
|
||||
if (envVariables.metrics) {
|
||||
*result = MetricDeviceContext::enableMetricApi();
|
||||
}
|
||||
|
||||
if ((*result == ZE_RESULT_SUCCESS) && envVariables.pin) {
|
||||
std::string gtpinFuncName{"OpenGTPin"};
|
||||
if (false == NEO::PinContext::init(gtpinFuncName)) {
|
||||
*result = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
if (*result != ZE_RESULT_SUCCESS) {
|
||||
delete globalDriver;
|
||||
globalDriverHandle = nullptr;
|
||||
globalDriver = nullptr;
|
||||
driverCount = 0;
|
||||
} else if (envVariables.pin) {
|
||||
std::unique_lock<std::recursive_mutex> mtx{this->gtpinInitMtx};
|
||||
this->gtPinInitializationStatus = GtPinInitializationStatus::pending;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +110,10 @@ ze_result_t DriverImp::driverInit(ze_init_flags_t flags) {
|
||||
}
|
||||
|
||||
ze_result_t driverHandleGet(uint32_t *pCount, ze_driver_handle_t *phDriverHandles) {
|
||||
auto retVal = Driver::get()->initGtpin();
|
||||
if (retVal != ZE_RESULT_SUCCESS) {
|
||||
return retVal;
|
||||
}
|
||||
if (*pCount == 0) {
|
||||
*pCount = driverCount;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
@@ -134,6 +134,28 @@ ze_result_t driverHandleGet(uint32_t *pCount, ze_driver_handle_t *phDriverHandle
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t DriverImp::initGtpin() {
|
||||
auto retVal = ZE_RESULT_SUCCESS;
|
||||
if (this->gtPinInitializationStatus == GtPinInitializationStatus::notNeeded) {
|
||||
return retVal;
|
||||
}
|
||||
std::unique_lock<std::recursive_mutex> mtx{this->gtpinInitMtx};
|
||||
if (this->gtPinInitializationStatus == GtPinInitializationStatus::inProgress) {
|
||||
return retVal;
|
||||
}
|
||||
if (this->gtPinInitializationStatus == GtPinInitializationStatus::pending) {
|
||||
this->gtPinInitializationStatus = GtPinInitializationStatus::inProgress;
|
||||
std::string gtpinFuncName{"OpenGTPin"};
|
||||
if (false == NEO::PinContext::init(gtpinFuncName)) {
|
||||
this->gtPinInitializationStatus = GtPinInitializationStatus::error;
|
||||
}
|
||||
}
|
||||
if (this->gtPinInitializationStatus == GtPinInitializationStatus::error) {
|
||||
retVal = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static DriverImp driverImp;
|
||||
Driver *Driver::driver = &driverImp;
|
||||
std::mutex driverInitMutex;
|
||||
|
||||
@@ -15,6 +15,7 @@ struct Driver {
|
||||
virtual void initialize(ze_result_t *result) = 0;
|
||||
static Driver *get() { return driver; }
|
||||
virtual ~Driver() = default;
|
||||
virtual ze_result_t initGtpin() = 0;
|
||||
|
||||
virtual unsigned int getPid() const = 0;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "level_zero/core/source/driver/driver.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
@@ -22,11 +23,21 @@ class DriverImp : public Driver {
|
||||
unsigned int getPid() const override {
|
||||
return pid;
|
||||
}
|
||||
ze_result_t initGtpin() override;
|
||||
|
||||
enum class GtPinInitializationStatus {
|
||||
notNeeded,
|
||||
pending,
|
||||
inProgress,
|
||||
error
|
||||
};
|
||||
|
||||
protected:
|
||||
uint32_t pid = 0;
|
||||
std::once_flag initDriverOnce;
|
||||
static ze_result_t initStatus;
|
||||
std::atomic<GtPinInitializationStatus> gtPinInitializationStatus{GtPinInitializationStatus::notNeeded};
|
||||
std::recursive_mutex gtpinInitMtx;
|
||||
};
|
||||
|
||||
struct L0EnvVariables {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -8,11 +8,13 @@
|
||||
#include "level_zero/core/test/common/ult_config_listener_l0.h"
|
||||
|
||||
#include "level_zero/core/source/driver/driver.h"
|
||||
#include "level_zero/core/source/driver/driver_handle_imp.h"
|
||||
|
||||
void L0::UltConfigListenerL0::OnTestStart(const ::testing::TestInfo &testInfo) {
|
||||
BaseUltConfigListener::OnTestStart(testInfo);
|
||||
|
||||
globalDriverHandle = nullptr;
|
||||
L0::globalDriver = nullptr;
|
||||
driverCount = 0;
|
||||
}
|
||||
|
||||
@@ -20,6 +22,7 @@ void L0::UltConfigListenerL0::OnTestEnd(const ::testing::TestInfo &testInfo) {
|
||||
|
||||
EXPECT_EQ(nullptr, globalDriverHandle);
|
||||
EXPECT_EQ(0u, driverCount);
|
||||
EXPECT_EQ(nullptr, L0::globalDriver);
|
||||
|
||||
BaseUltConfigListener::OnTestEnd(testInfo);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace ult {
|
||||
|
||||
template <>
|
||||
struct WhiteBox<::L0::DriverImp> : public ::L0::DriverImp {
|
||||
using ::L0::DriverImp::gtPinInitializationStatus;
|
||||
using ::L0::DriverImp::pid;
|
||||
};
|
||||
|
||||
@@ -31,11 +32,12 @@ struct Mock<Driver> : public Driver {
|
||||
|
||||
ze_result_t driverInit(ze_init_flags_t flag) override {
|
||||
initCalledCount++;
|
||||
|
||||
if (initCalledCount == 1) {
|
||||
pid = NEO::SysCalls::getCurrentProcessId();
|
||||
}
|
||||
|
||||
if (driverInitCallBase) {
|
||||
return DriverImp::driverInit(flag);
|
||||
}
|
||||
if (failInitDriver) {
|
||||
return ZE_RESULT_ERROR_UNINITIALIZED;
|
||||
}
|
||||
@@ -43,7 +45,11 @@ struct Mock<Driver> : public Driver {
|
||||
}
|
||||
|
||||
void initialize(ze_result_t *result) override {
|
||||
|
||||
initializeCalledCount++;
|
||||
if (initializeCallBase) {
|
||||
DriverImp::initialize(result);
|
||||
return;
|
||||
}
|
||||
pid = NEO::SysCalls::getCurrentProcessId();
|
||||
|
||||
if (failInitDriver) {
|
||||
@@ -54,7 +60,10 @@ struct Mock<Driver> : public Driver {
|
||||
|
||||
Driver *previousDriver = nullptr;
|
||||
uint32_t initCalledCount = 0;
|
||||
uint32_t initializeCalledCount = 0;
|
||||
bool failInitDriver = false;
|
||||
bool driverInitCallBase = false;
|
||||
bool initializeCallBase = false;
|
||||
};
|
||||
|
||||
} // namespace ult
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "shared/test/common/mocks/mock_device.h"
|
||||
#include "shared/test/common/mocks/mock_execution_environment.h"
|
||||
#include "shared/test/common/mocks/mock_io_functions.h"
|
||||
#include "shared/test/common/mocks/mock_os_library.h"
|
||||
#include "shared/test/common/mocks/mock_sip.h"
|
||||
#include "shared/test/common/mocks/ult_device_factory.h"
|
||||
#include "shared/test/common/test_macros/hw_test.h"
|
||||
@@ -1389,5 +1390,118 @@ TEST_F(DriverExperimentalApiTest, givenGetVersionStringAPIExistsThenGetCurrentVe
|
||||
free(driverVersionString);
|
||||
}
|
||||
|
||||
struct GtPinInitTest : public ::testing::Test {
|
||||
void SetUp() override {
|
||||
gtpinInitTimesCalled = 0u;
|
||||
driver.driverInitCallBase = true;
|
||||
driver.initializeCallBase = true;
|
||||
|
||||
uint32_t (*openPinHandler)(void *) = [](void *arg) -> uint32_t {
|
||||
gtpinInitTimesCalled++;
|
||||
uint32_t driverCount = 0;
|
||||
ze_driver_handle_t driverHandle{};
|
||||
auto result = zeDriverGet(&driverCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(1u, driverCount);
|
||||
if (result != ZE_RESULT_SUCCESS || driverCount != 1) {
|
||||
return 1;
|
||||
}
|
||||
result = zeDriverGet(&driverCount, &driverHandle);
|
||||
EXPECT_EQ(1u, driverCount);
|
||||
if (result != ZE_RESULT_SUCCESS || driverCount != 1) {
|
||||
return 1;
|
||||
}
|
||||
EXPECT_EQ(globalDriverHandle, driverHandle);
|
||||
if (globalDriverHandle != driverHandle) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, false);
|
||||
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
|
||||
osLibrary->procMap["OpenGTPin"] = reinterpret_cast<void *>(openPinHandler);
|
||||
}
|
||||
void TearDown() override {
|
||||
delete MockOsLibrary::loadLibraryNewObject;
|
||||
delete globalDriverHandle;
|
||||
gtpinInitTimesCalled = 0u;
|
||||
}
|
||||
|
||||
Mock<Driver> driver;
|
||||
static uint32_t gtpinInitTimesCalled;
|
||||
VariableBackup<uint32_t> gtpinCounterBackup{>pinInitTimesCalled, 0};
|
||||
VariableBackup<uint32_t> mockGetenvCalledBackup{&IoFunctions::mockGetenvCalled, 0};
|
||||
std::unordered_map<std::string, std::string> mockableEnvs = {{"ZET_ENABLE_PROGRAM_INSTRUMENTATION", "1"}};
|
||||
VariableBackup<std::unordered_map<std::string, std::string> *> mockableEnvValuesBackup{&IoFunctions::mockableEnvValues, &mockableEnvs};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, MockOsLibrary::load};
|
||||
VariableBackup<NEO::OsLibrary *> osLibraryBackup{&MockOsLibrary::loadLibraryNewObject, nullptr};
|
||||
VariableBackup<_ze_driver_handle_t *> globalDriverHandleBackup{&globalDriverHandle, nullptr};
|
||||
VariableBackup<decltype(L0::globalDriver)> globalDriverBackup{&L0::globalDriver, nullptr};
|
||||
VariableBackup<uint32_t> driverCountBackup{&driverCount};
|
||||
};
|
||||
uint32_t GtPinInitTest::gtpinInitTimesCalled = 0u;
|
||||
|
||||
TEST_F(GtPinInitTest, givenRequirementForGtpinWhenCallingZeInitMultipleTimesThenGtPinIsNotInitialized) {
|
||||
EXPECT_EQ(Mock<Driver>::GtPinInitializationStatus::notNeeded, driver.gtPinInitializationStatus.load());
|
||||
auto result = zeInit(ZE_INIT_FLAG_GPU_ONLY);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(1u, driver.initCalledCount);
|
||||
EXPECT_EQ(1u, driver.initializeCalledCount);
|
||||
EXPECT_EQ(0u, gtpinInitTimesCalled);
|
||||
EXPECT_EQ(Mock<Driver>::GtPinInitializationStatus::pending, driver.gtPinInitializationStatus.load());
|
||||
driver.gtPinInitializationStatus = Mock<Driver>::GtPinInitializationStatus::notNeeded;
|
||||
result = zeInit(ZE_INIT_FLAG_GPU_ONLY);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(2u, driver.initCalledCount);
|
||||
EXPECT_EQ(1u, driver.initializeCalledCount);
|
||||
EXPECT_EQ(0u, gtpinInitTimesCalled);
|
||||
EXPECT_EQ(Mock<Driver>::GtPinInitializationStatus::notNeeded, driver.gtPinInitializationStatus.load());
|
||||
}
|
||||
|
||||
TEST_F(GtPinInitTest, givenRequirementForGtpinWhenCallingZeDriverGetMultipleTimesThenGtPinIsInitializedOnlyOnce) {
|
||||
auto result = zeInit(ZE_INIT_FLAG_GPU_ONLY);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(1u, driver.initCalledCount);
|
||||
EXPECT_EQ(1u, driver.initializeCalledCount);
|
||||
EXPECT_EQ(0u, gtpinInitTimesCalled);
|
||||
uint32_t driverCount = 0;
|
||||
ze_driver_handle_t driverHandle{};
|
||||
result = zeDriverGet(&driverCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
ASSERT_EQ(1u, driverCount);
|
||||
result = zeDriverGet(&driverCount, &driverHandle);
|
||||
ASSERT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
ASSERT_EQ(1u, driverCount);
|
||||
EXPECT_EQ(globalDriverHandle, driverHandle);
|
||||
|
||||
EXPECT_EQ(1u, driver.initCalledCount);
|
||||
EXPECT_EQ(1u, driver.initializeCalledCount);
|
||||
EXPECT_EQ(1u, gtpinInitTimesCalled);
|
||||
}
|
||||
|
||||
TEST_F(GtPinInitTest, givenGtPinInitializationFailureWhenCallingZeDriverGetThenDependencyErrorIsReturnedEveryTime) {
|
||||
|
||||
uint32_t (*gtPinInit)(void *) = [](void *arg) -> uint32_t {
|
||||
return 1;
|
||||
};
|
||||
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["OpenGTPin"] = reinterpret_cast<void *>(gtPinInit);
|
||||
auto result = zeInit(ZE_INIT_FLAG_GPU_ONLY);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(1u, driver.initCalledCount);
|
||||
EXPECT_EQ(1u, driver.initializeCalledCount);
|
||||
EXPECT_EQ(0u, gtpinInitTimesCalled);
|
||||
uint32_t driverCount = 0;
|
||||
result = zeDriverGet(&driverCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, result);
|
||||
|
||||
result = zeDriverGet(&driverCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, result);
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
|
||||
Reference in New Issue
Block a user