From ba5c6f32b360d4522e6aac0e8e0e6efb388d80a8 Mon Sep 17 00:00:00 2001 From: Joshua Santosh Ranjan Date: Thu, 7 Mar 2024 07:27:55 +0000 Subject: [PATCH] feature: return error when file handles are exhaused in sysman engine Related-To: NEO-10513 Signed-off-by: Joshua Santosh Ranjan --- .../tools/source/sysman/engine/engine.cpp | 11 ++- .../tools/source/sysman/engine/engine.h | 5 +- .../tools/source/sysman/engine/engine_imp.cpp | 6 +- .../sysman/engine/linux/os_engine_imp.cpp | 36 +++++--- .../sysman/engine/linux/os_engine_imp.h | 5 +- .../engine/linux/os_engine_imp_prelim.cpp | 87 +++++++++++++----- .../tools/source/sysman/engine/os_engine.h | 4 +- .../sysman/engine/windows/os_engine_imp.cpp | 6 +- .../sysman/engine/windows/os_engine_imp.h | 4 +- .../sources/sysman/engine/linux/mock_engine.h | 4 +- .../sysman/engine/linux/mock_engine_prelim.h | 2 + .../engine/linux/test_zes_engine_prelim.cpp | 92 ++++++++++++++----- 12 files changed, 190 insertions(+), 72 deletions(-) diff --git a/level_zero/tools/source/sysman/engine/engine.cpp b/level_zero/tools/source/sysman/engine/engine.cpp index 7b74dfb633..95439c55cb 100644 --- a/level_zero/tools/source/sysman/engine/engine.cpp +++ b/level_zero/tools/source/sysman/engine/engine.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -25,7 +25,9 @@ EngineHandleContext::~EngineHandleContext() { void EngineHandleContext::createHandle(zes_engine_group_t engineType, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubdevice) { std::unique_ptr pEngine = std::make_unique(pOsSysman, engineType, engineInstance, subDeviceId, onSubdevice); - if (pEngine->initSuccess == true) { + // Only store error for all engines in device incase of dependencies unavailable. + deviceEngineInitStatus = pEngine->initStatus != ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE ? deviceEngineInitStatus : pEngine->initStatus; + if (pEngine->initStatus == ZE_RESULT_SUCCESS) { handleList.push_back(std::move(pEngine)); } } @@ -54,6 +56,11 @@ ze_result_t EngineHandleContext::engineGet(uint32_t *pCount, zes_engine_handle_t this->init(pOsSysman->getDeviceHandles()); this->engineInitDone = true; }); + + if (deviceEngineInitStatus != ZE_RESULT_SUCCESS) { + return deviceEngineInitStatus; + } + uint32_t handleListSize = static_cast(handleList.size()); uint32_t numToCopy = std::min(*pCount, handleListSize); if (0 == *pCount || *pCount > handleListSize) { diff --git a/level_zero/tools/source/sysman/engine/engine.h b/level_zero/tools/source/sysman/engine/engine.h index 16c823d1a9..22377e3c1f 100644 --- a/level_zero/tools/source/sysman/engine/engine.h +++ b/level_zero/tools/source/sysman/engine/engine.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -27,7 +27,7 @@ class Engine : _zes_engine_handle_t { return static_cast(handle); } inline zes_engine_handle_t toHandle() { return this; } - bool initSuccess = false; + ze_result_t initStatus = ZE_RESULT_SUCCESS; }; struct EngineHandleContext { @@ -49,6 +49,7 @@ struct EngineHandleContext { void createHandle(zes_engine_group_t engineType, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubdevice); std::once_flag initEngineOnce; bool engineInitDone = false; + ze_result_t deviceEngineInitStatus = ZE_RESULT_SUCCESS; }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/engine/engine_imp.cpp b/level_zero/tools/source/sysman/engine/engine_imp.cpp index 72bb6f7f01..0be77178c5 100644 --- a/level_zero/tools/source/sysman/engine/engine_imp.cpp +++ b/level_zero/tools/source/sysman/engine/engine_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -23,9 +23,9 @@ ze_result_t EngineImp::engineGetProperties(zes_engine_properties_t *pProperties) } void EngineImp::init() { - if (pOsEngine->isEngineModuleSupported()) { + initStatus = pOsEngine->isEngineModuleSupported(); + if (initStatus == ZE_RESULT_SUCCESS) { pOsEngine->getProperties(engineProperties); - this->initSuccess = true; } } diff --git a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp index 3623775a5e..dcb4279fdd 100644 --- a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp +++ b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.cpp @@ -51,9 +51,8 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::setpmuRead(static_cast(fdList[0].first), data, sizeof(data)); @@ -74,6 +73,16 @@ ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) { return ZE_RESULT_SUCCESS; } +void LinuxEngineImp::checkErrorNumberAndUpdateStatus() { + if (errno == -EMFILE || errno == -ENFILE) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Engine Handles could not be created because system has run out of file handles. Suggested action is to increase the file handle limit. \n"); + initStatus = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } else { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():No valid Filedescriptors: Engine Module is not supported \n", __FUNCTION__); + initStatus = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } +} + void LinuxEngineImp::init() { auto i915EngineClass = engineToI915Map.find(engineGroup); vfConfigs.clear(); @@ -81,6 +90,8 @@ void LinuxEngineImp::init() { auto fd = pPmuInterface->pmuInterfaceOpen(I915_PMU_ENGINE_BUSY(i915EngineClass->second, engineInstance), -1, PERF_FORMAT_TOTAL_TIME_ENABLED); if (fd >= 0) { fdList.push_back(std::make_pair(fd, -1)); + } else { + checkErrorNumberAndUpdateStatus(); } } @@ -88,21 +99,21 @@ ze_result_t LinuxEngineImp::getActivityExt(uint32_t *pCount, zes_engine_stats_t return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } -LinuxEngineImp::~LinuxEngineImp() { +void LinuxEngineImp::cleanup() { for (auto &fdPair : fdList) { - if (fdPair.first != -1) { + if (fdPair.first >= 0) { close(static_cast(fdPair.first)); } } fdList.clear(); } -bool LinuxEngineImp::isEngineModuleSupported() { - if (fdList.size() == 0) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():No valid Filedescriptors: Engine Module is not supported \n", __FUNCTION__); - return false; - } - return true; +LinuxEngineImp::~LinuxEngineImp() { + cleanup(); +} + +ze_result_t LinuxEngineImp::isEngineModuleSupported() { + return initStatus; } LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubDevice) : engineGroup(type), engineInstance(engineInstance), subDeviceId(subDeviceId), onSubDevice(onSubDevice) { @@ -111,6 +122,9 @@ LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uin pDevice = pLinuxSysmanImp->getDeviceHandle(); pPmuInterface = pLinuxSysmanImp->getPmuInterface(); init(); + if (initStatus != ZE_RESULT_SUCCESS) { + cleanup(); + } } std::unique_ptr OsEngine::create(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubDevice) { diff --git a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.h b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.h index 9ae5a3875a..a12f71e963 100644 --- a/level_zero/tools/source/sysman/engine/linux/os_engine_imp.h +++ b/level_zero/tools/source/sysman/engine/linux/os_engine_imp.h @@ -23,10 +23,11 @@ class LinuxEngineImp : public OsEngine, NEO::NonCopyableOrMovableClass { ze_result_t getActivity(zes_engine_stats_t *pStats) override; ze_result_t getActivityExt(uint32_t *pCount, zes_engine_stats_t *pStats) override; ze_result_t getProperties(zes_engine_properties_t &properties) override; - bool isEngineModuleSupported() override; + ze_result_t isEngineModuleSupported() override; static zes_engine_group_t getGroupFromEngineType(zes_engine_group_t type); LinuxEngineImp() = default; LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubDevice); + void cleanup(); ~LinuxEngineImp() override; protected: @@ -39,11 +40,13 @@ class LinuxEngineImp : public OsEngine, NEO::NonCopyableOrMovableClass { ze_bool_t onSubDevice = false; uint32_t numberOfVfs = 0; SysfsAccess *pSysfsAccess = nullptr; + void checkErrorNumberAndUpdateStatus(); private: void init(); std::vector> fdList{}; std::vector> vfConfigs{}; + ze_result_t initStatus = ZE_RESULT_SUCCESS; }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/engine/linux/os_engine_imp_prelim.cpp b/level_zero/tools/source/sysman/engine/linux/os_engine_imp_prelim.cpp index 118b2ff5a0..1298b959fe 100644 --- a/level_zero/tools/source/sysman/engine/linux/os_engine_imp_prelim.cpp +++ b/level_zero/tools/source/sysman/engine/linux/os_engine_imp_prelim.cpp @@ -87,10 +87,10 @@ static ze_result_t readBusynessFromGroupFd(PmuInterface *pPmuInterface, std::pai return ZE_RESULT_SUCCESS; } -static void openPmuHandlesForVfs(uint32_t numberOfVfs, - PmuInterface *pPmuInterface, - std::vector> &vfConfigs, - std::vector> &fdList) { +static ze_result_t openPmuHandlesForVfs(uint32_t numberOfVfs, + PmuInterface *pPmuInterface, + std::vector> &vfConfigs, + std::vector> &fdList) { // +1 to include PF for (uint64_t i = 0; i < numberOfVfs + 1; i++) { int64_t fd[2] = {-1, -1}; @@ -100,33 +100,53 @@ static void openPmuHandlesForVfs(uint32_t numberOfVfs, if (fd[0] >= 0) { fd[1] = pPmuInterface->pmuInterfaceOpen(vfConfigs[i].second, static_cast(fd[0]), PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); - if (fd[1] == -1) { + if (fd[1] < 0) { NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Total Active Ticks PMU Handle \n", __FUNCTION__); close(static_cast(fd[0])); fd[0] = -1; } } + if (fd[1] < 0) { + if (errno == -EMFILE || errno == -ENFILE) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Engine Handles could not be created because system has run out of file handles. Suggested action is to increase the file handle limit. \n"); + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + } + fdList.push_back(std::make_pair(fd[0], fd[1])); } + + return ZE_RESULT_SUCCESS; } ze_result_t LinuxEngineImp::getActivity(zes_engine_stats_t *pStats) { + + if (initStatus != ZE_RESULT_SUCCESS) { + // Handles are not expected to be created in case of init failure + DEBUG_BREAK_IF(true); + } + // read from global busyness fd return readBusynessFromGroupFd(pPmuInterface, fdList[0], pStats); } -LinuxEngineImp::~LinuxEngineImp() { - +void LinuxEngineImp::cleanup() { for (auto &fdPair : fdList) { - if (fdPair.first != -1) { + if (fdPair.first >= 0) { close(static_cast(fdPair.first)); } - if (fdPair.second != -1) { + if (fdPair.second >= 0) { close(static_cast(fdPair.second)); } } fdList.clear(); + vfConfigs.clear(); + numberOfVfs = 0; +} + +LinuxEngineImp::~LinuxEngineImp() { + cleanup(); } ze_result_t LinuxEngineImp::getActivityExt(uint32_t *pCount, zes_engine_stats_t *pStats) { @@ -148,8 +168,22 @@ ze_result_t LinuxEngineImp::getActivityExt(uint32_t *pCount, zes_engine_stats_t } // Open only if not opened previously + // fdList[0] has global busyness. + // So check if PF and VF busyness were not updated if (fdList.size() == 1) { - openPmuHandlesForVfs(numberOfVfs, pPmuInterface, vfConfigs, fdList); + auto status = openPmuHandlesForVfs(numberOfVfs, pPmuInterface, vfConfigs, fdList); + if (status != ZE_RESULT_SUCCESS) { + // Clean up all vf fds added + for (size_t i = 1; i < fdList.size(); i++) { + auto &fdPair = fdList[i]; + if (fdPair.first >= 0) { + close(static_cast(fdPair.first)); + close(static_cast(fdPair.second)); + } + fdList.resize(1); + } + return status; + } } *pCount = std::min(*pCount, numberOfVfs + 1); @@ -176,6 +210,15 @@ ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) { return ZE_RESULT_SUCCESS; } +void LinuxEngineImp::checkErrorNumberAndUpdateStatus() { + if (errno == -EMFILE || errno == -ENFILE) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Engine Handles could not be created because system has run out of file handles. Suggested action is to increase the file handle limit. \n"); + initStatus = ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } else { + initStatus = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } +} + void LinuxEngineImp::init() { uint64_t config = UINT64_MAX; switch (engineGroup) { @@ -201,14 +244,16 @@ void LinuxEngineImp::init() { // Fds for global busyness fd[0] = pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); - if (fd[0] == -1) { + if (fd[0] < 0) { NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Busy Ticks Handle \n", __FUNCTION__); + checkErrorNumberAndUpdateStatus(); return; } fd[1] = pPmuInterface->pmuInterfaceOpen(__PRELIM_I915_PMU_TOTAL_ACTIVE_TICKS(subDeviceId), static_cast(fd[0]), PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); - if (fd[1] == -1) { + if (fd[1] < 0) { NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Total Active Ticks Handle \n", __FUNCTION__); + checkErrorNumberAndUpdateStatus(); close(static_cast(fd[0])); return; } @@ -230,18 +275,8 @@ void LinuxEngineImp::init() { } } -bool LinuxEngineImp::isEngineModuleSupported() { - - if (fdList.size() == 0) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): as fileDescriptors could not be opened \n", __FUNCTION__); - return false; - } - - if (fdList[0].second < 0) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): as fileDescriptor value = %d Engine Module is not supported \n", __FUNCTION__, fdList[0].second); - return false; - } - return true; +ze_result_t LinuxEngineImp::isEngineModuleSupported() { + return initStatus; } LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubDevice) : engineGroup(type), engineInstance(engineInstance), subDeviceId(subDeviceId), onSubDevice(onSubDevice) { @@ -251,6 +286,10 @@ LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uin pPmuInterface = pLinuxSysmanImp->getPmuInterface(); pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess(); init(); + + if (initStatus != ZE_RESULT_SUCCESS) { + cleanup(); + } } std::unique_ptr OsEngine::create(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubDevice) { diff --git a/level_zero/tools/source/sysman/engine/os_engine.h b/level_zero/tools/source/sysman/engine/os_engine.h index 0bad6ff81c..416eb24ecc 100644 --- a/level_zero/tools/source/sysman/engine/os_engine.h +++ b/level_zero/tools/source/sysman/engine/os_engine.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -22,7 +22,7 @@ class OsEngine { virtual ze_result_t getActivity(zes_engine_stats_t *pStats) = 0; virtual ze_result_t getActivityExt(uint32_t *pCount, zes_engine_stats_t *pStats) = 0; virtual ze_result_t getProperties(zes_engine_properties_t &properties) = 0; - virtual bool isEngineModuleSupported() = 0; + virtual ze_result_t isEngineModuleSupported() = 0; static std::unique_ptr create(OsSysman *pOsSysman, zes_engine_group_t engineType, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubdevice); static ze_result_t getNumEngineTypeAndInstances(std::set> &engineGroupInstance, OsSysman *pOsSysman); virtual ~OsEngine() = default; diff --git a/level_zero/tools/source/sysman/engine/windows/os_engine_imp.cpp b/level_zero/tools/source/sysman/engine/windows/os_engine_imp.cpp index a3704f855f..4af75e46ca 100644 --- a/level_zero/tools/source/sysman/engine/windows/os_engine_imp.cpp +++ b/level_zero/tools/source/sysman/engine/windows/os_engine_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -76,8 +76,8 @@ ze_result_t WddmEngineImp::getProperties(zes_engine_properties_t &properties) { return ZE_RESULT_SUCCESS; } -bool WddmEngineImp::isEngineModuleSupported() { - return true; +ze_result_t WddmEngineImp::isEngineModuleSupported() { + return ZE_RESULT_SUCCESS; } WddmEngineImp::WddmEngineImp(OsSysman *pOsSysman, zes_engine_group_t engineType, uint32_t engineInstance, uint32_t subDeviceId) { diff --git a/level_zero/tools/source/sysman/engine/windows/os_engine_imp.h b/level_zero/tools/source/sysman/engine/windows/os_engine_imp.h index 8212390b56..b09d1faeeb 100644 --- a/level_zero/tools/source/sysman/engine/windows/os_engine_imp.h +++ b/level_zero/tools/source/sysman/engine/windows/os_engine_imp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,7 +18,7 @@ class WddmEngineImp : public OsEngine, NEO::NonCopyableOrMovableClass { ze_result_t getActivity(zes_engine_stats_t *pStats) override; ze_result_t getActivityExt(uint32_t *pCount, zes_engine_stats_t *pStats) override; ze_result_t getProperties(zes_engine_properties_t &properties) override; - bool isEngineModuleSupported() override; + ze_result_t isEngineModuleSupported() override; WddmEngineImp() = default; WddmEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance, uint32_t subDeviceId); diff --git a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h index b54ad1669c..73db2f6755 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -65,8 +65,10 @@ struct MockEnginePmuInterfaceImp : public PmuInterfaceImp { MockEnginePmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {} int64_t mockPerfEventFailureReturnValue = 0; + int32_t mockErrorNumber = -ENOSPC; int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override { if (mockPerfEventFailureReturnValue == -1) { + errno = mockErrorNumber; return mockPerfEventFailureReturnValue; } diff --git a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine_prelim.h b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine_prelim.h index 250aff894d..a44c510356 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine_prelim.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/mock_engine_prelim.h @@ -105,6 +105,7 @@ struct MockEnginePmuInterfaceImp : public PmuInterfaceImp { bool mockPmuRead = false; bool mockPerfEventOpenRead = false; + int32_t mockErrorNumber = -ENOSPC; int32_t mockPerfEventOpenFailAtCount = 1; int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override { @@ -119,6 +120,7 @@ struct MockEnginePmuInterfaceImp : public PmuInterfaceImp { } int64_t mockedPerfEventOpenAndFailureReturn(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) { + errno = mockErrorNumber; return -1; } diff --git a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/test_zes_engine_prelim.cpp b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/test_zes_engine_prelim.cpp index ec9a043fe8..4b72564a6f 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/test_zes_engine_prelim.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/engine/linux/test_zes_engine_prelim.cpp @@ -122,6 +122,40 @@ TEST_F(ZesEngineFixture, GivenPmuOpenFailsWhenCallingzesDeviceEnumEngineGroupsTh EXPECT_EQ(handleCount, 0u); } +TEST_F(ZesEngineFixture, GivenPmuOpenFailsDueToTooManyOpenFilesWhenCallingzesDeviceEnumEngineGroupsThenErrorIsObserved) { + auto pMemoryManagerTest = std::make_unique(*neoDevice->getExecutionEnvironment()); + pMemoryManagerTest->localMemorySupported[0] = true; + device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get()); + pSysfsAccess->mockReadVal = 1; + pSysfsAccess->mockReadSymLinkSuccess = true; + pPmuInterface->mockPerfEventOpenRead = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 3; + pPmuInterface->mockErrorNumber = -EMFILE; + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->init(deviceHandles); + + uint32_t handleCount = 0; + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &handleCount, nullptr), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); + EXPECT_EQ(handleCount, 0u); +} + +TEST_F(ZesEngineFixture, GivenPmuOpenFailsDueToTooManyOpenFilesInSystemWhenEnumeratingEngineGroupsThenErrorIsObserved) { + auto pMemoryManagerTest = std::make_unique(*neoDevice->getExecutionEnvironment()); + pMemoryManagerTest->localMemorySupported[0] = true; + device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get()); + pSysfsAccess->mockReadVal = 1; + pSysfsAccess->mockReadSymLinkSuccess = true; + pPmuInterface->mockPerfEventOpenRead = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 3; + pPmuInterface->mockErrorNumber = -ENFILE; + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->init(deviceHandles); + + uint32_t handleCount = 0; + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &handleCount, nullptr), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); + EXPECT_EQ(handleCount, 0u); +} + TEST_F(ZesEngineFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { zes_engine_properties_t properties; auto handles = getEngineHandles(handleComponentCount); @@ -374,23 +408,48 @@ TEST_F(ZesEngineFixture, GivenDiscreteDeviceWithBusyTicksInvalidVfWhenCallingZes EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesEngineGetActivityExt(handle, &count, engineStats.data())); } -TEST_F(ZesEngineFixture, GivenTestDiscreteDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { +TEST_F(ZesEngineFixture, GivenTooManyFilesErrorWhenCallingZesEngineGetActivityExtThenReturnFailure) { auto pMemoryManagerTest = std::make_unique(*neoDevice->getExecutionEnvironment()); pMemoryManagerTest->localMemorySupported[0] = true; device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get()); - - pSysfsAccess->mockReadSymLinkFailure = true; - - auto pOsEngineTest1 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); - - zes_engine_stats_t stats = {}; - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats)); - + pSysfsAccess->mockReadVal = 1; pSysfsAccess->mockReadSymLinkSuccess = true; - pFsAccess->mockReadVal = true; + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->init(deviceHandles); + auto handles = getEngineHandles(handleComponentCount); + EXPECT_EQ(handleComponentCount, handles.size()); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = 0; + pPmuInterface->mockPerfEventOpenRead = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 3; + pPmuInterface->mockErrorNumber = -EMFILE; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivityExt(handle, &count, nullptr)); + EXPECT_EQ(count, pSysfsAccess->mockReadVal + 1); + std::vector engineStats(count); + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, zesEngineGetActivityExt(handle, &count, engineStats.data())); +} - auto pOsEngineTest2 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest2->getActivity(&stats)); +TEST_F(ZesEngineFixture, GivenTooManyFilesInSystemErrorWhenCallingZesEngineGetActivityExtThenReturnFailure) { + auto pMemoryManagerTest = std::make_unique(*neoDevice->getExecutionEnvironment()); + pMemoryManagerTest->localMemorySupported[0] = true; + device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get()); + pSysfsAccess->mockReadVal = 1; + pSysfsAccess->mockReadSymLinkSuccess = true; + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->init(deviceHandles); + auto handles = getEngineHandles(handleComponentCount); + EXPECT_EQ(handleComponentCount, handles.size()); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = 0; + pPmuInterface->mockPerfEventOpenRead = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 3; + pPmuInterface->mockErrorNumber = -ENFILE; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivityExt(handle, &count, nullptr)); + EXPECT_EQ(count, pSysfsAccess->mockReadVal + 1); + std::vector engineStats(count); + EXPECT_EQ(ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE, zesEngineGetActivityExt(handle, &count, engineStats.data())); } TEST_F(ZesEngineFixture, GivenUnknownEngineTypeThengetEngineGroupFromTypeReturnsGroupAllEngineGroup) { @@ -398,15 +457,6 @@ TEST_F(ZesEngineFixture, GivenUnknownEngineTypeThengetEngineGroupFromTypeReturns EXPECT_EQ(group, ZES_ENGINE_GROUP_ALL); } -TEST_F(ZesEngineFixture, GivenTestIntegratedDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { - zes_engine_stats_t stats = {}; - - pFsAccess->mockReadVal = true; - - auto pOsEngineTest1 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats)); -} - TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndPmuReadFailsThenVerifyEngineGetActivityReturnsFailure) { pPmuInterface->mockPmuRead = true;