diff --git a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.cpp b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.cpp index 27ed32f16c..445bfd8260 100644 --- a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.cpp +++ b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.cpp @@ -17,6 +17,29 @@ namespace L0 { namespace Sysman { +class LinuxPowerImp::PowerLimitRestorer : NEO::NonCopyableOrMovableClass { + public: + PowerLimitRestorer(L0::Sysman::SysfsAccess *pSysfsAccess, std::string powerLimit) : pSysfsAccess(pSysfsAccess), powerLimit(powerLimit) { + result = pSysfsAccess->read(powerLimit, powerLimitValue); + } + + ~PowerLimitRestorer() { + if (result == ZE_RESULT_SUCCESS) { + result = pSysfsAccess->write(powerLimit, powerLimitValue); + DEBUG_BREAK_IF(result != ZE_RESULT_SUCCESS); + } + } + operator ze_result_t() const { + return result; + } + + protected: + ze_result_t result = ZE_RESULT_ERROR_UNINITIALIZED; + SysfsAccess *pSysfsAccess = nullptr; + std::string powerLimit = {}; + uint64_t powerLimitValue = 0; +}; + ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { pProperties->onSubdevice = isSubdevice; pProperties->subdeviceId = subdeviceId; @@ -25,7 +48,82 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { pProperties->defaultLimit = -1; pProperties->minLimit = -1; pProperties->maxLimit = -1; - return ZE_RESULT_SUCCESS; + + if (isSubdevice) { + return ZE_RESULT_SUCCESS; + } + + auto result = getDefaultLimit(pProperties->defaultLimit); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + + auto powerLimitRestorer = L0::Sysman::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedPowerLimit); + if (powerLimitRestorer != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(powerLimitRestorer)); + return getErrorCode(powerLimitRestorer); + } + + result = getMinLimit(pProperties->minLimit); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + + return getMaxLimit(pProperties->maxLimit); +} + +ze_result_t LinuxPowerImp::getMinLimit(int32_t &minLimit) { + // Fw clamps to minimum value if power limit requested to set is less than min limit, Set to 100 micro watt to get min limit + uint64_t powerLimit = 100; + auto result = pSysfsAccess->write(sustainedPowerLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + result = pSysfsAccess->read(sustainedPowerLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + minLimit = static_cast(powerLimit / milliFactor); + return result; +} + +ze_result_t LinuxPowerImp::getMaxLimit(int32_t &maxLimit) { + // Fw clamps to maximum value if power limit requested to set is greater than max limit, Set to max value to get max limit + uint64_t powerLimit = std::numeric_limits::max(); + auto result = pSysfsAccess->write(sustainedPowerLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + result = pSysfsAccess->read(sustainedPowerLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + maxLimit = static_cast(powerLimit / milliFactor); + return result; +} + +ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { + uint64_t powerLimit = 0; + std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, subdeviceId, false); + auto result = pSysfsAccess->read(defaultPowerLimit, powerLimit); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->read() failed to read %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), defaultPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + defaultLimit = static_cast(powerLimit / milliFactor); + return result; } ze_result_t LinuxPowerImp::getPropertiesExt(zes_power_ext_properties_t *pExtPoperties) { diff --git a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.h b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.h index 1c2838f0b7..4117f28c1d 100644 --- a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.h +++ b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp_prelim.h @@ -9,6 +9,7 @@ #include "shared/source/helpers/non_copyable_or_moveable.h" #include "level_zero/sysman/source/api/power/sysman_os_power.h" +#include "level_zero/sysman/source/shared/linux/sysman_fs_access.h" #include "igfxfmid.h" @@ -56,6 +57,7 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass { uint32_t subdeviceId = 0; uint32_t powerLimitCount = 0; PRODUCT_FAMILY productFamily{}; + class PowerLimitRestorer; ze_result_t getErrorCode(ze_result_t result) { if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) { @@ -63,6 +65,10 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass { } return result; } + ze_result_t getMinLimit(int32_t &minLimit); + ze_result_t getMaxLimit(int32_t &maxLimit); + ze_result_t getDefaultLimit(int32_t &defaultLimit); }; + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_prelim.h b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_prelim.h index 53c4bf686b..27ef048f1e 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_prelim.h +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_prelim.h @@ -41,6 +41,8 @@ constexpr uint64_t expectedEnergyCounter = 123456785u; constexpr uint64_t expectedEnergyCounterTile0 = 123456785u; constexpr uint64_t expectedEnergyCounterTile1 = 128955785u; constexpr uint32_t mockDefaultPowerLimitVal = 300000000; +constexpr uint64_t mockMinPowerLimitVal = 300000000; +constexpr uint64_t mockMaxPowerLimitVal = 600000000; const std::map deviceKeyOffsetMapPower = { {"PACKAGE_ENERGY", 0x400}, {"COMPUTE_TEMPERATURES", 0x68}, @@ -49,13 +51,13 @@ const std::map deviceKeyOffsetMapPower = { struct MockPowerSysfsAccess : public L0::Sysman::SysfsAccess { ze_result_t mockReadResult = ZE_RESULT_SUCCESS; - ze_result_t mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS; ze_result_t mockReadPeakResult = ZE_RESULT_SUCCESS; ze_result_t mockWriteResult = ZE_RESULT_SUCCESS; - ze_result_t mockWriteUnsignedResult = ZE_RESULT_SUCCESS; ze_result_t mockReadIntResult = ZE_RESULT_SUCCESS; ze_result_t mockWritePeakLimitResult = ZE_RESULT_SUCCESS; ze_result_t mockscanDirEntriesResult = ZE_RESULT_SUCCESS; + std::vector mockReadValUnsignedLongResult{}; + std::vector mockWriteUnsignedResult{}; ze_result_t getValString(const std::string file, std::string &val) { ze_result_t result = ZE_RESULT_ERROR_UNKNOWN; @@ -97,6 +99,8 @@ struct MockPowerSysfsAccess : public L0::Sysman::SysfsAccess { val = expectedEnergyCounterTile1; } else if (file.compare(i915HwmonDir + "/" + energyCounterNode) == 0) { val = expectedEnergyCounter; + } else if (file.compare(i915HwmonDir + "/" + defaultPowerLimit) == 0) { + val = mockDefaultPowerLimitVal; } else { result = ZE_RESULT_ERROR_NOT_AVAILABLE; } @@ -141,8 +145,13 @@ struct MockPowerSysfsAccess : public L0::Sysman::SysfsAccess { } ze_result_t read(const std::string file, uint64_t &val) override { - if (mockReadValUnsignedLongResult != ZE_RESULT_SUCCESS) { - return mockReadValUnsignedLongResult; + ze_result_t result = ZE_RESULT_SUCCESS; + if (!mockReadValUnsignedLongResult.empty()) { + result = mockReadValUnsignedLongResult.front(); + mockReadValUnsignedLongResult.erase(mockReadValUnsignedLongResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } } return getValUnsignedLong(file, val); @@ -186,12 +195,22 @@ struct MockPowerSysfsAccess : public L0::Sysman::SysfsAccess { ze_result_t write(const std::string file, const uint64_t val) override { ze_result_t result = ZE_RESULT_SUCCESS; - if (mockWriteUnsignedResult != ZE_RESULT_SUCCESS) { - return mockWriteUnsignedResult; + if (!mockWriteUnsignedResult.empty()) { + result = mockWriteUnsignedResult.front(); + mockWriteUnsignedResult.erase(mockWriteUnsignedResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } } if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) { - sustainedPowerLimitVal = val; + if (val < mockMinPowerLimitVal) { + sustainedPowerLimitVal = mockMinPowerLimitVal; + } else if (val > mockMaxPowerLimitVal) { + sustainedPowerLimitVal = mockMaxPowerLimitVal; + } else { + sustainedPowerLimitVal = val; + } } else if ((file.compare(i915HwmonDir + "/" + criticalPowerLimit1) == 0) || (file.compare(i915HwmonDir + "/" + criticalPowerLimit2) == 0)) { if (mockWritePeakLimitResult != ZE_RESULT_SUCCESS) { return mockWritePeakLimitResult; @@ -275,6 +294,7 @@ class PublicLinuxPowerImp : public L0::Sysman::LinuxPowerImp { public: PublicLinuxPowerImp(L0::Sysman::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : L0::Sysman::LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId) {} using L0::Sysman::LinuxPowerImp::pPmt; + using L0::Sysman::LinuxPowerImp::pSysfsAccess; }; class SysmanDevicePowerFixture : public SysmanDeviceFixture { diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper_prelim.cpp index cf989790b3..4cc12a5fbd 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper_prelim.cpp +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper_prelim.cpp @@ -52,14 +52,15 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti if (properties.onSubdevice) { EXPECT_FALSE(properties.canControl); EXPECT_EQ(properties.defaultLimit, -1); - + EXPECT_EQ(properties.maxLimit, -1); + EXPECT_EQ(properties.minLimit, -1); } else { EXPECT_EQ(properties.canControl, true); - EXPECT_EQ(properties.defaultLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -75,7 +76,6 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; properties.pNext = &extProperties; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_EQ(properties.defaultLimit, -1); EXPECT_TRUE(defaultLimit.limitValueLocked); EXPECT_TRUE(defaultLimit.enabledStateLocked); EXPECT_TRUE(defaultLimit.intervalValueLocked); @@ -90,10 +90,11 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti EXPECT_TRUE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); EXPECT_EQ(defaultLimit.limit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -107,17 +108,20 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleAndExtPro properties.pNext = &extProperties; extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_EQ(properties.defaultLimit, -1); if (properties.onSubdevice) { EXPECT_FALSE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_PACKAGE); + EXPECT_EQ(properties.maxLimit, -1); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, -1); } else { EXPECT_TRUE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -150,7 +154,8 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenReadingToSysNodesFailsWhe pmtMapElement.second = nullptr; } } - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); @@ -227,7 +232,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; zes_power_properties_t properties = {}; @@ -298,7 +303,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC for (auto handle : handles) { ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; zes_power_properties_t properties = {}; diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_prelim.cpp index b19ed8fd6c..40ff7691e0 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_prelim.cpp +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_prelim.cpp @@ -98,9 +98,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } } @@ -121,9 +121,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); EXPECT_TRUE(defaultLimit.limitValueLocked); EXPECT_TRUE(defaultLimit.enabledStateLocked); @@ -150,23 +150,117 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWithNoStypeForExtPropertie EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } } -TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesThenUnknownLimitsAreReturned) { +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.defaultLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSustainedLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.maxLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndMinLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndMaxLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.maxLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteForMinLimitFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteForMaxLimitFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.maxLimit, -1); +} + +HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteToOriginalLimitFailsThenVerifySustainedLimitIsMaximum, IsPVC) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxPowerImp->getProperties(&properties)); + + std::vector allLimits(mockLimitCount); auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + uint32_t limitCount = mockLimitCount; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); + for (uint32_t i = 0; i < limitCount; i++) { + if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) { + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + EXPECT_EQ(allLimits[i].limit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + } + } } } @@ -179,7 +273,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun pPmt->preadFunction = preadMockPower; } while (++subdeviceId < subDeviceCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_energy_counter_t energyCounter = {}; @@ -257,7 +351,7 @@ HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPo ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); @@ -306,7 +400,7 @@ HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPo ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); @@ -353,7 +447,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerLimitNodeReturnErrorW auto handles = getPowerHandles(powerHandleComponentCount); pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -368,17 +462,25 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerLimitNodeReturnErrorW TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToSustainedLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - for (auto handle : handles) { ASSERT_NE(nullptr, handle); uint32_t count = mockLimitCount; std::vector allLimits(mockLimitCount); EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_SUCCESS; + } +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToSustainedLimitIntervalSysNodeFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { + auto handles = getPowerHandles(powerHandleComponentCount); + pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + uint32_t count = mockLimitCount; + std::vector allLimits(mockLimitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); } } @@ -390,9 +492,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndReadingToSustainedLimit ASSERT_NE(nullptr, handle); uint32_t count = mockLimitCount; std::vector allLimits(mockLimitCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); count = mockLimitCount; pSysfsAccess->mockReadIntResult = ZE_RESULT_ERROR_NOT_AVAILABLE; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); @@ -403,8 +505,9 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingToSysNodesFailsWhenCallingGetPowerL for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); auto handles = getPowerHandles(powerHandleComponentCount); @@ -514,7 +617,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingPeakPowerLimitNodeReturnErrorWhenSe auto handles = getPowerHandles(powerHandleComponentCount); pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -529,7 +632,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingPeakPowerLimitNodeReturnErrorWhenSe TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerNodeReturnErrorWhenGetPowerLimitsForSustainedPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_sustained_limit_t sustainedGet = {}; @@ -539,7 +642,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerNodeReturnErrorWhenGe TEST_F(SysmanDevicePowerFixture, GivenReadingpeakPowerNodeReturnErrorWhenGetPowerLimitsForpeakPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -703,7 +806,6 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun } TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterWhenEnergyHwmonFileReturnsErrorAndPmtFailsThenFailureIsReturned) { - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } @@ -723,6 +825,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); ASSERT_NE(nullptr, handle); zes_power_energy_counter_t energyCounter = {}; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetEnergyCounter(handle, &energyCounter)); diff --git a/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.cpp b/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.cpp index fb6c3c9df4..719714e83a 100644 --- a/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.cpp +++ b/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.cpp @@ -22,6 +22,29 @@ const std::string LinuxPowerImp::sustainedPowerLimitInterval("power1_max_interva const std::string LinuxPowerImp::energyCounterNode("energy1_input"); const std::string LinuxPowerImp::defaultPowerLimit("power1_rated_max"); +class LinuxPowerImp::PowerLimitRestorer : NEO::NonCopyableOrMovableClass { + public: + PowerLimitRestorer(SysfsAccess *pSysfsAccess, std::string powerLimit) : pSysfsAccess(pSysfsAccess), powerLimit(powerLimit) { + result = pSysfsAccess->read(powerLimit, powerLimitValue); + } + + ~PowerLimitRestorer() { + if (result == ZE_RESULT_SUCCESS) { + result = pSysfsAccess->write(powerLimit, powerLimitValue); + DEBUG_BREAK_IF(result != ZE_RESULT_SUCCESS); + } + } + operator ze_result_t() const { + return result; + } + + protected: + ze_result_t result = ZE_RESULT_ERROR_UNINITIALIZED; + SysfsAccess *pSysfsAccess = nullptr; + std::string powerLimit = {}; + uint64_t powerLimitValue = 0; +}; + ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { pProperties->onSubdevice = isSubdevice; pProperties->subdeviceId = subdeviceId; @@ -30,7 +53,84 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { pProperties->defaultLimit = -1; pProperties->minLimit = -1; pProperties->maxLimit = -1; - return ZE_RESULT_SUCCESS; + + if (isSubdevice) { + return ZE_RESULT_SUCCESS; + } + + auto result = getDefaultLimit(pProperties->defaultLimit); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + + std::string sustainedLimit = i915HwmonDir + "/" + sustainedPowerLimit; + auto powerLimitRestorer = L0::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedLimit); + if (powerLimitRestorer != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(powerLimitRestorer)); + return getErrorCode(powerLimitRestorer); + } + + result = getMinLimit(pProperties->minLimit); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + + return getMaxLimit(pProperties->maxLimit); +} + +ze_result_t LinuxPowerImp::getMinLimit(int32_t &minLimit) { + // Fw clamps to minimum value if power limit requested to set is less than min limit, Set to 100 micro watt to get min limit + uint64_t powerLimit = 100; + std::string sustainedLimit = i915HwmonDir + "/" + sustainedPowerLimit; + auto result = pSysfsAccess->write(sustainedLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + result = pSysfsAccess->read(sustainedLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + minLimit = static_cast(powerLimit / milliFactor); + return result; +} + +ze_result_t LinuxPowerImp::getMaxLimit(int32_t &maxLimit) { + // Fw clamps to maximum value if power limit requested to set is greater than max limit, Set to max value to get max limit + uint64_t powerLimit = std::numeric_limits::max(); + std::string sustainedLimit = i915HwmonDir + "/" + sustainedPowerLimit; + auto result = pSysfsAccess->write(sustainedLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + result = pSysfsAccess->read(sustainedLimit, powerLimit); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + maxLimit = static_cast(powerLimit / milliFactor); + return result; +} + +ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { + uint64_t powerLimit = 0; + auto result = pSysfsAccess->read(i915HwmonDir + "/" + defaultPowerLimit, powerLimit); + if (result != ZE_RESULT_SUCCESS) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->read() failed to read %s/%s and returning error:0x%x \n", __FUNCTION__, i915HwmonDir.c_str(), defaultPowerLimit.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + // Values are retrieved from KMD in micro watts, Conversion to milli is required. + defaultLimit = static_cast(powerLimit / milliFactor); + return result; } ze_result_t LinuxPowerImp::getPropertiesExt(zes_power_ext_properties_t *pExtPoperties) { diff --git a/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.h b/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.h index 5ccb9104f9..825fb0cf63 100644 --- a/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.h +++ b/level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -8,6 +8,7 @@ #pragma once #include "shared/source/helpers/non_copyable_or_moveable.h" +#include "level_zero/tools/source/sysman/linux/fs_access.h" #include "level_zero/tools/source/sysman/power/os_power.h" #include "igfxfmid.h" @@ -56,6 +57,7 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass { uint32_t subdeviceId = 0; uint32_t powerLimitCount = 0; PRODUCT_FAMILY productFamily{}; + class PowerLimitRestorer; ze_result_t getErrorCode(ze_result_t result) { if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) { @@ -63,5 +65,9 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass { } return result; } + ze_result_t getMinLimit(int32_t &minLimit); + ze_result_t getMaxLimit(int32_t &maxLimit); + ze_result_t getDefaultLimit(int32_t &defaultLimit); }; + } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power_prelim.h b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power_prelim.h index 9b289c477a..5658652d4f 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power_prelim.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power_prelim.h @@ -39,6 +39,8 @@ constexpr uint64_t expectedEnergyCounter = 123456785u; constexpr uint64_t expectedEnergyCounterTile0 = 123456785u; constexpr uint64_t expectedEnergyCounterTile1 = 128955785u; constexpr uint32_t mockDefaultPowerLimitVal = 300000000; +constexpr uint64_t mockMinPowerLimitVal = 300000000; +constexpr uint64_t mockMaxPowerLimitVal = 600000000; const std::map deviceKeyOffsetMapPower = { {"PACKAGE_ENERGY", 0x400}, {"COMPUTE_TEMPERATURES", 0x68}, @@ -47,13 +49,13 @@ const std::map deviceKeyOffsetMapPower = { struct MockPowerSysfsAccess : public SysfsAccess { ze_result_t mockReadResult = ZE_RESULT_SUCCESS; - ze_result_t mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS; ze_result_t mockReadPeakResult = ZE_RESULT_SUCCESS; ze_result_t mockWriteResult = ZE_RESULT_SUCCESS; - ze_result_t mockWriteUnsignedResult = ZE_RESULT_SUCCESS; ze_result_t mockReadIntResult = ZE_RESULT_SUCCESS; ze_result_t mockWritePeakLimitResult = ZE_RESULT_SUCCESS; ze_result_t mockscanDirEntriesResult = ZE_RESULT_SUCCESS; + std::vector mockReadValUnsignedLongResult{}; + std::vector mockWriteUnsignedResult{}; ze_result_t getValString(const std::string file, std::string &val) { ze_result_t result = ZE_RESULT_ERROR_UNKNOWN; @@ -95,6 +97,8 @@ struct MockPowerSysfsAccess : public SysfsAccess { val = expectedEnergyCounterTile1; } else if (file.compare(i915HwmonDir + "/" + energyCounterNode) == 0) { val = expectedEnergyCounter; + } else if (file.compare(i915HwmonDir + "/" + defaultPowerLimit) == 0) { + val = mockDefaultPowerLimitVal; } else { result = ZE_RESULT_ERROR_NOT_AVAILABLE; } @@ -139,8 +143,13 @@ struct MockPowerSysfsAccess : public SysfsAccess { } ze_result_t read(const std::string file, uint64_t &val) override { - if (mockReadValUnsignedLongResult != ZE_RESULT_SUCCESS) { - return mockReadValUnsignedLongResult; + ze_result_t result = ZE_RESULT_SUCCESS; + if (!mockReadValUnsignedLongResult.empty()) { + result = mockReadValUnsignedLongResult.front(); + mockReadValUnsignedLongResult.erase(mockReadValUnsignedLongResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } } return getValUnsignedLong(file, val); @@ -184,12 +193,22 @@ struct MockPowerSysfsAccess : public SysfsAccess { ze_result_t write(const std::string file, const uint64_t val) override { ze_result_t result = ZE_RESULT_SUCCESS; - if (mockWriteUnsignedResult != ZE_RESULT_SUCCESS) { - return mockWriteUnsignedResult; + if (!mockWriteUnsignedResult.empty()) { + result = mockWriteUnsignedResult.front(); + mockWriteUnsignedResult.erase(mockWriteUnsignedResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } } if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) { - sustainedPowerLimitVal = val; + if (val < mockMinPowerLimitVal) { + sustainedPowerLimitVal = mockMinPowerLimitVal; + } else if (val > mockMaxPowerLimitVal) { + sustainedPowerLimitVal = mockMaxPowerLimitVal; + } else { + sustainedPowerLimitVal = val; + } } else if ((file.compare(i915HwmonDir + "/" + criticalPowerLimit1) == 0) || (file.compare(i915HwmonDir + "/" + criticalPowerLimit2) == 0)) { if (mockWritePeakLimitResult != ZE_RESULT_SUCCESS) { return mockWritePeakLimitResult; @@ -273,6 +292,7 @@ class PublicLinuxPowerImp : public L0::LinuxPowerImp { public: PublicLinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId) {} using LinuxPowerImp::pPmt; + using LinuxPowerImp::pSysfsAccess; }; class SysmanDevicePowerFixture : public SysmanDeviceFixture { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_helper_prelim.cpp b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_helper_prelim.cpp index 6b139f4943..a1ab683235 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_helper_prelim.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_helper_prelim.cpp @@ -65,14 +65,15 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti if (properties.onSubdevice) { EXPECT_FALSE(properties.canControl); EXPECT_EQ(properties.defaultLimit, -1); - + EXPECT_EQ(properties.maxLimit, -1); + EXPECT_EQ(properties.minLimit, -1); } else { EXPECT_EQ(properties.canControl, true); - EXPECT_EQ(properties.defaultLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -88,7 +89,6 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; properties.pNext = &extProperties; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_EQ(properties.defaultLimit, -1); EXPECT_TRUE(defaultLimit.limitValueLocked); EXPECT_TRUE(defaultLimit.enabledStateLocked); EXPECT_TRUE(defaultLimit.intervalValueLocked); @@ -103,10 +103,11 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti EXPECT_TRUE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); EXPECT_EQ(defaultLimit.limit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -120,17 +121,20 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleAndExtPro properties.pNext = &extProperties; extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_EQ(properties.defaultLimit, -1); if (properties.onSubdevice) { EXPECT_FALSE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_PACKAGE); + EXPECT_EQ(properties.maxLimit, -1); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, -1); } else { EXPECT_TRUE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); } } @@ -164,7 +168,8 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenReadingToSysNodesFailsWhe pmtMapElement.second = nullptr; } } - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle()); auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); @@ -241,7 +246,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; zes_power_properties_t properties = {}; @@ -312,7 +317,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC for (auto handle : handles) { ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; zes_power_properties_t properties = {}; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_prelim.cpp b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_prelim.cpp index 40b586fc14..d1d219fc90 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_prelim.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_prelim.cpp @@ -115,9 +115,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } } @@ -138,9 +138,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); EXPECT_TRUE(defaultLimit.limitValueLocked); EXPECT_TRUE(defaultLimit.enabledStateLocked); @@ -167,23 +167,116 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWithNoStypeForExtPropertie EXPECT_EQ(properties.subdeviceId, 0u); EXPECT_EQ(properties.canControl, true); EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, (int32_t)(mockMinPowerLimitVal / milliFactor)); } } -TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesThenUnknownLimitsAreReturned) { +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.defaultLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSustainedLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.maxLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndMinLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndMaxLimitReadFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.maxLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteForMinLimitFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.minLimit, -1); +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteForMaxLimitFailsThenFailureIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.maxLimit, -1); +} + +HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsWriteToOriginalLimitFailsThenVerifySustainedLimitIsMaximum, IsPVC) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0)); + pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get(); + pLinuxPowerImp->pPmt = static_cast(pLinuxSysmanImp->getPlatformMonitoringTechAccess(0)); + pLinuxPowerImp->isPowerModuleSupported(); + + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxPowerImp->getProperties(&properties)); + std::vector allLimits(mockLimitCount); auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); - EXPECT_EQ(properties.defaultLimit, -1); - EXPECT_EQ(properties.maxLimit, -1); - EXPECT_EQ(properties.minLimit, -1); + uint32_t limitCount = mockLimitCount; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); + for (uint32_t i = 0; i < limitCount; i++) { + if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) { + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + EXPECT_EQ(allLimits[i].limit, (int32_t)(mockMaxPowerLimitVal / milliFactor)); + } + } } } @@ -197,7 +290,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun pPmt->preadFunction = preadMockPower; } - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_energy_counter_t energyCounter = {}; @@ -258,7 +351,7 @@ HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPo ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); @@ -307,7 +400,7 @@ HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPo ASSERT_NE(nullptr, handle); uint32_t limitCount = 0; - const int32_t testLimit = 3000000; + const int32_t testLimit = 300000; const int32_t testInterval = 10; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); @@ -354,7 +447,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerLimitNodeReturnErrorW auto handles = getPowerHandles(powerHandleComponentCount); pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -368,18 +461,25 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerLimitNodeReturnErrorW TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToSustainedLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - - pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - for (auto handle : handles) { ASSERT_NE(nullptr, handle); uint32_t count = mockLimitCount; std::vector allLimits(mockLimitCount); EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_SUCCESS; + } +} + +TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToSustainedLimitIntervalSysNodeFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { + auto handles = getPowerHandles(powerHandleComponentCount); + pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + uint32_t count = mockLimitCount; + std::vector allLimits(mockLimitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); } } @@ -391,9 +491,9 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndReadingToSustainedLimit ASSERT_NE(nullptr, handle); uint32_t count = mockLimitCount; std::vector allLimits(mockLimitCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); count = mockLimitCount; pSysfsAccess->mockReadIntResult = ZE_RESULT_ERROR_NOT_AVAILABLE; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); @@ -404,8 +504,9 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingToSysNodesFailsWhenCallingGetPowerL for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle()); auto handles = getPowerHandles(powerHandleComponentCount); @@ -515,7 +616,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingPeakPowerLimitNodeReturnErrorWhenSe auto handles = getPowerHandles(powerHandleComponentCount); pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -530,7 +631,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingPeakPowerLimitNodeReturnErrorWhenSe TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerNodeReturnErrorWhenGetPowerLimitsForSustainedPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_sustained_limit_t sustainedGet = {}; @@ -540,7 +641,7 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerNodeReturnErrorWhenGe TEST_F(SysmanDevicePowerFixture, GivenReadingpeakPowerNodeReturnErrorWhenGetPowerLimitsForpeakPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { ASSERT_NE(nullptr, handle); @@ -597,7 +698,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndPermissionsThenFirstDis EXPECT_EQ(sustainedGet.power, sustainedSet.power); } -TEST_F(SysmanDevicePowerFixture, GivenScanDiectoriesFailAndPmtIsNotNullPointerThenPowerModuleIsSupported) { +TEST_F(SysmanDevicePowerFixture, GivenScanDirectoriesFailAndPmtIsNotNullPointerThenPowerModuleIsSupported) { pSysfsAccess->mockscanDirEntriesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle()); @@ -703,7 +804,6 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun } TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterWhenEnergyHwmonFileReturnsErrorAndPmtFailsThenFailureIsReturned) { - pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE; for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } @@ -721,6 +821,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); ASSERT_NE(nullptr, handle); zes_power_energy_counter_t energyCounter = {}; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetEnergyCounter(handle, &energyCounter));