mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
Add support for hwmon interface for sysman power
Signed-off-by: Mayank Raghuwanshi <mayank.raghuwanshi@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
229ab9e30c
commit
0f2754e943
@@ -6,8 +6,8 @@
|
||||
|
||||
set(L0_SRCS_TOOLS_SYSMAN_POWER_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/os_power_imp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/os_power_imp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_power_imp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_power_imp.h
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
|
||||
namespace L0 {
|
||||
|
||||
const std::string LinuxPowerImp::hwmonDir("device/hwmon");
|
||||
const std::string LinuxPowerImp::i915("i915");
|
||||
const std::string LinuxPowerImp::sustainedPowerLimitEnabled("power1_max_enable");
|
||||
const std::string LinuxPowerImp::sustainedPowerLimit("power1_max");
|
||||
const std::string LinuxPowerImp::sustainedPowerLimitInterval("power1_max_interval");
|
||||
const std::string LinuxPowerImp::burstPowerLimitEnabled("power1_cap_enable");
|
||||
const std::string LinuxPowerImp::burstPowerLimit("power1_cap");
|
||||
const std::string LinuxPowerImp::energyCounterNode("energy1_input");
|
||||
const std::string LinuxPowerImp::defaultPowerLimit("power_default_limit");
|
||||
const std::string LinuxPowerImp::minPowerLimit("power_min_limit");
|
||||
const std::string LinuxPowerImp::maxPowerLimit("power_max_limit");
|
||||
|
||||
void powerGetTimestamp(uint64_t ×tamp) {
|
||||
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
|
||||
timestamp = std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
|
||||
@@ -22,27 +34,133 @@ void powerGetTimestamp(uint64_t ×tamp) {
|
||||
ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
|
||||
pProperties->onSubdevice = false;
|
||||
pProperties->subdeviceId = 0;
|
||||
pProperties->canControl = canControl;
|
||||
pProperties->isEnergyThresholdSupported = false;
|
||||
pProperties->defaultLimit = -1;
|
||||
pProperties->minLimit = -1;
|
||||
pProperties->maxLimit = -1;
|
||||
|
||||
uint32_t val = 0;
|
||||
auto result = pSysfsAccess->read(i915HwmonDir + "/" + defaultPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS == result) {
|
||||
pProperties->defaultLimit = static_cast<int32_t>(val / milliFactor); // need to convert from microwatt to milliwatt
|
||||
}
|
||||
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + minPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS == result) {
|
||||
pProperties->minLimit = static_cast<int32_t>(val / milliFactor); // need to convert from microwatt to milliwatt
|
||||
}
|
||||
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + maxPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS == result && val != std::numeric_limits<uint32_t>::max()) {
|
||||
pProperties->maxLimit = static_cast<int32_t>(val / milliFactor); // need to convert from microwatt to milliwatt
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t LinuxPowerImp::getEnergyCounter(zes_power_energy_counter_t *pEnergy) {
|
||||
const std::string key("PACKAGE_ENERGY");
|
||||
uint64_t energy = 0;
|
||||
ze_result_t result = pPmt->readValue(key, energy);
|
||||
// PMT will return in joules and need to convert into microjoules
|
||||
pEnergy->energy = energy * convertJouleToMicroJoule;
|
||||
|
||||
ze_result_t result = pSysfsAccess->read(i915HwmonDir + "/" + energyCounterNode, pEnergy->energy);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
const std::string key("PACKAGE_ENERGY");
|
||||
uint64_t energy = 0;
|
||||
result = pPmt->readValue(key, energy);
|
||||
// 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 / 1048576) * convertJouleToMicroJoule;
|
||||
}
|
||||
powerGetTimestamp(pEnergy->timestamp);
|
||||
|
||||
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) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
uint64_t val = 0;
|
||||
if (pSustained != nullptr) {
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimitEnabled, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
pSustained->enabled = static_cast<ze_bool_t>(val);
|
||||
|
||||
if (pSustained->enabled) {
|
||||
val = 0;
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
val /= milliFactor; // Convert microWatts to milliwatts
|
||||
pSustained->power = static_cast<int32_t>(val);
|
||||
|
||||
val = 0;
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimitInterval, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
pSustained->interval = static_cast<int32_t>(val);
|
||||
}
|
||||
}
|
||||
if (pBurst != nullptr) {
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + burstPowerLimitEnabled, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
pBurst->enabled = static_cast<ze_bool_t>(val);
|
||||
|
||||
if (pBurst->enabled) {
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + burstPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
val /= milliFactor; // Convert microWatts to milliwatts
|
||||
pBurst->power = static_cast<int32_t>(val);
|
||||
}
|
||||
}
|
||||
if (pPeak != nullptr) {
|
||||
pPeak->powerAC = -1;
|
||||
pPeak->powerDC = -1;
|
||||
result = ZE_RESULT_SUCCESS;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
int32_t val = 0;
|
||||
if (pSustained != nullptr) {
|
||||
uint64_t isSustainedPowerLimitEnabled = 0;
|
||||
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimitEnabled, isSustainedPowerLimitEnabled);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
|
||||
if (isSustainedPowerLimitEnabled) {
|
||||
val = static_cast<uint32_t>(pSustained->power) * milliFactor; // Convert milliWatts to microwatts
|
||||
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
|
||||
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimitInterval, pSustained->interval);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pBurst != nullptr) {
|
||||
result = pSysfsAccess->write(i915HwmonDir + "/" + burstPowerLimitEnabled, static_cast<int>(pBurst->enabled));
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
|
||||
if (pBurst->enabled) {
|
||||
val = static_cast<uint32_t>(pBurst->power) * milliFactor; // Convert milliWatts to microwatts
|
||||
result = pSysfsAccess->write(i915HwmonDir + "/" + burstPowerLimit, val);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return getErrorCode(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxPowerImp::getEnergyThreshold(zes_energy_threshold_t *pThreshold) {
|
||||
@@ -54,13 +172,36 @@ ze_result_t LinuxPowerImp::setEnergyThreshold(double threshold) {
|
||||
}
|
||||
|
||||
bool LinuxPowerImp::isPowerModuleSupported() {
|
||||
return (pPmt != nullptr);
|
||||
std::vector<std::string> listOfAllHwmonDirs = {};
|
||||
bool hwmonDirExists = false;
|
||||
if (ZE_RESULT_SUCCESS != pSysfsAccess->scanDirEntries(hwmonDir, listOfAllHwmonDirs)) {
|
||||
hwmonDirExists = false;
|
||||
}
|
||||
for (const auto &tempHwmonDirEntry : listOfAllHwmonDirs) {
|
||||
const std::string i915NameFile = hwmonDir + "/" + tempHwmonDirEntry + "/" + "name";
|
||||
std::string name;
|
||||
if (ZE_RESULT_SUCCESS != pSysfsAccess->read(i915NameFile, name)) {
|
||||
continue;
|
||||
}
|
||||
if (name == i915) {
|
||||
i915HwmonDir = hwmonDir + "/" + tempHwmonDirEntry;
|
||||
hwmonDirExists = true;
|
||||
canControl = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hwmonDirExists == false) {
|
||||
return (pPmt != nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman) {
|
||||
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
// Lets hardcode subDeviceId to 0, as we are expecting this code to execute on device without subdevice
|
||||
uint32_t subDeviceId = 0;
|
||||
pPmt = pLinuxSysmanImp->getPlatformMonitoringTechAccess(subDeviceId);
|
||||
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
}
|
||||
|
||||
OsPower *OsPower::create(OsSysman *pOsSysman) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "level_zero/tools/source/sysman/power/os_power.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace L0 {
|
||||
|
||||
@@ -32,5 +33,28 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
|
||||
|
||||
protected:
|
||||
PlatformMonitoringTech *pPmt = nullptr;
|
||||
SysfsAccess *pSysfsAccess = nullptr;
|
||||
|
||||
private:
|
||||
std::string i915HwmonDir;
|
||||
static const std::string hwmonDir;
|
||||
static const std::string i915;
|
||||
static const std::string sustainedPowerLimitEnabled;
|
||||
static const std::string sustainedPowerLimit;
|
||||
static const std::string sustainedPowerLimitInterval;
|
||||
static const std::string burstPowerLimitEnabled;
|
||||
static const std::string burstPowerLimit;
|
||||
static const std::string energyCounterNode;
|
||||
static const std::string defaultPowerLimit;
|
||||
static const std::string minPowerLimit;
|
||||
static const std::string maxPowerLimit;
|
||||
bool canControl = false;
|
||||
|
||||
ze_result_t getErrorCode(ze_result_t result) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} // namespace L0
|
||||
|
||||
Reference in New Issue
Block a user