feature: Add FsAccess and Derived class in Sysman Kmd Interface
- The FsAccess, ProcFsAccess and SysfsAccess classes have been added in a file in the Sysman Shared directory. The instances of these classes are maintained in the Sysman Kmd Interface classes. - Added functions for opendir, readdir and closedir in the shared code. - Added a ULT in the sysman directory to cover these new functions from the shared code. Related-To: LOCI-4689 Signed-off-by: Bari, Pratik <pratik.bari@intel.com>
This commit is contained in:
parent
e77e49853b
commit
f9e4381c1e
|
@ -8,6 +8,8 @@ if(UNIX)
|
|||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_kmd_interface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_fs_access_interface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_kmd_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_fs_access_interface.h
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace L0 {
|
||||
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;
|
||||
std::map<std::string, std::pair<int, uint32_t>>::iterator leastUsedIterator = it;
|
||||
while (++it != fdMap.end()) {
|
||||
if (it->second.second < fdCountRef) {
|
||||
fdCountRef = it->second.second;
|
||||
leastUsedIterator = it;
|
||||
}
|
||||
}
|
||||
NEO::SysCalls::close(leastUsedIterator->second.first);
|
||||
fdMap.erase(leastUsedIterator);
|
||||
}
|
||||
|
||||
int FdCacheInterface::getFd(std::string file) {
|
||||
int fd = -1;
|
||||
if (fdMap.find(file) == fdMap.end()) {
|
||||
fd = NEO::SysCalls::open(file.c_str(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (fdMap.size() == maxSize) {
|
||||
eraseLeastUsedEntryFromCache();
|
||||
}
|
||||
fdMap[file] = std::make_pair(fd, 1);
|
||||
} else {
|
||||
auto &fdPair = fdMap[file];
|
||||
fdPair.second++;
|
||||
}
|
||||
return fdMap[file].first;
|
||||
}
|
||||
|
||||
FdCacheInterface::~FdCacheInterface() {
|
||||
for (auto it = fdMap.begin(); it != fdMap.end(); ++it) {
|
||||
NEO::SysCalls::close(it->second.second);
|
||||
}
|
||||
fdMap.clear();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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);
|
||||
}
|
||||
|
||||
ssize_t bytesRead = NEO::SysCalls::pread(fd, readVal.data(), readVal.size(), 0);
|
||||
if (bytesRead < 0) {
|
||||
return getResult(errno);
|
||||
}
|
||||
|
||||
std::istringstream stream(readVal);
|
||||
stream >> val;
|
||||
if (stream.fail()) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// Generic Filesystem Access
|
||||
FsAccessInterface::FsAccessInterface() {
|
||||
pFdCacheInterface = std::make_unique<FdCacheInterface>();
|
||||
}
|
||||
|
||||
std::unique_ptr<FsAccessInterface> FsAccessInterface::create() {
|
||||
return std::unique_ptr<FsAccessInterface>(new FsAccessInterface());
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, uint64_t &val) {
|
||||
return readValue<uint64_t>(file, val);
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, double &val) {
|
||||
return readValue<double>(file, val);
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, int32_t &val) {
|
||||
return readValue<int32_t>(file, val);
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, uint32_t &val) {
|
||||
return readValue<uint32_t>(file, val);
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, std::string &val) {
|
||||
// Read a single line from text file without trailing newline
|
||||
std::ifstream fs;
|
||||
val.clear();
|
||||
|
||||
fs.open(file.c_str());
|
||||
if (fs.fail()) {
|
||||
return getResult(errno);
|
||||
}
|
||||
fs >> val;
|
||||
if (fs.fail()) {
|
||||
fs.close();
|
||||
return getResult(errno);
|
||||
}
|
||||
fs.close();
|
||||
// Strip trailing newline
|
||||
if (val.back() == '\n') {
|
||||
val.pop_back();
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::read(const std::string file, std::vector<std::string> &val) {
|
||||
// Read a entire text file, one line per vector entry
|
||||
std::string line;
|
||||
std::ifstream fs;
|
||||
val.clear();
|
||||
|
||||
fs.open(file.c_str());
|
||||
if (fs.fail()) {
|
||||
return getResult(errno);
|
||||
}
|
||||
while (std::getline(fs, line)) {
|
||||
if (fs.fail()) {
|
||||
fs.close();
|
||||
return getResult(errno);
|
||||
}
|
||||
if (line.back() == '\n') {
|
||||
line.pop_back();
|
||||
}
|
||||
val.push_back(line);
|
||||
}
|
||||
fs.close();
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ssize_t bytesWritten = NEO::SysCalls::pwrite(fd, val.data(), val.size(), 0);
|
||||
NEO::SysCalls::close(fd);
|
||||
if (bytesWritten < 0) {
|
||||
return getResult(errno);
|
||||
}
|
||||
|
||||
if (bytesWritten != static_cast<ssize_t>(val.size())) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::canRead(const std::string file) {
|
||||
struct stat sb;
|
||||
if (statSyscall(file.c_str(), &sb) != 0) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
if (sb.st_mode & S_IRUSR) {
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::canWrite(const std::string file) {
|
||||
struct stat sb;
|
||||
if (statSyscall(file.c_str(), &sb) != 0) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
if (sb.st_mode & S_IWUSR) {
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||
}
|
||||
|
||||
bool FsAccessInterface::fileExists(const std::string file) {
|
||||
if (NEO::SysCalls::access(file.c_str(), F_OK)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::getFileMode(const std::string file, ::mode_t &mode) {
|
||||
struct stat sb;
|
||||
if (0 != statSyscall(file.c_str(), &sb)) {
|
||||
return getResult(errno);
|
||||
}
|
||||
mode = sb.st_mode;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::readSymLink(const std::string path, std::string &val) {
|
||||
// returns the value of symlink at path
|
||||
char buf[PATH_MAX];
|
||||
ssize_t len = NEO::SysCalls::readlink(path.c_str(), buf, PATH_MAX - 1);
|
||||
if (len < 0) {
|
||||
return getResult(errno);
|
||||
}
|
||||
buf[len] = '\0';
|
||||
val = std::string(buf);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::getRealPath(const std::string path, std::string &val) {
|
||||
// returns the real file path after resolving all symlinks in path
|
||||
char buf[PATH_MAX];
|
||||
char *realPath = NEO::SysCalls::realpath(path.c_str(), buf);
|
||||
if (!realPath) {
|
||||
return getResult(errno);
|
||||
}
|
||||
val = std::string(buf);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FsAccessInterface::listDirectory(const std::string path, std::vector<std::string> &list) {
|
||||
list.clear();
|
||||
::DIR *procDir = NEO::SysCalls::opendir(path.c_str());
|
||||
if (!procDir) {
|
||||
return getResult(errno);
|
||||
}
|
||||
struct ::dirent *ent;
|
||||
int err = 0;
|
||||
// readdir doesn't clear errno, so make sure it is clear
|
||||
errno = 0;
|
||||
while (NULL != (ent = NEO::SysCalls::readdir(procDir))) {
|
||||
// Ignore . and ..
|
||||
std::string name = std::string(ent->d_name);
|
||||
if (!name.compare(".") || !name.compare("..")) {
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
list.push_back(std::string(ent->d_name));
|
||||
errno = 0;
|
||||
}
|
||||
err = errno;
|
||||
NEO::SysCalls::closedir(procDir);
|
||||
// Check if in above while loop, readdir encountered any error.
|
||||
if ((err != 0) && (err != ENOENT)) {
|
||||
list.clear();
|
||||
return getResult(err);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
std::string FsAccessInterface::getBaseName(const std::string path) {
|
||||
size_t pos = path.rfind("/");
|
||||
if (std::string::npos == pos) {
|
||||
return path;
|
||||
}
|
||||
return path.substr(pos + 1, std::string::npos);
|
||||
}
|
||||
|
||||
std::string FsAccessInterface::getDirName(const std::string path) {
|
||||
size_t pos = path.rfind("/");
|
||||
if (std::string::npos == pos) {
|
||||
return std::string("");
|
||||
}
|
||||
// Include trailing slash
|
||||
return path.substr(0, pos);
|
||||
}
|
||||
|
||||
bool FsAccessInterface::isRootUser() {
|
||||
return (geteuid() == 0);
|
||||
}
|
||||
|
||||
bool FsAccessInterface::directoryExists(const std::string path) {
|
||||
if (accessSyscall(path.c_str(), F_OK)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Procfs Access
|
||||
ProcFsAccessInterface::ProcFsAccessInterface() = default;
|
||||
ProcFsAccessInterface::~ProcFsAccessInterface() = default;
|
||||
|
||||
const std::string ProcFsAccessInterface::procDir = "/proc/";
|
||||
const std::string ProcFsAccessInterface::fdDir = "/fd/";
|
||||
|
||||
std::string ProcFsAccessInterface::fullPath(const ::pid_t pid) {
|
||||
// Returns the full path for proc entry for process pid
|
||||
return std::string(procDir + std::to_string(pid));
|
||||
}
|
||||
|
||||
std::string ProcFsAccessInterface::fdDirPath(const ::pid_t pid) {
|
||||
// Returns the full path to file descritpor directory
|
||||
// for process pid
|
||||
return std::string(fullPath(pid) + fdDir);
|
||||
}
|
||||
|
||||
std::string ProcFsAccessInterface::fullFdPath(const ::pid_t pid, const int fd) {
|
||||
// Returns the full path for filedescriptor fd
|
||||
// for process pid
|
||||
return std::string(fdDirPath(pid) + std::to_string(fd));
|
||||
}
|
||||
|
||||
std::unique_ptr<ProcFsAccessInterface> ProcFsAccessInterface::create() {
|
||||
return std::unique_ptr<ProcFsAccessInterface>(new ProcFsAccessInterface());
|
||||
}
|
||||
|
||||
ze_result_t ProcFsAccessInterface::listProcesses(std::vector<::pid_t> &list) {
|
||||
// Returns a vector with all the active process ids in the system
|
||||
list.clear();
|
||||
std::vector<std::string> dir;
|
||||
ze_result_t result = FsAccessInterface::listDirectory(procDir, dir);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &&file : dir) {
|
||||
::pid_t pid;
|
||||
std::istringstream stream(file);
|
||||
stream >> pid;
|
||||
if (stream.fail()) {
|
||||
// Non numeric filename, not a process, skip
|
||||
continue;
|
||||
}
|
||||
list.push_back(pid);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t ProcFsAccessInterface::getFileDescriptors(const ::pid_t pid, std::vector<int> &list) {
|
||||
// Returns a vector with all the filedescriptor numbers opened by a pid
|
||||
list.clear();
|
||||
std::vector<std::string> dir;
|
||||
ze_result_t result = FsAccessInterface::listDirectory(fdDirPath(pid), dir);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &&file : dir) {
|
||||
int fd;
|
||||
std::istringstream stream(file);
|
||||
stream >> fd;
|
||||
if (stream.fail()) {
|
||||
// Non numeric filename, not a file descriptor
|
||||
continue;
|
||||
}
|
||||
list.push_back(fd);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t ProcFsAccessInterface::getFileName(const ::pid_t pid, const int fd, std::string &val) {
|
||||
// Given a process id and a file descriptor number
|
||||
// return full name of the open file.
|
||||
// NOTE: For sockets, the name will be of the format "socket:[nnnnnnn]"
|
||||
return FsAccessInterface::readSymLink(fullFdPath(pid, fd), val);
|
||||
}
|
||||
|
||||
bool ProcFsAccessInterface::isAlive(const ::pid_t pid) {
|
||||
return FsAccessInterface::fileExists(fullPath(pid));
|
||||
}
|
||||
|
||||
void ProcFsAccessInterface::kill(const ::pid_t pid) {
|
||||
::kill(pid, SIGKILL);
|
||||
}
|
||||
|
||||
::pid_t ProcFsAccessInterface::myProcessId() {
|
||||
return ::getpid();
|
||||
}
|
||||
|
||||
// Sysfs Access
|
||||
SysFsAccessInterface::SysFsAccessInterface() = default;
|
||||
SysFsAccessInterface::~SysFsAccessInterface() = default;
|
||||
|
||||
const std::string SysFsAccessInterface::drmPath = "/sys/class/drm/";
|
||||
const std::string SysFsAccessInterface::devicesPath = "device/drm/";
|
||||
const std::string SysFsAccessInterface::primaryDevName = "card";
|
||||
const std::string SysFsAccessInterface::drmDriverDevNodeDir = "/dev/dri/";
|
||||
const std::string SysFsAccessInterface::intelGpuBindEntry = "/sys/bus/pci/drivers/i915/bind";
|
||||
const std::string SysFsAccessInterface::intelGpuUnbindEntry = "/sys/bus/pci/drivers/i915/unbind";
|
||||
|
||||
std::string SysFsAccessInterface::fullPath(const std::string file) {
|
||||
// Prepend sysfs directory path for this device
|
||||
return std::string(dirname + file);
|
||||
}
|
||||
|
||||
SysFsAccessInterface::SysFsAccessInterface(const std::string dev) {
|
||||
// dev could be either /dev/dri/cardX or /dev/dri/renderDX
|
||||
std::string fileName = FsAccessInterface::getBaseName(dev);
|
||||
std::string devicesDir = drmPath + fileName + std::string("/") + devicesPath;
|
||||
|
||||
FsAccessInterface::listDirectory(devicesDir, deviceNames);
|
||||
for (auto &&next : deviceNames) {
|
||||
if (!next.compare(0, primaryDevName.length(), primaryDevName)) {
|
||||
dirname = drmPath + next + std::string("/");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<SysFsAccessInterface> SysFsAccessInterface::create(const std::string dev) {
|
||||
return std::unique_ptr<SysFsAccessInterface>(new SysFsAccessInterface(dev));
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::canRead(const std::string file) {
|
||||
// Prepend sysfs directory path and call the base canRead
|
||||
return FsAccessInterface::canRead(fullPath(file));
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::canWrite(const std::string file) {
|
||||
// Prepend sysfs directory path and call the base canWrite
|
||||
return FsAccessInterface::canWrite(fullPath(file));
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::getFileMode(const std::string file, ::mode_t &mode) {
|
||||
// Prepend sysfs directory path and call the base getFileMode
|
||||
return FsAccessInterface::getFileMode(fullPath(file), mode);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, std::string &val) {
|
||||
// Prepend sysfs directory path and call the base read
|
||||
return FsAccessInterface::read(fullPath(file).c_str(), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, int32_t &val) {
|
||||
return FsAccessInterface::read(fullPath(file), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, uint32_t &val) {
|
||||
return FsAccessInterface::read(fullPath(file), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, double &val) {
|
||||
return FsAccessInterface::read(fullPath(file), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, uint64_t &val) {
|
||||
return FsAccessInterface::read(fullPath(file), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::read(const std::string file, std::vector<std::string> &val) {
|
||||
// Prepend sysfs directory path and call the base read
|
||||
return FsAccessInterface::read(fullPath(file), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::write(const std::string file, const std::string val) {
|
||||
// Prepend sysfs directory path and call the base write
|
||||
return FsAccessInterface::write(fullPath(file).c_str(), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::write(const std::string file, const int val) {
|
||||
std::ostringstream stream;
|
||||
stream << val;
|
||||
|
||||
if (stream.fail()) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
return FsAccessInterface::write(fullPath(file), stream.str());
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::write(const std::string file, const double val) {
|
||||
std::ostringstream stream;
|
||||
stream << val;
|
||||
|
||||
if (stream.fail()) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
return FsAccessInterface::write(fullPath(file), stream.str());
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::write(const std::string file, const uint64_t val) {
|
||||
std::ostringstream stream;
|
||||
stream << val;
|
||||
|
||||
if (stream.fail()) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
return FsAccessInterface::write(fullPath(file), stream.str());
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::scanDirEntries(const std::string path, std::vector<std::string> &list) {
|
||||
list.clear();
|
||||
return FsAccessInterface::listDirectory(fullPath(path).c_str(), list);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::readSymLink(const std::string path, std::string &val) {
|
||||
// Prepend sysfs directory path and call the base readSymLink
|
||||
return FsAccessInterface::readSymLink(fullPath(path).c_str(), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::getRealPath(const std::string path, std::string &val) {
|
||||
// Prepend sysfs directory path and call the base getRealPath
|
||||
return FsAccessInterface::getRealPath(fullPath(path).c_str(), val);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::bindDevice(std::string device) {
|
||||
return FsAccessInterface::write(intelGpuBindEntry, device);
|
||||
}
|
||||
|
||||
ze_result_t SysFsAccessInterface::unbindDevice(std::string device) {
|
||||
return FsAccessInterface::write(intelGpuUnbindEntry, device);
|
||||
}
|
||||
|
||||
bool SysFsAccessInterface::fileExists(const std::string file) {
|
||||
// Prepend sysfs directory path and call the base fileExists
|
||||
return FsAccessInterface::fileExists(fullPath(file).c_str());
|
||||
}
|
||||
|
||||
bool SysFsAccessInterface::directoryExists(const std::string path) {
|
||||
return FsAccessInterface::directoryExists(fullPath(path).c_str());
|
||||
}
|
||||
|
||||
bool SysFsAccessInterface::isMyDeviceFile(const std::string dev) {
|
||||
// dev is a full pathname.
|
||||
if (getDirName(dev).compare(drmDriverDevNodeDir)) {
|
||||
for (auto &&next : deviceNames) {
|
||||
if (!getBaseName(dev).compare(next)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SysFsAccessInterface::isRootUser() {
|
||||
return FsAccessInterface::isRootUser();
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/os_interface/linux/sys_calls.h"
|
||||
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class FdCacheInterface {
|
||||
public:
|
||||
FdCacheInterface() = default;
|
||||
~FdCacheInterface();
|
||||
|
||||
static const int maxSize = 10;
|
||||
int getFd(std::string file);
|
||||
|
||||
protected:
|
||||
std::map<std::string, std::pair<int, uint32_t>> fdMap = {};
|
||||
|
||||
private:
|
||||
void eraseLeastUsedEntryFromCache();
|
||||
};
|
||||
|
||||
class FsAccessInterface {
|
||||
public:
|
||||
static std::unique_ptr<FsAccessInterface> create();
|
||||
virtual ~FsAccessInterface();
|
||||
|
||||
virtual ze_result_t canRead(const std::string file);
|
||||
virtual ze_result_t canWrite(const std::string file);
|
||||
virtual ze_result_t getFileMode(const std::string file, ::mode_t &mode);
|
||||
|
||||
virtual ze_result_t read(const std::string file, uint64_t &val);
|
||||
virtual ze_result_t read(const std::string file, std::string &val);
|
||||
virtual ze_result_t read(const std::string file, std::vector<std::string> &val);
|
||||
virtual ze_result_t read(const std::string file, double &val);
|
||||
virtual ze_result_t read(const std::string file, uint32_t &val);
|
||||
virtual ze_result_t read(const std::string file, int32_t &val);
|
||||
|
||||
virtual ze_result_t write(const std::string file, const std::string val);
|
||||
|
||||
virtual ze_result_t readSymLink(const std::string path, std::string &buf);
|
||||
virtual ze_result_t getRealPath(const std::string path, std::string &buf);
|
||||
virtual ze_result_t listDirectory(const std::string path, std::vector<std::string> &list);
|
||||
virtual bool isRootUser();
|
||||
std::string getBaseName(const std::string path);
|
||||
std::string getDirName(const std::string path);
|
||||
virtual bool fileExists(const std::string file);
|
||||
virtual bool directoryExists(const std::string path);
|
||||
|
||||
protected:
|
||||
FsAccessInterface();
|
||||
decltype(&NEO::SysCalls::access) accessSyscall = NEO::SysCalls::access;
|
||||
decltype(&stat) statSyscall = stat;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
ze_result_t readValue(const std::string file, T &val);
|
||||
std::unique_ptr<FdCacheInterface> pFdCacheInterface = nullptr;
|
||||
};
|
||||
|
||||
class ProcFsAccessInterface : private FsAccessInterface {
|
||||
public:
|
||||
static std::unique_ptr<ProcFsAccessInterface> create();
|
||||
~ProcFsAccessInterface() override;
|
||||
|
||||
MOCKABLE_VIRTUAL ze_result_t listProcesses(std::vector<::pid_t> &list);
|
||||
MOCKABLE_VIRTUAL ::pid_t myProcessId();
|
||||
MOCKABLE_VIRTUAL ze_result_t getFileDescriptors(const ::pid_t pid, std::vector<int> &list);
|
||||
MOCKABLE_VIRTUAL ze_result_t getFileName(const ::pid_t pid, const int fd, std::string &val);
|
||||
MOCKABLE_VIRTUAL bool isAlive(const ::pid_t pid);
|
||||
MOCKABLE_VIRTUAL void kill(const ::pid_t pid);
|
||||
|
||||
protected:
|
||||
ProcFsAccessInterface();
|
||||
|
||||
private:
|
||||
std::string fullPath(const ::pid_t pid);
|
||||
std::string fdDirPath(const ::pid_t pid);
|
||||
std::string fullFdPath(const ::pid_t pid, const int fd);
|
||||
static const std::string procDir;
|
||||
static const std::string fdDir;
|
||||
};
|
||||
|
||||
class SysFsAccessInterface : protected FsAccessInterface {
|
||||
public:
|
||||
static std::unique_ptr<SysFsAccessInterface> create(const std::string file);
|
||||
~SysFsAccessInterface() override;
|
||||
|
||||
ze_result_t canRead(const std::string file) override;
|
||||
ze_result_t canWrite(const std::string file) override;
|
||||
ze_result_t getFileMode(const std::string file, ::mode_t &mode) override;
|
||||
|
||||
ze_result_t read(const std::string file, std::string &val) override;
|
||||
ze_result_t read(const std::string file, int32_t &val) override;
|
||||
ze_result_t read(const std::string file, uint32_t &val) override;
|
||||
ze_result_t read(const std::string file, uint64_t &val) override;
|
||||
ze_result_t read(const std::string file, double &val) override;
|
||||
ze_result_t read(const std::string file, std::vector<std::string> &val) override;
|
||||
|
||||
ze_result_t write(const std::string file, const std::string val) override;
|
||||
MOCKABLE_VIRTUAL ze_result_t write(const std::string file, const int val);
|
||||
MOCKABLE_VIRTUAL ze_result_t write(const std::string file, const uint64_t val);
|
||||
MOCKABLE_VIRTUAL ze_result_t write(const std::string file, const double val);
|
||||
ze_result_t write(const std::string file, std::vector<std::string> val);
|
||||
|
||||
MOCKABLE_VIRTUAL ze_result_t scanDirEntries(const std::string path, std::vector<std::string> &list);
|
||||
ze_result_t readSymLink(const std::string path, std::string &buf) override;
|
||||
ze_result_t getRealPath(const std::string path, std::string &buf) override;
|
||||
MOCKABLE_VIRTUAL ze_result_t bindDevice(const std::string device);
|
||||
MOCKABLE_VIRTUAL ze_result_t unbindDevice(const std::string device);
|
||||
bool fileExists(const std::string file) override;
|
||||
MOCKABLE_VIRTUAL bool isMyDeviceFile(const std::string dev);
|
||||
bool directoryExists(const std::string path) override;
|
||||
bool isRootUser() override;
|
||||
|
||||
protected:
|
||||
SysFsAccessInterface();
|
||||
SysFsAccessInterface(const std::string file);
|
||||
std::vector<std::string> deviceNames;
|
||||
|
||||
private:
|
||||
std::string fullPath(const std::string file);
|
||||
std::string dirname;
|
||||
static const std::string drmPath;
|
||||
static const std::string devicesPath;
|
||||
static const std::string primaryDevName;
|
||||
static const std::string drmDriverDevNodeDir;
|
||||
static const std::string intelGpuBindEntry;
|
||||
static const std::string intelGpuUnbindEntry;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
|
@ -13,11 +13,26 @@
|
|||
#include "shared/source/os_interface/linux/i915_prelim.h"
|
||||
|
||||
#include "level_zero/sysman/source/linux/pmu/sysman_pmu_imp.h"
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
using NEO::PrelimI915::I915_SAMPLE_BUSY;
|
||||
|
||||
SysmanKmdInterface::SysmanKmdInterface() = default;
|
||||
|
||||
SysmanKmdInterfaceI915::SysmanKmdInterfaceI915(const PRODUCT_FAMILY productFamily) {
|
||||
initSysfsNameToFileMap(productFamily);
|
||||
}
|
||||
|
||||
SysmanKmdInterfaceXe::SysmanKmdInterfaceXe(const PRODUCT_FAMILY productFamily) {
|
||||
initSysfsNameToFileMap(productFamily);
|
||||
}
|
||||
|
||||
SysmanKmdInterface::~SysmanKmdInterface() = default;
|
||||
SysmanKmdInterfaceI915::~SysmanKmdInterfaceI915() = default;
|
||||
SysmanKmdInterfaceXe::~SysmanKmdInterfaceXe() = default;
|
||||
|
||||
std::unique_ptr<SysmanKmdInterface> SysmanKmdInterface::create(const NEO::Drm &drm) {
|
||||
std::unique_ptr<SysmanKmdInterface> pSysmanKmdInterface;
|
||||
auto drmVersion = drm.getDrmVersion(drm.getFileDescriptor());
|
||||
|
@ -32,6 +47,33 @@ std::unique_ptr<SysmanKmdInterface> SysmanKmdInterface::create(const NEO::Drm &d
|
|||
return pSysmanKmdInterface;
|
||||
}
|
||||
|
||||
FsAccessInterface *SysmanKmdInterface::getFsAccess() {
|
||||
|
||||
if (nullptr == pFsAccess.get()) {
|
||||
pFsAccess = FsAccessInterface::create();
|
||||
}
|
||||
UNRECOVERABLE_IF(nullptr == pFsAccess.get());
|
||||
return pFsAccess.get();
|
||||
}
|
||||
|
||||
ProcFsAccessInterface *SysmanKmdInterface::getProcFsAccess() {
|
||||
|
||||
if (nullptr == pProcfsAccess.get()) {
|
||||
pProcfsAccess = ProcFsAccessInterface::create();
|
||||
}
|
||||
UNRECOVERABLE_IF(nullptr == pProcfsAccess.get());
|
||||
return pProcfsAccess.get();
|
||||
}
|
||||
|
||||
SysFsAccessInterface *SysmanKmdInterface::getSysFsAccess(std::string deviceName) {
|
||||
|
||||
if (nullptr == pSysfsAccess.get()) {
|
||||
pSysfsAccess = SysFsAccessInterface::create(deviceName);
|
||||
}
|
||||
UNRECOVERABLE_IF(nullptr == pSysfsAccess.get());
|
||||
return pSysfsAccess.get();
|
||||
}
|
||||
|
||||
std::string SysmanKmdInterfaceI915::getBasePath(uint32_t subDeviceId) const {
|
||||
return "gt/gt" + std::to_string(subDeviceId) + "/";
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ class Drm;
|
|||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class FsAccessInterface;
|
||||
class ProcFsAccessInterface;
|
||||
class SysFsAccessInterface;
|
||||
class PmuInterface;
|
||||
typedef std::pair<std::string, std::string> valuePair;
|
||||
|
||||
|
@ -79,7 +82,8 @@ enum class SysfsName {
|
|||
|
||||
class SysmanKmdInterface {
|
||||
public:
|
||||
virtual ~SysmanKmdInterface() = default;
|
||||
SysmanKmdInterface();
|
||||
virtual ~SysmanKmdInterface();
|
||||
static std::unique_ptr<SysmanKmdInterface> create(const NEO::Drm &drm);
|
||||
|
||||
virtual std::string getBasePath(uint32_t subDeviceId) const = 0;
|
||||
|
@ -89,12 +93,20 @@ class SysmanKmdInterface {
|
|||
virtual std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const = 0;
|
||||
virtual bool isStandbyModeControlAvailable() const = 0;
|
||||
virtual bool clientInfoAvailableInFdInfo() = 0;
|
||||
FsAccessInterface *getFsAccess();
|
||||
ProcFsAccessInterface *getProcFsAccess();
|
||||
SysFsAccessInterface *getSysFsAccess(std::string deviceName);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<FsAccessInterface> pFsAccess;
|
||||
std::unique_ptr<ProcFsAccessInterface> pProcfsAccess;
|
||||
std::unique_ptr<SysFsAccessInterface> pSysfsAccess;
|
||||
};
|
||||
|
||||
class SysmanKmdInterfaceI915 : public SysmanKmdInterface {
|
||||
public:
|
||||
SysmanKmdInterfaceI915(const PRODUCT_FAMILY productFamily) { initSysfsNameToFileMap(productFamily); }
|
||||
~SysmanKmdInterfaceI915() override = default;
|
||||
SysmanKmdInterfaceI915(const PRODUCT_FAMILY productFamily);
|
||||
~SysmanKmdInterfaceI915() override;
|
||||
|
||||
std::string getBasePath(uint32_t subDeviceId) const override;
|
||||
std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) override;
|
||||
|
@ -111,8 +123,8 @@ class SysmanKmdInterfaceI915 : public SysmanKmdInterface {
|
|||
|
||||
class SysmanKmdInterfaceXe : public SysmanKmdInterface {
|
||||
public:
|
||||
SysmanKmdInterfaceXe(const PRODUCT_FAMILY productFamily) { initSysfsNameToFileMap(productFamily); }
|
||||
~SysmanKmdInterfaceXe() override = default;
|
||||
SysmanKmdInterfaceXe(const PRODUCT_FAMILY productFamily);
|
||||
~SysmanKmdInterfaceXe() override;
|
||||
|
||||
std::string getBasePath(uint32_t subDeviceId) const override;
|
||||
std::string getSysfsFilePath(SysfsName sysfsName, uint32_t subDeviceId, bool baseDirectoryExists) override;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "shared/test/common/mocks/mock_driver_info.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h"
|
||||
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
|
||||
|
||||
namespace NEO {
|
||||
|
@ -20,6 +22,12 @@ namespace L0 {
|
|||
namespace Sysman {
|
||||
namespace ult {
|
||||
|
||||
struct dirent mockEntries[] = {
|
||||
{0, 0, 0, 0, "."},
|
||||
{0, 0, 0, 0, "mockDir1"},
|
||||
{0, 0, 0, 0, "mockDir2"},
|
||||
};
|
||||
|
||||
inline static int mockAccessFailure(const char *pathname, int mode) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -42,6 +50,34 @@ inline static int mockStatNoPermissions(const char *pathname, struct stat *sb) n
|
|||
return 0;
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFixture, GivenValidSysmanKmdInterfaceWhenCallingListDirectoriesThenSuccessIsReturned) {
|
||||
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
auto pFsAccess = pSysmanKmdInterface->getFsAccess();
|
||||
const uint32_t numEntries = sizeof(mockEntries) / sizeof(mockEntries[0]);
|
||||
|
||||
VariableBackup<decltype(NEO::SysCalls::sysCallsOpendir)> mockOpendir(&NEO::SysCalls::sysCallsOpendir, [](const char *name) -> DIR * {
|
||||
return reinterpret_cast<DIR *>(0xc001);
|
||||
});
|
||||
|
||||
VariableBackup<decltype(NEO::SysCalls::sysCallsReaddir)> mockReaddir(
|
||||
&NEO::SysCalls::sysCallsReaddir, [](DIR * dir) -> struct dirent * {
|
||||
static uint32_t entryIndex = 0u;
|
||||
if (entryIndex >= numEntries) {
|
||||
entryIndex = 0;
|
||||
return nullptr;
|
||||
}
|
||||
return &mockEntries[entryIndex++];
|
||||
});
|
||||
|
||||
VariableBackup<decltype(NEO::SysCalls::sysCallsClosedir)> mockClosedir(&NEO::SysCalls::sysCallsClosedir, [](DIR *dir) -> int {
|
||||
return 0;
|
||||
});
|
||||
|
||||
std::vector<std::string> listFiles;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, pFsAccess->listDirectory("MockDir", listFiles));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFixture, GivenCreateFsAccessHandleWhenCallinggetFsAccessThenCreatedFsAccessHandleWillBeRetrieved) {
|
||||
if (pLinuxSysmanImp->pFsAccess != nullptr) {
|
||||
// delete previously allocated pFsAccess
|
||||
|
|
|
@ -11,15 +11,12 @@
|
|||
#include "shared/source/device/device.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h"
|
||||
#include "level_zero/tools/source/sysman/linux/os_sysman_imp.h"
|
||||
|
||||
#include "igfxfmid.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace L0::Sysman;
|
||||
|
||||
namespace L0 {
|
||||
|
||||
const bool LinuxFrequencyImp::canControl = true; // canControl is true on i915 (GEN9 Hardcode)
|
||||
|
@ -387,37 +384,46 @@ ze_result_t LinuxFrequencyImp::getMinVal(double &minVal) {
|
|||
}
|
||||
|
||||
void LinuxFrequencyImp::init() {
|
||||
|
||||
const std::string baseDir = pSysmanKmdInterface->getBasePath(subdeviceId);
|
||||
bool baseDirectoryExists = false;
|
||||
|
||||
const std::string baseDir = "gt/gt" + std::to_string(subdeviceId) + "/";
|
||||
if (pSysfsAccess->directoryExists(baseDir)) {
|
||||
baseDirectoryExists = true;
|
||||
minFreqFile = baseDir + "rps_min_freq_mhz";
|
||||
minDefaultFreqFile = baseDir + ".defaults/rps_min_freq_mhz";
|
||||
maxFreqFile = baseDir + "rps_max_freq_mhz";
|
||||
boostFreqFile = baseDir + "rps_boost_freq_mhz";
|
||||
maxDefaultFreqFile = baseDir + ".defaults/rps_max_freq_mhz";
|
||||
requestFreqFile = baseDir + "punit_req_freq_mhz";
|
||||
tdpFreqFile = baseDir + "rapl_PL1_freq_mhz";
|
||||
actualFreqFile = baseDir + "rps_act_freq_mhz";
|
||||
efficientFreqFile = baseDir + "rps_RP1_freq_mhz";
|
||||
maxValFreqFile = baseDir + "rps_RP0_freq_mhz";
|
||||
minValFreqFile = baseDir + "rps_RPn_freq_mhz";
|
||||
throttleReasonStatusFile = baseDir + "throttle_reason_status";
|
||||
throttleReasonPL1File = baseDir + "throttle_reason_pl1";
|
||||
throttleReasonPL2File = baseDir + "throttle_reason_pl2";
|
||||
throttleReasonPL4File = baseDir + "throttle_reason_pl4";
|
||||
throttleReasonThermalFile = baseDir + "throttle_reason_thermal";
|
||||
} else {
|
||||
minFreqFile = "gt_min_freq_mhz";
|
||||
maxFreqFile = "gt_max_freq_mhz";
|
||||
boostFreqFile = "gt_boost_freq_mhz";
|
||||
requestFreqFile = "gt_cur_freq_mhz";
|
||||
tdpFreqFile = "rapl_PL1_freq_mhz";
|
||||
actualFreqFile = "gt_act_freq_mhz";
|
||||
efficientFreqFile = "gt_RP1_freq_mhz";
|
||||
maxValFreqFile = "gt_RP0_freq_mhz";
|
||||
minValFreqFile = "gt_RPn_freq_mhz";
|
||||
throttleReasonStatusFile = "gt_throttle_reason_status";
|
||||
throttleReasonPL1File = "gt_throttle_reason_status_pl1";
|
||||
throttleReasonPL2File = "gt_throttle_reason_status_pl2";
|
||||
throttleReasonPL4File = "gt_throttle_reason_status_pl4";
|
||||
throttleReasonThermalFile = "gt_throttle_reason_status_thermal";
|
||||
}
|
||||
|
||||
minFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinFrequency, subdeviceId, baseDirectoryExists);
|
||||
minDefaultFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinDefaultFrequency, subdeviceId, baseDirectoryExists);
|
||||
maxFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxFrequency, subdeviceId, baseDirectoryExists);
|
||||
maxDefaultFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxDefaultFrequency, subdeviceId, baseDirectoryExists);
|
||||
boostFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameBoostFrequency, subdeviceId, baseDirectoryExists);
|
||||
requestFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCurrentFrequency, subdeviceId, baseDirectoryExists);
|
||||
tdpFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameTdpFrequency, subdeviceId, baseDirectoryExists);
|
||||
actualFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameActualFrequency, subdeviceId, baseDirectoryExists);
|
||||
efficientFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEfficientFrequency, subdeviceId, baseDirectoryExists);
|
||||
maxValFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxValueFrequency, subdeviceId, baseDirectoryExists);
|
||||
minValFreqFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinValueFrequency, subdeviceId, baseDirectoryExists);
|
||||
throttleReasonStatusFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonStatus, subdeviceId, baseDirectoryExists);
|
||||
throttleReasonPL1File = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL1, subdeviceId, baseDirectoryExists);
|
||||
throttleReasonPL2File = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL2, subdeviceId, baseDirectoryExists);
|
||||
throttleReasonPL4File = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL4, subdeviceId, baseDirectoryExists);
|
||||
throttleReasonThermalFile = pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonThermal, subdeviceId, baseDirectoryExists);
|
||||
}
|
||||
|
||||
LinuxFrequencyImp::LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) : isSubdevice(onSubdevice), subdeviceId(subdeviceId), frequencyDomainNumber(frequencyDomainNumber) {
|
||||
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
pDevice = Device::fromHandle(pLinuxSysmanImp->getSysmanDeviceImp()->hCoreDevice);
|
||||
pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#include "level_zero/tools/source/sysman/frequency/os_frequency.h"
|
||||
#include "level_zero/tools/source/sysman/linux/fs_access.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
class SysmanKmdInterface;
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
namespace L0 {
|
||||
|
||||
class LinuxFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass {
|
||||
|
@ -43,7 +38,6 @@ class LinuxFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass {
|
|||
~LinuxFrequencyImp() override = default;
|
||||
|
||||
protected:
|
||||
L0::Sysman::SysmanKmdInterface *pSysmanKmdInterface = nullptr;
|
||||
SysfsAccess *pSysfsAccess = nullptr;
|
||||
ze_result_t getMin(double &min);
|
||||
ze_result_t setMin(double min);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "level_zero/core/source/device/device_imp.h"
|
||||
#include "level_zero/core/source/driver/driver_handle_imp.h"
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h"
|
||||
#include "level_zero/tools/source/sysman/firmware_util/firmware_util.h"
|
||||
#include "level_zero/tools/source/sysman/linux/fs_access.h"
|
||||
#include "level_zero/tools/source/sysman/pci/linux/os_pci_imp.h"
|
||||
|
@ -55,8 +54,6 @@ ze_result_t LinuxSysmanImp::init() {
|
|||
|
||||
DEBUG_BREAK_IF(nullptr == pPmuInterface);
|
||||
|
||||
pSysmanKmdInterface = L0::Sysman::SysmanKmdInterface::create(getDrm());
|
||||
|
||||
getMemoryType();
|
||||
return createPmtHandles();
|
||||
}
|
||||
|
|
|
@ -22,12 +22,6 @@
|
|||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
class SysmanKmdInterface;
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
namespace L0 {
|
||||
|
||||
class PmuInterface;
|
||||
|
@ -92,10 +86,8 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
|
|||
bool isMemoryDiagnostics = false;
|
||||
Device *pDevice = nullptr;
|
||||
std::string gtDevicePath;
|
||||
L0::Sysman::SysmanKmdInterface *getSysmanKmdInterface() { return pSysmanKmdInterface.get(); }
|
||||
|
||||
protected:
|
||||
std::unique_ptr<L0::Sysman::SysmanKmdInterface> pSysmanKmdInterface;
|
||||
FsAccess *pFsAccess = nullptr;
|
||||
ProcfsAccess *pProcfsAccess = nullptr;
|
||||
SysfsAccess *pSysfsAccess = nullptr;
|
||||
|
|
|
@ -5,15 +5,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h"
|
||||
#include "level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/mock_sysfs_frequency_prelim.h"
|
||||
#include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "igfxfmid.h"
|
||||
|
||||
using namespace L0::Sysman;
|
||||
|
||||
#include <cmath>
|
||||
|
||||
extern bool sysmanUltsEnable;
|
||||
|
@ -110,48 +107,6 @@ class SysmanDeviceFrequencyFixture : public SysmanDeviceFixture {
|
|||
}
|
||||
};
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenKmdInterfaceWhenGettingFilenamesForFrequencyFilesForI915VersionAndBaseDirectoryExistsThenProperPathsAreReturned) {
|
||||
auto pSysmanKmdInterface = std::make_unique<SysmanKmdInterfaceI915>(device->getNEODevice()->getHardwareInfo().platform.eProductFamily);
|
||||
bool baseDirectoryExists = true;
|
||||
EXPECT_STREQ("gt/gt1/rps_min_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_max_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/.defaults/rps_min_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinDefaultFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/.defaults/rps_max_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxDefaultFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_boost_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameBoostFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/punit_req_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCurrentFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rapl_PL1_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameTdpFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_act_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameActualFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_RP1_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEfficientFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_RP0_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxValueFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/rps_RPn_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinValueFrequency, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/throttle_reason_status", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonStatus, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/throttle_reason_pl1", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL1, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/throttle_reason_pl2", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL2, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/throttle_reason_pl4", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL4, 1, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("gt/gt1/throttle_reason_thermal", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonThermal, 1, baseDirectoryExists).c_str());
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenKmdInterfaceWhenGettingFilenamesForFrequencyFilesForXeVersionAndBaseDirectoryExistsThenProperPathsAreReturned) {
|
||||
auto pSysmanKmdInterface = std::make_unique<SysmanKmdInterfaceXe>(device->getNEODevice()->getHardwareInfo().platform.eProductFamily);
|
||||
bool baseDirectoryExists = true;
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_min_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_max_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/.defaults/rps_min_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinDefaultFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/.defaults/rps_max_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxDefaultFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_boost_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameBoostFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/punit_req_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameCurrentFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rapl_PL1_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameTdpFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_act_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameActualFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_RP1_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameEfficientFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_RP0_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMaxValueFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/rps_RPn_freq_mhz", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameMinValueFrequency, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/throttle_reason_status", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonStatus, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/throttle_reason_pl1", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL1, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/throttle_reason_pl2", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL2, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/throttle_reason_pl4", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonPL4, 0, baseDirectoryExists).c_str());
|
||||
EXPECT_STREQ("device/tile0/gt0/throttle_reason_thermal", pSysmanKmdInterface->getSysfsFilePath(SysfsName::sysfsNameThrottleReasonThermal, 0, baseDirectoryExists).c_str());
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyHandlesThenNonZeroCountIsReturnedAndCallSucceds) {
|
||||
uint32_t count = 0U;
|
||||
|
||||
|
|
|
@ -48,5 +48,8 @@ int scandir(const char *dirp,
|
|||
int (*compar)(const struct dirent **,
|
||||
const struct dirent **));
|
||||
int unlink(const std::string &pathname);
|
||||
DIR *opendir(const char *name);
|
||||
struct dirent *readdir(DIR *dir);
|
||||
int closedir(DIR *dir);
|
||||
} // namespace SysCalls
|
||||
} // namespace NEO
|
||||
|
|
|
@ -171,5 +171,17 @@ int unlink(const std::string &pathname) {
|
|||
return ::unlink(pathname.c_str());
|
||||
}
|
||||
|
||||
DIR *opendir(const char *name) {
|
||||
return ::opendir(name);
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *dir) {
|
||||
return ::readdir(dir);
|
||||
}
|
||||
|
||||
int closedir(DIR *dir) {
|
||||
return ::closedir(dir);
|
||||
}
|
||||
|
||||
} // namespace SysCalls
|
||||
} // namespace NEO
|
||||
|
|
|
@ -58,6 +58,9 @@ int mkstempCalled = 0;
|
|||
int renameCalled = 0;
|
||||
int pathFileExistsCalled = 0;
|
||||
int flockCalled = 0;
|
||||
int opendirCalled = 0;
|
||||
int readdirCalled = 0;
|
||||
int closedirCalled = 0;
|
||||
|
||||
std::vector<void *> mmapVector(64);
|
||||
std::vector<void *> mmapCapturedExtendedPointers(64);
|
||||
|
@ -92,6 +95,9 @@ int (*sysCallsStat)(const std::string &filePath, struct stat *statbuf) = nullptr
|
|||
int (*sysCallsMkstemp)(char *fileName) = nullptr;
|
||||
int (*sysCallsMkdir)(const std::string &dir) = nullptr;
|
||||
bool (*sysCallsPathExists)(const std::string &path) = nullptr;
|
||||
DIR *(*sysCallsOpendir)(const char *name) = nullptr;
|
||||
struct dirent *(*sysCallsReaddir)(DIR *dir) = nullptr;
|
||||
int (*sysCallsClosedir)(DIR *dir) = nullptr;
|
||||
|
||||
int mkdir(const std::string &path) {
|
||||
if (sysCallsMkdir != nullptr) {
|
||||
|
@ -413,5 +419,32 @@ int stat(const std::string &filePath, struct stat *statbuf) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
DIR *opendir(const char *name) {
|
||||
opendirCalled++;
|
||||
if (sysCallsOpendir != nullptr) {
|
||||
return sysCallsOpendir(name);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *dir) {
|
||||
readdirCalled++;
|
||||
if (sysCallsReaddir != nullptr) {
|
||||
return sysCallsReaddir(dir);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int closedir(DIR *dir) {
|
||||
closedirCalled++;
|
||||
if (sysCallsClosedir != nullptr) {
|
||||
return sysCallsClosedir(dir);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace SysCalls
|
||||
} // namespace NEO
|
||||
|
|
|
@ -41,6 +41,9 @@ extern int (*sysCallsUnlink)(const std::string &pathname);
|
|||
extern int (*sysCallsStat)(const std::string &filePath, struct stat *statbuf);
|
||||
extern int (*sysCallsMkstemp)(char *fileName);
|
||||
extern bool (*sysCallsPathExists)(const std::string &path);
|
||||
extern DIR *(*sysCallsOpendir)(const char *name);
|
||||
extern struct dirent *(*sysCallsReaddir)(DIR *dir);
|
||||
extern int (*sysCallsClosedir)(DIR *dir);
|
||||
|
||||
extern int flockRetVal;
|
||||
extern int closeFuncRetVal;
|
||||
|
|
Loading…
Reference in New Issue