From 9991945c66c5a990b942d159d148ee6bf84c6603 Mon Sep 17 00:00:00 2001 From: Anvesh Bakwad Date: Mon, 23 Dec 2024 14:18:54 +0000 Subject: [PATCH] feature(sysman): Add support for card and package domains in Power module Related-To: NEO-10484 Signed-off-by: Anvesh Bakwad Signed-off-by: Pratik Bari --- .../api/power/linux/sysman_os_power_imp.cpp | 428 +++++----- .../api/power/linux/sysman_os_power_imp.h | 9 +- .../sysman/source/api/power/sysman_os_power.h | 3 +- .../sysman/source/api/power/sysman_power.cpp | 14 +- .../sysman/source/api/power/sysman_power.h | 2 +- .../source/api/power/sysman_power_imp.cpp | 2 +- .../api/power/windows/sysman_os_power_imp.cpp | 2 +- .../kmd_interface/sysman_kmd_interface.h | 17 + .../sysman_kmd_interface_i915_prelim.cpp | 19 + .../sysman_kmd_interface_i915_upstream.cpp | 19 + .../kmd_interface/sysman_kmd_interface_xe.cpp | 21 + .../gen12lp/dg1/sysman_product_helper_dg1.cpp | 8 + .../product_helper/sysman_product_helper.h | 3 + .../product_helper/sysman_product_helper_hw.h | 3 + .../sysman_product_helper_hw.inl | 17 +- .../pvc/sysman_product_helper_pvc.cpp | 10 + .../dg2/sysman_product_helper_dg2.cpp | 8 + .../linux/sysman_fs_access_interface.cpp | 11 + .../unit_tests/sources/linux/test_sysman.cpp | 26 +- .../sources/power/linux/CMakeLists.txt | 2 + .../sources/power/linux/mock_sysfs_power.h | 98 ++- .../sources/power/linux/mock_sysfs_power_xe.h | 279 +++++++ .../sources/power/linux/test_zes_power.cpp | 767 +++++++++--------- .../power/linux/test_zes_power_helper.cpp | 170 +--- .../sources/power/linux/test_zes_power_xe.cpp | 596 ++++++++++++++ .../mock_sysman_kmd_interface_i915.h | 11 + .../mock_sysman_kmd_interface_xe.h | 13 + .../test_sysman_kmd_interface_i915_prelim.cpp | 16 + ...est_sysman_kmd_interface_i915_upstream.cpp | 16 + .../test_sysman_kmd_interface_xe.cpp | 19 + .../sysman_product_helper_power_tests.cpp | 543 +++++++++++-- ...ysman_product_helper_temperature_tests.cpp | 6 + .../linux/test_zes_temperature.cpp | 14 + 33 files changed, 2325 insertions(+), 847 deletions(-) create mode 100644 level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_xe.h create mode 100644 level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_xe.cpp 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 be0ef4d864..c9d8e1f505 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 @@ -18,6 +18,8 @@ namespace L0 { namespace Sysman { +static const std::string hwmonDir("device/hwmon"); + ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { pProperties->onSubdevice = isSubdevice; pProperties->subdeviceId = subdeviceId; @@ -42,11 +44,17 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) { } ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { + std::string defaultPowerLimitFile = {}; + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + defaultPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNameDefaultPowerLimit); + } else if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + defaultPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNamePackageDefaultPowerLimit); + } + uint64_t powerLimit = 0; - std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, subdeviceId, false); - auto result = pSysfsAccess->read(defaultPowerLimit, powerLimit); + 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); } @@ -57,28 +65,21 @@ ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) { } ze_result_t LinuxPowerImp::getPropertiesExt(zes_power_ext_properties_t *pExtPoperties) { - pExtPoperties->domain = isSubdevice ? ZES_POWER_DOMAIN_PACKAGE : powerDomain; + pExtPoperties->domain = powerDomain; if (pExtPoperties->defaultLimit) { - if (!isSubdevice) { - uint64_t val = 0; - std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, subdeviceId, false); - ze_result_t result = pSysfsAccess->read(defaultPowerLimit, val); - if (result == ZE_RESULT_SUCCESS) { - pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameDefaultPowerLimit), 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; } @@ -105,85 +106,108 @@ ze_result_t LinuxPowerImp::getPmtEnergyCounter(zes_power_energy_counter_t *pEner return ZE_RESULT_ERROR_NOT_AVAILABLE; } - // PMT will return energy counter in Q20 format(fixed point representation) where first 20 bits(from LSB) represent decimal part and remaining integral part which is converted into joule by division with 1048576(2^20) and then converted into microjoules + // PMT will return energy counter in Q20 format(fixed point representation) where first 20 bits(from LSB) represent decimal part and + // remaining integral part which is converted into joule by division with 1048576(2^20) and then converted into microjoules pEnergy->energy = (energy / fixedPointToJoule) * convertJouleToMicroJoule; return ZE_RESULT_SUCCESS; } ze_result_t LinuxPowerImp::getEnergyCounter(zes_power_energy_counter_t *pEnergy) { - pEnergy->timestamp = SysmanDevice::getSysmanTimestamp(); - std::string energyCounterNode = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEnergyCounterNode, subdeviceId, false); - ze_result_t result = pSysfsAccess->read(energyCounterNode, pEnergy->energy); - if (result != ZE_RESULT_SUCCESS) { - if (isTelemetrySupportAvailable) { - return getPmtEnergyCounter(pEnergy); - } + ze_result_t result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + + // Try to get energy counter from PMT if supported + bool isTelemetrySupportAvailable = PlatformMonitoringTech::isTelemetrySupportAvailable(pLinuxSysmanImp, subdeviceId); + if (isTelemetrySupportAvailable && (pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(powerDomain))) { + result = getPmtEnergyCounter(pEnergy); } + + // If PMT method fails, try to read from sysfs + if (result != ZE_RESULT_SUCCESS) { + result = pSysfsAccess->read(energyCounterNodeFile, pEnergy->energy); + } + + 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(), energyCounterNodeFile.c_str(), getErrorCode(result)); + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + pEnergy->timestamp = SysmanDevice::getSysmanTimestamp(); + return result; } 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::sysfsNameSustainedPowerLimit), 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::sysfsNameCriticalPowerLimit), 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 getErrorCode(result); + } + pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameSustainedPowerLimit), 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 getErrorCode(result); + } + pSysmanKmdInterface->convertSysfsValueUnit(SysfsValueUnit::milli, pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameCriticalPowerLimit), 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::sysfsNameSustainedPowerLimit), 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::sysfsNameCriticalPowerLimit), 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::sysfsNameSustainedPowerLimit), 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); + } + } + + if (pPeak != nullptr) { + val = static_cast(pPeak->powerAC); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameCriticalPowerLimit), 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 getErrorCode(result); + } + } + + return ZE_RESULT_SUCCESS; } + ze_result_t LinuxPowerImp::getEnergyThreshold(zes_energy_threshold_t *pThreshold) { NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s() returning UNSUPPORTED_FEATURE \n", __FUNCTION__); return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; @@ -194,111 +218,131 @@ 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); - } - - 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::sysfsNameSustainedPowerLimit), 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++; - } - - 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(); - } + if (isSubdevice || pLimitExt == nullptr) { + return result; } + + uint64_t val = 0; + uint8_t count = 0; + + if (count < *pCount) { + 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); + } + + 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::sysfsNameSustainedPowerLimit), 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 (count < *pCount) { + 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 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::sysfsNameSustainedPowerLimit), 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 (pSustained[i].level == ZES_POWER_LEVEL_SUSTAINED) { + val = static_cast(pSustained[i].limit); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameSustainedPowerLimit), 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, 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(), sustainedPowerLimitIntervalFile.c_str(), getErrorCode(result)); + return getErrorCode(result); + } + + } else if (pSustained[i].level == ZES_POWER_LEVEL_PEAK) { + val = static_cast(pSustained[i].limit); + pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(SysfsName::sysfsNameCriticalPowerLimit), 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 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) { std::string intelGraphicsHwmonName = pSysmanKmdInterface->getHwmonName(subdeviceId, isSubdevice); - if (name == intelGraphicsHwmonName) { - return true; - } - return false; + return (name == intelGraphicsHwmonName); } bool LinuxPowerImp::isPowerModuleSupported() { - std::vector listOfAllHwmonDirs = {}; - bool hwmonDirExists = false; - const std::string hwmonDir("device/hwmon"); - if (ZE_RESULT_SUCCESS != pSysfsAccess->scanDirEntries(hwmonDir, listOfAllHwmonDirs)) { - hwmonDirExists = false; + + if (isSubdevice && !(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(powerDomain))) { + return false; } + + if (!pSysfsAccess->fileExists(energyCounterNodeFile) && !pSysfsAccess->fileExists(sustainedPowerLimitFile) && !pSysfsAccess->fileExists(criticalPowerLimitFile)) { + return false; + } + + return true; +} + +void LinuxPowerImp::getPowerLimitFiles() { + std::vector listOfAllHwmonDirs = {}; + if (ZE_RESULT_SUCCESS != pSysfsAccess->scanDirEntries(hwmonDir, listOfAllHwmonDirs)) { + return; + } + for (const auto &tempHwmonDirEntry : listOfAllHwmonDirs) { const std::string hwmonNameFile = hwmonDir + "/" + tempHwmonDirEntry + "/" + "name"; std::string name; @@ -307,30 +351,44 @@ bool LinuxPowerImp::isPowerModuleSupported() { } if (isIntelGraphicsHwmonDir(name)) { intelGraphicsHwmonDir = hwmonDir + "/" + tempHwmonDirEntry; - hwmonDirExists = true; canControl = (!isSubdevice) && (pSysmanProductHelper->isPowerSetLimitSupported()); + break; } } - if (!isSubdevice) { - uint64_t val = 0; - sustainedPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimit, subdeviceId, false); - criticalPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCriticalPowerLimit, subdeviceId, false); - sustainedPowerLimitInterval = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimitInterval, subdeviceId, false); - if (ZE_RESULT_SUCCESS == pSysfsAccess->read(sustainedPowerLimit, val)) { - powerLimitCount++; - } - - if (ZE_RESULT_SUCCESS == pSysfsAccess->read(criticalPowerLimit, val)) { - powerLimitCount++; - } + if (intelGraphicsHwmonDir.empty()) { + return; } - if (hwmonDirExists == false) { - isTelemetrySupportAvailable = PlatformMonitoringTech::isTelemetrySupportAvailable(pLinuxSysmanImp, subdeviceId); - return isTelemetrySupportAvailable; + std::string fileName = pSysmanKmdInterface->getEnergyCounterNodeFilePath(isSubdevice, powerDomain); + if (fileName.empty()) { + return; + } + energyCounterNodeFile = intelGraphicsHwmonDir + "/" + fileName; + + if (isSubdevice) { + return; + } + + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + sustainedPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNameSustainedPowerLimit); + criticalPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNameCriticalPowerLimit); + sustainedPowerLimitIntervalFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNameSustainedPowerLimitInterval); + } else if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + sustainedPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNamePackageSustainedPowerLimit); + criticalPowerLimitFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNamePackageCriticalPowerLimit); + sustainedPowerLimitIntervalFile = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePathForPower(SysfsName::sysfsNamePackageSustainedPowerLimitInterval); + } else { + return; + } + + if (pSysfsAccess->fileExists(sustainedPowerLimitFile)) { + powerLimitCount++; + } + + if (pSysfsAccess->fileExists(criticalPowerLimitFile)) { + powerLimitCount++; } - return true; } LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain) : isSubdevice(onSubdevice), subdeviceId(subdeviceId), powerDomain(powerDomain) { @@ -338,16 +396,18 @@ LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_ pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); pSysfsAccess = pSysmanKmdInterface->getSysFsAccess(); pSysmanProductHelper = pLinuxSysmanImp->getSysmanProductHelper(); -} - -std::vector OsPower::getNumberOfPowerDomainsSupported(OsSysman *pOsSysman) { - std::vector powerDomains = {ZES_POWER_DOMAIN_CARD}; - return powerDomains; + getPowerLimitFiles(); } OsPower *OsPower::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain) { LinuxPowerImp *pLinuxPowerImp = new LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId, powerDomain); return static_cast(pLinuxPowerImp); } + +std::vector OsPower::getPowerDomains(OsSysman *pOsSysman) { + std::vector powerDomains = {ZES_POWER_DOMAIN_CARD, ZES_POWER_DOMAIN_PACKAGE}; + return powerDomains; +} + } // namespace Sysman } // namespace L0 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 198bd65c21..50933a85c0 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 @@ -45,13 +45,14 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass { SysFsAccessInterface *pSysfsAccess = nullptr; SysmanKmdInterface *pSysmanKmdInterface = nullptr; SysmanProductHelper *pSysmanProductHelper = nullptr; - bool isTelemetrySupportAvailable = false; + void getPowerLimitFiles(); private: std::string intelGraphicsHwmonDir = {}; - std::string criticalPowerLimit = {}; - std::string sustainedPowerLimit = {}; - std::string sustainedPowerLimitInterval = {}; + std::string criticalPowerLimitFile = {}; + std::string sustainedPowerLimitFile = {}; + std::string sustainedPowerLimitIntervalFile = {}; + std::string energyCounterNodeFile = {}; bool canControl = false; bool isSubdevice = false; uint32_t subdeviceId = 0; diff --git a/level_zero/sysman/source/api/power/sysman_os_power.h b/level_zero/sysman/source/api/power/sysman_os_power.h index 0b0a153b82..0f81896487 100644 --- a/level_zero/sysman/source/api/power/sysman_os_power.h +++ b/level_zero/sysman/source/api/power/sysman_os_power.h @@ -29,8 +29,7 @@ class OsPower { virtual bool isPowerModuleSupported() = 0; static OsPower *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain); - static std::vector getNumberOfPowerDomainsSupported(OsSysman *pOsSysman); - + static std::vector getPowerDomains(OsSysman *pOsSysman); virtual ~OsPower() = default; }; diff --git a/level_zero/sysman/source/api/power/sysman_power.cpp b/level_zero/sysman/source/api/power/sysman_power.cpp index 186683b4b4..c0a074ef95 100644 --- a/level_zero/sysman/source/api/power/sysman_power.cpp +++ b/level_zero/sysman/source/api/power/sysman_power.cpp @@ -35,21 +35,16 @@ void PowerHandleContext::createHandle(ze_bool_t isSubDevice, uint32_t subDeviceI delete pPower; } } -ze_result_t PowerHandleContext::init(uint32_t subDeviceCount) { - auto totalDomains = OsPower::getNumberOfPowerDomainsSupported(pOsSysman); +void PowerHandleContext::init(uint32_t subDeviceCount) { + auto totalDomains = OsPower::getPowerDomains(pOsSysman); - for (auto &powerDomain : totalDomains) { + for (const auto &powerDomain : totalDomains) { createHandle(false, 0, powerDomain); - } - - for (uint32_t subDeviceId = 0; subDeviceId < subDeviceCount; subDeviceId++) { - for (auto &powerDomain : totalDomains) { + for (uint32_t subDeviceId = 0; subDeviceId < subDeviceCount; subDeviceId++) { createHandle(true, subDeviceId, powerDomain); } } - - return ZE_RESULT_SUCCESS; } void PowerHandleContext::initPower() { @@ -71,6 +66,7 @@ ze_result_t PowerHandleContext::powerGet(uint32_t *pCount, zes_pwr_handle_t *phP phPower[i] = handleList[i]->toHandle(); } } + return ZE_RESULT_SUCCESS; } diff --git a/level_zero/sysman/source/api/power/sysman_power.h b/level_zero/sysman/source/api/power/sysman_power.h index 4e1529cc6d..d624331128 100644 --- a/level_zero/sysman/source/api/power/sysman_power.h +++ b/level_zero/sysman/source/api/power/sysman_power.h @@ -38,7 +38,7 @@ struct PowerHandleContext { PowerHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){}; ~PowerHandleContext(); - ze_result_t init(uint32_t subDeviceCount); + void init(uint32_t subDeviceCount); ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower); ze_result_t powerGetCardDomain(zes_pwr_handle_t *phPower); diff --git a/level_zero/sysman/source/api/power/sysman_power_imp.cpp b/level_zero/sysman/source/api/power/sysman_power_imp.cpp index 93b242e418..681452d8d9 100644 --- a/level_zero/sysman/source/api/power/sysman_power_imp.cpp +++ b/level_zero/sysman/source/api/power/sysman_power_imp.cpp @@ -68,7 +68,7 @@ PowerImp::PowerImp(OsSysman *pOsSysman, ze_bool_t isSubDevice, uint32_t subDevic pOsPower = OsPower::create(pOsSysman, isSubDevice, subDeviceId, powerDomain); UNRECOVERABLE_IF(nullptr == pOsPower); - this->isCardPower = isSubDevice ? false : true; + this->isCardPower = powerDomain == ZES_POWER_DOMAIN_CARD; init(); } diff --git a/level_zero/sysman/source/api/power/windows/sysman_os_power_imp.cpp b/level_zero/sysman/source/api/power/windows/sysman_os_power_imp.cpp index e0133d79bf..37561ef8a6 100644 --- a/level_zero/sysman/source/api/power/windows/sysman_os_power_imp.cpp +++ b/level_zero/sysman/source/api/power/windows/sysman_os_power_imp.cpp @@ -531,7 +531,7 @@ WddmPowerImp::WddmPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t initPowerLimits(); } -std::vector OsPower::getNumberOfPowerDomainsSupported(OsSysman *pOsSysman) { +std::vector OsPower::getPowerDomains(OsSysman *pOsSysman) { WddmSysmanImp *pWddmSysmanImp = static_cast(pOsSysman); auto pSysmanProductHelper = pWddmSysmanImp->getSysmanProductHelper(); return pSysmanProductHelper->getNumberOfPowerDomainsSupported(pWddmSysmanImp); diff --git a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h index 796bea3b6e..2cd2b27602 100644 --- a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h +++ b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h @@ -93,6 +93,11 @@ enum class SysfsName { sysfsNamePerformanceBaseFrequencyFactorScale, sysfsNamePerformanceMediaFrequencyFactorScale, sysfsNamePerformanceSystemPowerBalance, + sysfsNamePackageSustainedPowerLimit, + sysfsNamePackageSustainedPowerLimitInterval, + sysfsNamePackageDefaultPowerLimit, + sysfsNamePackageCriticalPowerLimit, + sysfsNamePackageEnergyCounterNode, }; enum class SysfsValueUnit { @@ -111,6 +116,8 @@ class SysmanKmdInterface { virtual std::string getBasePath(uint32_t subDeviceId) const = 0; virtual std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) = 0; virtual std::string getSysfsFilePathForPhysicalMemorySize(uint32_t subDeviceId) = 0; + virtual std::string getSysfsFilePathForPower(SysfsName sysfsName) = 0; + virtual std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) = 0; virtual int64_t getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pmuInterface) = 0; virtual std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const = 0; virtual bool isStandbyModeControlAvailable() const = 0; @@ -149,6 +156,7 @@ class SysmanKmdInterface { virtual void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) = 0; virtual bool isVfEngineUtilizationSupported() const = 0; virtual ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair &configPair) = 0; + virtual bool isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const = 0; protected: std::unique_ptr pFsAccess; @@ -177,6 +185,8 @@ class SysmanKmdInterfaceI915Upstream : public SysmanKmdInterface, SysmanKmdInter std::string getBasePath(uint32_t subDeviceId) const override; std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) override; std::string getSysfsFilePathForPhysicalMemorySize(uint32_t subDeviceId) override; + std::string getSysfsFilePathForPower(SysfsName sysfsName) override; + std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) override; int64_t getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pmuInterface) override; std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override; bool isStandbyModeControlAvailable() const override { return true; } @@ -203,6 +213,7 @@ class SysmanKmdInterfaceI915Upstream : public SysmanKmdInterface, SysmanKmdInter void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override; bool isVfEngineUtilizationSupported() const override { return false; } ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair &configPair) override; + bool isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const override; protected: std::map sysfsNameToFileMap; @@ -222,6 +233,8 @@ class SysmanKmdInterfaceI915Prelim : public SysmanKmdInterface, SysmanKmdInterfa std::string getBasePath(uint32_t subDeviceId) const override; std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) override; std::string getSysfsFilePathForPhysicalMemorySize(uint32_t subDeviceId) override; + std::string getSysfsFilePathForPower(SysfsName sysfsName) override; + std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) override; int64_t getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pmuInterface) override; std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override; bool isStandbyModeControlAvailable() const override { return true; } @@ -248,6 +261,7 @@ class SysmanKmdInterfaceI915Prelim : public SysmanKmdInterface, SysmanKmdInterfa void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override; bool isVfEngineUtilizationSupported() const override { return true; } ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair &configPair) override; + bool isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const override; protected: std::map sysfsNameToFileMap; @@ -267,6 +281,8 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface { std::string getBasePath(uint32_t subDeviceId) const override; std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) override; std::string getSysfsFilePathForPhysicalMemorySize(uint32_t subDeviceId) override; + std::string getSysfsFilePathForPower(SysfsName sysfsName) override; + std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) override; std::string getEngineBasePath(uint32_t subDeviceId) const override; int64_t getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pmuInterface) override; std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override; @@ -295,6 +311,7 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface { void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override; bool isVfEngineUtilizationSupported() const override { return false; } ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair &configPair) override; + bool isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const override { return false; } protected: std::map sysfsNameToFileMap; diff --git a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_prelim.cpp b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_prelim.cpp index 7fdaf57920..ed8d2cf3d0 100644 --- a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_prelim.cpp +++ b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_prelim.cpp @@ -96,6 +96,25 @@ std::string SysmanKmdInterfaceI915Prelim::getSysfsFilePathForPhysicalMemorySize( return filePathPhysicalMemorySize; } +std::string SysmanKmdInterfaceI915Prelim::getSysfsFilePathForPower(SysfsName sysfsName) { + std::string filePath = sysfsNameToFileMap[sysfsName].second; + return filePath; +} + +std::string SysmanKmdInterfaceI915Prelim::getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) { + if ((isSubdevice && powerDomain == ZES_POWER_DOMAIN_PACKAGE) || (!isSubdevice && powerDomain == ZES_POWER_DOMAIN_CARD)) { + return getSysfsFilePathForPower(SysfsName::sysfsNameEnergyCounterNode); + } + return {}; +} + +bool SysmanKmdInterfaceI915Prelim::isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const { + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + return false; + } + return true; +} + int64_t SysmanKmdInterfaceI915Prelim::getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface) { uint64_t config = UINT64_MAX; switch (engineGroup) { diff --git a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_upstream.cpp b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_upstream.cpp index b7547026cf..978ca850f2 100644 --- a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_upstream.cpp +++ b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_i915_upstream.cpp @@ -89,6 +89,25 @@ std::string SysmanKmdInterfaceI915Upstream::getSysfsFilePathForPhysicalMemorySiz return filePathPhysicalMemorySize; } +std::string SysmanKmdInterfaceI915Upstream::getSysfsFilePathForPower(SysfsName sysfsName) { + std::string filePath = sysfsNameToFileMap[sysfsName].second; + return filePath; +} + +std::string SysmanKmdInterfaceI915Upstream::getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) { + if ((isSubdevice && powerDomain == ZES_POWER_DOMAIN_PACKAGE) || (!isSubdevice && powerDomain == ZES_POWER_DOMAIN_CARD)) { + return getSysfsFilePathForPower(SysfsName::sysfsNameEnergyCounterNode); + } + return {}; +} + +bool SysmanKmdInterfaceI915Upstream::isPowerSupportForSubdeviceAvailable(zes_power_domain_t powerDomain) const { + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + return false; + } + return true; +} + int64_t SysmanKmdInterfaceI915Upstream::getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface) { uint64_t config = UINT64_MAX; auto engineClass = engineGroupToEngineClass.find(engineGroup); diff --git a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_xe.cpp b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_xe.cpp index 4f094c8852..d10bdbbba4 100644 --- a/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_xe.cpp +++ b/level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface_xe.cpp @@ -65,6 +65,11 @@ void SysmanKmdInterfaceXe::initSysfsNameToFileMap(SysmanProductHelper *pSysmanPr sysfsNameToFileMap[SysfsName::sysfsNamePerformanceMediaFrequencyFactor] = std::make_pair("media_freq_factor", ""); sysfsNameToFileMap[SysfsName::sysfsNamePerformanceMediaFrequencyFactorScale] = std::make_pair("media_freq_factor.scale", ""); sysfsNameToFileMap[SysfsName::sysfsNamePerformanceSystemPowerBalance] = std::make_pair("", "sys_pwr_balance"); + sysfsNameToFileMap[SysfsName::sysfsNamePackageSustainedPowerLimit] = std::make_pair("", "power2_max"); + sysfsNameToFileMap[SysfsName::sysfsNamePackageSustainedPowerLimitInterval] = std::make_pair("", "power2_max_interval"); + sysfsNameToFileMap[SysfsName::sysfsNamePackageDefaultPowerLimit] = std::make_pair("", "power2_rated_max"); + sysfsNameToFileMap[SysfsName::sysfsNamePackageEnergyCounterNode] = std::make_pair("", "energy2_input"); + sysfsNameToFileMap[SysfsName::sysfsNamePackageCriticalPowerLimit] = std::make_pair("", pSysmanProductHelper->getPackageCriticalPowerLimitFile()); } void SysmanKmdInterfaceXe::initSysfsNameToNativeUnitMap(SysmanProductHelper *pSysmanProductHelper) { @@ -75,6 +80,7 @@ void SysmanKmdInterfaceXe::initSysfsNameToNativeUnitMap(SysmanProductHelper *pSy sysfsNameToNativeUnitMap[SysfsName::sysfsNameSustainedPowerLimit] = SysfsValueUnit::micro; sysfsNameToNativeUnitMap[SysfsName::sysfsNameDefaultPowerLimit] = SysfsValueUnit::micro; sysfsNameToNativeUnitMap[SysfsName::sysfsNameCriticalPowerLimit] = pSysmanProductHelper->getCardCriticalPowerLimitNativeUnit(); + sysfsNameToNativeUnitMap[SysfsName::sysfsNamePackageCriticalPowerLimit] = pSysmanProductHelper->getPackageCriticalPowerLimitNativeUnit(); } std::string SysmanKmdInterfaceXe::getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool prefixBaseDirectory) { @@ -93,6 +99,21 @@ std::string SysmanKmdInterfaceXe::getSysfsFilePathForPhysicalMemorySize(uint32_t return filePathPhysicalMemorySize; } +std::string SysmanKmdInterfaceXe::getSysfsFilePathForPower(SysfsName sysfsName) { + std::string filePath = sysfsNameToFileMap[sysfsName].second; + return filePath; +} + +std::string SysmanKmdInterfaceXe::getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) { + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + return getSysfsFilePathForPower(SysfsName::sysfsNameEnergyCounterNode); + } else if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + return getSysfsFilePathForPower(SysfsName::sysfsNamePackageEnergyCounterNode); + } else { + return {}; + } +} + int64_t SysmanKmdInterfaceXe::getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface) { return -1; } diff --git a/level_zero/sysman/source/shared/linux/product_helper/gen12lp/dg1/sysman_product_helper_dg1.cpp b/level_zero/sysman/source/shared/linux/product_helper/gen12lp/dg1/sysman_product_helper_dg1.cpp index 9dff13a18d..75dabbf6ab 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/gen12lp/dg1/sysman_product_helper_dg1.cpp +++ b/level_zero/sysman/source/shared/linux/product_helper/gen12lp/dg1/sysman_product_helper_dg1.cpp @@ -164,6 +164,14 @@ bool SysmanProductHelperHw::isUpstreamPortConnected() { return true; } +template <> +bool SysmanProductHelperHw::isPmtNodeAvailableForEnergyCounter(zes_power_domain_t powerDomain) { + if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + return false; + } + return true; +} + template class SysmanProductHelperHw; } // namespace Sysman diff --git a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h index 3d0879f83c..a66e0969e7 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h +++ b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h @@ -80,6 +80,9 @@ class SysmanProductHelper { virtual bool isPowerSetLimitSupported() = 0; virtual std::string getCardCriticalPowerLimitFile() = 0; virtual SysfsValueUnit getCardCriticalPowerLimitNativeUnit() = 0; + virtual std::string getPackageCriticalPowerLimitFile() = 0; + virtual SysfsValueUnit getPackageCriticalPowerLimitNativeUnit() = 0; + virtual bool isPmtNodeAvailableForEnergyCounter(zes_power_domain_t powerDomain) = 0; // Diagnostics virtual bool isDiagnosticsSupported() = 0; diff --git a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h index bbeae73c0b..6b0410b33c 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h +++ b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h @@ -55,6 +55,9 @@ class SysmanProductHelperHw : public SysmanProductHelper { bool isPowerSetLimitSupported() override; std::string getCardCriticalPowerLimitFile() override; SysfsValueUnit getCardCriticalPowerLimitNativeUnit() override; + std::string getPackageCriticalPowerLimitFile() override; + SysfsValueUnit getPackageCriticalPowerLimitNativeUnit() override; + bool isPmtNodeAvailableForEnergyCounter(zes_power_domain_t powerDomain) override; // Diagnostics bool isDiagnosticsSupported() override; diff --git a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl index 4711e38d2b..554ffabbe8 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl +++ b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl @@ -268,7 +268,7 @@ bool SysmanProductHelperHw::isPowerSetLimitSupported() { template std::string SysmanProductHelperHw::getCardCriticalPowerLimitFile() { - return "power1_crit"; + return ""; } template @@ -276,6 +276,21 @@ SysfsValueUnit SysmanProductHelperHw::getCardCriticalPowerLimitNativ return SysfsValueUnit::micro; } +template +std::string SysmanProductHelperHw::getPackageCriticalPowerLimitFile() { + return "power2_crit"; +} + +template +SysfsValueUnit SysmanProductHelperHw::getPackageCriticalPowerLimitNativeUnit() { + return SysfsValueUnit::micro; +} + +template +bool SysmanProductHelperHw::isPmtNodeAvailableForEnergyCounter(zes_power_domain_t powerDomain) { + return false; +} + template bool SysmanProductHelperHw::isDiagnosticsSupported() { return false; diff --git a/level_zero/sysman/source/shared/linux/product_helper/xe_hpc_core/pvc/sysman_product_helper_pvc.cpp b/level_zero/sysman/source/shared/linux/product_helper/xe_hpc_core/pvc/sysman_product_helper_pvc.cpp index e8cec5fa98..32f26c7971 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/xe_hpc_core/pvc/sysman_product_helper_pvc.cpp +++ b/level_zero/sysman/source/shared/linux/product_helper/xe_hpc_core/pvc/sysman_product_helper_pvc.cpp @@ -463,6 +463,16 @@ SysfsValueUnit SysmanProductHelperHw::getCardCriticalPowerLimitNativ return SysfsValueUnit::milli; } +template <> +std::string SysmanProductHelperHw::getPackageCriticalPowerLimitFile() { + return "curr2_crit"; +} + +template <> +SysfsValueUnit SysmanProductHelperHw::getPackageCriticalPowerLimitNativeUnit() { + return SysfsValueUnit::milli; +} + template <> bool SysmanProductHelperHw::isDiagnosticsSupported() { return true; diff --git a/level_zero/sysman/source/shared/linux/product_helper/xe_hpg_core/dg2/sysman_product_helper_dg2.cpp b/level_zero/sysman/source/shared/linux/product_helper/xe_hpg_core/dg2/sysman_product_helper_dg2.cpp index 9b852275d5..fb3d225148 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/xe_hpg_core/dg2/sysman_product_helper_dg2.cpp +++ b/level_zero/sysman/source/shared/linux/product_helper/xe_hpg_core/dg2/sysman_product_helper_dg2.cpp @@ -212,6 +212,14 @@ bool SysmanProductHelperHw::isUpstreamPortConnected() { return true; } +template <> +bool SysmanProductHelperHw::isPmtNodeAvailableForEnergyCounter(zes_power_domain_t powerDomain) { + if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + return false; + } + return true; +} + template class SysmanProductHelperHw; } // namespace Sysman diff --git a/level_zero/sysman/source/shared/linux/sysman_fs_access_interface.cpp b/level_zero/sysman/source/shared/linux/sysman_fs_access_interface.cpp index 7938df6ca8..810fded5ee 100644 --- a/level_zero/sysman/source/shared/linux/sysman_fs_access_interface.cpp +++ b/level_zero/sysman/source/shared/linux/sysman_fs_access_interface.cpp @@ -197,9 +197,20 @@ ze_result_t FsAccessInterface::canWrite(const std::string file) { } bool FsAccessInterface::fileExists(const std::string file) { + struct stat sb; + + if (NEO::SysCalls::stat(file.c_str(), &sb) != 0) { + return false; + } + + if (!S_ISREG(sb.st_mode)) { + return false; + } + if (NEO::SysCalls::access(file.c_str(), F_OK)) { return false; } + return true; } diff --git a/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp index 9c8a1d0fd1..0da4156931 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp +++ b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp @@ -33,11 +33,16 @@ inline static int mockStatFailure(const std::string &filePath, struct stat *stat return -1; } -inline static int mockStatSuccess(const std::string &filePath, struct stat *statbuf) noexcept { +inline static int mockStatFailure2(const std::string &filePath, struct stat *statbuf) noexcept { statbuf->st_mode = S_IWUSR | S_IRUSR; return 0; } +inline static int mockStatSuccess(const std::string &filePath, struct stat *statbuf) noexcept { + statbuf->st_mode = S_IWUSR | S_IRUSR | S_IFREG; + return 0; +} + inline static int mockStatNoPermissions(const std::string &filePath, struct stat *statbuf) noexcept { statbuf->st_mode = 0; return 0; @@ -235,6 +240,7 @@ TEST_F(SysmanDeviceFixture, GivenPublicFsAccessClassWhenCallingCanWriteWithInval TEST_F(SysmanDeviceFixture, GivenValidPathnameWhenCallingFsAccessExistsThenSuccessIsReturned) { VariableBackup allowFakeDevicePathBackup(&SysCalls::allowFakeDevicePath, true); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); auto fsAccess = &pLinuxSysmanImp->getFsAccess(); char cwd[PATH_MAX]; @@ -242,7 +248,24 @@ TEST_F(SysmanDeviceFixture, GivenValidPathnameWhenCallingFsAccessExistsThenSucce EXPECT_TRUE(fsAccess->fileExists(path)); } +TEST_F(SysmanDeviceFixture, GivenStatCallFailsWhenCallingFsAccessExistsThenErrorIsReturned) { + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatFailure); + auto fsAccess = &pLinuxSysmanImp->getSysfsAccess(); + + std::string path = ""; + EXPECT_FALSE(fsAccess->fileExists(path)); +} + +TEST_F(SysmanDeviceFixture, GivenPathIsNotOfFileTypeWhenCallingFsAccessExistsThenErrorIsReturned) { + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatFailure2); + auto fsAccess = &pLinuxSysmanImp->getSysfsAccess(); + + std::string path = ""; + EXPECT_FALSE(fsAccess->fileExists(path)); +} + TEST_F(SysmanDeviceFixture, GivenInvalidPathnameWhenCallingFsAccessExistsThenErrorIsReturned) { + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); auto fsAccess = &pLinuxSysmanImp->getFsAccess(); std::string path = "noSuchFileOrDirectory"; @@ -409,6 +432,7 @@ TEST_F(SysmanDeviceFixture, GivenSysfsAccessClassAndOpenSysCallFailsWhenCallingR } TEST_F(SysmanDeviceFixture, GivenValidPidWhenCallingProcfsAccessIsAliveThenSuccessIsReturned) { + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&SysCalls::allowFakeDevicePath, true); auto procfsAccess = &pLinuxSysmanImp->getProcfsAccess(); diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/power/linux/CMakeLists.txt index 57135a9ab2..c138801b29 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/CMakeLists.txt @@ -9,6 +9,8 @@ set(L0_TESTS_SYSMAN_POWER_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_power.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_power_helper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_sysfs_power.h + ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_power_xe.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_sysfs_power_xe.h ) if(UNIX) diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power.h b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power.h index 6e22719130..ec5348863e 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power.h +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power.h @@ -23,7 +23,8 @@ namespace ult { constexpr uint64_t setEnergyCounter = (83456u * 1048576u); constexpr uint64_t mockKeyOffset = 0x420; -constexpr uint32_t mockLimitCount = 2u; +constexpr uint32_t singleLimitCount = 1u; +constexpr uint32_t maxLimitCountSupported = 2u; const std::string hwmonDir("device/hwmon"); const std::string i915HwmonDir("device/hwmon/hwmon2"); const std::string nonI915HwmonDir("device/hwmon/hwmon1"); @@ -31,23 +32,33 @@ const std::string i915HwmonDirTile0("device/hwmon/hwmon3"); const std::string i915HwmonDirTile1("device/hwmon/hwmon4"); const std::vector listOfMockedHwmonDirs = {"hwmon0", "hwmon1", "hwmon2", "hwmon3", "hwmon4"}; const std::string sustainedPowerLimit("power1_max"); +const std::string packageSustainedPowerLimit("power2_max"); const std::string sustainedPowerLimitInterval("power1_max_interval"); const std::string criticalPowerLimit1("curr1_crit"); const std::string criticalPowerLimit2("power1_crit"); const std::string energyCounterNode("energy1_input"); const std::string defaultPowerLimit("power1_rated_max"); constexpr uint64_t expectedEnergyCounter = 123456785u; -constexpr uint64_t expectedEnergyCounterTile0 = 123456785u; -constexpr uint64_t expectedEnergyCounterTile1 = 128955785u; +constexpr uint64_t expectedEnergyCounterTileVal = 123456785u; constexpr uint32_t mockDefaultPowerLimitVal = 600000000; constexpr uint64_t mockMinPowerLimitVal = 300000000; constexpr uint64_t mockMaxPowerLimitVal = 600000000; -const std::string realPathTelem = "/sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8e:00.1/pmt_telemetry.1.auto/intel_pmt/telem1"; -const std::string sysfsPathTelem = "/sys/class/intel_pmt/telem1"; -const std::string telemOffsetFileName("/sys/class/intel_pmt/telem1/offset"); -const std::string telemGuidFileName("/sys/class/intel_pmt/telem1/guid"); -const std::string telemFileName("/sys/class/intel_pmt/telem1/telem"); +const std::string realPathTelem1 = "/sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8e:00.1/pmt_telemetry.1.auto/intel_pmt/telem1"; +const std::string realPathTelem2 = "/sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8e:00.1/pmt_telemetry.1.auto/intel_pmt/telem2"; +const std::string realPathTelem3 = "/sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8e:00.1/pmt_telemetry.1.auto/intel_pmt/telem3"; +const std::string sysfsPathTelem1 = "/sys/class/intel_pmt/telem1"; +const std::string sysfsPathTelem2 = "/sys/class/intel_pmt/telem2"; +const std::string sysfsPathTelem3 = "/sys/class/intel_pmt/telem3"; +const std::string telem1OffsetFileName("/sys/class/intel_pmt/telem1/offset"); +const std::string telem1GuidFileName("/sys/class/intel_pmt/telem1/guid"); +const std::string telem1TelemFileName("/sys/class/intel_pmt/telem1/telem"); +const std::string telem2OffsetFileName("/sys/class/intel_pmt/telem2/offset"); +const std::string telem2GuidFileName("/sys/class/intel_pmt/telem2/guid"); +const std::string telem2TelemFileName("/sys/class/intel_pmt/telem2/telem"); +const std::string telem3OffsetFileName("/sys/class/intel_pmt/telem3/offset"); +const std::string telem3GuidFileName("/sys/class/intel_pmt/telem3/guid"); +const std::string telem3TelemFileName("/sys/class/intel_pmt/telem3/telem"); struct MockPowerSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface { @@ -56,9 +67,20 @@ struct MockPowerSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface { ze_result_t mockWriteResult = 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{}; + std::vector mockscanDirEntriesResult{}; + + uint64_t sustainedPowerLimitVal = 0; + uint64_t criticalPowerLimitVal = 0; + int32_t sustainedPowerLimitIntervalVal = 0; + + bool isCardDomainSupported = true; + bool isSustainedPowerLimitFilePresent = true; + bool isEnergyCounterFilePresent = true; + bool isCriticalPowerLimitFilePresent = true; + bool isTelemDataAvailable = true; ze_result_t getValString(const std::string file, std::string &val) { ze_result_t result = ZE_RESULT_ERROR_UNKNOWN; @@ -80,11 +102,6 @@ struct MockPowerSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface { return result; } - uint64_t sustainedPowerLimitVal = 0; - uint64_t criticalPowerLimitVal = 0; - int32_t sustainedPowerLimitIntervalVal = 0; - - ze_result_t getValUnsignedLongHelper(const std::string file, uint64_t &val); ze_result_t getValUnsignedLong(const std::string file, uint64_t &val) { ze_result_t result = ZE_RESULT_SUCCESS; if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) { @@ -94,14 +111,15 @@ struct MockPowerSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface { return mockReadPeakResult; } val = criticalPowerLimitVal; - } else if (file.compare(i915HwmonDirTile0 + "/" + energyCounterNode) == 0) { - val = expectedEnergyCounterTile0; - } else if (file.compare(i915HwmonDirTile1 + "/" + energyCounterNode) == 0) { - val = expectedEnergyCounterTile1; + } else if ((file.compare(i915HwmonDirTile0 + "/" + energyCounterNode) == 0) || (file.compare(i915HwmonDirTile1 + "/" + energyCounterNode) == 0)) { + val = expectedEnergyCounterTileVal; } else if (file.compare(i915HwmonDir + "/" + energyCounterNode) == 0) { val = expectedEnergyCounter; } else if (file.compare(i915HwmonDir + "/" + defaultPowerLimit) == 0) { val = mockDefaultPowerLimitVal; + } else if ((file == telem1TelemFileName) || (file == telem2TelemFileName)) { + val = setEnergyCounter; + result = isTelemDataAvailable ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_NOT_AVAILABLE; } else { result = ZE_RESULT_ERROR_NOT_AVAILABLE; } @@ -224,12 +242,29 @@ struct MockPowerSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface { return result; } - ze_result_t scanDirEntries(const std::string file, std::vector &listOfEntries) override { - if (mockscanDirEntriesResult != ZE_RESULT_SUCCESS) { - return mockscanDirEntriesResult; + ze_result_t scanDirEntries(const std::string path, std::vector &listOfEntries) override { + if (!mockscanDirEntriesResult.empty()) { + ze_result_t result = mockscanDirEntriesResult.front(); + mockscanDirEntriesResult.erase(mockscanDirEntriesResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } } - return getscanDirEntries(file, listOfEntries); + return getscanDirEntries(path, listOfEntries); + } + + bool fileExists(const std::string file) override { + if (file.find(energyCounterNode) != std::string::npos) { + return isEnergyCounterFilePresent; + } else if (file.find(sustainedPowerLimit) != std::string::npos) { + return isCardDomainSupported && isSustainedPowerLimitFilePresent; + } else if (file.find(criticalPowerLimit1) != std::string::npos) { + return isCriticalPowerLimitFilePresent; + } else if (file.find(criticalPowerLimit2) != std::string::npos) { + return isCriticalPowerLimitFilePresent; + } + return false; } MockPowerSysfsAccessInterface() = default; @@ -242,7 +277,6 @@ struct MockPowerFsAccessInterface : public L0::Sysman::FsAccessInterface { class PublicLinuxPowerImp : public L0::Sysman::LinuxPowerImp { public: PublicLinuxPowerImp(L0::Sysman::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain) : L0::Sysman::LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId, powerDomain) {} - using L0::Sysman::LinuxPowerImp::isTelemetrySupportAvailable; using L0::Sysman::LinuxPowerImp::pSysfsAccess; }; @@ -262,8 +296,8 @@ class SysmanDevicePowerFixtureI915 : public SysmanDeviceFixture { pSysmanKmdInterface->pFsAccess.reset(pFsAccess); pSysmanKmdInterface->pSysfsAccess.reset(pSysfsAccess); pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); - pLinuxSysmanImp->pFsAccess = pFsAccess; - getPowerHandles(0); + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; } void TearDown() override { SysmanDeviceFixture::TearDown(); @@ -276,19 +310,6 @@ class SysmanDevicePowerFixtureI915 : public SysmanDeviceFixture { } }; -class SysmanDevicePowerFixtureXe : public SysmanDeviceFixture { - protected: - L0::Sysman::SysmanDevice *device = nullptr; - void SetUp() override { - SysmanDeviceFixture::SetUp(); - device = pSysmanDevice; - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - } - void TearDown() override { - SysmanDeviceFixture::TearDown(); - } -}; - class SysmanDevicePowerMultiDeviceFixture : public SysmanMultiDeviceFixture { protected: L0::Sysman::SysmanDevice *device = nullptr; @@ -303,6 +324,7 @@ class SysmanDevicePowerMultiDeviceFixture : public SysmanMultiDeviceFixture { pSysfsAccess = new MockPowerSysfsAccessInterface(); pSysmanKmdInterface->pSysfsAccess.reset(pSysfsAccess); pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; } void TearDown() override { SysmanMultiDeviceFixture::TearDown(); diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_xe.h b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_xe.h new file mode 100644 index 0000000000..8f28e4b23f --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_xe.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2020-2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/helpers/string.h" + +#include "level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h" +#include "level_zero/sysman/source/api/power/sysman_power_imp.h" +#include "level_zero/sysman/source/device/sysman_device_imp.h" +#include "level_zero/sysman/source/shared/linux/pmt/sysman_pmt.h" +#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h" +#include "level_zero/sysman/source/sysman_const.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +const std::string hwmonDir("device/hwmon"); +const std::string xeHwmonDir("device/hwmon/hwmon1"); +const std::string baseTelemSysFS("/sys/class/intel_pmt"); +const std::string sustainedPowerLimit("power1_max"); +const std::string sustainedPowerLimitInterval("power1_max_interval"); +const std::string criticalPowerLimit("power1_crit"); +const std::string criticalPowerLimit2("curr1_crit"); +const std::string energyCounterNode("energy1_input"); +const std::string defaultPowerLimit("power1_rated_max"); + +const std::string packageSustainedPowerLimit("power2_max"); +const std::string packageSustainedPowerLimitInterval("power2_max_interval"); +const std::string packageCriticalPowerLimit1("power2_crit"); +const std::string packageCriticalPowerLimit2("curr2_crit"); +const std::string packageEnergyCounterNode("energy2_input"); +const std::string packageDefaultPowerLimit("power2_rated_max"); +constexpr uint32_t mockDefaultPowerLimitVal = 600000000; +constexpr uint64_t expectedEnergyCounter = 123456785u; +constexpr uint64_t mockMinPowerLimitVal = 300000000; +constexpr uint64_t mockMaxPowerLimitVal = 600000000; + +struct MockXePowerSysfsAccess : public L0::Sysman::SysFsAccessInterface { + + uint64_t sustainedPowerLimitVal = 0; + uint64_t criticalPowerLimitVal = 0; + int32_t sustainedPowerLimitIntervalVal = 0; + std::vector mockReadValUnsignedLongResult{}; + ze_result_t mockScanDirEntriesResult = ZE_RESULT_SUCCESS; + ze_result_t mockReadResult = ZE_RESULT_SUCCESS; + + bool isCardEnergyCounterFilePresent = true; + bool isPackageEnergyCounterFilePresent = true; + bool isSustainedPowerLimitFilePresent = true; + bool isPackagedSustainedPowerLimitFilePresent = true; + bool isCriticalPowerLimitFilePresent = true; + bool isPackageCriticalPowerLimit1Present = true; + bool isPackageCriticalPowerLimit2Present = true; + bool isTelemDataAvailable = true; + + ze_result_t read(const std::string file, std::string &val) override { + if (mockReadResult != ZE_RESULT_SUCCESS) { + return mockReadResult; + } + ze_result_t result = ZE_RESULT_ERROR_UNKNOWN; + if (file.compare(xeHwmonDir + "/" + "name") == 0) { + val = "xe"; + result = ZE_RESULT_SUCCESS; + } else { + val = ""; + result = ZE_RESULT_ERROR_NOT_AVAILABLE; + } + return result; + } + + ze_result_t scanDirEntries(const std::string file, std::vector &listOfEntries) override { + if (mockScanDirEntriesResult != ZE_RESULT_SUCCESS) { + return mockScanDirEntriesResult; + } + if (file.compare(hwmonDir) == 0) { + listOfEntries.push_back("hwmon1"); + return ZE_RESULT_SUCCESS; + } + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + ze_result_t read(const std::string file, uint64_t &val) override { + + ze_result_t result = ZE_RESULT_SUCCESS; + + if (!mockReadValUnsignedLongResult.empty()) { + result = mockReadValUnsignedLongResult.front(); + mockReadValUnsignedLongResult.erase(mockReadValUnsignedLongResult.begin()); + if (result != ZE_RESULT_SUCCESS) { + return result; + } + } + + if ((file.compare(xeHwmonDir + "/" + sustainedPowerLimit) == 0) || (file.compare(xeHwmonDir + "/" + packageSustainedPowerLimit) == 0)) { + val = sustainedPowerLimitVal; + } else if ((file.compare(xeHwmonDir + "/" + criticalPowerLimit) == 0) || (file.compare(xeHwmonDir + "/" + packageCriticalPowerLimit1) == 0)) { + val = criticalPowerLimitVal; + } else if ((file.compare(xeHwmonDir + "/" + criticalPowerLimit2) == 0) || (file.compare(xeHwmonDir + "/" + packageCriticalPowerLimit2) == 0)) { + val = criticalPowerLimitVal; + } else if ((file.compare(xeHwmonDir + "/" + defaultPowerLimit) == 0) || (file.compare(xeHwmonDir + "/" + packageDefaultPowerLimit) == 0)) { + val = mockDefaultPowerLimitVal; + } else if ((file.compare(xeHwmonDir + "/" + energyCounterNode) == 0) || (file.compare(xeHwmonDir + "/" + packageEnergyCounterNode) == 0)) { + val = expectedEnergyCounter; + } else { + result = ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + return result; + } + + ze_result_t read(const std::string file, int32_t &val) override { + + if ((file.compare(xeHwmonDir + "/" + sustainedPowerLimitInterval) == 0) || (file.compare(xeHwmonDir + "/" + packageSustainedPowerLimitInterval) == 0)) { + val = sustainedPowerLimitIntervalVal; + return ZE_RESULT_SUCCESS; + } + + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + ze_result_t write(const std::string file, const uint64_t val) override { + ze_result_t result = ZE_RESULT_SUCCESS; + + if ((file.compare(xeHwmonDir + "/" + sustainedPowerLimit) == 0) || (file.compare(xeHwmonDir + "/" + packageSustainedPowerLimit) == 0)) { + if (val < mockMinPowerLimitVal) { + sustainedPowerLimitVal = mockMinPowerLimitVal; + } else if (val > mockMaxPowerLimitVal) { + sustainedPowerLimitVal = mockMaxPowerLimitVal; + } else { + sustainedPowerLimitVal = val; + } + } else if ((file.compare(xeHwmonDir + "/" + criticalPowerLimit) == 0) || (file.compare(xeHwmonDir + "/" + packageCriticalPowerLimit1) == 0)) { + criticalPowerLimitVal = val; + } else if ((file.compare(xeHwmonDir + "/" + criticalPowerLimit2) == 0) || (file.compare(xeHwmonDir + "/" + packageCriticalPowerLimit2) == 0)) { + criticalPowerLimitVal = val; + } else { + result = ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + return result; + } + + ze_result_t write(const std::string file, const int val) override { + + ze_result_t result = ZE_RESULT_SUCCESS; + if ((file.compare(xeHwmonDir + "/" + sustainedPowerLimitInterval) == 0) || (file.compare(xeHwmonDir + "/" + packageSustainedPowerLimitInterval) == 0)) { + sustainedPowerLimitIntervalVal = val; + } else { + result = ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + return result; + } + + bool fileExists(const std::string file) override { + if (file.find(energyCounterNode) != std::string::npos) { + return isCardEnergyCounterFilePresent; + } else if (file.find(packageEnergyCounterNode) != std::string::npos) { + return isPackageEnergyCounterFilePresent; + } else if (file.find(sustainedPowerLimit) != std::string::npos) { + return isSustainedPowerLimitFilePresent; + } else if (file.find(packageSustainedPowerLimit) != std::string::npos) { + return isPackagedSustainedPowerLimitFilePresent; + } else if (file.find(criticalPowerLimit) != std::string::npos) { + return isCriticalPowerLimitFilePresent; + } else if (file.find(criticalPowerLimit2) != std::string::npos) { + return isCriticalPowerLimitFilePresent; + } else if (file.find(packageCriticalPowerLimit1) != std::string::npos) { + return isPackageCriticalPowerLimit1Present; + } else if (file.find(packageCriticalPowerLimit2) != std::string::npos) { + return isPackageCriticalPowerLimit2Present; + } + return false; + } + + MockXePowerSysfsAccess() = default; +}; + +struct MockXePowerFsAccess : public L0::Sysman::FsAccessInterface { + + ze_result_t listDirectory(const std::string directory, std::vector &listOfTelemNodes) override { + if (directory.compare(baseTelemSysFS) == 0) { + listOfTelemNodes.push_back("telem1"); + return ZE_RESULT_SUCCESS; + } + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + ze_result_t getRealPath(const std::string path, std::string &buf) override { + if (path.compare("/sys/class/intel_pmt/telem1") == 0) { + buf = "/sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8e:00.1/pmt_telemetry.1.auto/intel_pmt/telem1"; + } else { + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + return ZE_RESULT_SUCCESS; + } + + MockXePowerFsAccess() = default; +}; + +class PublicLinuxPowerImp : public L0::Sysman::LinuxPowerImp { + public: + PublicLinuxPowerImp(L0::Sysman::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_power_domain_t powerDomain) : L0::Sysman::LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId, powerDomain) {} + using L0::Sysman::LinuxPowerImp::pSysfsAccess; +}; + +class SysmanDevicePowerFixtureXe : public SysmanDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + MockXePowerFsAccess *pFsAccess = nullptr; + MockXePowerSysfsAccess *pSysfsAccess = nullptr; + MockSysmanKmdInterfaceXe *pSysmanKmdInterface = nullptr; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + device = pSysmanDevice; + pFsAccess = new MockXePowerFsAccess(); + pSysfsAccess = new MockXePowerSysfsAccess(); + pSysmanKmdInterface = new MockSysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper()); + pSysmanKmdInterface->pSysfsAccess.reset(pSysfsAccess); + pSysmanKmdInterface->pFsAccess.reset(pFsAccess); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + } + + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } + + std::vector getPowerHandles(uint32_t count) { + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } +}; + +class SysmanMultiDevicePowerFixtureXe : public SysmanMultiDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + MockXePowerFsAccess *pFsAccess = nullptr; + MockXePowerSysfsAccess *pSysfsAccess = nullptr; + MockSysmanKmdInterfaceXe *pSysmanKmdInterface = nullptr; + + void SetUp() override { + SysmanMultiDeviceFixture::SetUp(); + device = pSysmanDevice; + pFsAccess = new MockXePowerFsAccess(); + pSysfsAccess = new MockXePowerSysfsAccess(); + pSysmanKmdInterface = new MockSysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper()); + pSysmanKmdInterface->pSysfsAccess.reset(pSysfsAccess); + pSysmanKmdInterface->pFsAccess.reset(pFsAccess); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + pLinuxSysmanImp->pSysfsAccess = pSysfsAccess; + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + getPowerHandles(0); + } + void TearDown() override { + SysmanMultiDeviceFixture::TearDown(); + } + + std::vector getPowerHandles(uint32_t count) { + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } +}; + +} // namespace ult +} // namespace Sysman +} // namespace L0 \ No newline at end of file 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 c1502ebcbe..bd75be7922 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 @@ -12,28 +12,28 @@ namespace L0 { namespace Sysman { namespace ult { -constexpr uint32_t powerHandleComponentCount = 1u; +constexpr uint32_t i915PowerHandleComponentCount = 1u; -TEST_F(SysmanDevicePowerFixtureI915, GivenComponentCountZeroWhenEnumeratingPowerDomainsWhenhwmonInterfaceExistsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { +TEST_F(SysmanDevicePowerFixtureI915, GivenComponentCountZeroWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); } -TEST_F(SysmanDevicePowerFixtureI915, GivenInvalidComponentCountWhenEnumeratingPowerDomainsWhenhwmonInterfaceExistsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { +TEST_F(SysmanDevicePowerFixtureI915, GivenInvalidComponentCountWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); count = count + 1; EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); } -TEST_F(SysmanDevicePowerFixtureI915, GivenComponentCountZeroWhenEnumeratingPowerDomainsWhenhwmonInterfaceExistsThenValidPowerHandlesIsReturned) { +TEST_F(SysmanDevicePowerFixtureI915, GivenComponentCountZeroWhenEnumeratingPowerDomainsThenValidPowerHandlesIsReturned) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); @@ -42,7 +42,7 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenComponentCountZeroWhenEnumeratingPower } } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerPointerWhenGettingCardPowerDomainWhenhwmonInterfaceExistsAndThenCallSucceeds) { +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerPointerWhenGettingCardPowerDomainAndThenCallSucceeds) { zes_pwr_handle_t phPower = {}; EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_SUCCESS); } @@ -52,6 +52,7 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenInvalidPowerPointerWhenGettingCardPowe } TEST_F(SysmanDevicePowerFixtureI915, GivenUninitializedPowerHandlesAndWhenGettingCardPowerDomainThenReturnsFailure) { + auto handles = getPowerHandles(0); for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } @@ -61,71 +62,96 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenUninitializedPowerHandlesAndWhenGettin EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesWhenhwmonInterfaceExistsThenCallSucceeds) { - MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); - pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; - std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); - std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); +TEST_F(SysmanDevicePowerFixtureI915, GivenScanDirectoriesFailAndPmtIsNullWhenGettingCardPowerThenReturnsFailure) { + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + auto handles = getPowerHandles(0); for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; } pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - 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.canControl, true); - EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.maxLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.minLimit, -1); - } + zes_pwr_handle_t phPower = {}; + EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) { +TEST_F(SysmanDevicePowerFixtureI915, GivenHwmonDirectoriesDoesNotExistWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysfsAccess->mockscanDirEntriesResult.clear(); + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenHwmonDirectoriesDoesNotContainNameFileWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysfsAccess->mockReadResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenEnergyCounterNodeIsNotAvailableWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysmanKmdInterface->isEnergyNodeAvailable = false; + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPowerDomainIsCardWhenGettingPowerPropertiessThenCallSucceeds) { MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + 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.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); +} - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - zes_power_ext_properties_t extProperties = {}; - zes_power_limit_ext_desc_t defaultLimit = {}; +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceedsForCardDomain) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); - extProperties.defaultLimit = &defaultLimit; - extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; - properties.pNext = &extProperties; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); - EXPECT_EQ(properties.canControl, true); - EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.minLimit, -1); - EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); - EXPECT_TRUE(defaultLimit.limitValueLocked); - EXPECT_TRUE(defaultLimit.enabledStateLocked); - EXPECT_TRUE(defaultLimit.intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, defaultLimit.source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, defaultLimit.limitUnit); - EXPECT_EQ(defaultLimit.limit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); - } + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + + extProperties.defaultLimit = &defaultLimit; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + properties.pNext = &extProperties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(properties.subdeviceId, 0u); + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); + EXPECT_TRUE(defaultLimit.limitValueLocked); + EXPECT_TRUE(defaultLimit.enabledStateLocked); + EXPECT_TRUE(defaultLimit.intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, defaultLimit.source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, defaultLimit.limitUnit); + EXPECT_EQ(defaultLimit.limit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); } TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWithNoStypeForExtPropertiesWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) { @@ -134,49 +160,41 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWithNoStypeForExtPrope std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - auto handles = getPowerHandles(powerHandleComponentCount); - - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - zes_power_ext_properties_t extProperties = {}; - zes_power_limit_ext_desc_t defaultLimit = {}; - - extProperties.defaultLimit = &defaultLimit; - properties.pNext = &extProperties; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); - EXPECT_EQ(properties.canControl, true); - EXPECT_EQ(properties.isEnergyThresholdSupported, false); - EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); - EXPECT_EQ(properties.minLimit, -1); - } + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + extProperties.defaultLimit = &defaultLimit; + properties.pNext = &extProperties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(properties.subdeviceId, 0u); + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPowerSetLimitSupportedIsUnsupportedWhenCallingzesPowerGetPropertiesThenVerifyCanControlIsSetToFalse) { +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPowerSetLimitIsUnsupportedWhenCallingZesPowerGetPropertiesThenCanControlIsFalse) { std::unique_ptr pSysmanProductHelper = std::make_unique(); std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.canControl); +} - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - zes_power_properties_t properties{}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - EXPECT_FALSE(properties.canControl); - } +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWithUnknownPowerDomainWhenGetDefaultLimitIsCalledThenProperErrorCodeIsReturned) { + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_UNKNOWN)); + zes_power_properties_t properties{}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getProperties(&properties)); + EXPECT_EQ(properties.defaultLimit, -1); } TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesAndSysfsReadFailsThenFailureIsReturned) { @@ -194,7 +212,7 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndHandleCountZeroWhen uint32_t count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumPowerDomains(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); for (auto handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { delete handle; @@ -205,50 +223,88 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndHandleCountZeroWhen count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumPowerDomains(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, powerHandleComponentCount); + EXPECT_EQ(count, i915PowerHandleComponentCount); } -HWTEST2_F(SysmanDevicePowerFixtureI915, GivenSetPowerLimitsWhenGettingPowerLimitsWhenHwmonInterfaceExistThenLimitsSetEarlierAreRetrieved, IsXeHpOrXeHpcOrXeHpgCore) { - auto handles = getPowerHandles(powerHandleComponentCount); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - zes_power_sustained_limit_t sustainedSet = {}; - zes_power_sustained_limit_t sustainedGet = {}; - sustainedSet.enabled = 1; - sustainedSet.interval = 10; - sustainedSet.power = 300000; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); - EXPECT_EQ(sustainedGet.power, sustainedSet.power); +HWTEST2_F(SysmanDevicePowerFixtureI915, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsPVC) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_sustained_limit_t sustainedSet = {}; + zes_power_sustained_limit_t sustainedGet = {}; + sustainedSet.enabled = 1; + sustainedSet.interval = 10; + sustainedSet.power = 300000; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + EXPECT_EQ(sustainedGet.power, sustainedSet.power); + zes_power_burst_limit_t burstGet = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + EXPECT_EQ(burstGet.enabled, false); + EXPECT_EQ(burstGet.power, -1); - zes_power_burst_limit_t burstGet = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, nullptr)); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); - EXPECT_EQ(burstGet.enabled, false); - EXPECT_EQ(burstGet.power, -1); + zes_power_peak_limit_t peakSet = {}; + zes_power_peak_limit_t peakGet = {}; + peakSet.powerAC = 300000; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + EXPECT_EQ(peakGet.powerAC, peakSet.powerAC); + EXPECT_EQ(peakGet.powerDC, -1); +} - zes_power_peak_limit_t peakSet = {}; - zes_power_peak_limit_t peakGet = {}; - peakSet.powerAC = 300000; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); - EXPECT_EQ(peakGet.powerAC, peakSet.powerAC); - EXPECT_EQ(peakGet.powerDC, -1); - } +HWTEST2_F(SysmanDevicePowerFixtureI915, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsDG1) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_sustained_limit_t sustainedSet = {}; + zes_power_sustained_limit_t sustainedGet = {}; + sustainedSet.enabled = 1; + sustainedSet.interval = 10; + sustainedSet.power = 300000; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + EXPECT_EQ(sustainedGet.power, sustainedSet.power); + zes_power_burst_limit_t burstGet = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + EXPECT_EQ(burstGet.enabled, false); + EXPECT_EQ(burstGet.power, -1); + + zes_power_peak_limit_t peakSet = {}; + zes_power_peak_limit_t peakGet = {}; + peakSet.powerAC = 300000; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); } TEST_F(SysmanDevicePowerFixtureI915, GivenDefaultLimitSysfsNodesNotAvailableWhenGettingPowerPropertiesThenApiCallReturnsFailure) { - auto handles = getPowerHandles(powerHandleComponentCount); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetProperties(handle, &properties)); - } + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetProperties(handle, &properties)); +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenGetPropertiesExtCallFailsWhenGettingPowerPropertiesThenApiCallReturnsFailure) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + + extProperties.defaultLimit = &defaultLimit; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + properties.pNext = &extProperties; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetProperties(handle, &properties)); } TEST_F(SysmanDevicePowerFixtureI915, GivenDefaultLimitSysfsNodesNotAvailableWhenGettingPowerPropertiesExtThenApiCallReturnsFailure) { - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_properties_t properties = {}; @@ -259,112 +315,104 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenDefaultLimitSysfsNodesNotAvailableWhen extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; properties.pNext = &extProperties; - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetProperties(handle, &properties)); } } HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsPVC) { - auto handles = getPowerHandles(powerHandleComponentCount); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); - uint32_t limitCount = 0; - const int32_t testLimit = 300000; - const int32_t testInterval = 10; + uint32_t limitCount = 0; + const int32_t testLimit = 300000; + const int32_t testInterval = 10; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, maxLimitCountSupported); - limitCount++; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + limitCount++; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, maxLimitCountSupported); - std::vector allLimits(limitCount); - 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_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_FALSE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - allLimits[i].interval = testInterval; - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_TRUE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - } + std::vector allLimits(limitCount); + 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_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_FALSE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + allLimits[i].interval = testInterval; + } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_TRUE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; } - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); - 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(testInterval, allLimits[i].interval); - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_EQ(0, allLimits[i].interval); - } - EXPECT_EQ(testLimit, allLimits[i].limit); + } + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); + 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(testInterval, allLimits[i].interval); + } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_EQ(0, allLimits[i].interval); } + EXPECT_EQ(testLimit, allLimits[i].limit); } } HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsDG1) { - auto handles = getPowerHandles(powerHandleComponentCount); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); - uint32_t limitCount = 0; - const int32_t testLimit = 300000; - const int32_t testInterval = 10; + uint32_t limitCount = 0; + const int32_t testLimit = 300000; + const int32_t testInterval = 10; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, singleLimitCount); - limitCount++; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + limitCount++; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, singleLimitCount); - std::vector allLimits(limitCount); - 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_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_FALSE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - allLimits[i].interval = testInterval; - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_TRUE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - } + std::vector allLimits(limitCount); + 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_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_FALSE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + allLimits[i].interval = testInterval; } - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); - 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(testInterval, allLimits[i].interval); - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_EQ(0, allLimits[i].interval); - } - EXPECT_EQ(testLimit, allLimits[i].limit); + } + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); + 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(testInterval, allLimits[i].interval); } + EXPECT_EQ(testLimit, allLimits[i].limit); } } -TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerLimitNodeReturnErrorWhenSetOrGetPowerLimitsWhenHwmonInterfaceExistForSustainedPowerLimitEnabledThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerLimitNodeFailsWhenSetOrGetPowerLimitsIsCalledForSustainedPowerLimitThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); @@ -379,162 +427,112 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerLimitNodeReturnEr } } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToSustainedLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToSustainedLimitSysNodeFailsWhenCallingSetPowerLimitsExtThenProperErrorCodeIsReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); - 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.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); - } + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = maxLimitCountSupported; + std::vector allLimits(maxLimitCountSupported); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); + pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToSustainedLimitIntervalSysNodeFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToSustainedLimitIntervalSysNodeFailsWhenCallingSetPowerLimitsExtThenProperErrorCodeIsReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); 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())); - } + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = maxLimitCountSupported; + std::vector allLimits(maxLimitCountSupported); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndReadingToSustainedLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); - - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - uint32_t count = mockLimitCount; - std::vector allLimits(mockLimitCount); - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - 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())); - } -} - -TEST_F(SysmanDevicePowerFixtureI915, GivenReadingToSysNodesFailsWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) { - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndReadingFromSustainedLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = maxLimitCountSupported; + std::vector allLimits(maxLimitCountSupported); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - - auto handles = getPowerHandles(powerHandleComponentCount); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - uint32_t count = 0; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr)); - EXPECT_EQ(count, 0u); - } + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + count = maxLimitCountSupported; + pSysfsAccess->mockReadIntResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenReadingFromSysNodesFailsWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) { + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + pSysfsAccess->isCriticalPowerLimitFilePresent = false; - pSysfsAccess->mockWritePeakLimitResult = 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())); - } + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr)); + EXPECT_EQ(count, 0u); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndReadingToPeakLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); - +HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndReadingToPeakLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned, IsPVC) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockReadPeakResult = 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_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); - } + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = maxLimitCountSupported; + std::vector allLimits(maxLimitCountSupported); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data())); } TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenSettingBurstPowerLimitThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); - + auto handles = getPowerHandles(i915PowerHandleComponentCount); for (auto handle : handles) { ASSERT_NE(nullptr, handle); zes_power_limit_ext_desc_t allLimits{}; uint32_t count = 1; allLimits.level = ZES_POWER_LEVEL_BURST; - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, &allLimits)); } } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenProperValuesAreReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenOnlySustainedLimitIsReturned, IsDG1) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + zes_power_limit_ext_desc_t allLimits{}; + uint32_t count = 0; - 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, singleLimitCount); - 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(ZES_POWER_LEVEL_SUSTAINED, allLimits.level); - } + count = 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, &allLimits)); + EXPECT_EQ(count, 1u); + ASSERT_EQ(ZES_POWER_LEVEL_SUSTAINED, allLimits.level); + 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); } HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned, IsPVC) { - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockWritePeakLimitResult = 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())); - } + auto handle = handles[0]; + ASSERT_NE(nullptr, handle); + uint32_t count = maxLimitCountSupported; + std::vector allLimits(maxLimitCountSupported); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data())); } -HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned, IsDG1) { - auto handles = getPowerHandles(powerHandleComponentCount); - - pSysfsAccess->mockWritePeakLimitResult = 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())); - } -} - -TEST_F(SysmanDevicePowerFixtureI915, GivenReadingPeakPowerLimitNodeReturnErrorWhenSetOrGetPowerLimitsWhenHwmonInterfaceExistForPeakPowerLimitEnabledThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenReadingPeakPowerLimitNodeFailsWhenSetOrGetPowerLimitsIsCalledForPeakPowerLimitThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); @@ -549,8 +547,8 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenReadingPeakPowerLimitNodeReturnErrorWh } } -TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerNodeReturnErrorWhenGetPowerLimitsForSustainedPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerNodeReturnErrorWhenGetPowerLimitsForSustainedPowerThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { @@ -560,8 +558,8 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenReadingSustainedPowerNodeReturnErrorWh } } -TEST_F(SysmanDevicePowerFixtureI915, GivenReadingpeakPowerNodeReturnErrorWhenGetPowerLimitsForpeakPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenReadingpeakPowerNodeReturnErrorWhenGetPowerLimitsForpeakPowerThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); for (auto handle : handles) { @@ -572,7 +570,7 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenReadingpeakPowerNodeReturnErrorWhenGet } HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPermissionsThenFirstDisableSustainedPowerLimitAndThenEnableItAndCheckSuccesIsReturned, IsXeHpOrXeHpcOrXeHpgCore) { - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); ASSERT_NE(nullptr, handles[0]); zes_power_sustained_limit_t sustainedSet = {}; zes_power_sustained_limit_t sustainedGet = {}; @@ -584,8 +582,8 @@ HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleAndPermissionsThenF EXPECT_EQ(sustainedGet.power, sustainedSet.power); } -TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerNodeReturnErrorWhenSetPowerLimitsForSustainedPowerWhenHwmonInterfaceExistThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerNodeReturnErrorWhenSetPowerLimitsForSustainedPowerThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); ASSERT_NE(nullptr, handles[0]); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); @@ -596,8 +594,8 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerNodeReturnErrorWh EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr)); } -TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerIntervalNodeReturnErrorWhenSetPowerLimitsForSustainedPowerIntervalWhenHwmonInterfaceExistThenProperErrorCodesReturned) { - auto handles = getPowerHandles(powerHandleComponentCount); +TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerIntervalNodeFailsWhenSetPowerLimitsForSustainedPowerIntervalThenProperErrorCodesReturned) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); ASSERT_NE(nullptr, handles[0]); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); @@ -609,7 +607,7 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenwritingSustainedPowerIntervalNodeRetur } HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenWritingToSustainedPowerEnableNodeWithoutPermissionsThenValidErrorIsReturned, IsXeHpOrXeHpcOrXeHpgCore) { - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); ASSERT_NE(nullptr, handles[0]); pSysfsAccess->mockWriteUnsignedResult.push_back(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS); @@ -618,38 +616,57 @@ HWTEST2_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenWritingToSustai EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr)); } -TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesThenCallSucceeds) { - - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - 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); - } +TEST_F(SysmanDevicePowerFixtureI915, GivenHwmonDirectoriesArePresentAndPowerLimitFilesDontExistThenPowerModuleIsNotSupported) { + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + pSysfsAccess->isCriticalPowerLimitFilePresent = false; + pSysfsAccess->isEnergyCounterFilePresent = false; + auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount(); + ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true; + uint32_t subdeviceId = 0; + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_CARD); + EXPECT_FALSE(pPowerImp->isPowerModuleSupported()); + pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_PACKAGE); + EXPECT_FALSE(pPowerImp->isPowerModuleSupported()); } -TEST_F(SysmanDevicePowerFixtureI915, GivenHwMonDoesNotExistAndTelemDataNotAvailableWhenGettingPowerEnergyCounterThenFailureIsReturned) { - 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_NOT_AVAILABLE, zesPowerGetEnergyCounter(handle, &energyCounter)); - } +TEST_F(SysmanDevicePowerFixtureI915, GivenHwmonDirectoriesArePresentAndAtLeastOnePowerLimitFileExistsThenPowerModuleIsSupportedForCardDomain) { + auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount(); + ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true; + uint32_t subdeviceId = 0; + + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_CARD); + + pSysfsAccess->isSustainedPowerLimitFilePresent = true; + pSysfsAccess->isCriticalPowerLimitFilePresent = false; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); + + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + pSysfsAccess->isCriticalPowerLimitFilePresent = true; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); + + pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_CARD); + + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + pSysfsAccess->isCriticalPowerLimitFilePresent = false; + pSysfsAccess->isEnergyCounterFilePresent = true; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); +} + +TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesThenCallSucceeds) { + auto handles = getPowerHandles(i915PowerHandleComponentCount); + + auto handle = handles[0]; + 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); } TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerEnergyThresholdThenUnsupportedFeatureErrorIsReturned) { - + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); zes_energy_threshold_t threshold; - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); for (auto handle : handles) { ASSERT_NE(nullptr, handle); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetEnergyThreshold(handle, &threshold)); @@ -657,22 +674,14 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerEnergy } TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenSettingPowerEnergyThresholdThenUnsupportedFeatureErrorIsReturned) { - + pSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); double threshold = 0; - auto handles = getPowerHandles(powerHandleComponentCount); + auto handles = getPowerHandles(i915PowerHandleComponentCount); for (auto handle : handles) { EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetEnergyThreshold(handle, threshold)); } } -TEST_F(SysmanDevicePowerFixtureXe, GivenKmdInterfaceWhenGettingSysFsFilenamesForPowerForXeVersionThenProperPathsAreReturned) { - auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getSysmanProductHelper()); - EXPECT_STREQ("energy1_input", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEnergyCounterNode, 0, false).c_str()); - EXPECT_STREQ("power1_rated_max", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, 0, false).c_str()); - EXPECT_STREQ("power1_max", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimit, 0, false).c_str()); - EXPECT_STREQ("power1_max_interval", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimitInterval, 0, false).c_str()); -} - } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper.cpp b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper.cpp index d760966e88..da8be3bceb 100644 --- a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper.cpp +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_helper.cpp @@ -11,32 +11,29 @@ namespace L0 { namespace Sysman { namespace ult { -constexpr uint32_t powerHandleComponentCount = 1u; +constexpr uint32_t powerHandleComponentCount = 2u; using SysmanDevicePowerFixtureHelper = SysmanDevicePowerFixtureI915; -TEST_F(SysmanDevicePowerFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) { - +TEST_F(SysmanDevicePowerFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterAndPmtSupportIsNotAvailableThenValidPowerReadingsRetrievedFromSysfsNode) { auto handles = getPowerHandles(powerHandleComponentCount); for (auto handle : handles) { - zes_power_energy_counter_t energyCounter = {}; - ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); - EXPECT_EQ(energyCounter.energy, expectedEnergyCounter); + if (handle != nullptr) { + zes_power_energy_counter_t energyCounter = {}; + ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + EXPECT_EQ(energyCounter.energy, expectedEnergyCounter); + } } } constexpr uint32_t powerHandleComponentCountMultiDevice = 3u; using SysmanDevicePowerMultiDeviceFixtureHelper = SysmanDevicePowerMultiDeviceFixture; -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidDeviceHandlesAndHwmonInterfaceExistThenSuccessIsReturned) { - auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount(); +TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenPowerHandleWithUnknownPowerDomainThenPowerModuleIsNotSupported) { uint32_t subdeviceId = 0; - do { - ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true; - PublicLinuxPowerImp *pPowerImp = new PublicLinuxPowerImp(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_CARD); - EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); - delete pPowerImp; - - } while (++subdeviceId < subDeviceCount); + ze_bool_t onSubdevice = false; + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_UNKNOWN); + pPowerImp->pSysfsAccess = pSysfsAccess; + EXPECT_FALSE(pPowerImp->isPowerModuleSupported()); } TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenInvalidComponentCountWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { @@ -49,7 +46,7 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenInvalidComponentCountWhen EXPECT_EQ(count, powerHandleComponentCountMultiDevice); } -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerPointerWhenGettingCardPowerDomainWhenhwmonInterfaceExistsAndThenCallSucceeds) { +TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerPointerWhenGettingCardPowerDomainWhenhwmonInterfaceExistsThenCallSucceeds) { zes_pwr_handle_t phPower = {}; EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_SUCCESS); } @@ -102,13 +99,14 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGetti EXPECT_EQ(defaultLimit.level, ZES_POWER_LEVEL_UNKNOWN); EXPECT_EQ(defaultLimit.source, ZES_POWER_SOURCE_ANY); EXPECT_EQ(defaultLimit.limitUnit, ZES_LIMIT_UNIT_POWER); + if (properties.onSubdevice) { - EXPECT_FALSE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_PACKAGE); + EXPECT_FALSE(properties.canControl); EXPECT_EQ(defaultLimit.limit, -1); } else { - EXPECT_TRUE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_CARD); + EXPECT_TRUE(properties.canControl); EXPECT_EQ(defaultLimit.limit, static_cast(mockDefaultPowerLimitVal / milliFactor)); EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); @@ -133,15 +131,16 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleAndExtPro properties.pNext = &extProperties; extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + if (properties.onSubdevice) { - EXPECT_FALSE(properties.canControl); EXPECT_EQ(extProperties.domain, ZES_POWER_DOMAIN_PACKAGE); + EXPECT_FALSE(properties.canControl); 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_TRUE(properties.canControl); EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); EXPECT_EQ(properties.minLimit, -1); @@ -150,72 +149,35 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleAndExtPro } } -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenScanDirectoriesFailAndTelemetrySupportNotAvailableWhenGettingCardPowerThenFailureIsReturned) { - - pSysfsAccess->mockscanDirEntriesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; - - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); - - zes_pwr_handle_t phPower = {}; - EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); -} - -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenPowerHandleDomainIsNotCardWhenGettingCardPowerDomainThenErrorIsReturned) { - uint32_t count = 0; - EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, powerHandleComponentCountMultiDevice); - - auto handle = pSysmanDeviceImp->pPowerHandleContext->handleList.front(); - delete handle; - - pSysmanDeviceImp->pPowerHandleContext->handleList.erase(pSysmanDeviceImp->pPowerHandleContext->handleList.begin()); - zes_pwr_handle_t phPower = {}; - EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); -} - -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenReadingToSysNodesFailsWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) { - for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { - delete handle; - } - pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); - pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); +TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenSysfsPowerLimitsAreNotPresentWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) { + pSysfsAccess->isSustainedPowerLimitFilePresent = false; + pSysfsAccess->isCriticalPowerLimitFilePresent = false; auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); for (auto handle : handles) { ASSERT_NE(nullptr, handle); uint32_t count = 0; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr)); + std::vector allLimits(maxLimitCountSupported); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data())); EXPECT_EQ(count, 0u); } } -TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) { +TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterAndPmtSupportIsNotAvailableThenValidPowerReadingsRetrievedFromSysfsNode) { auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); - for (auto handle : handles) { ASSERT_NE(nullptr, handle); - zes_power_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); zes_power_energy_counter_t energyCounter = {}; ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); - if (properties.subdeviceId == 0) { - EXPECT_EQ(energyCounter.energy, expectedEnergyCounterTile0); - } else if (properties.subdeviceId == 1) { - EXPECT_EQ(energyCounter.energy, expectedEnergyCounterTile1); - } + EXPECT_EQ(energyCounter.energy, expectedEnergyCounterTileVal); } } -HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsXeHpOrXeHpcOrXeHpgCore) { +HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsPVC) { auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); for (auto handle : handles) { ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); @@ -258,7 +220,6 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); for (auto handle : handles) { ASSERT_NE(nullptr, handle); - uint32_t limitCount = 0; const int32_t testLimit = 300000; const int32_t testInterval = 10; @@ -269,7 +230,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC if (!properties.onSubdevice) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + EXPECT_EQ(limitCount, maxLimitCountSupported); } else { EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, &limits)); EXPECT_EQ(limitCount, 0u); @@ -278,7 +239,7 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC limitCount++; if (!properties.onSubdevice) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); + EXPECT_EQ(limitCount, maxLimitCountSupported); } else { EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); EXPECT_EQ(limitCount, 0u); @@ -326,77 +287,6 @@ HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenC } } -HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsDG1) { - auto handles = getPowerHandles(powerHandleComponentCountMultiDevice); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - uint32_t limitCount = 0; - const int32_t testLimit = 300000; - const int32_t testInterval = 10; - - zes_power_properties_t properties = {}; - zes_power_limit_ext_desc_t limits = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); - - if (!properties.onSubdevice) { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); - } else { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, &limits)); - EXPECT_EQ(limitCount, 0u); - } - - limitCount++; - if (!properties.onSubdevice) { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, mockLimitCount); - } else { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); - EXPECT_EQ(limitCount, 0u); - } - - std::vector allLimits(limitCount); - if (!properties.onSubdevice) { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); - } else { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); - EXPECT_EQ(limitCount, 0u); - } - for (uint32_t i = 0; i < limitCount; i++) { - if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) { - EXPECT_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_FALSE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - allLimits[i].interval = testInterval; - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_FALSE(allLimits[i].limitValueLocked); - EXPECT_TRUE(allLimits[i].enabledStateLocked); - EXPECT_TRUE(allLimits[i].intervalValueLocked); - EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); - EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); - allLimits[i].limit = testLimit; - } - } - if (!properties.onSubdevice) { - EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); - 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(testInterval, allLimits[i].interval); - } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { - EXPECT_EQ(0, allLimits[i].interval); - } - EXPECT_EQ(testLimit, allLimits[i].limit); - } - } else { - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); - } - } -} - } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_xe.cpp b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_xe.cpp new file mode 100644 index 0000000000..68ceed3f23 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power_xe.cpp @@ -0,0 +1,596 @@ +/* + * Copyright (C) 2020-2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/linux/mocks/mock_sysman_product_helper.h" +#include "level_zero/sysman/test/unit_tests/sources/power/linux/mock_sysfs_power_xe.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +static constexpr uint32_t powerHandleComponentCount = 2u; +static constexpr uint32_t singleLimitCount = 1u; +static constexpr uint32_t maxLimitCountSupported = 2u; + +TEST_F(SysmanDevicePowerFixtureXe, GivenKmdInterfaceWhenGettingSysFsFilenamesForPowerForXeVersionThenProperPathsAreReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); + EXPECT_STREQ("energy1_input", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEnergyCounterNode, 0, false).c_str()); + EXPECT_STREQ("power1_rated_max", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, 0, false).c_str()); + EXPECT_STREQ("power1_max", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimit, 0, false).c_str()); + EXPECT_STREQ("power1_max_interval", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameSustainedPowerLimitInterval, 0, false).c_str()); +} + +HWTEST2_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesArePresentAndAtLeastOneOfThePowerLimitFilesExistsThenPowerModuleForCardPowerDomainIsSupported, IsPVC) { + auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD); + + // Loop through all combinations of the three boolean flags (true/false) for the file existence + for (bool isCardEnergyCounterFilePresent : {false, true}) { + for (bool isSustainedPowerLimitFilePresent : {false, true}) { + for (bool isCriticalPowerLimitFilePresent : {false, true}) { + // Set the file existence flags based on the current combination + pSysfsAccess->isCardEnergyCounterFilePresent = isCardEnergyCounterFilePresent; + pSysfsAccess->isSustainedPowerLimitFilePresent = isSustainedPowerLimitFilePresent; + pSysfsAccess->isCriticalPowerLimitFilePresent = isCriticalPowerLimitFilePresent; + + // The expected result is true if at least one of the files is present + bool expected = isCardEnergyCounterFilePresent || isSustainedPowerLimitFilePresent || isCriticalPowerLimitFilePresent; + + // Verify if the power module is supported as expected + EXPECT_EQ(pPowerImp->isPowerModuleSupported(), expected); + } + } + } +} + +HWTEST2_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesArePresentAndAtLeastOneOfThePowerLimitFilesExistsThenPowerModuleForCardPowerDomainIsSupported, IsNotPVC) { + auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD); + + pSysfsAccess->isCriticalPowerLimitFilePresent = false; + // Loop through all combinations of the three boolean flags (true/false) for the file existence + for (bool isCardEnergyCounterFilePresent : {false, true}) { + for (bool isSustainedPowerLimitFilePresent : {false, true}) { + // Set the file existence flags based on the current combination + pSysfsAccess->isCardEnergyCounterFilePresent = isCardEnergyCounterFilePresent; + pSysfsAccess->isSustainedPowerLimitFilePresent = isSustainedPowerLimitFilePresent; + + // The expected result is true if at least one of the files is present + bool expected = isCardEnergyCounterFilePresent || isSustainedPowerLimitFilePresent; + + // Verify if the power module is supported as expected + EXPECT_EQ(pPowerImp->isPowerModuleSupported(), expected); + } + } +} + +HWTEST2_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesArePresentAndAtLeastOneOfThePowerLimitFilesExistsThenPowerModuleForPackagePowerDomainIsSupported, IsPVC) { + auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_PACKAGE); + + // Loop through all combinations of the three boolean flags (true/false) for the file existence + for (bool isPackageEnergyCounterFilePresent : {false, true}) { + for (bool isPackagedSustainedPowerLimitFilePresent : {false, true}) { + for (bool isPackageCriticalPowerLimit2Present : {false, true}) { + // Set the file existence flags based on the current combination + pSysfsAccess->isPackageEnergyCounterFilePresent = isPackageEnergyCounterFilePresent; + pSysfsAccess->isPackagedSustainedPowerLimitFilePresent = isPackagedSustainedPowerLimitFilePresent; + pSysfsAccess->isPackageCriticalPowerLimit2Present = isPackageCriticalPowerLimit2Present; + + // The expected result is true if at least one of the files is present + bool expected = isPackageEnergyCounterFilePresent || isPackagedSustainedPowerLimitFilePresent || isPackageCriticalPowerLimit2Present; + + // Verify if the power module is supported as expected + EXPECT_EQ(pPowerImp->isPowerModuleSupported(), expected); + } + } + } +} + +HWTEST2_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesArePresentAndAtLeastOneOfThePowerLimitFilesExistsThenPowerModuleForPackagePowerDomainIsSupported, IsNotPVC) { + auto pPowerImp = std::make_unique(pOsSysman, false, 0, ZES_POWER_DOMAIN_PACKAGE); + + // Loop through all combinations of the three boolean flags (true/false) for the file existence + for (bool isPackageEnergyCounterFilePresent : {false, true}) { + for (bool isPackagedSustainedPowerLimitFilePresent : {false, true}) { + for (bool isPackageCriticalPowerLimit1Present : {false, true}) { + // Set the file existence flags based on the current combination + pSysfsAccess->isPackageEnergyCounterFilePresent = isPackageEnergyCounterFilePresent; + pSysfsAccess->isPackagedSustainedPowerLimitFilePresent = isPackagedSustainedPowerLimitFilePresent; + pSysfsAccess->isPackageCriticalPowerLimit1Present = isPackageCriticalPowerLimit1Present; + + // The expected result is true if at least one of the files is present + bool expected = isPackageEnergyCounterFilePresent || isPackagedSustainedPowerLimitFilePresent || isPackageCriticalPowerLimit1Present; + + // Verify if the power module is supported as expected + EXPECT_EQ(pPowerImp->isPowerModuleSupported(), expected); + } + } + } +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenComponentCountZeroWhenEnumeratingPowerDomainsWhenhwmonInterfaceExistsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandlesForPackageDomainWhenGetCardPowerDomainIsCalledThenErrorIsReturned) { + + auto handles = getPowerHandles(powerHandleComponentCount); + pSysmanDeviceImp->pPowerHandleContext->handleList.erase(std::remove_if(pSysmanDeviceImp->pPowerHandleContext->handleList.begin(), + pSysmanDeviceImp->pPowerHandleContext->handleList.end(), [](L0::Sysman::Power *powerHandle) { + if (powerHandle->isCardPower) { + delete powerHandle; + return true; + } + return false; + }), + pSysmanDeviceImp->pPowerHandleContext->handleList.end()); + zes_pwr_handle_t phPower = {}; + EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenPowerHandleWithPackageDomainThenPowerModuleIsSupported) { + ze_bool_t onSubdevice = false; + uint32_t subdeviceId = 0; + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_PACKAGE); + pPowerImp->pSysfsAccess = pSysfsAccess; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenPowerHandleWithUnknownPowerDomainThenPowerModuleIsNotSupported) { + ze_bool_t onSubdevice = false; + uint32_t subdeviceId = 0; + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_UNKNOWN); + pPowerImp->pSysfsAccess = pSysfsAccess; + EXPECT_FALSE(pPowerImp->isPowerModuleSupported()); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenPowerHandleWithPackageDomainAndHwmonExistsAndSustainedPowerLimitFileIsNotPresentThenPowerModuleIsSupported) { + ze_bool_t onSubdevice = false; + uint32_t subdeviceId = 0; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_PACKAGE); + pPowerImp->pSysfsAccess = pSysfsAccess; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenPowerHandleWithPackageDomainAndHwmonExistsAndCriticalPowerLimitFileIsNotPresentThenPowerModuleIsSupported) { + ze_bool_t onSubdevice = false; + uint32_t subdeviceId = 0; + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + auto pPowerImp = std::make_unique(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_PACKAGE); + pPowerImp->pSysfsAccess = pSysfsAccess; + EXPECT_TRUE(pPowerImp->isPowerModuleSupported()); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesDoesNotExistWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysfsAccess->mockScanDirEntriesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenHwmonDirectoriesDoNotContainNameFileWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysfsAccess->mockReadResult = ZE_RESULT_ERROR_NOT_AVAILABLE; + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenEnergyCounterNodeIsNotAvailableWhenGettingPowerHandlesThenNoHandlesAreReturned) { + pSysmanKmdInterface->isEnergyNodeAvailable = false; + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandleWhenGettingPowerPropertiesWhenhwmonInterfaceExistsThenCallSucceeds) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); + + for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); + 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.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, static_cast(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); + } +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandleWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceedsForCardDomain) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); + + for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); + auto handles = getPowerHandles(powerHandleComponentCount); + std::vector mockPowerDomains = {ZES_POWER_DOMAIN_CARD, ZES_POWER_DOMAIN_PACKAGE}; + uint32_t count = 0; + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + + extProperties.defaultLimit = &defaultLimit; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + properties.pNext = &extProperties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(properties.subdeviceId, 0u); + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(extProperties.domain, mockPowerDomains[count++]); + EXPECT_TRUE(defaultLimit.limitValueLocked); + EXPECT_TRUE(defaultLimit.enabledStateLocked); + EXPECT_TRUE(defaultLimit.intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, defaultLimit.source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, defaultLimit.limitUnit); + EXPECT_EQ(defaultLimit.limit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + } +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandleWithNoStypeForExtPropertiesWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); + + for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + + extProperties.defaultLimit = &defaultLimit; + properties.pNext = &extProperties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(properties.subdeviceId, 0u); + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); + } +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandleWithNoDefaultLimitStructureForExtPropertiesWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); + + for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(properties.subdeviceId, 0u); + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.minLimit, -1); + } +} + +TEST_F(SysmanDevicePowerFixtureXe, GivenInvalidComponentCountWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + count = count + 1; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); +} + +HWTEST2_F(SysmanMultiDevicePowerFixtureXe, GivenInvalidComponentCountWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds, IsPVC) { + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + count = count + 1; + EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); +} + +TEST_F(SysmanMultiDevicePowerFixtureXe, GivenValidPowerHandleWhenGettingPowerPropertiesThenCallSucceeds) { + MockSysmanProductHelper *pMockSysmanProductHelper = new MockSysmanProductHelper(); + pMockSysmanProductHelper->isPowerSetLimitSupportedResult = true; + std::unique_ptr pSysmanProductHelper(static_cast(pMockSysmanProductHelper)); + std::swap(pLinuxSysmanImp->pSysmanProductHelper, pSysmanProductHelper); + + for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pPowerHandleContext->handleList.clear(); + pSysmanDeviceImp->pPowerHandleContext->init(pLinuxSysmanImp->getSubDeviceCount()); + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + if (handle) { + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + zes_power_limit_ext_desc_t defaultLimit = {}; + + extProperties.defaultLimit = &defaultLimit; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + properties.pNext = &extProperties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + EXPECT_EQ(properties.minLimit, -1); + EXPECT_EQ(properties.isEnergyThresholdSupported, false); + EXPECT_TRUE(defaultLimit.limitValueLocked); + EXPECT_TRUE(defaultLimit.enabledStateLocked); + EXPECT_TRUE(defaultLimit.intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, defaultLimit.source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, defaultLimit.limitUnit); + if (properties.onSubdevice) { + EXPECT_EQ(properties.canControl, false); + EXPECT_EQ(properties.defaultLimit, -1); + EXPECT_EQ(properties.maxLimit, -1); + EXPECT_EQ(defaultLimit.limit, -1); + } else { + EXPECT_EQ(properties.canControl, true); + EXPECT_EQ(properties.defaultLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(properties.maxLimit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + EXPECT_EQ(defaultLimit.limit, (int32_t)(mockDefaultPowerLimitVal / milliFactor)); + } + } + } +} + +HWTEST2_F(SysmanMultiDevicePowerFixtureXe, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsPVC) { + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + if (handle) { + zes_power_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + zes_power_sustained_limit_t sustainedSet = {}; + zes_power_sustained_limit_t sustainedGet = {}; + sustainedSet.power = 300000; + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + EXPECT_EQ(sustainedGet.power, sustainedSet.power); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + } + + zes_power_burst_limit_t burstGet = {}; + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + EXPECT_EQ(burstGet.enabled, false); + EXPECT_EQ(burstGet.power, -1); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + } + + zes_power_peak_limit_t peakSet = {}; + zes_power_peak_limit_t peakGet = {}; + peakSet.powerAC = 300000; + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + EXPECT_EQ(peakGet.powerAC, peakSet.powerAC); + EXPECT_EQ(peakGet.powerDC, -1); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + } + } + } +} + +HWTEST2_F(SysmanMultiDevicePowerFixtureXe, GivenSetPowerLimitsWhenGettingPowerLimitsThenLimitsSetEarlierAreRetrieved, IsBMG) { + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + if (handle) { + auto phPower = Power::fromHandle(handle); + zes_power_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + zes_power_sustained_limit_t sustainedSet = {}; + zes_power_sustained_limit_t sustainedGet = {}; + sustainedSet.power = 300000; + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + EXPECT_EQ(sustainedGet.power, sustainedSet.power); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, &sustainedGet, nullptr, nullptr)); + } + + zes_power_burst_limit_t burstGet = {}; + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + EXPECT_EQ(burstGet.enabled, false); + EXPECT_EQ(burstGet.power, -1); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, &burstGet, nullptr)); + } + + zes_power_peak_limit_t peakSet = {}; + zes_power_peak_limit_t peakGet = {}; + peakSet.powerAC = 300000; + if (!properties.onSubdevice) { + if (!phPower->isCardPower) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + EXPECT_EQ(peakGet.powerAC, peakSet.powerAC); + EXPECT_EQ(peakGet.powerDC, -1); + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handle, nullptr, nullptr, &peakSet)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + } + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimits(handle, nullptr, nullptr, &peakGet)); + } + } + } +} + +HWTEST2_F(SysmanMultiDevicePowerFixtureXe, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsPVC) { + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + if (handle) { + uint32_t limitCount = 0; + const int32_t testLimit = 300000; + const int32_t testInterval = 10; + + zes_power_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, maxLimitCountSupported); + + limitCount++; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, maxLimitCountSupported); + + std::vector allLimits(limitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); + EXPECT_EQ(limitCount, maxLimitCountSupported); + + for (uint32_t i = 0; i < limitCount; i++) { + if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) { + EXPECT_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_FALSE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + allLimits[i].interval = testInterval; + } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_TRUE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + } + } + if (!properties.onSubdevice) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); + 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(testInterval, allLimits[i].interval); + } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_EQ(0, allLimits[i].interval); + } + EXPECT_EQ(testLimit, allLimits[i].limit); + } + } else { + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); + } + } + } +} + +HWTEST2_F(SysmanDevicePowerFixtureXe, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsBMG) { + auto handles = getPowerHandles(powerHandleComponentCount); + for (auto handle : handles) { + if (handle) { + auto phPower = Power::fromHandle(handle); + uint32_t limitCount = 0; + const int32_t testLimit = 300000; + const int32_t testInterval = 10; + + zes_power_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, phPower->isCardPower ? singleLimitCount : maxLimitCountSupported); + + limitCount++; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr)); + EXPECT_EQ(limitCount, phPower->isCardPower ? singleLimitCount : maxLimitCountSupported); + + std::vector allLimits(limitCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data())); + EXPECT_EQ(limitCount, phPower->isCardPower ? singleLimitCount : maxLimitCountSupported); + + for (uint32_t i = 0; i < limitCount; i++) { + if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) { + EXPECT_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_FALSE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + allLimits[i].interval = testInterval; + } else if (!phPower->isCardPower && allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_FALSE(allLimits[i].limitValueLocked); + EXPECT_TRUE(allLimits[i].enabledStateLocked); + EXPECT_TRUE(allLimits[i].intervalValueLocked); + EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source); + EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit); + allLimits[i].limit = testLimit; + } + } + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data())); + 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(testInterval, allLimits[i].interval); + } else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) { + EXPECT_EQ(0, allLimits[i].interval); + } + EXPECT_EQ(testLimit, allLimits[i].limit); + } + } + } +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_i915.h b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_i915.h index db734b4c7d..0cd5039aee 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_i915.h +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_i915.h @@ -20,6 +20,17 @@ class MockSysmanKmdInterfacePrelim : public L0::Sysman::SysmanKmdInterfaceI915Pr using L0::Sysman::SysmanKmdInterface::pSysfsAccess; MockSysmanKmdInterfacePrelim(SysmanProductHelper *pSysmanProductHelper) : SysmanKmdInterfaceI915Prelim(pSysmanProductHelper) {} ~MockSysmanKmdInterfacePrelim() override = default; + bool isEnergyNodeAvailable = true; + + std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) override { + if ((isSubdevice && powerDomain == ZES_POWER_DOMAIN_PACKAGE) || (!isSubdevice && powerDomain == ZES_POWER_DOMAIN_CARD)) { + return isEnergyNodeAvailable ? "energy1_input" : ""; + } else if (powerDomain == ZES_POWER_DOMAIN_UNKNOWN) { + return "invalidNode"; + } + + return ""; + } }; class MockSysmanKmdInterfaceUpstream : public L0::Sysman::SysmanKmdInterfaceI915Upstream { diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h index f1ecfc6bfb..f56bfdf81f 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h @@ -19,8 +19,21 @@ class MockSysmanKmdInterfaceXe : public L0::Sysman::SysmanKmdInterfaceXe { using L0::Sysman::SysmanKmdInterface::pSysfsAccess; MockSysmanKmdInterfaceXe(SysmanProductHelper *pSysmanProductHelper) : SysmanKmdInterfaceXe(pSysmanProductHelper) {} ~MockSysmanKmdInterfaceXe() override = default; + bool isEnergyNodeAvailable = true; ADDMETHOD_NOBASE(getEngineActivityFd, int64_t, -1, (zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface)); + + std::string getEnergyCounterNodeFilePath(bool isSubdevice, zes_power_domain_t powerDomain) override { + if (powerDomain == ZES_POWER_DOMAIN_CARD) { + return isEnergyNodeAvailable ? "energy1_input" : ""; + } else if (powerDomain == ZES_POWER_DOMAIN_PACKAGE) { + return isEnergyNodeAvailable ? "energy2_input" : ""; + } else if (powerDomain == ZES_POWER_DOMAIN_UNKNOWN) { + return "invalidNode"; + } + + return ""; + } }; } // namespace ult diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_prelim.cpp index 3078c2113b..ca688c50c3 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_prelim.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_prelim.cpp @@ -236,6 +236,22 @@ TEST_F(SysmanFixtureDeviceI915Prelim, GivenSysmanKmdInterfaceInstanceWhenCheckin EXPECT_TRUE(pSysmanKmdInterface->isVfEngineUtilizationSupported()); } +TEST_F(SysmanFixtureDeviceI915Prelim, GivenSysmanKmdInterfaceWhenGetEnergyCounterNodeFilePathIsCalledForDifferentPowerDomainsThenProperPathIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + std::string expectedFilePath = "energy1_input"; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_PACKAGE)); + expectedFilePath = ""; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_PACKAGE)); +} + +TEST_F(SysmanFixtureDeviceI915Prelim, GivenSysmanKmdInterfaceWhenIsPowerSupportForSubdeviceAvailableIsCalledForDifferentPowerDomainsThenProperValueIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_TRUE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_FALSE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_CARD)); +} + } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_upstream.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_upstream.cpp index 6f2a8b9d2a..d341c1a962 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_upstream.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_i915_upstream.cpp @@ -248,6 +248,22 @@ TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceInstanceWhenGetti EXPECT_EQ(pSysmanKmdInterface->getBusyAndTotalTicksConfigs(0, 0, 1, configPair), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); } +TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceWhenGetEnergyCounterNodeFilePathIsCalledForDifferentPowerDomainsThenProperPathIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + std::string expectedFilePath = "energy1_input"; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_PACKAGE)); + expectedFilePath = ""; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_PACKAGE)); +} + +TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceWhenIsPowerSupportForSubdeviceAvailableIsCalledForDifferentPowerDomainsThenProperValueIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_TRUE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_FALSE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_CARD)); +} + } // namespace ult } // namespace Sysman } // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp index 2586c08f8e..6180704ffb 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp @@ -173,6 +173,25 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenCheckingWhetherClientIn EXPECT_TRUE(pSysmanKmdInterface->clientInfoAvailableInFdInfo()); } +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenGetEnergyCounterNodeFilePathIsCalledForDifferentPowerDomainsThenProperPathIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + std::string expectedFilePath = "energy1_input"; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_CARD)); + expectedFilePath = "energy2_input"; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_PACKAGE)); + expectedFilePath = ""; + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(true, ZES_POWER_DOMAIN_UNKNOWN)); + EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFilePath(false, ZES_POWER_DOMAIN_UNKNOWN)); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenIsPowerSupportForSubdeviceAvailableIsCalledForDifferentPowerDomainsThenFalseValueIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_FALSE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_FALSE(pSysmanKmdInterface->isPowerSupportForSubdeviceAvailable(ZES_POWER_DOMAIN_CARD)); +} + TEST_F(SysmanFixtureDeviceXe, GivenGroupEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdIsCalledThenInValidFdIsReturned) { auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); 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 d019617121..32d718b221 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 @@ -18,10 +18,8 @@ using SysmanProductHelperPowerTest = SysmanDeviceFixture; constexpr uint32_t powerHandleComponentCount = 1u; static int mockReadLinkSuccess(const char *path, char *buf, size_t bufsize) { - std::map fileNameLinkMap = { - {sysfsPathTelem, realPathTelem}, - }; + {sysfsPathTelem1, realPathTelem1}}; auto it = fileNameLinkMap.find(std::string(path)); if (it != fileNameLinkMap.end()) { std::memcpy(buf, it->second.c_str(), it->second.size()); @@ -30,6 +28,39 @@ static int mockReadLinkSuccess(const char *path, char *buf, size_t bufsize) { return -1; } +static int mockReadLinkFailure(const char *path, char *buf, size_t bufsize) { + errno = ENOENT; + return -1; +} + +static int mockMultiDeviceReadLinkSuccess(const char *path, char *buf, size_t bufsize) { + std::map fileNameLinkMap = { + {sysfsPathTelem1, realPathTelem1}, + {sysfsPathTelem2, realPathTelem2}, + {sysfsPathTelem3, realPathTelem3}}; + auto it = fileNameLinkMap.find(std::string(path)); + if (it != fileNameLinkMap.end()) { + std::memcpy(buf, it->second.c_str(), it->second.size()); + return static_cast(it->second.size()); + } + return -1; +} + +static int mockOpenSuccess(const char *pathname, int flags) { + int returnValue = -1; + std::string strPathName(pathname); + if ((strPathName == telem1OffsetFileName) || (strPathName == telem2OffsetFileName) || (strPathName == telem3OffsetFileName)) { + returnValue = 4; + } else if ((strPathName == telem1GuidFileName) || (strPathName == telem2GuidFileName) || (strPathName == telem3GuidFileName)) { + returnValue = 5; + } else if ((strPathName == telem1TelemFileName) || (strPathName == telem2TelemFileName) || (strPathName == telem3TelemFileName)) { + returnValue = 6; + } else if (strPathName.find(energyCounterNode) != std::string::npos) { + returnValue = 7; + } + return returnValue; +} + static ssize_t mockReadSuccess(int fd, void *buf, size_t count, off_t offset) { std::ostringstream oStream; uint64_t val = 0; @@ -54,20 +85,9 @@ static ssize_t mockReadSuccess(int fd, void *buf, size_t count, off_t offset) { return count; } -static int mockOpenSuccess(const char *pathname, int flags) { - - int returnValue = -1; - std::string strPathName(pathname); - if (strPathName == telemOffsetFileName) { - returnValue = 4; - } else if (strPathName == telemGuidFileName) { - returnValue = 5; - } else if (strPathName == telemFileName) { - returnValue = 6; - } else if (strPathName.find(energyCounterNode) != std::string::npos) { - returnValue = 7; - } - return returnValue; +inline static int mockStatSuccess(const std::string &filePath, struct stat *statbuf) noexcept { + statbuf->st_mode = S_IWUSR | S_IRUSR | S_IFREG; + return 0; } HWTEST2_F(SysmanProductHelperPowerTest, GivenValidProductHelperHandleWhenCallingGetPowerLimitValueThenCorrectValueIsReturned, IsPVC) { @@ -116,7 +136,7 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenValidProductHelperHandleWhenCalling HWTEST2_F(SysmanProductHelperPowerTest, GivenValidProductHelperHandleWhenFetchingCardCriticalPowerLimitFileThenFilenameIsReturned, IsNotPVC) { auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); - EXPECT_STREQ("power1_crit", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCriticalPowerLimit, 0, false).c_str()); + EXPECT_STREQ("", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCriticalPowerLimit, 0, false).c_str()); } HWTEST2_F(SysmanProductHelperPowerTest, GivenValidProductHelperHandleWhenCallingGetCardCriticalPowerLimitNativeUnitThenCorrectValueIsReturned, IsNotPVC) { @@ -135,86 +155,201 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenValidProductHelperHandleWhenCalling EXPECT_TRUE(pSysmanProductHelper->isPowerSetLimitSupported()); } -HWTEST2_F(SysmanProductHelperPowerTest, GivenSysfsReadFailsAndKeyOffsetMapNotAvailableForGuidWhenGettingPowerEnergyCounterThenFailureIsReturned, IsDG1) { - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); - VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { - std::ostringstream oStream; - uint64_t val = 0; - if (fd == 4) { - memcpy(buf, &val, count); - return count; - } else if (fd == 5) { - oStream << "0xABCDE"; - } else if (fd == 7) { - return -1; - } else { - oStream << "-1"; - } - std::string value = oStream.str(); - memcpy(buf, value.data(), count); - return count; - }); - - std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD)); - pLinuxPowerImp->isTelemetrySupportAvailable = true; +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidRootDevicePowerHandleForCardDomainWithTelemetrySupportNotAvailableAndSysfsNodeReadFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsPVC) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkFailure); zes_power_energy_counter_t energyCounter = {}; - EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, pLinuxPowerImp->getEnergyCounter(&energyCounter)); + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); } -HWTEST2_F(SysmanProductHelperPowerTest, GivenSysfsReadFailsAndPmtReadValueFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsDG1) { +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidRootDevicePowerHandleForCardDomainWithTelemetryDataNotAvailableAndSysfsNodeReadAlsoFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsPVC) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0xb15a0ede"; + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } + return count; + }); + zes_power_energy_counter_t energyCounter = {}; + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidSubdevicePowerHandleForPackagePackageDomainWithTelemetrySupportNotAvailableAndSysfsNodeReadFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsPVC) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkFailure); + zes_power_energy_counter_t energyCounter = {}; + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, true, 0, ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidSubdevicePowerHandleForPackageDomainWithTelemetrySupportAvailableAndSysfsNodeReadFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsPVC) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0xb15a0ede"; + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } + return count; + }); + zes_power_energy_counter_t energyCounter = {}; + std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, true, 0, ZES_POWER_DOMAIN_PACKAGE)); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandlesWithTelemetrySupportNotAvailableButSysfsReadSucceedsWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromSysfsNode, IsPVC) { VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { - std::ostringstream oStream; - uint64_t val = 0; + uint64_t telem1Offset = 0; + std::string validGuid = "0xb15a0ede"; + if (fd == 4) { - memcpy(buf, &val, count); - return count; + memcpy(buf, &telem1Offset, count); } else if (fd == 5) { - oStream << "0x490e01"; + memcpy(buf, validGuid.data(), count); } else if (fd == 6) { - if (offset == mockKeyOffset) { - errno = ENOENT; - return -1; - } - } else if (fd == 7) { - return -1; - } else { - oStream << "-1"; + count = -1; + } + return count; + }); + + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } +} + +using SysmanProductHelperPowerMultiDeviceTest = SysmanDevicePowerMultiDeviceFixture; +constexpr uint32_t i915PowerHandleComponentCount = 3u; +HWTEST2_F(SysmanProductHelperPowerMultiDeviceTest, GivenValidPowerHandlesWithTelemetryDataNotAvailableButSysfsReadSucceedsWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromSysfsNode, IsPVC) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockMultiDeviceReadLinkSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0xb15a0ede"; + uint32_t mockKeyValue = 0x3; + + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + memcpy(buf, &mockKeyValue, count); + } + return count; + }); + + std::unique_ptr pMockFsAccess = std::make_unique(); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, i915PowerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + if (!properties.onSubdevice) { + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + } else { + EXPECT_EQ(ZES_POWER_DOMAIN_PACKAGE, extProperties.domain); + } + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleForCardDomainAndTelemetryDataNotAvailableAndSysfsReadAlsoFailsWhenGettingPowerEnergyCounterThenFailureIsReturned, IsDG1) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0x490e01"; + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + count = -1; } - std::string value = oStream.str(); - memcpy(buf, value.data(), count); return count; }); std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD)); - pLinuxPowerImp->isTelemetrySupportAvailable = true; zes_power_energy_counter_t energyCounter = {}; - EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); -} - -HWTEST2_F(SysmanProductHelperPowerTest, GivenSysfsReadFailsWhenGettingPowerEnergyCounterThenSuccesIsReturned, IsDG1) { - - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); - VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess); - - std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, false, 0, ZES_POWER_DOMAIN_CARD)); - pLinuxPowerImp->isTelemetrySupportAvailable = true; - zes_power_energy_counter_t energyCounter = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxPowerImp->getEnergyCounter(&energyCounter)); - uint64_t expectedEnergyCounter = convertJouleToMicroJoule * (setEnergyCounter / 1048576); - EXPECT_EQ(energyCounter.energy, expectedEnergyCounter); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxPowerImp->getEnergyCounter(&energyCounter)); } HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleAndHwMonDoesNotExistWhenGettingPowerLimitsThenUnsupportedFeatureErrorIsReturned, IsDG1) { - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + uint32_t count = 0; std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); @@ -229,28 +364,232 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleAndHwMonDoesNotExis } } -HWTEST2_F(SysmanProductHelperPowerTest, GivenScanDirectoriesFailAndTelemetrySupportAvailableThenPowerModuleIsSupported, IsDG1) { - +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandlesWithTelemetrySupportAvailableWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromPmtNode, IsDG1) { VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0x490e01"; + uint32_t mockKeyValue = 0x3; - auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount(); - pSysmanDeviceImp->pPowerHandleContext->init(subDeviceCount); - ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true; - uint32_t subdeviceId = 0; - std::unique_ptr pLinuxPowerImp(new PublicLinuxPowerImp(pOsSysman, onSubdevice, subdeviceId, ZES_POWER_DOMAIN_CARD)); - EXPECT_TRUE(pLinuxPowerImp->isPowerModuleSupported()); + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + memcpy(buf, &mockKeyValue, count); + } + return count; + }); + + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandlesWithTelemetrySupportNotAvailableButSysfsReadSucceedsWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromSysfsNode, IsDG1) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0x490e01"; + + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + count = -1; + } + return count; + }); + + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandlesWithTelemetrySupportAvailableWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromPmtNode, IsDG2) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0x4f9302"; + uint32_t mockKeyValue = 0x3; + + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + memcpy(buf, &mockKeyValue, count); + } + return count; + }); + + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pMockSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_SUCCESS); + pMockSysfsAccess->mockReadValUnsignedLongResult.push_back(ZE_RESULT_ERROR_NOT_AVAILABLE); + + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandlesWithTelemetrySupportNotAvailableButSysfsReadSucceedsWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrievedFromSysfsNode, IsDG2) { + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); + VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); + VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint64_t telem1Offset = 0; + std::string validGuid = "0x4f9302"; + + if (fd == 4) { + memcpy(buf, &telem1Offset, count); + } else if (fd == 5) { + memcpy(buf, validGuid.data(), count); + } else if (fd == 6) { + count = -1; + } + return count; + }); + + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, powerHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + + zes_power_properties_t properties = {}; + zes_power_ext_properties_t extProperties = {}; + + properties.pNext = &extProperties; + extProperties.stype = ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties)); + + EXPECT_EQ(ZES_POWER_DOMAIN_CARD, extProperties.domain); + + zes_power_energy_counter_t energyCounter = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter)); + } } HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleWhenSettingPowerLimitsThenUnsupportedFeatureErrorIsReturned, IsDG1) { - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + uint32_t count = 0; std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); @@ -266,12 +605,20 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenValidPowerHandleWhenSettingPowerLim } HWTEST2_F(SysmanProductHelperPowerTest, GivenComponentCountZeroWhenEnumeratingPowerDomainsThenValidPowerHandlesIsReturned, IsDG1) { - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); + MockPowerSysfsAccessInterface *pMockSysfsAccess = new MockPowerSysfsAccessInterface(); + std::unique_ptr pMockFsAccess = std::make_unique(); + auto pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper()); + + pMockSysfsAccess->mockscanDirEntriesResult.push_back(ZE_RESULT_SUCCESS); + pSysmanKmdInterface->pSysfsAccess.reset(pMockSysfsAccess); + pLinuxSysmanImp->pFsAccess = pMockFsAccess.get(); + pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); + uint32_t count = 0; EXPECT_EQ(zesDeviceEnumPowerDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); EXPECT_EQ(count, powerHandleComponentCount); @@ -283,6 +630,30 @@ HWTEST2_F(SysmanProductHelperPowerTest, GivenComponentCountZeroWhenEnumeratingPo } } +HWTEST2_F(SysmanProductHelperPowerTest, GivenSysmanProductHelperInstanceWhenCheckingAvailabiityOfPmtNodeForPowerDomainThenValidResultIsReturnedForDifferentPowerDomain, IsDG1) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_TRUE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_CARD)); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_PACKAGE)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenSysmanProductHelperInstanceWhenCheckingAvailabiityOfPmtNodeForPowerDomainThenValidResultIsReturnedForDifferentPowerDomain, IsDG2) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_TRUE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_CARD)); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_PACKAGE)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenSysmanProductHelperInstanceWhenCheckingAvailabiityOfPmtNodeForPowerDomainThenValidResultIsReturnedForDifferentPowerDomain, IsPVC) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_CARD)); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_PACKAGE)); +} + +HWTEST2_F(SysmanProductHelperPowerTest, GivenSysmanProductHelperInstanceWhenCheckingAvailabiityOfPmtNodeForPowerDomainThenValidResultIsReturnedForDifferentPowerDomain, IsBMG) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_CARD)); + EXPECT_FALSE(pSysmanProductHelper->isPmtNodeAvailableForEnergyCounter(ZES_POWER_DOMAIN_PACKAGE)); +} + } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_temperature_tests.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_temperature_tests.cpp index 29022ce34b..4580da0bd7 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_temperature_tests.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_temperature_tests.cpp @@ -40,6 +40,11 @@ static int mockReadLinkSingleTelemetryNodesSuccess(const char *path, char *buf, return -1; } +inline static int mockStatSuccess(const std::string &filePath, struct stat *statbuf) noexcept { + statbuf->st_mode = S_IWUSR | S_IRUSR | S_IFREG; + return 0; +} + static int mockOpenSuccess(const char *pathname, int flags) { int returnValue = -1; std::string strPathName(pathname); @@ -1022,6 +1027,7 @@ HWTEST2_F(SysmanProductHelperTemperatureTest, GivenValidTemperatureHandleWhenZes static uint32_t validTemperatureHandleCount = 3u; VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSingleTelemetryNodesSuccess); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { diff --git a/level_zero/sysman/test/unit_tests/sources/temperature/linux/test_zes_temperature.cpp b/level_zero/sysman/test/unit_tests/sources/temperature/linux/test_zes_temperature.cpp index 5cf6703377..2415d2ab77 100644 --- a/level_zero/sysman/test/unit_tests/sources/temperature/linux/test_zes_temperature.cpp +++ b/level_zero/sysman/test/unit_tests/sources/temperature/linux/test_zes_temperature.cpp @@ -175,11 +175,17 @@ static ssize_t mockReadSuccessDg2(int fd, void *buf, size_t count, off_t offset) return count; } +inline static int mockStatSuccess(const std::string &filePath, struct stat *statbuf) noexcept { + statbuf->st_mode = S_IWUSR | S_IRUSR | S_IFREG; + return 0; +} + HWTEST2_F(SysmanMultiDeviceTemperatureFixture, GivenComponentCountZeroWhenCallingZetSysmanTemperatureGetThenZeroCountIsReturnedAndVerifySysmanTemperatureGetCallSucceeds, IsPVC) { VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); uint32_t count = 0; @@ -203,6 +209,7 @@ HWTEST2_F(SysmanMultiDeviceTemperatureFixture, GivenValidTempHandleWhenGettingTe VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForTwoTileDevices); @@ -231,6 +238,7 @@ HWTEST2_F(SysmanMultiDeviceTemperatureFixture, GivenValidTempHandleWhenGettingTe VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForTwoTileDevices); @@ -246,6 +254,7 @@ HWTEST2_F(SysmanMultiDeviceTemperatureFixture, GivenValidTempHandleWhenSettingTe VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForTwoTileDevices); @@ -279,6 +288,7 @@ HWTEST2_F(SysmanDeviceTemperatureFixture, GivenValidPowerHandleAndHandleCountZer VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); uint32_t count = 0; @@ -299,6 +309,7 @@ HWTEST2_F(SysmanDeviceTemperatureFixture, GivenValidTempHandleWhenGettingGPUAndG VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSingleTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessDg1); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForNoSubDevices); @@ -329,6 +340,7 @@ HWTEST2_F(SysmanDeviceTemperatureFixture, GivenValidTempHandleWhenGettingGPUAndG VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSingleTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessDg2); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForNoSubDevices); @@ -380,6 +392,7 @@ HWTEST2_F(SysmanDeviceTemperatureFixture, GivenComponentCountZeroWhenCallingZetS VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); uint32_t count = 0; @@ -403,6 +416,7 @@ HWTEST2_F(SysmanDeviceTemperatureFixture, GivenValidTempHandleWhenGettingTempera VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkMultiTelemetryNodesSuccess); VariableBackup mockOpen(&NEO::SysCalls::sysCallsOpen, &mockOpenSuccess); VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccessPvc); + VariableBackup mockStat(&NEO::SysCalls::sysCallsStat, &mockStatSuccess); VariableBackup allowFakeDevicePathBackup(&NEO::SysCalls::allowFakeDevicePath, true); auto handles = getTempHandles(handleComponentCountForSingleTileDevice);