Create Sysman Frequency API handles based on available subdevice/device

Change-Id: I2049515150004551c3f61647d20f1df7b375f587
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2020-09-10 10:54:55 +05:30
committed by sys_ocldev
parent d0a6b8aece
commit e904a1f0b4
13 changed files with 430 additions and 207 deletions

View File

@@ -10,6 +10,7 @@
#include "shared/source/helpers/basic_math.h"
#include "level_zero/tools/source/sysman/frequency/frequency_imp.h"
#include "level_zero/tools/source/sysman/frequency/os_frequency.h"
namespace L0 {
@@ -19,9 +20,18 @@ FrequencyHandleContext::~FrequencyHandleContext() {
}
}
ze_result_t FrequencyHandleContext::init() {
Frequency *pFrequency = new FrequencyImp(pOsSysman);
void FrequencyHandleContext::createHandle(ze_device_handle_t deviceHandle, uint16_t frequencyDomain) {
Frequency *pFrequency = new FrequencyImp(pOsSysman, deviceHandle, frequencyDomain);
handleList.push_back(pFrequency);
}
ze_result_t FrequencyHandleContext::init(std::vector<ze_device_handle_t> deviceHandles) {
for (auto deviceHandle : deviceHandles) {
auto totalDomains = OsFrequency::getHardwareBlockCount(deviceHandle);
for (uint16_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) {
createHandle(deviceHandle, frequencyDomain);
}
}
return ZE_RESULT_SUCCESS;
}

View File

@@ -6,6 +6,7 @@
*/
#pragma once
#include "level_zero/core/source/device/device.h"
#include <level_zero/zes_api.h>
#include <vector>
@@ -39,12 +40,15 @@ struct FrequencyHandleContext {
FrequencyHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
~FrequencyHandleContext();
ze_result_t init();
ze_result_t init(std::vector<ze_device_handle_t> deviceHandles);
ze_result_t frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency);
OsSysman *pOsSysman;
OsSysman *pOsSysman = nullptr;
std::vector<Frequency *> handleList = {};
private:
void createHandle(ze_device_handle_t deviceHandle, uint16_t frequencyDomain);
};
} // namespace L0

View File

@@ -15,7 +15,6 @@
namespace L0 {
const double FrequencyImp::step = 50.0 / 3; // Step of 16.6666667 Mhz (GEN9 Hardcode)
const bool FrequencyImp::canControl = true; // canControl is true on i915 (GEN9 Hardcode)
ze_result_t FrequencyImp::frequencyGetProperties(zes_freq_properties_t *pProperties) {
*pProperties = zesFrequencyProperties;
@@ -36,11 +35,7 @@ ze_result_t FrequencyImp::frequencyGetAvailableClocks(uint32_t *pCount, double *
}
ze_result_t FrequencyImp::frequencyGetRange(zes_freq_range_t *pLimits) {
ze_result_t result = pOsFrequency->getMax(pLimits->max);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return pOsFrequency->getMin(pLimits->min);
return pOsFrequency->osFrequencyGetRange(pLimits);
}
ze_result_t FrequencyImp::frequencySetRange(const zes_freq_range_t *pLimits) {
@@ -58,77 +53,21 @@ ze_result_t FrequencyImp::frequencySetRange(const zes_freq_range_t *pLimits) {
if (newMin > newMax || !newMinValid || !newMaxValid) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
double currentMax;
pOsFrequency->getMax(currentMax);
if (newMin > currentMax) {
// set the max first
ze_result_t result = pOsFrequency->setMax(newMax);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return pOsFrequency->setMin(newMin);
}
// set the min first
ze_result_t result = pOsFrequency->setMin(newMin);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return pOsFrequency->setMax(newMax);
return pOsFrequency->osFrequencySetRange(pLimits);
}
ze_result_t FrequencyImp::frequencyGetState(zes_freq_state_t *pState) {
ze_result_t result;
result = pOsFrequency->getRequest(pState->request);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = pOsFrequency->getTdp(pState->tdp);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = pOsFrequency->getEfficient(pState->efficient);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = pOsFrequency->getActual(pState->actual);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
pState->stype = ZES_STRUCTURE_TYPE_FREQ_STATE;
pState->pNext = nullptr;
pState->currentVoltage = -1.0;
pState->throttleReasons = 0u;
return result;
return pOsFrequency->osFrequencyGetState(pState);
}
ze_result_t FrequencyImp::frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
return pOsFrequency->osFrequencyGetThrottleTime(pThrottleTime);
}
void FrequencyImp::init() {
zesFrequencyProperties.stype = ZES_STRUCTURE_TYPE_FREQ_PROPERTIES;
zesFrequencyProperties.pNext = nullptr;
zesFrequencyProperties.type = ZES_FREQ_DOMAIN_GPU;
zesFrequencyProperties.onSubdevice = false;
zesFrequencyProperties.subdeviceId = 0;
zesFrequencyProperties.canControl = canControl;
ze_result_t result3 = pOsFrequency->getMinVal(zesFrequencyProperties.min);
ze_result_t result4 = pOsFrequency->getMaxVal(zesFrequencyProperties.max);
// If can't figure out the valid range, then can't control it.
if (ZE_RESULT_SUCCESS != result3 || ZE_RESULT_SUCCESS != result4) {
zesFrequencyProperties.canControl = false;
zesFrequencyProperties.min = 0.0;
zesFrequencyProperties.max = 0.0;
}
zesFrequencyProperties.isThrottleEventSupported = false;
zesFrequencyProperties.type = static_cast<zes_freq_domain_t>(frequencyDomain);
pOsFrequency->osFrequencyGetProperties(zesFrequencyProperties);
double freqRange = zesFrequencyProperties.max - zesFrequencyProperties.min;
numClocks = static_cast<uint32_t>(round(freqRange / step)) + 1;
pClocks = new double[numClocks];
@@ -137,8 +76,10 @@ void FrequencyImp::init() {
}
}
FrequencyImp::FrequencyImp(OsSysman *pOsSysman) {
pOsFrequency = OsFrequency::create(pOsSysman);
FrequencyImp::FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, uint16_t frequencyDomain) : deviceHandle(handle), frequencyDomain(frequencyDomain) {
ze_device_properties_t deviceProperties = {};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
pOsFrequency = OsFrequency::create(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId);
UNRECOVERABLE_IF(nullptr == pOsFrequency);
init();

View File

@@ -25,18 +25,19 @@ class FrequencyImp : public Frequency, NEO::NonCopyableOrMovableClass {
ze_result_t frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override;
FrequencyImp() = default;
FrequencyImp(OsSysman *pOsSysman);
FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, uint16_t frequencyDomain);
~FrequencyImp() override;
OsFrequency *pOsFrequency = nullptr;
void init();
private:
static const double step;
static const bool canControl;
zes_freq_properties_t zesFrequencyProperties = {};
double *pClocks = nullptr;
uint32_t numClocks = 0;
ze_device_handle_t deviceHandle = nullptr;
uint16_t frequencyDomain = 0;
};
} // namespace L0

View File

@@ -6,7 +6,7 @@
set(L0_SRCS_TOOLS_SYSMAN_FREQUENCY_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/os_frequency_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/os_frequency_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_frequency_imp.h
)

View File

@@ -11,14 +11,90 @@
namespace L0 {
const std::string LinuxFrequencyImp::minFreqFile("gt_min_freq_mhz");
const std::string LinuxFrequencyImp::maxFreqFile("gt_max_freq_mhz");
const std::string LinuxFrequencyImp::requestFreqFile("gt_cur_freq_mhz");
const std::string LinuxFrequencyImp::tdpFreqFile("gt_boost_freq_mhz");
const std::string LinuxFrequencyImp::actualFreqFile("gt_act_freq_mhz");
const std::string LinuxFrequencyImp::efficientFreqFile("gt_RP1_freq_mhz");
const std::string LinuxFrequencyImp::maxValFreqFile("gt_RP0_freq_mhz");
const std::string LinuxFrequencyImp::minValFreqFile("gt_RPn_freq_mhz");
const bool LinuxFrequencyImp::canControl = true; // canControl is true on i915 (GEN9 Hardcode)
ze_result_t LinuxFrequencyImp::osFrequencyGetProperties(zes_freq_properties_t &properties) {
properties.pNext = nullptr;
properties.canControl = canControl;
ze_result_t result1 = getMinVal(properties.min);
ze_result_t result2 = getMaxVal(properties.max);
// If can't figure out the valid range, then can't control it.
if (ZE_RESULT_SUCCESS != result1 || ZE_RESULT_SUCCESS != result2) {
properties.canControl = false;
properties.min = 0.0;
properties.max = 0.0;
}
properties.isThrottleEventSupported = false;
properties.onSubdevice = isSubdevice;
properties.subdeviceId = subdeviceId;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFrequencyImp::osFrequencyGetRange(zes_freq_range_t *pLimits) {
ze_result_t result = getMax(pLimits->max);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return getMin(pLimits->min);
}
ze_result_t LinuxFrequencyImp::osFrequencySetRange(const zes_freq_range_t *pLimits) {
double newMin = round(pLimits->min);
double newMax = round(pLimits->max);
double currentMax = 0.0;
ze_result_t result = getMax(currentMax);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
if (newMin > currentMax) {
// set the max first
ze_result_t result = setMax(newMax);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return setMin(newMin);
}
// set the min first
result = setMin(newMin);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return setMax(newMax);
}
ze_result_t LinuxFrequencyImp::osFrequencyGetState(zes_freq_state_t *pState) {
ze_result_t result;
result = getRequest(pState->request);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = getTdp(pState->tdp);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = getEfficient(pState->efficient);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = getActual(pState->actual);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
pState->pNext = nullptr;
pState->currentVoltage = -1.0;
pState->throttleReasons = 0u;
return result;
}
ze_result_t LinuxFrequencyImp::osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t LinuxFrequencyImp::getMin(double &min) {
double intval;
@@ -154,20 +230,30 @@ ze_result_t LinuxFrequencyImp::getMinVal(double &minVal) {
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFrequencyImp::getThrottleReasons(uint32_t &throttleReasons) {
throttleReasons = 0u;
return ZE_RESULT_SUCCESS;
void LinuxFrequencyImp::init() {
minFreqFile = "gt_min_freq_mhz";
maxFreqFile = "gt_max_freq_mhz";
requestFreqFile = "gt_cur_freq_mhz";
tdpFreqFile = "gt_boost_freq_mhz";
actualFreqFile = "gt_act_freq_mhz";
efficientFreqFile = "gt_RP1_freq_mhz";
maxValFreqFile = "gt_RP0_freq_mhz";
minValFreqFile = "gt_RPn_freq_mhz";
}
LinuxFrequencyImp::LinuxFrequencyImp(OsSysman *pOsSysman) {
LinuxFrequencyImp::LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : isSubdevice(onSubdevice), subdeviceId(subdeviceId) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
init();
}
OsFrequency *OsFrequency::create(OsSysman *pOsSysman) {
LinuxFrequencyImp *pLinuxFrequencyImp = new LinuxFrequencyImp(pOsSysman);
OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
LinuxFrequencyImp *pLinuxFrequencyImp = new LinuxFrequencyImp(pOsSysman, onSubdevice, subdeviceId);
return static_cast<OsFrequency *>(pLinuxFrequencyImp);
}
uint16_t OsFrequency::getHardwareBlockCount(ze_device_handle_t handle) {
return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU
}
} // namespace L0

View File

@@ -16,33 +16,41 @@ namespace L0 {
class LinuxFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getMin(double &min) override;
ze_result_t setMin(double min) override;
ze_result_t getMax(double &max) override;
ze_result_t setMax(double max) override;
ze_result_t getRequest(double &request) override;
ze_result_t getTdp(double &tdp) override;
ze_result_t getActual(double &actual) override;
ze_result_t getEfficient(double &efficient) override;
ze_result_t getMaxVal(double &maxVal) override;
ze_result_t getMinVal(double &minVal) override;
ze_result_t getThrottleReasons(uint32_t &throttleReasons) override;
ze_result_t osFrequencyGetProperties(zes_freq_properties_t &properties) override;
ze_result_t osFrequencyGetRange(zes_freq_range_t *pLimits) override;
ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) override;
ze_result_t osFrequencyGetState(zes_freq_state_t *pState) override;
ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override;
LinuxFrequencyImp() = default;
LinuxFrequencyImp(OsSysman *pOsSysman);
LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
~LinuxFrequencyImp() override = default;
protected:
SysfsAccess *pSysfsAccess = nullptr;
ze_result_t getMin(double &min);
ze_result_t setMin(double min);
ze_result_t getMax(double &max);
ze_result_t setMax(double max);
ze_result_t getRequest(double &request);
ze_result_t getTdp(double &tdp);
ze_result_t getActual(double &actual);
ze_result_t getEfficient(double &efficient);
ze_result_t getMaxVal(double &maxVal);
ze_result_t getMinVal(double &minVal);
private:
static const std::string minFreqFile;
static const std::string maxFreqFile;
static const std::string requestFreqFile;
static const std::string tdpFreqFile;
static const std::string actualFreqFile;
static const std::string efficientFreqFile;
static const std::string maxValFreqFile;
static const std::string minValFreqFile;
std::string minFreqFile;
std::string maxFreqFile;
std::string requestFreqFile;
std::string tdpFreqFile;
std::string actualFreqFile;
std::string efficientFreqFile;
std::string maxValFreqFile;
std::string minValFreqFile;
static const bool canControl;
bool isSubdevice = false;
uint32_t subdeviceId = 0;
void init();
};
} // namespace L0

View File

@@ -13,19 +13,14 @@ namespace L0 {
class OsFrequency {
public:
virtual ze_result_t getMin(double &min) = 0;
virtual ze_result_t setMin(double min) = 0;
virtual ze_result_t getMax(double &max) = 0;
virtual ze_result_t setMax(double max) = 0;
virtual ze_result_t getRequest(double &request) = 0;
virtual ze_result_t getTdp(double &tdp) = 0;
virtual ze_result_t getActual(double &actual) = 0;
virtual ze_result_t getEfficient(double &efficient) = 0;
virtual ze_result_t getMaxVal(double &maxVal) = 0;
virtual ze_result_t getMinVal(double &minVal) = 0;
virtual ze_result_t getThrottleReasons(uint32_t &throttleReasons) = 0;
virtual ze_result_t osFrequencyGetProperties(zes_freq_properties_t &properties) = 0;
virtual ze_result_t osFrequencyGetRange(zes_freq_range_t *pLimits) = 0;
virtual ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) = 0;
virtual ze_result_t osFrequencyGetState(zes_freq_state_t *pState) = 0;
virtual ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) = 0;
static OsFrequency *create(OsSysman *pOsSysman);
static OsFrequency *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
static uint16_t getHardwareBlockCount(ze_device_handle_t handle);
virtual ~OsFrequency() {}
};

View File

@@ -11,66 +11,40 @@ namespace L0 {
class WddmFrequencyImp : public OsFrequency {
public:
ze_result_t getMin(double &min) override;
ze_result_t setMin(double min) override;
ze_result_t getMax(double &max) override;
ze_result_t setMax(double max) override;
ze_result_t getRequest(double &request) override;
ze_result_t getTdp(double &tdp) override;
ze_result_t getActual(double &actual) override;
ze_result_t getEfficient(double &efficient) override;
ze_result_t getMaxVal(double &maxVal) override;
ze_result_t getMinVal(double &minVal) override;
ze_result_t getThrottleReasons(uint32_t &throttleReasons) override;
ze_result_t osFrequencyGetProperties(zes_freq_properties_t &properties) override;
ze_result_t osFrequencyGetRange(zes_freq_range_t *pLimits) override;
ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) override;
ze_result_t osFrequencyGetState(zes_freq_state_t *pState) override;
ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override;
};
ze_result_t WddmFrequencyImp::getMin(double &min) {
ze_result_t WddmFrequencyImp::osFrequencyGetProperties(zes_freq_properties_t &properties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::setMin(double min) {
ze_result_t WddmFrequencyImp::osFrequencyGetRange(zes_freq_range_t *pLimits) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getMax(double &max) {
ze_result_t WddmFrequencyImp::osFrequencySetRange(const zes_freq_range_t *pLimits) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::setMax(double max) {
ze_result_t WddmFrequencyImp::osFrequencyGetState(zes_freq_state_t *pState) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getRequest(double &request) {
ze_result_t WddmFrequencyImp::osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getTdp(double &tdp) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getActual(double &actual) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getEfficient(double &efficient) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getMaxVal(double &maxVal) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getMinVal(double &minVal) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFrequencyImp::getThrottleReasons(uint32_t &throttleReasons) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
OsFrequency *OsFrequency::create(OsSysman *pOsSysman) {
OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
WddmFrequencyImp *pWddmFrequencyImp = new WddmFrequencyImp();
return static_cast<OsFrequency *>(pWddmFrequencyImp);
}
uint16_t OsFrequency::getHardwareBlockCount(ze_device_handle_t handle) {
return 1;
}
} // namespace L0

View File

@@ -54,12 +54,23 @@ SysmanDeviceImp::~SysmanDeviceImp() {
}
void SysmanDeviceImp::init() {
uint32_t subDeviceCount = 0;
std::vector<ze_device_handle_t> deviceHandles;
// We received a device handle. Check for subdevices in this device
Device::fromHandle(hCoreDevice)->getSubDevices(&subDeviceCount, nullptr);
if (subDeviceCount == 0) {
deviceHandles.resize(1, hCoreDevice);
} else {
deviceHandles.resize(subDeviceCount, nullptr);
Device::fromHandle(hCoreDevice)->getSubDevices(&subDeviceCount, deviceHandles.data());
}
pOsSysman->init();
if (pPowerHandleContext) {
pPowerHandleContext->init();
}
if (pFrequencyHandleContext) {
pFrequencyHandleContext->init();
pFrequencyHandleContext->init(deviceHandles);
}
if (pFabricPortHandleContext) {
pFabricPortHandleContext->init();