fix: Add support for min, max and default limits

Related-To: NEO-8373

Signed-off-by: Bellekallu Rajkiran <bellekallu.rajkiran@intel.com>
This commit is contained in:
Bellekallu Rajkiran
2023-11-15 06:47:47 +00:00
committed by Compute-Runtime-Automation
parent 5772b17924
commit 48fdd857a4
10 changed files with 573 additions and 109 deletions

View File

@@ -17,6 +17,29 @@
namespace L0 {
namespace Sysman {
class LinuxPowerImp::PowerLimitRestorer : NEO::NonCopyableOrMovableClass {
public:
PowerLimitRestorer(L0::Sysman::SysfsAccess *pSysfsAccess, std::string powerLimit) : pSysfsAccess(pSysfsAccess), powerLimit(powerLimit) {
result = pSysfsAccess->read(powerLimit, powerLimitValue);
}
~PowerLimitRestorer() {
if (result == ZE_RESULT_SUCCESS) {
result = pSysfsAccess->write(powerLimit, powerLimitValue);
DEBUG_BREAK_IF(result != ZE_RESULT_SUCCESS);
}
}
operator ze_result_t() const {
return result;
}
protected:
ze_result_t result = ZE_RESULT_ERROR_UNINITIALIZED;
SysfsAccess *pSysfsAccess = nullptr;
std::string powerLimit = {};
uint64_t powerLimitValue = 0;
};
ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
pProperties->onSubdevice = isSubdevice;
pProperties->subdeviceId = subdeviceId;
@@ -25,7 +48,82 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
pProperties->defaultLimit = -1;
pProperties->minLimit = -1;
pProperties->maxLimit = -1;
return ZE_RESULT_SUCCESS;
if (isSubdevice) {
return ZE_RESULT_SUCCESS;
}
auto result = getDefaultLimit(pProperties->defaultLimit);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
auto powerLimitRestorer = L0::Sysman::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedPowerLimit);
if (powerLimitRestorer != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(powerLimitRestorer));
return getErrorCode(powerLimitRestorer);
}
result = getMinLimit(pProperties->minLimit);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
return getMaxLimit(pProperties->maxLimit);
}
ze_result_t LinuxPowerImp::getMinLimit(int32_t &minLimit) {
// Fw clamps to minimum value if power limit requested to set is less than min limit, Set to 100 micro watt to get min limit
uint64_t powerLimit = 100;
auto result = pSysfsAccess->write(sustainedPowerLimit, powerLimit);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
return getErrorCode(result);
}
result = pSysfsAccess->read(sustainedPowerLimit, powerLimit);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
return getErrorCode(result);
}
// Values are retrieved from KMD in micro watts, Conversion to milli is required.
minLimit = static_cast<int32_t>(powerLimit / milliFactor);
return result;
}
ze_result_t LinuxPowerImp::getMaxLimit(int32_t &maxLimit) {
// Fw clamps to maximum value if power limit requested to set is greater than max limit, Set to max value to get max limit
uint64_t powerLimit = std::numeric_limits<int32_t>::max();
auto result = pSysfsAccess->write(sustainedPowerLimit, powerLimit);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
return getErrorCode(result);
}
result = pSysfsAccess->read(sustainedPowerLimit, powerLimit);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
return getErrorCode(result);
}
// Values are retrieved from KMD in micro watts, Conversion to milli is required.
maxLimit = static_cast<int32_t>(powerLimit / milliFactor);
return result;
}
ze_result_t LinuxPowerImp::getDefaultLimit(int32_t &defaultLimit) {
uint64_t powerLimit = 0;
std::string defaultPowerLimit = intelGraphicsHwmonDir + "/" + pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameDefaultPowerLimit, subdeviceId, false);
auto result = pSysfsAccess->read(defaultPowerLimit, powerLimit);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): SysfsAccess->read() failed to read %s/%s and returning error:0x%x \n", __FUNCTION__, intelGraphicsHwmonDir.c_str(), defaultPowerLimit.c_str(), getErrorCode(result));
return getErrorCode(result);
}
// Values are retrieved from KMD in micro watts, Conversion to milli is required.
defaultLimit = static_cast<int32_t>(powerLimit / milliFactor);
return result;
}
ze_result_t LinuxPowerImp::getPropertiesExt(zes_power_ext_properties_t *pExtPoperties) {

View File

@@ -9,6 +9,7 @@
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/api/power/sysman_os_power.h"
#include "level_zero/sysman/source/shared/linux/sysman_fs_access.h"
#include "igfxfmid.h"
@@ -56,6 +57,7 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
uint32_t subdeviceId = 0;
uint32_t powerLimitCount = 0;
PRODUCT_FAMILY productFamily{};
class PowerLimitRestorer;
ze_result_t getErrorCode(ze_result_t result) {
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
@@ -63,6 +65,10 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
}
return result;
}
ze_result_t getMinLimit(int32_t &minLimit);
ze_result_t getMaxLimit(int32_t &maxLimit);
ze_result_t getDefaultLimit(int32_t &defaultLimit);
};
} // namespace Sysman
} // namespace L0