refactor: Move PMT common code to PMT specific class

Facilitate PMT utilization for other modules with refactoring
common PMT calls.

Related-To: NEO-8848

Signed-off-by: Bellekallu Rajkiran <bellekallu.rajkiran@intel.com>
This commit is contained in:
Bellekallu Rajkiran
2024-06-12 08:28:00 +00:00
committed by Compute-Runtime-Automation
parent 433ecf4058
commit 0ce762a91c
9 changed files with 131 additions and 79 deletions

View File

@@ -54,56 +54,21 @@ static const std::map<int, zes_engine_type_flags_t> engineMap = {
{3, ZES_ENGINE_TYPE_FLAG_MEDIA},
{4, ZES_ENGINE_TYPE_FLAG_COMPUTE}};
bool LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(uint64_t &telemOffset, const std::string &key, std::string &telemDir) {
std::string &rootPath = pLinuxSysmanImp->getPciRootPath();
if (rootPath.empty()) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Root path has no value \n", __FUNCTION__);
return false;
}
std::map<uint32_t, std::string> telemPciPath;
NEO::PmtUtil::getTelemNodesInPciPath(std::string_view(rootPath), telemPciPath);
uint32_t subDeviceCount = pLinuxSysmanImp->getSubDeviceCount() + 1;
if (telemPciPath.size() < subDeviceCount) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Number of telemetry nodes:%d is lessthan %d \n", __FUNCTION__, telemPciPath.size(), subDeviceCount);
return false;
}
auto iterator = telemPciPath.begin();
telemDir = iterator->second;
std::array<char, NEO::PmtUtil::guidStringSize> guidString = {};
if (!NEO::PmtUtil::readGuid(telemDir, guidString)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read GUID from %s \n", __FUNCTION__, telemDir.c_str());
return false;
}
uint64_t offset = ULONG_MAX;
if (!NEO::PmtUtil::readOffset(telemDir, offset)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read offset from %s\n", __FUNCTION__, telemDir.c_str());
return false;
}
std::map<std::string, uint64_t> keyOffsetMap;
if (ZE_RESULT_SUCCESS == PlatformMonitoringTech::getKeyOffsetMap(guidString.data(), keyOffsetMap)) {
auto keyOffset = keyOffsetMap.find(key.c_str());
if (keyOffset != keyOffsetMap.end()) {
telemOffset = keyOffset->second + offset;
return true;
}
}
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to find keyOffset in keyOffsetMap \n", __FUNCTION__);
return false;
}
bool LinuxGlobalOperationsImp::getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) {
uint64_t offset = 0;
std::string telemDir = {};
if (!LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(offset, "PPIN", telemDir)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get telemetry offset and directory for PPIN \n", __FUNCTION__);
if (!PlatformMonitoringTech::getTelemOffsetAndTelemDir(pLinuxSysmanImp, offset, telemDir)) {
return false;
}
uint64_t containerOffset = 0;
if (!PlatformMonitoringTech::getTelemOffsetForContainer(telemDir, "PPIN", containerOffset)) {
return false;
}
offset += containerOffset;
uint64_t value;
ssize_t bytesRead = NEO::PmtUtil::readTelem(telemDir.data(), sizeof(uint64_t), offset, &value);
if (bytesRead == sizeof(uint64_t)) {
@@ -119,11 +84,19 @@ bool LinuxGlobalOperationsImp::getSerialNumber(char (&serialNumber)[ZES_STRING_P
bool LinuxGlobalOperationsImp::getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) {
uint64_t offset = 0;
std::string telemDir = {};
constexpr uint32_t boardNumberSize = 32;
if (!LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(offset, "BoardNumber", telemDir)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get telemetry offset and directory for BoardNumber \n", __FUNCTION__);
if (!PlatformMonitoringTech::getTelemOffsetAndTelemDir(pLinuxSysmanImp, offset, telemDir)) {
return false;
}
uint64_t containerOffset = 0;
if (!PlatformMonitoringTech::getTelemOffsetForContainer(telemDir, "BoardNumber", containerOffset)) {
return false;
}
offset += containerOffset;
constexpr uint32_t boardNumberSize = 32;
std::array<uint8_t, boardNumberSize> value;
ssize_t bytesRead = NEO::PmtUtil::readTelem(telemDir.data(), boardNumberSize, offset, value.data());
if (bytesRead == boardNumberSize) {

View File

@@ -78,7 +78,6 @@ class LinuxGlobalOperationsImp : public OsGlobalOperations, NEO::NonCopyableOrMo
static const std::string srcVersionFile;
static const std::string agamaVersionFile;
static const std::string ueventWedgedFile;
bool getTelemOffsetAndTelemDir(uint64_t &telemOffset, const std::string &key, std::string &telemDir);
std::string devicePciBdf = "";
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
uint32_t rootDeviceIndex = 0u;

View File

@@ -9,6 +9,7 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/os_interface/linux/file_descriptor.h"
#include "shared/source/os_interface/linux/pmt_util.h"
#include "level_zero/sysman/source/device/sysman_device_imp.h"
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
@@ -203,6 +204,46 @@ void PlatformMonitoringTech::create(LinuxSysmanImp *pLinuxSysmanImp, std::string
}
}
bool PlatformMonitoringTech::getTelemOffsetAndTelemDir(LinuxSysmanImp *pLinuxSysmanImp, uint64_t &telemOffset, std::string &telemDir) {
std::string &rootPath = pLinuxSysmanImp->getPciRootPath();
std::map<uint32_t, std::string> telemPciPath;
NEO::PmtUtil::getTelemNodesInPciPath(std::string_view(rootPath), telemPciPath);
uint32_t subDeviceCount = pLinuxSysmanImp->getSubDeviceCount() + 1;
if (telemPciPath.size() < subDeviceCount) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Number of telemetry nodes:%d is lessthan %d \n", __FUNCTION__, telemPciPath.size(), subDeviceCount);
return false;
}
auto iterator = telemPciPath.begin();
telemDir = iterator->second;
if (!NEO::PmtUtil::readOffset(telemDir, telemOffset)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read offset from %s\n", __FUNCTION__, telemDir.c_str());
return false;
}
return true;
}
bool PlatformMonitoringTech::getTelemOffsetForContainer(const std::string &telemDir, const std::string &key, uint64_t &telemOffset) {
std::array<char, NEO::PmtUtil::guidStringSize> guidString = {};
if (!NEO::PmtUtil::readGuid(telemDir, guidString)) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read GUID from %s \n", __FUNCTION__, telemDir.c_str());
return false;
}
std::map<std::string, uint64_t> keyOffsetMap;
if (ZE_RESULT_SUCCESS == PlatformMonitoringTech::getKeyOffsetMap(guidString.data(), keyOffsetMap)) {
auto keyOffset = keyOffsetMap.find(key.c_str());
if (keyOffset != keyOffsetMap.end()) {
telemOffset = keyOffset->second;
return true;
}
}
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to find keyOffset in keyOffsetMap \n", __FUNCTION__);
return false;
}
PlatformMonitoringTech::~PlatformMonitoringTech() {
}

View File

@@ -36,6 +36,8 @@ class PlatformMonitoringTech : NEO::NonCopyableOrMovableClass {
static void create(LinuxSysmanImp *pLinuxSysmanImp, std::string &gpuUpstreamPortPath,
std::map<uint32_t, L0::Sysman::PlatformMonitoringTech *> &mapOfSubDeviceIdToPmtObject);
static ze_result_t getKeyOffsetMap(std::string guid, std::map<std::string, uint64_t> &keyOffsetMap);
static bool getTelemOffsetAndTelemDir(LinuxSysmanImp *pLinuxSysmanImp, uint64_t &telemOffset, std::string &telemDir);
static bool getTelemOffsetForContainer(const std::string &telemDir, const std::string &key, uint64_t &telemOffset);
protected:
static uint32_t rootDeviceTelemNodeIndex;

View File

@@ -7,6 +7,8 @@
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
#include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h"
#include <csignal>
#include <fcntl.h>
#include <fstream>
@@ -18,18 +20,6 @@ namespace Sysman {
FsAccessInterface::~FsAccessInterface() = default;
static ze_result_t getResult(int err) {
if ((EPERM == err) || (EACCES == err)) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
} else if (ENOENT == err) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
} else if (EBUSY == err) {
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
} else {
return ZE_RESULT_ERROR_UNKNOWN;
}
}
void FdCacheInterface::eraseLeastUsedEntryFromCache() {
auto it = fdMap.begin();
uint32_t fdCountRef = it->second.second;
@@ -76,12 +66,12 @@ ze_result_t FsAccessInterface::readValue(const std::string file, T &val) {
std::string readVal(64, '\0');
int fd = pFdCacheInterface->getFd(file);
if (fd < 0) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
ssize_t bytesRead = NEO::SysCalls::pread(fd, readVal.data(), readVal.size(), 0);
if (bytesRead < 0) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
std::istringstream stream(readVal);
@@ -125,12 +115,12 @@ ze_result_t FsAccessInterface::read(const std::string file, std::string &val) {
fs.open(file.c_str());
if (fs.fail()) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
fs >> val;
if (fs.fail()) {
fs.close();
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
fs.close();
// Strip trailing newline
@@ -148,12 +138,12 @@ ze_result_t FsAccessInterface::read(const std::string file, std::vector<std::str
fs.open(file.c_str());
if (fs.fail()) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
while (std::getline(fs, line)) {
if (fs.fail()) {
fs.close();
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
if (line.back() == '\n') {
line.pop_back();
@@ -168,13 +158,13 @@ ze_result_t FsAccessInterface::read(const std::string file, std::vector<std::str
ze_result_t FsAccessInterface::write(const std::string file, const std::string val) {
int fd = NEO::SysCalls::open(file.c_str(), O_WRONLY);
if (fd < 0) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
ssize_t bytesWritten = NEO::SysCalls::pwrite(fd, val.data(), val.size(), 0);
NEO::SysCalls::close(fd);
if (bytesWritten < 0) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
if (bytesWritten != static_cast<ssize_t>(val.size())) {
@@ -216,7 +206,7 @@ bool FsAccessInterface::fileExists(const std::string file) {
ze_result_t FsAccessInterface::getFileMode(const std::string file, ::mode_t &mode) {
struct stat sb;
if (0 != NEO::SysCalls::stat(file.c_str(), &sb)) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
mode = sb.st_mode;
return ZE_RESULT_SUCCESS;
@@ -227,7 +217,7 @@ ze_result_t FsAccessInterface::readSymLink(const std::string path, std::string &
char buf[PATH_MAX];
ssize_t len = NEO::SysCalls::readlink(path.c_str(), buf, PATH_MAX - 1);
if (len < 0) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
buf[len] = '\0';
val = std::string(buf);
@@ -239,7 +229,7 @@ ze_result_t FsAccessInterface::getRealPath(const std::string path, std::string &
char buf[PATH_MAX];
char *realPath = NEO::SysCalls::realpath(path.c_str(), buf);
if (!realPath) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
val = std::string(buf);
return ZE_RESULT_SUCCESS;
@@ -249,7 +239,7 @@ ze_result_t FsAccessInterface::listDirectory(const std::string path, std::vector
list.clear();
::DIR *procDir = NEO::SysCalls::opendir(path.c_str());
if (!procDir) {
return getResult(errno);
return LinuxSysmanImp::getResult(errno);
}
struct ::dirent *ent;
int err = 0;
@@ -270,7 +260,7 @@ ze_result_t FsAccessInterface::listDirectory(const std::string path, std::vector
// Check if in above while loop, readdir encountered any error.
if ((err != 0) && (err != ENOENT)) {
list.clear();
return getResult(err);
return LinuxSysmanImp::getResult(err);
}
return ZE_RESULT_SUCCESS;
}

View File

@@ -63,12 +63,20 @@ ze_result_t LinuxSysmanImp::init() {
return createPmtHandles();
}
std::string &LinuxSysmanImp::getDeviceName() {
return deviceName;
ze_result_t LinuxSysmanImp::getResult(int err) {
if ((EPERM == err) || (EACCES == err)) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
} else if (ENOENT == err) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
} else if (EBUSY == err) {
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
} else {
return ZE_RESULT_ERROR_UNKNOWN;
}
}
std::string &LinuxSysmanImp::getPciRootPath() {
return rootPath;
std::string &LinuxSysmanImp::getDeviceName() {
return deviceName;
}
SysmanHwDeviceIdDrm::SingleInstance LinuxSysmanImp::getSysmanHwDeviceIdInstance() {

View File

@@ -70,7 +70,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
decltype(&NEO::SysCalls::pwrite) pwriteFunction = NEO::SysCalls::pwrite;
ze_result_t createPmtHandles();
SysmanDeviceImp *getParentSysmanDeviceImp() { return pParentSysmanDeviceImp; }
std::string &getPciRootPath();
std::string &getPciRootPath() { return rootPath; }
std::string &getDeviceName();
std::string devicePciBdf = "";
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
@@ -79,6 +79,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
bool isMemoryDiagnostics = false;
std::string gtDevicePath;
SysmanKmdInterface *getSysmanKmdInterface() { return pSysmanKmdInterface.get(); }
static ze_result_t getResult(int err);
protected:
std::unique_ptr<SysmanProductHelper> pSysmanProductHelper;

View File

@@ -275,6 +275,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@@ -332,6 +333,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
@@ -391,6 +393,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
@@ -448,6 +451,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
@@ -457,7 +461,7 @@ TEST_F(SysmanGlobalOperationsFixture,
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndOpenSysCallFailsWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
GivenValidDeviceHandleAndOpenGuidReadFailsWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
@@ -474,9 +478,33 @@ TEST_F(SysmanGlobalOperationsFixture,
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "0x41fe79a5\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
@@ -500,6 +528,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);
@@ -515,6 +544,7 @@ TEST_F(SysmanGlobalOperationsFixture,
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties = {ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_result_t result = zesDeviceGetProperties(device, &properties);

View File

@@ -366,6 +366,14 @@ TEST(SysmanUnknownDriverModelTest, GivenDriverModelTypeIsNotDrmWhenExecutingSysm
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pLinuxSysmanImp->init());
}
TEST(SysmanErrorCodeTest, GivenDifferentErrorCodesWhenCallingGetResultThenVerifyProperZeResultErrorIsReturned) {
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, LinuxSysmanImp::getResult(EPERM));
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, LinuxSysmanImp::getResult(EACCES));
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, LinuxSysmanImp::getResult(ENOENT));
EXPECT_EQ(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE, LinuxSysmanImp::getResult(EBUSY));
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, LinuxSysmanImp::getResult(EEXIST));
}
} // namespace ult
} // namespace Sysman
} // namespace L0