From b33b4233ad9dd7807b1397d9d5049c68d51808b3 Mon Sep 17 00:00:00 2001 From: Anvesh Bakwad Date: Thu, 20 Feb 2025 13:08:13 +0000 Subject: [PATCH] refactor(sysman): Refactor the Power limits related methods Related-To: NEO-14011 Signed-off-by: Anvesh Bakwad --- .../api/power/linux/sysman_os_power_imp.cpp | 305 +++++++++--------- .../api/power/linux/sysman_os_power_imp.h | 8 +- .../sources/power/linux/test_zes_power.cpp | 56 +++- .../sysman_product_helper_power_tests.cpp | 4 +- 4 files changed, 206 insertions(+), 167 deletions(-) diff --git a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp index d045dc05ef..54fb8b1054 100644 --- a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp +++ b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp @@ -43,10 +43,10 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { uint64_t powerLimit = 0; - std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageDefaultPowerLimit, subdeviceId, false); - auto result = pSysfsAccess->read(defaultPowerLimit, powerLimit); + std::string defaultPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageDefaultPowerLimit, subdeviceId, false); + auto result = pSysfsAccess->read(defaultPowerLimitFile, 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)); + 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(), defaultPowerLimitFile.c_str(), getErrorCode(result)); return getErrorCode(result); } @@ -59,26 +59,19 @@ ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { ze_result_t LinuxPowerImp::getPropertiesExt(zes_power_ext_properties_t *pExtPoperties) { pExtPoperties->domain = powerDomain; if (pExtPoperties->defaultLimit) { - if (!isSubdevice) { - uint64_t val = 0; - std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageDefaultPowerLimit, subdeviceId, false); - ze_result_t result = pSysfsAccess->read(defaultPowerLimit, val); - if (result == ZE_RESULT_SUCCESS) { - pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageDefaultPowerLimit), val, val); - pExtPoperties->defaultLimit->limit = static_cast(val); - } else { - 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); - } - } else { - pExtPoperties->defaultLimit->limit = -1; - } + pExtPoperties->defaultLimit->limit = -1; pExtPoperties->defaultLimit->limitUnit = ZES_LIMIT_UNIT_POWER; pExtPoperties->defaultLimit->enabledStateLocked = true; pExtPoperties->defaultLimit->intervalValueLocked = true; pExtPoperties->defaultLimit->limitValueLocked = true; pExtPoperties->defaultLimit->source = ZES_POWER_SOURCE_ANY; pExtPoperties->defaultLimit->level = ZES_POWER_LEVEL_UNKNOWN; + if (!isSubdevice) { + auto result = getDefaultLimit(pExtPoperties->defaultLimit->limit); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + } } return ZE_RESULT_SUCCESS; } @@ -131,65 +124,74 @@ ze_result_t LinuxPowerImp::getEnergyCounter(zes_power_energy_counter_t *pEnergy) ze_result_t LinuxPowerImp::getLimits(zes_power_sustained_limit_t *pSustained, zes_power_burst_limit_t *pBurst, zes_power_peak_limit_t *pPeak) { ze_result_t result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; - if (!isSubdevice) { - uint64_t val = 0; - if (pSustained != nullptr) { - val = 0; - result = pSysfsAccess->read(sustainedPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - 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(), sustainedPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), val, val); - pSustained->power = static_cast(val); - pSustained->enabled = true; - pSustained->interval = -1; - } - if (pBurst != nullptr) { - pBurst->power = -1; - pBurst->enabled = false; - } - if (pPeak != nullptr) { - result = pSysfsAccess->read(criticalPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - 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(), criticalPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageCriticalPowerLimit), val, val); - pPeak->powerAC = static_cast(val); - pPeak->powerDC = -1; - } - result = ZE_RESULT_SUCCESS; + if (isSubdevice) { + return result; } - return result; + + uint64_t val = 0; + + if (pSustained != nullptr) { + val = 0; + result = pSysfsAccess->read(sustainedPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + 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(), sustainedPowerLimitFile.c_str(), getErrorCode(result)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), val, val); + pSustained->power = static_cast(val); + pSustained->enabled = true; + pSustained->interval = -1; + } + + if (pBurst != nullptr) { + pBurst->power = -1; + pBurst->enabled = false; + } + + if (pPeak != nullptr) { + result = pSysfsAccess->read(criticalPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + 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(), criticalPowerLimitFile.c_str(), getErrorCode(result)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageCriticalPowerLimit), val, val); + pPeak->powerAC = static_cast(val); + pPeak->powerDC = -1; + } + + return ZE_RESULT_SUCCESS; } ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustained, const zes_power_burst_limit_t *pBurst, const zes_power_peak_limit_t *pPeak) { ze_result_t result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; - if (canControl) { - uint64_t val = 0; - if (pSustained != nullptr) { - val = static_cast(pSustained->power); - pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), SysfsValueUnit::milli, val, val); - result = pSysfsAccess->write(sustainedPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - } - if (pPeak != nullptr) { - val = static_cast(pPeak->powerAC); - pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageCriticalPowerLimit), SysfsValueUnit::milli, val, val); - result = pSysfsAccess->write(criticalPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), criticalPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - } - result = ZE_RESULT_SUCCESS; + if (!canControl) { + return result; } - return result; + + uint64_t val = 0; + + if (pSustained != nullptr) { + val = static_cast(pSustained->power); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), SysfsValueUnit::milli, val, val); + result = pSysfsAccess->write(sustainedPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimitFile.c_str(), getErrorCode(result)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + } + + if (pPeak != nullptr) { + val = static_cast(pPeak->powerAC); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageCriticalPowerLimit), SysfsValueUnit::milli, val, val); + result = pSysfsAccess->write(criticalPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), criticalPowerLimitFile.c_str(), getErrorCode(result)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + } + + return ZE_RESULT_SUCCESS; } ze_result_t LinuxPowerImp::getEnergyThreshold(zes_energy_threshold_t *pThreshold) { @@ -202,94 +204,101 @@ ze_result_t LinuxPowerImp::setEnergyThreshold(double threshold) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } -ze_result_t LinuxPowerImp::getLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) { +ze_result_t LinuxPowerImp::getLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pLimitExt) { ze_result_t result = ZE_RESULT_SUCCESS; + if ((*pCount == 0) || (powerLimitCount < *pCount)) { *pCount = powerLimitCount; } - if (pSustained != nullptr) { - uint64_t val = 0; - uint8_t count = 0; - if (count < *pCount) { - result = pSysfsAccess->read(sustainedPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - 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(), sustainedPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } + if (isSubdevice || pLimitExt == nullptr) { + return result; + } - int32_t interval = 0; - result = pSysfsAccess->read(sustainedPowerLimitInterval, interval); - if (ZE_RESULT_SUCCESS != result) { - 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(), sustainedPowerLimitInterval.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - - pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), val, val); - pSustained[count].limit = static_cast(val); - pSustained[count].enabledStateLocked = true; - pSustained[count].intervalValueLocked = false; - pSustained[count].limitValueLocked = false; - pSustained[count].source = ZES_POWER_SOURCE_ANY; - pSustained[count].level = ZES_POWER_LEVEL_SUSTAINED; - pSustained[count].limitUnit = ZES_LIMIT_UNIT_POWER; - pSustained[count].interval = interval; - count++; + uint64_t val = 0; + uint8_t count = 0; + if (sustainedPowerLimitFileExists) { + result = pSysfsAccess->read(sustainedPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + 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(), sustainedPowerLimitFile.c_str(), getErrorCode(result)); + return getErrorCode(result); } - if (count < *pCount) { - result = pSysfsAccess->read(criticalPowerLimit, val); - 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(), criticalPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - pSustained[count].enabledStateLocked = true; - pSustained[count].intervalValueLocked = true; - pSustained[count].limitValueLocked = false; - pSustained[count].source = ZES_POWER_SOURCE_ANY; - pSustained[count].level = ZES_POWER_LEVEL_PEAK; - pSustained[count].interval = 0; - pSustained[count].limit = pSysmanProductHelper->getPowerLimitValue(val); - pSustained[count].limitUnit = pSysmanProductHelper->getPowerLimitUnit(); + int32_t interval = 0; + result = pSysfsAccess->read(sustainedPowerLimitIntervalFile, interval); + if (ZE_RESULT_SUCCESS != result) { + 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(), sustainedPowerLimitIntervalFile.c_str(), getErrorCode(result)); + return getErrorCode(result); } + + pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), val, val); + pLimitExt[count].limit = static_cast(val); + pLimitExt[count].enabledStateLocked = true; + pLimitExt[count].intervalValueLocked = false; + pLimitExt[count].limitValueLocked = false; + pLimitExt[count].source = ZES_POWER_SOURCE_ANY; + pLimitExt[count].level = ZES_POWER_LEVEL_SUSTAINED; + pLimitExt[count].limitUnit = ZES_LIMIT_UNIT_POWER; + pLimitExt[count].interval = interval; + count++; + } + + if (criticalPowerLimitFileExists) { + result = pSysfsAccess->read(criticalPowerLimitFile, val); + 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(), criticalPowerLimitFile.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + pLimitExt[count].enabledStateLocked = true; + pLimitExt[count].intervalValueLocked = true; + pLimitExt[count].limitValueLocked = false; + pLimitExt[count].source = ZES_POWER_SOURCE_ANY; + pLimitExt[count].level = ZES_POWER_LEVEL_PEAK; + pLimitExt[count].interval = 0; + pLimitExt[count].limit = pSysmanProductHelper->getPowerLimitValue(val); + pLimitExt[count].limitUnit = pSysmanProductHelper->getPowerLimitUnit(); } return result; } -ze_result_t LinuxPowerImp::setLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) { +ze_result_t LinuxPowerImp::setLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pLimitExt) { ze_result_t result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; - if (canControl) { - uint64_t val = 0; - for (uint32_t i = 0; i < *pCount; i++) { - if (pSustained[i].level == ZES_POWER_LEVEL_SUSTAINED) { - val = static_cast(pSustained[i].limit); - pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), SysfsValueUnit::milli, val, val); - result = pSysfsAccess->write(sustainedPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - result = pSysfsAccess->write(sustainedPowerLimitInterval, pSustained[i].interval); - if (ZE_RESULT_SUCCESS != result) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimitInterval.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - } else if (pSustained[i].level == ZES_POWER_LEVEL_PEAK) { - val = pSysmanProductHelper->setPowerLimitValue(pSustained[i].limit); - result = pSysfsAccess->write(criticalPowerLimit, val); - if (ZE_RESULT_SUCCESS != result) { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), criticalPowerLimit.c_str(), getErrorCode(result)); - return getErrorCode(result); - } - } else { - NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s() returning UNSUPPORTED_FEATURE \n", __FUNCTION__); - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; - } - } - result = ZE_RESULT_SUCCESS; + if (!canControl) { + return result; } - return result; + + uint64_t val = 0; + + for (uint32_t i = 0; i < *pCount; i++) { + if (pLimitExt[i].level == ZES_POWER_LEVEL_SUSTAINED) { + val = static_cast(pLimitExt[i].limit); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNamePackageSustainedPowerLimit), SysfsValueUnit::milli, val, val); + result = pSysfsAccess->write(sustainedPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimitFile.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + result = pSysfsAccess->write(sustainedPowerLimitIntervalFile, pLimitExt[i].interval); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), sustainedPowerLimitIntervalFile.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + } else if (pLimitExt[i].level == ZES_POWER_LEVEL_PEAK) { + val = pSysmanProductHelper->setPowerLimitValue(pLimitExt[i].limit); + result = pSysfsAccess->write(criticalPowerLimitFile, val); + if (ZE_RESULT_SUCCESS != result) { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->write() failed to write into %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), criticalPowerLimitFile.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + } else { + NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s() returning UNSUPPORTED_FEATURE \n", __FUNCTION__); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + } + + return ZE_RESULT_SUCCESS; } bool LinuxPowerImp::isIntelGraphicsHwmonDir(const std::string &name) { @@ -334,19 +343,21 @@ void LinuxPowerImp::init() { } if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { - criticalPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageCriticalPowerLimit, subdeviceId, false); - sustainedPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageSustainedPowerLimit, subdeviceId, false); - sustainedPowerLimitInterval = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageSustainedPowerLimitInterval, subdeviceId, false); + criticalPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageCriticalPowerLimit, subdeviceId, false); + sustainedPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageSustainedPowerLimit, subdeviceId, false); + sustainedPowerLimitIntervalFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNamePackageSustainedPowerLimitInterval, subdeviceId, false); } else { return; } - if (pSysfsAccess->fileExists(sustainedPowerLimit)) { + if (pSysfsAccess->fileExists(sustainedPowerLimitFile)) { powerLimitCount++; + sustainedPowerLimitFileExists = true; } - if (pSysfsAccess->fileExists(criticalPowerLimit)) { + if (pSysfsAccess->fileExists(criticalPowerLimitFile)) { powerLimitCount++; + criticalPowerLimitFileExists = true; } } @@ -357,7 +368,7 @@ bool LinuxPowerImp::isPowerModuleSupported() { return isEnergyCounterAvailable; } - return isEnergyCounterAvailable || pSysfsAccess->fileExists(sustainedPowerLimit) || pSysfsAccess->fileExists(criticalPowerLimit); + return isEnergyCounterAvailable || sustainedPowerLimitFileExists || criticalPowerLimitFileExists; } LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain) : isSubdevice(onSubdevice), subdeviceId(subdeviceId), powerDomain(powerDomain) { diff --git a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h index ce3099f237..6b8e187c41 100644 --- a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h +++ b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h @@ -49,10 +49,12 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableAndNonMovableClass { private: std::string intelGraphicsHwmonDir = {}; - std::string criticalPowerLimit = {}; - std::string sustainedPowerLimit = {}; - std::string sustainedPowerLimitInterval = {}; std::string energyCounterNodeFile = {}; + std::string criticalPowerLimitFile = {}; + std::string sustainedPowerLimitFile = {}; + std::string sustainedPowerLimitIntervalFile = {}; + bool sustainedPowerLimitFileExists = false; + bool criticalPowerLimitFileExists = false; bool canControl = false; bool isSubdevice = false; uint32_t subdeviceId = 0; diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power.cpp b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power.cpp index d61354029c..ad6e5dba68 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power.cpp +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power.cpp @@ -87,13 +87,12 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenPowerHandleWithUnknownPowerDomainWhenI } TEST_F(SysmanDevicePowerFixtureI915, GivenTelemetrySupportAndEnergyCounterNodeExistanceStatesWhenIsPowerModuleSupportedIsCalledForSubdeviceHandleThenCorrectSupportStatusIsReturnedForPackageDomain) { - auto pPowerImp = std::make_unique(pOsSysman, true, 0, ZES_POWER_DOMAIN_PACKAGE); - // Loop through all combinations of the three boolean flags (false/true) for the file existence for (bool isPackageEnergyCounterFilePresent : {false, true}) { for (bool isTelemetrySupportAvailable : {false, true}) { // Set the file existence flags based on the current combination pSysfsAccess->isEnergyCounterFilePresent = isPackageEnergyCounterFilePresent; + auto pPowerImp = std::make_unique(pOsSysman, true, 0, ZES_POWER_DOMAIN_PACKAGE); pPowerImp->isTelemetrySupportAvailable = isTelemetrySupportAvailable; // The expected result is true if at least one of the path is present bool expected = (isTelemetrySupportAvailable || isPackageEnergyCounterFilePresent); @@ -105,19 +104,18 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenTelemetrySupportAndEnergyCounterNodeEx } TEST_F(SysmanDevicePowerFixtureI915, GivenVariousPowerLimitFileExistanceStatesWhenIsPowerModuleSupportedIsCalledForRootDeviceHandleThenCorrectSupportStatusIsReturnedForPackageDomain) { - auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_PACKAGE); - // Loop through all combinations of the three boolean flags (false/true) for the file existence for (bool isPackageEnergyCounterFilePresent : {false, true}) { for (bool isTelemetrySupportAvailable : {false, true}) { for (bool isPackagedSustainedPowerLimitFilePresent : {false, true}) { for (bool isPackageCriticalPowerLimit2Present : {false, true}) { // Set the file existence flags based on the current combination - pPowerImp->isTelemetrySupportAvailable = isTelemetrySupportAvailable; pSysfsAccess->isEnergyCounterFilePresent = isPackageEnergyCounterFilePresent; pSysfsAccess->isSustainedPowerLimitFilePresent = isPackagedSustainedPowerLimitFilePresent; pSysfsAccess->isCriticalPowerLimitFilePresent = isPackageCriticalPowerLimit2Present; + auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_PACKAGE); + pPowerImp->isTelemetrySupportAvailable = isTelemetrySupportAvailable; // The expected result is true if at least one of the files is present bool expected = (isTelemetrySupportAvailable || isPackageEnergyCounterFilePresent || isPackagedSustainedPowerLimitFilePresent || isPackageCriticalPowerLimit2Present); @@ -422,7 +420,8 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenSettingBurstPowerL } } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenProperValuesAreReturned) { +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPeakPowerLimitFileDoesNotExistWhenCallingGetPowerLimitsExtThenOnlySustainedLimitIsReturned) { + pSysfsAccess->isCriticalPowerLimitFilePresent = false; auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { @@ -431,20 +430,47 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenCallingGetPowerLim uint32_t count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr)); - EXPECT_EQ(count, mockLimitCount); - - count = 1; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, &allLimits)); EXPECT_EQ(count, 1u); - EXPECT_EQ(false, allLimits.limitValueLocked); - EXPECT_EQ(true, allLimits.enabledStateLocked); - EXPECT_EQ(false, allLimits.intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits.source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits.limitUnit); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, &allLimits)); EXPECT_EQ(ZES_POWER_LEVEL_SUSTAINED, allLimits.level); } } +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndSustainedPowerLimitFileDoesNotExistWhenCallingGetPowerLimitsExtThenOnlyCriticalLimitIsReturned) { + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + auto handles = getPowerHandles(powerHandleComponentCount); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + zes_power_limit_ext_desc_t allLimits{}; + uint32_t count = 0; + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr)); + EXPECT_EQ(count, 1u); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, &allLimits)); + EXPECT_EQ(ZES_POWER_LEVEL_PEAK, allLimits.level); + } +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenProperValuesAreReturned) { + auto handles = getPowerHandles(powerHandleComponentCount); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + uint32_t limitCount = 0; + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, mockLimitCount); + + std::vector allLimits(limitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); + EXPECT_EQ(ZES_POWER_LEVEL_SUSTAINED, allLimits[0].level); + EXPECT_EQ(ZES_POWER_LEVEL_PEAK, allLimits[1].level); + } +} + TEST_F(SysmanDevicePowerFixtureI915, GivenReadingPeakPowerLimitNodeReturnErrorWhenSetOrGetPowerLimitsWhenHwmonInterfaceExistForPeakPowerLimitEnabledThenProperErrorCodesReturned) { auto handles = getPowerHandles(powerHandleComponentCount); diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_power_tests.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_power_tests.cpp index 48e3b5a20b..66c4c33f89 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_power_tests.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_power_tests.cpp @@ -604,14 +604,14 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleAndPermissionsThenF EXPECT_EQ(sustainedGet.power, sustainedSet.power); } -HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleWhenWritingToSustainedPowerEnableNodeWithoutPermissionsThenValidErrorIsReturned, IsXeHpOrXeHpcOrXeHpgCore) { +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleWhenWritingToSustainedPowerEnableNodeWithoutPermissionsThenErrorIsReturned, IsXeHpOrXeHpcOrXeHpgCore) { auto handles = getPowerHandles(powerHandleComponentCount); ASSERT_NE(nullptr, handles[0]); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS); zes_power_sustained_limit_t sustainedSet = {}; sustainedSet.enabled = 0; - EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr)); } using SysmanProductHelperPowerMultiDeviceTest = SysmanDevicePowerMultiDeviceFixture;