diff --git a/level_zero/core/source/driver/driver.cpp b/level_zero/core/source/driver/driver.cpp index 4a953528e3..e89d9a1cee 100644 --- a/level_zero/core/source/driver/driver.cpp +++ b/level_zero/core/source/driver/driver.cpp @@ -24,6 +24,7 @@ namespace L0 { _ze_driver_handle_t *GlobalDriverHandle; +bool LevelZeroDriverInitialized = false; uint32_t driverCount = 1; void DriverImp::initialize(ze_result_t *result) { @@ -125,9 +126,17 @@ static DriverImp driverImp; Driver *Driver::driver = &driverImp; ze_result_t init(ze_init_flags_t flags) { - if (flags && !(flags & ZE_INIT_FLAG_GPU_ONLY)) + if (flags && !(flags & ZE_INIT_FLAG_GPU_ONLY)) { + L0::LevelZeroDriverInitialized = false; return ZE_RESULT_ERROR_UNINITIALIZED; - else - return Driver::get()->driverInit(flags); + } else { + ze_result_t result = Driver::get()->driverInit(flags); + if (result == ZE_RESULT_SUCCESS) { + L0::LevelZeroDriverInitialized = true; + } else { + L0::LevelZeroDriverInitialized = false; + } + return result; + } } } // namespace L0 diff --git a/level_zero/core/source/driver/driver.h b/level_zero/core/source/driver/driver.h index 5f776005c0..4bab543763 100644 --- a/level_zero/core/source/driver/driver.h +++ b/level_zero/core/source/driver/driver.h @@ -26,4 +26,5 @@ ze_result_t driverHandleGet(uint32_t *pCount, ze_driver_handle_t *phDrivers); extern bool sysmanInitFromCore; extern uint32_t driverCount; extern _ze_driver_handle_t *GlobalDriverHandle; +extern bool LevelZeroDriverInitialized; } // namespace L0 diff --git a/level_zero/core/source/linux/driver_teardown.cpp b/level_zero/core/source/linux/driver_teardown.cpp index 6488a05e36..47ebafa3bc 100644 --- a/level_zero/core/source/linux/driver_teardown.cpp +++ b/level_zero/core/source/linux/driver_teardown.cpp @@ -7,6 +7,7 @@ #include "shared/source/os_interface/os_library.h" +#include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/global_teardown.h" #include @@ -14,15 +15,19 @@ namespace L0 { ze_result_t setDriverTeardownHandleInLoader(std::string loaderLibraryName) { - ze_result_t result = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; - std::unique_ptr loaderLibrary = std::unique_ptr{NEO::OsLibrary::load(loaderLibraryName.c_str())}; - if (loaderLibrary) { - zelSetDriverTeardown_fn setDriverTeardown = reinterpret_cast(loaderLibrary->getProcAddress("zelSetDriverTeardown")); - if (setDriverTeardown) { - result = setDriverTeardown(); + if (L0::LevelZeroDriverInitialized) { + ze_result_t result = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + std::unique_ptr loaderLibrary = std::unique_ptr{NEO::OsLibrary::load(loaderLibraryName.c_str())}; + if (loaderLibrary) { + zelSetDriverTeardown_fn setDriverTeardown = reinterpret_cast(loaderLibrary->getProcAddress("zelSetDriverTeardown")); + if (setDriverTeardown) { + result = setDriverTeardown(); + } } + return result; + } else { + return ZE_RESULT_ERROR_UNINITIALIZED; } - return result; } } // namespace L0 diff --git a/level_zero/core/source/windows/driver_teardown.cpp b/level_zero/core/source/windows/driver_teardown.cpp index f34eac5afa..c7c23e1e94 100644 --- a/level_zero/core/source/windows/driver_teardown.cpp +++ b/level_zero/core/source/windows/driver_teardown.cpp @@ -5,6 +5,7 @@ * */ +#include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/global_teardown.h" #include "level_zero/tools/source/sysman/os_sysman_driver.h" #include "level_zero/tools/source/sysman/sysman.h" @@ -14,16 +15,20 @@ namespace L0 { ze_result_t setDriverTeardownHandleInLoader(std::string loaderLibraryName) { - HMODULE handle = nullptr; - ze_result_t result = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; - handle = GetModuleHandleA(loaderLibraryName.c_str()); - if (handle) { - zelSetDriverTeardown_fn setDriverTeardown = reinterpret_cast(GetProcAddress(handle, "zelSetDriverTeardown")); - if (setDriverTeardown) { - result = setDriverTeardown(); + if (L0::LevelZeroDriverInitialized) { + HMODULE handle = nullptr; + ze_result_t result = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + handle = GetModuleHandleA(loaderLibraryName.c_str()); + if (handle) { + zelSetDriverTeardown_fn setDriverTeardown = reinterpret_cast(GetProcAddress(handle, "zelSetDriverTeardown")); + if (setDriverTeardown) { + result = setDriverTeardown(); + } } + return result; + } else { + return ZE_RESULT_ERROR_UNINITIALIZED; } - return result; } } // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_driver.h b/level_zero/core/test/unit_tests/mocks/mock_driver.h index b29acfb788..9444c4ed24 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_driver.h +++ b/level_zero/core/test/unit_tests/mocks/mock_driver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -28,11 +28,15 @@ struct Mock : public Driver { ze_result_t driverInit(ze_init_flags_t flag) override { initCalledCount++; + if (failInitDriver) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } return ZE_RESULT_SUCCESS; } Driver *previousDriver = nullptr; uint32_t initCalledCount = 0; + bool failInitDriver = false; }; } // namespace ult diff --git a/level_zero/core/test/unit_tests/os_interface/global_teardown_tests.cpp b/level_zero/core/test/unit_tests/os_interface/global_teardown_tests.cpp index 9627c501b0..0e99ea1673 100644 --- a/level_zero/core/test/unit_tests/os_interface/global_teardown_tests.cpp +++ b/level_zero/core/test/unit_tests/os_interface/global_teardown_tests.cpp @@ -10,6 +10,7 @@ #include "shared/source/os_interface/os_library.h" #include "shared/test/common/test_macros/test.h" +#include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/driver/driver_handle_imp.h" #include "level_zero/core/source/global_teardown.h" #include "level_zero/sysman/source/sysman_driver_handle_imp.h" @@ -18,14 +19,25 @@ namespace L0 { namespace ult { TEST(GlobalTearDownCallbackTests, givenL0LoaderThenGlobalTeardownCallbackIsCalled) { + L0::LevelZeroDriverInitialized = true; std::unique_ptr loaderLibrary = std::unique_ptr{NEO::OsLibrary::load(L0::ult::testLoaderDllName)}; EXPECT_EQ(ZE_RESULT_SUCCESS, setDriverTeardownHandleInLoader(L0::ult::testLoaderDllName)); + L0::LevelZeroDriverInitialized = false; +} +TEST(GlobalTearDownCallbackTests, givenL0LoaderButL0DriverDidNotInitThenSetTearDownReturnsUninitialized) { + L0::LevelZeroDriverInitialized = false; + std::unique_ptr loaderLibrary = std::unique_ptr{NEO::OsLibrary::load(L0::ult::testLoaderDllName)}; + EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, setDriverTeardownHandleInLoader(L0::ult::testLoaderDllName)); } TEST(GlobalTearDownCallbackTests, givenL0LoaderIsMissingThenGlobalTeardownCallbackIsNotCalled) { + L0::LevelZeroDriverInitialized = true; EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, setDriverTeardownHandleInLoader("invalid.so")); + L0::LevelZeroDriverInitialized = false; } TEST(GlobalTearDownCallbackTests, givenL0LoaderWithoutGlobalTeardownCallbackThenGlobalTeardownCallbackIsNotCalled) { + L0::LevelZeroDriverInitialized = true; EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, setDriverTeardownHandleInLoader(L0::ult::testDllName)); + L0::LevelZeroDriverInitialized = false; } TEST(GlobalTearDownTests, givenCallToGlobalTearDownFunctionThenGlobalDriversAreNull) { globalDriverTeardown(); diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index 83ee4314d3..aaeb5de304 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -43,6 +43,32 @@ TEST(zeInit, whenCallingZeInitThenInitializeOnDriverIsCalled) { EXPECT_EQ(1u, driver.initCalledCount); } +TEST(zeInit, whenCallingZeInitThenLevelZeroDriverInitializedIsSetToTrue) { + Mock driver; + + auto result = zeInit(ZE_INIT_FLAG_GPU_ONLY); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_TRUE(LevelZeroDriverInitialized); + EXPECT_EQ(1u, driver.initCalledCount); +} + +TEST(zeInit, whenCallingZeInitWithFailureInIinitThenLevelZeroDriverInitializedIsSetToFalse) { + Mock driver; + driver.failInitDriver = true; + + auto result = zeInit(ZE_INIT_FLAG_GPU_ONLY); + EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, result); + EXPECT_FALSE(LevelZeroDriverInitialized); +} + +TEST(zeInit, whenCallingZeInitWithVpuOnlyThenLevelZeroDriverInitializedIsSetToFalse) { + Mock driver; + + auto result = zeInit(ZE_INIT_FLAG_VPU_ONLY); + EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, result); + EXPECT_FALSE(LevelZeroDriverInitialized); +} + TEST(zeInit, whenCallingZeInitWithNoFlagsThenInitializeOnDriverIsCalled) { Mock driver;