From b0e3d8656e3805a8c6ad60e4fbd53d22e6ef5da5 Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Wed, 19 Feb 2025 09:29:27 +0000 Subject: [PATCH] refactor: Add OV detection mechanism for ULLS light Related-To: NEO-13922 Signed-off-by: Lukasz Jobczyk --- .../os_interface/linux/os_context_linux.cpp | 12 +++- .../os_interface/linux/os_context_linux.h | 3 + .../os_interface/linux/os_library_linux.cpp | 20 +++++- .../os_interface/linux/os_library_linux.h | 5 +- shared/source/release_helper/release_helper.h | 2 + .../release_helper/release_helper_base.inl | 5 ++ .../mocks/linux/mock_os_context_linux.h | 3 +- .../test/common/mocks/mock_release_helper.h | 1 + .../linux/drm_direct_submission_tests.cpp | 2 + .../linux/os_context_linux_tests.cpp | 62 +++++++++++++++++++ 10 files changed, 111 insertions(+), 4 deletions(-) diff --git a/shared/source/os_interface/linux/os_context_linux.cpp b/shared/source/os_interface/linux/os_context_linux.cpp index 106c2efb70..4fd5a3d224 100644 --- a/shared/source/os_interface/linux/os_context_linux.cpp +++ b/shared/source/os_interface/linux/os_context_linux.cpp @@ -15,10 +15,12 @@ #include "shared/source/helpers/ptr_math.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/ioctl_helper.h" +#include "shared/source/os_interface/linux/os_library_linux.h" #include "shared/source/os_interface/os_context.h" #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/product_helper.h" #include "shared/source/os_interface/sys_calls_common.h" +#include "shared/source/release_helper/release_helper.h" namespace NEO { @@ -34,6 +36,7 @@ OsContextLinux::OsContextLinux(Drm &drm, uint32_t rootDeviceIndex, uint32_t cont drm(drm) { pagingFence.fill(0u); fenceVal.fill(0u); + this->isOpenVinoLoaded(); } bool OsContextLinux::initializeContext(bool allocateInterrupt) { @@ -88,11 +91,18 @@ bool OsContextLinux::initializeContext(bool allocateInterrupt) { return true; } +void OsContextLinux::isOpenVinoLoaded() { + std::call_once(this->ovLoadedFlag, [this]() { + this->ovLoaded = NEO::Linux::isLibraryLoaded("libopenvino_intel_gpu_plugin.so"); + }); +} + bool OsContextLinux::isDirectSubmissionSupported() const { auto &rootDeviceEnvironment = this->getDrm().getRootDeviceEnvironment(); auto &productHelper = rootDeviceEnvironment.getHelper(); + const auto releaseHelper = rootDeviceEnvironment.getReleaseHelper(); - return this->getDrm().isVmBindAvailable() && productHelper.isDirectSubmissionSupported(rootDeviceEnvironment.getReleaseHelper()); + return (this->getDrm().isVmBindAvailable() || (this->ovLoaded && releaseHelper && releaseHelper->isDirectSubmissionLightSupported())) && productHelper.isDirectSubmissionSupported(rootDeviceEnvironment.getReleaseHelper()); } Drm &OsContextLinux::getDrm() const { diff --git a/shared/source/os_interface/linux/os_context_linux.h b/shared/source/os_interface/linux/os_context_linux.h index 57fa508db6..715268d14a 100644 --- a/shared/source/os_interface/linux/os_context_linux.h +++ b/shared/source/os_interface/linux/os_context_linux.h @@ -50,6 +50,7 @@ class OsContextLinux : public OsContext { protected: bool initializeContext(bool allocateInterrupt) override; + void isOpenVinoLoaded(); unsigned int engineFlag = 0; std::vector drmContextIds; @@ -58,7 +59,9 @@ class OsContextLinux : public OsContext { std::array pagingFence; std::array fenceVal; + std::once_flag ovLoadedFlag{}; Drm &drm; bool contextHangDetected = false; + bool ovLoaded = false; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/os_library_linux.cpp b/shared/source/os_interface/linux/os_library_linux.cpp index c1a455c380..a59d389b2e 100644 --- a/shared/source/os_interface/linux/os_library_linux.cpp +++ b/shared/source/os_interface/linux/os_library_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -10,6 +10,7 @@ #include "shared/source/helpers/debug_helpers.h" #include "shared/source/os_interface/linux/sys_calls.h" +#include #include #include @@ -81,5 +82,22 @@ std::string OsLibrary::getFullPath() { } return std::string(); } + +bool isLibraryLoaded(const std::string &libraryName) { + auto handle = SysCalls::dlopen(0, RTLD_LAZY); + struct link_map *map = nullptr; + int retVal = NEO::SysCalls::dlinfo(handle, RTLD_DI_LINKMAP, &map); + if (retVal == 0 && map != nullptr) { + while (map) { + if (strstr(map->l_name, libraryName.c_str())) { + dlclose(handle); + return true; + } + map = map->l_next; + } + } + dlclose(handle); + return false; +} } // namespace Linux } // namespace NEO diff --git a/shared/source/os_interface/linux/os_library_linux.h b/shared/source/os_interface/linux/os_library_linux.h index ff1473a32c..08c923ca3f 100644 --- a/shared/source/os_interface/linux/os_library_linux.h +++ b/shared/source/os_interface/linux/os_library_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -25,5 +25,8 @@ class OsLibrary : public NEO::OsLibrary { void *getProcAddress(const std::string &procName) override; std::string getFullPath() override; }; + +bool isLibraryLoaded(const std::string &libraryName); + } // namespace Linux } // namespace NEO diff --git a/shared/source/release_helper/release_helper.h b/shared/source/release_helper/release_helper.h index 4875589ff8..2a8d7097bc 100644 --- a/shared/source/release_helper/release_helper.h +++ b/shared/source/release_helper/release_helper.h @@ -59,6 +59,7 @@ class ReleaseHelper { virtual uint32_t getStackSizePerRay() const = 0; virtual bool isLocalOnlyAllowed() const = 0; virtual bool isDummyBlitWaRequired() const = 0; + virtual bool isDirectSubmissionLightSupported() const = 0; virtual const SizeToPreferredSlmValueArray &getSizeToPreferredSlmValue(bool isHeapless) const = 0; virtual bool isNumRtStacksPerDssFixedValue() const = 0; virtual bool getFtrXe2Compression() const = 0; @@ -100,6 +101,7 @@ class ReleaseHelperHw : public ReleaseHelper { uint32_t getStackSizePerRay() const override; bool isLocalOnlyAllowed() const override; bool isDummyBlitWaRequired() const override; + bool isDirectSubmissionLightSupported() const override; const SizeToPreferredSlmValueArray &getSizeToPreferredSlmValue(bool isHeapless) const override; bool isNumRtStacksPerDssFixedValue() const override; bool getFtrXe2Compression() const override; diff --git a/shared/source/release_helper/release_helper_base.inl b/shared/source/release_helper/release_helper_base.inl index 792badfaae..b2bf16f27f 100644 --- a/shared/source/release_helper/release_helper_base.inl +++ b/shared/source/release_helper/release_helper_base.inl @@ -64,6 +64,11 @@ bool ReleaseHelperHw::isDirectSubmissionSupported() const { return false; } +template +bool ReleaseHelperHw::isDirectSubmissionLightSupported() const { + return false; +} + template bool ReleaseHelperHw::isRcsExposureDisabled() const { return false; diff --git a/shared/test/common/mocks/linux/mock_os_context_linux.h b/shared/test/common/mocks/linux/mock_os_context_linux.h index c45ba6420d..a09186f77f 100644 --- a/shared/test/common/mocks/linux/mock_os_context_linux.h +++ b/shared/test/common/mocks/linux/mock_os_context_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -14,6 +14,7 @@ class MockOsContextLinux : public OsContextLinux { using OsContextLinux::drmContextIds; using OsContextLinux::drmVmIds; using OsContextLinux::fenceVal; + using OsContextLinux::ovLoaded; using OsContextLinux::pagingFence; MockOsContextLinux(Drm &drm, uint32_t rootDeviceIndex, uint32_t contextId, const EngineDescriptor &engineDescriptor) diff --git a/shared/test/common/mocks/mock_release_helper.h b/shared/test/common/mocks/mock_release_helper.h index 08099b6f8e..ddb04caf79 100644 --- a/shared/test/common/mocks/mock_release_helper.h +++ b/shared/test/common/mocks/mock_release_helper.h @@ -41,6 +41,7 @@ class MockReleaseHelper : public ReleaseHelper { ADDMETHOD_CONST_NOBASE(isDummyBlitWaRequired, bool, false, ()); ADDMETHOD_CONST_NOBASE(isNumRtStacksPerDssFixedValue, bool, true, ()); ADDMETHOD_CONST_NOBASE(getFtrXe2Compression, bool, false, ()); + ADDMETHOD_CONST_NOBASE(isDirectSubmissionLightSupported, bool, false, ()); const SizeToPreferredSlmValueArray &getSizeToPreferredSlmValue(bool isHeapless) const override { static SizeToPreferredSlmValueArray sizeToPreferredSlmValue = {}; diff --git a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp index 9026f49702..cd1daca4d9 100644 --- a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp @@ -16,6 +16,7 @@ #include "shared/source/os_interface/linux/drm_memory_operations_handler.h" #include "shared/source/os_interface/linux/os_context_linux.h" #include "shared/source/os_interface/linux/sys_calls.h" +#include "shared/source/release_helper/release_helper.h" #include "shared/source/utilities/wait_util.h" #include "shared/test/common/cmd_parse/hw_parse.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" @@ -52,6 +53,7 @@ struct DrmDirectSubmissionTest : public DrmMemoryManagerBasic { true, executionEnvironment); device.reset(MockDevice::create(&executionEnvironment, 0u)); + executionEnvironment.rootDeviceEnvironments[0]->initReleaseHelper(); osContext = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]->osInterface->getDriverModel()->as(), device->getRootDeviceIndex(), 0u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, device->getDeviceBitfield())); diff --git a/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp b/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp index 6c8071cd51..15159793a1 100644 --- a/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/os_context_linux_tests.cpp @@ -8,14 +8,21 @@ #include "shared/source/os_interface/linux/drm_memory_operations_handler.h" #include "shared/source/os_interface/linux/ioctl_helper.h" #include "shared/source/os_interface/linux/os_context_linux.h" +#include "shared/source/os_interface/linux/sys_calls.h" +#include "shared/source/os_interface/product_helper.h" +#include "shared/source/release_helper/release_helper.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" +#include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/mocks/linux/mock_os_context_linux.h" #include "shared/test/common/mocks/mock_execution_environment.h" +#include "shared/test/common/mocks/mock_os_library.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" +#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h" #include "gtest/gtest.h" +#include #include using namespace NEO; @@ -134,4 +141,59 @@ TEST(OSContextLinux, givenPerContextVmsAndBindCompleteWhenGetFenceAddressAndValT EXPECT_GT(fenceAddressToWait, 0u); EXPECT_GT(fenceValToWait, 0u); +} + +TEST(OSContextLinux, WhenCreateOsContextLinuxThenCheckIfOVLoaded) { + auto executionEnvironment = std::make_unique(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.requirePerContextVM = true; + + { + VariableBackup mockDlinfo(&SysCalls::sysCallsDlinfo, [](void *handle, int request, void *info) -> int { + return -2; + }); + MockOsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + EXPECT_FALSE(osContext.ovLoaded); + } + { + VariableBackup mockDlinfo(&SysCalls::sysCallsDlinfo, [](void *handle, int request, void *info) -> int { + return 0; + }); + MockOsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + EXPECT_FALSE(osContext.ovLoaded); + } + { + VariableBackup mockDlinfo(&SysCalls::sysCallsDlinfo, [](void *handle, int request, void *info) -> int { + static char name[] = "libexample.so"; + static link_map map{}; + map.l_name = name; + *static_cast(info) = ↦ + return 0; + }); + MockOsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + EXPECT_FALSE(osContext.ovLoaded); + } + { + VariableBackup mockDlinfo(&SysCalls::sysCallsDlinfo, [](void *handle, int request, void *info) -> int { + static char name[] = "libopenvino_intel_gpu_plugin.so"; + static link_map map{}; + map.l_name = name; + *static_cast(info) = ↦ + return 0; + }); + MockOsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + EXPECT_TRUE(osContext.ovLoaded); + } +} + +TEST(OSContextLinux, givenOVLoadedWhenCheckForDirectSubmissionSupportThenProperValueIsReturned) { + auto executionEnvironment = std::make_unique(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + drm.requirePerContextVM = true; + MockOsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor()); + osContext.ovLoaded = true; + auto directSubmissionSupported = osContext.isDirectSubmissionSupported(); + + auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getProductHelper(); + EXPECT_EQ(directSubmissionSupported, productHelper.isDirectSubmissionSupported(executionEnvironment->rootDeviceEnvironments[0]->getReleaseHelper()) && executionEnvironment->rootDeviceEnvironments[0]->getReleaseHelper()->isDirectSubmissionLightSupported()); } \ No newline at end of file