feature: Add Sysman Support for Engine Busyness w.r.t Xe driver

For the Xe driver, the configs for the Active Ticks and Total Ticks are
first fetched from the Event Files and later shifted on the basis of the
values present in the corresponding files from format directory.

Related-To: NEO-14280

Signed-off-by: Pratik Bari <pratik.bari@intel.com>
This commit is contained in:
Pratik Bari
2025-03-13 14:19:38 +00:00
committed by Compute-Runtime-Automation
parent c84c6fdd1a
commit d563abcda7
19 changed files with 532 additions and 163 deletions

View File

@@ -21,9 +21,6 @@
namespace L0 {
namespace Sysman {
const std::string deviceDir("device");
const std::string sysDevicesDir("/sys/devices/");
const std::map<uint16_t, std::string> SysmanKmdInterfaceI915::i915EngineClassToSysfsEngineMap = {
{drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER, "rcs"},
{static_cast<uint16_t>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_COMPUTE), "ccs"},
@@ -176,7 +173,7 @@ void SysmanKmdInterface::convertSysfsValueUnit(const SysfsValueUnit dstUnit, con
uint32_t SysmanKmdInterface::getEventType() {
auto pFsAccess = getFsAccess();
const std::string eventTypeSysfsNode = sysDevicesDir + sysmanDeviceDirName + "/" + "type";
const std::string eventTypeSysfsNode = std::string(sysDevicesDir) + sysmanDeviceDirName + "/" + "type";
auto eventTypeVal = 0u;
if (ZE_RESULT_SUCCESS != pFsAccess->read(eventTypeSysfsNode, eventTypeVal)) {
return 0;
@@ -214,7 +211,7 @@ ze_result_t SysmanKmdInterface::getDeviceDirName(std::string &dirName, const boo
if (!isIntegratedDevice) {
auto pSysFsAccess = getSysFsAccess();
std::string bdfDir;
result = pSysFsAccess->readSymLink(deviceDir, bdfDir);
result = pSysFsAccess->readSymLink(std::string(deviceDir), bdfDir);
if (ZE_RESULT_SUCCESS != result) {
return result;
}

View File

@@ -31,6 +31,9 @@ class PmuInterface;
class LinuxSysmanImp;
class SysmanProductHelper;
constexpr std::string_view deviceDir("device");
constexpr std::string_view sysDevicesDir("/sys/devices/");
typedef std::pair<std::string, std::string> valuePair;
enum EngineClass {
@@ -295,7 +298,7 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface {
std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override;
bool isStandbyModeControlAvailable() const override { return false; }
bool clientInfoAvailableInFdInfo() const override { return true; }
bool isGroupEngineInterfaceAvailable() const override { return true; }
bool isGroupEngineInterfaceAvailable() const override { return false; }
ze_result_t getNumEngineTypeAndInstances(std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines,
LinuxSysmanImp *pLinuxSysmanImp,
SysFsAccessInterface *pSysfsAccess,

View File

@@ -150,8 +150,8 @@ ze_result_t SysmanKmdInterfaceI915Prelim::readBusynessFromGroupFd(PmuInterface *
auto ret = pPmuInterface->pmuRead(static_cast<int>(fdPair.first), data, sizeof(data));
if (ret < 0) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():pmuRead is returning value:%d and error:0x%x \n", __FUNCTION__, ret, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():pmuRead is returning value:%d and error:0x%x \n", __FUNCTION__, ret, ZE_RESULT_ERROR_UNKNOWN);
return ZE_RESULT_ERROR_UNKNOWN;
}
pStats->activeTime = data[2];

View File

@@ -115,8 +115,8 @@ ze_result_t SysmanKmdInterfaceI915Upstream::readBusynessFromGroupFd(PmuInterface
uint64_t data[2] = {};
auto ret = pPmuInterface->pmuRead(static_cast<int>(fdPair.first), data, sizeof(data));
if (ret < 0) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():pmuRead is returning value:%d and error:0x%x \n", __FUNCTION__, ret, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():pmuRead is returning value:%d and error:0x%x \n", __FUNCTION__, ret, ZE_RESULT_ERROR_UNKNOWN);
return ZE_RESULT_ERROR_UNKNOWN;
}
pStats->activeTime = data[0] / microSecondsToNanoSeconds;

View File

@@ -105,11 +105,80 @@ std::string SysmanKmdInterfaceXe::getEnergyCounterNodeFile(zes_power_domain_t po
}
ze_result_t SysmanKmdInterfaceXe::getEngineActivityFdList(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface, std::vector<std::pair<int64_t, int64_t>> &fdList) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
ze_result_t result = ZE_RESULT_SUCCESS;
auto engineClass = engineGroupToEngineClass.find(engineGroup);
if (engineClass == engineGroupToEngineClass.end()) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Engine Group not supported and returning error:0x%x\n", __FUNCTION__, result);
return result;
}
const std::string activeTicksEventFile = std::string(sysDevicesDir) + sysmanDeviceDirName + "/events/engine-active-ticks";
uint64_t activeTicksConfig = UINT64_MAX;
auto ret = pPmuInterface->getConfigFromEventFile(activeTicksEventFile, activeTicksConfig);
if (ret < 0) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get config for the active ticks from event file and returning error:0x%x\n", __FUNCTION__, result);
return result;
}
const std::string totalTicksEventFile = std::string(sysDevicesDir) + "/" + sysmanDeviceDirName + "/events/engine-total-ticks";
uint64_t totalTicksConfig = UINT64_MAX;
ret = pPmuInterface->getConfigFromEventFile(totalTicksEventFile, totalTicksConfig);
if (ret < 0) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get config for the total ticks from event file and returning error:0x%x\n", __FUNCTION__, result);
return result;
}
const std::string formatDir = std::string(sysDevicesDir) + sysmanDeviceDirName + "/format/";
ret = pPmuInterface->getConfigAfterFormat(formatDir, activeTicksConfig, engineClass->second, engineInstance, subDeviceId);
if (ret < 0) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get config for the active ticks after format and returning error:0x%x\n", __FUNCTION__, result);
return result;
}
ret = pPmuInterface->getConfigAfterFormat(formatDir, totalTicksConfig, engineClass->second, engineInstance, subDeviceId);
if (ret < 0) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get config for the total ticks after format and returning error:0x%x\n", __FUNCTION__, result);
return result;
}
int64_t fd[2];
fd[0] = pPmuInterface->pmuInterfaceOpen(activeTicksConfig, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
if (fd[0] < 0) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Busy Ticks Handle \n", __FUNCTION__);
return checkErrorNumberAndReturnStatus();
}
fd[1] = pPmuInterface->pmuInterfaceOpen(totalTicksConfig, static_cast<int>(fd[0]), PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
if (fd[1] < 0) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Total Active Ticks Handle \n", __FUNCTION__);
close(static_cast<int>(fd[0]));
return checkErrorNumberAndReturnStatus();
}
fdList.push_back(std::make_pair(fd[0], fd[1]));
return result;
}
ze_result_t SysmanKmdInterfaceXe::readBusynessFromGroupFd(PmuInterface *const &pPmuInterface, std::pair<int64_t, int64_t> &fdPair, zes_engine_stats_t *pStats) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
uint64_t data[4] = {};
auto ret = pPmuInterface->pmuRead(static_cast<int>(fdPair.first), data, sizeof(data));
if (ret < 0) {
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():pmuRead is returning value:%d and error:0x%x \n", __FUNCTION__, ret, ZE_RESULT_ERROR_UNKNOWN);
return ZE_RESULT_ERROR_UNKNOWN;
}
pStats->activeTime = data[2];
pStats->timestamp = data[3] ? data[3] : SysmanDevice::getSysmanTimestamp();
return ZE_RESULT_SUCCESS;
}
std::string SysmanKmdInterfaceXe::getHwmonName(uint32_t subDeviceId, bool isSubdevice) const {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -7,6 +7,7 @@
#pragma once
#include <cstdint>
#include <string>
#include <unistd.h>
namespace L0 {
@@ -16,7 +17,9 @@ class PmuInterface {
public:
virtual ~PmuInterface() = default;
virtual int64_t pmuInterfaceOpen(uint64_t config, int group, uint32_t format) = 0;
virtual int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) = 0;
virtual int32_t pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) = 0;
virtual int32_t getConfigFromEventFile(const std::string_view &eventFile, uint64_t &config) = 0;
virtual int32_t getConfigAfterFormat(const std::string_view &formatDir, uint64_t &config, uint32_t engineClass, uint32_t engineInstance, uint32_t gt) = 0;
static PmuInterface *create(LinuxSysmanImp *pLinuxSysmanImp);
};

View File

@@ -10,6 +10,7 @@
#include "shared/source/memory_manager/memory_manager.h"
#include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h"
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
namespace L0 {
namespace Sysman {
@@ -18,7 +19,7 @@ const std::string PmuInterfaceImp::deviceDir("device");
const std::string PmuInterfaceImp::sysDevicesDir("/sys/devices/");
static constexpr int64_t perfEventOpenSyscallNumber = 298;
int PmuInterfaceImp::getErrorNo() {
int32_t PmuInterfaceImp::getErrorNo() {
return errno;
}
@@ -52,7 +53,7 @@ int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint32_t f
return ret;
}
int PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) {
int32_t PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) {
ssize_t len;
len = this->readFunction(fd, data, sizeOfdata);
if (len != sizeOfdata) {
@@ -61,6 +62,99 @@ int PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) {
return 0;
}
int32_t PmuInterfaceImp::getConfigFromEventFile(const std::string_view &eventFile, uint64_t &config) {
// The event file from the events directory has following contents
// event=0x02 --> for /sys/devices/xe_<bdf>/events/engine-active-ticks
// event=0x03 --> for /sys/devices/xe_<bdf>/events/engine-total-ticks
// The config values fetched are in hexadecimal format
auto pFsAccess = pSysmanKmdInterface->getFsAccess();
std::string readVal = "";
ze_result_t result = pFsAccess->read(std::string(eventFile), readVal);
if (result != ZE_RESULT_SUCCESS) {
return -1;
}
size_t pos = readVal.rfind("=");
if (pos == std::string::npos) {
return -1;
}
readVal = readVal.substr(pos + 1, std::string::npos);
config = std::strtoul(readVal.c_str(), nullptr, 16);
return 0;
}
static ze_result_t getShiftValue(const std::string_view &readFile, FsAccessInterface *pFsAccess, uint32_t &shiftValue) {
// The contents of the file passed as an argument is of the form 'config:<start_val>-<end_val>'
// The start_val is the shift value. It is in decimal format.
// Eg. if the contents are config:60-63, the shift value in this case is 60
ze_result_t result = ZE_RESULT_SUCCESS;
std::string readVal = "";
result = pFsAccess->read(std::string(readFile), readVal);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
size_t pos = readVal.rfind(":");
if (pos == std::string::npos) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
readVal = readVal.substr(pos + 1, std::string::npos);
pos = readVal.rfind("-");
if (pos == std::string::npos) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
readVal = readVal.substr(0, pos);
shiftValue = static_cast<uint32_t>(std::strtoul(readVal.c_str(), nullptr, 10));
return result;
}
int32_t PmuInterfaceImp::getConfigAfterFormat(const std::string_view &formatDir, uint64_t &config, uint32_t engineClass, uint32_t engineInstance, uint32_t gt) {
// The final config is computed by the bitwise OR operation of the config fetched from the event file and value obtained by shifting the parameters gt,
// engineClass and engineInstance with the shift value fetched from the corresponding file in /sys/devices/xe_<bdf>/format/ directory.
// The contents of these files in the form of 'config:<start_val>-<end_val>'. For eg.
// config:60-63 --> for /sys/devices/xe_<bdf>/format/gt
// config:20-27 --> for /sys/devices/xe_<bdf>/format/engine_class
// config:12-19 --> for /sys/devices/xe_<bdf>/format/engine_instance
// The start_val is the shift value by which the parameter should be shifted. The final config is computed as follows.
// config |= gt << gt_shift_value
// config |= engineClass << engineClass_shift_value
// config |= engineInstance << engineInstance_shift_value
auto pFsAccess = pSysmanKmdInterface->getFsAccess();
std::string readVal = "";
uint32_t shiftValue = 0;
std::string readFile = std::string(formatDir) + "gt";
ze_result_t result = getShiftValue(readFile, pFsAccess, shiftValue);
if (result != ZE_RESULT_SUCCESS) {
return -1;
}
config |= gt << shiftValue;
shiftValue = 0;
readFile = std::string(formatDir) + "engine_class";
result = getShiftValue(readFile, pFsAccess, shiftValue);
if (result != ZE_RESULT_SUCCESS) {
return -1;
}
config |= engineClass << shiftValue;
shiftValue = 0;
readFile = std::string(formatDir) + "engine_instance";
result = getShiftValue(readFile, pFsAccess, shiftValue);
if (result != ZE_RESULT_SUCCESS) {
return -1;
}
config |= engineInstance << shiftValue;
return 0;
}
PmuInterfaceImp::PmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) {
pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
}

View File

@@ -10,7 +10,6 @@
#include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h"
#include <linux/perf_event.h>
#include <string>
#include <sys/sysinfo.h>
#include <unistd.h>
@@ -25,10 +24,12 @@ class PmuInterfaceImp : public PmuInterface, NEO::NonCopyableAndNonMovableClass
PmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp);
~PmuInterfaceImp() override = default;
int64_t pmuInterfaceOpen(uint64_t config, int group, uint32_t format) override;
int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override;
int32_t pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override;
int32_t getConfigFromEventFile(const std::string_view &eventFile, uint64_t &config) override;
int32_t getConfigAfterFormat(const std::string_view &formatDir, uint64_t &config, uint32_t engineClass, uint32_t engineInstance, uint32_t gt) override;
protected:
virtual int getErrorNo();
virtual int32_t getErrorNo();
virtual int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags);
decltype(&read) readFunction = read;
decltype(&syscall) syscallFunction = syscall;

View File

@@ -17,7 +17,7 @@ namespace L0 {
namespace Sysman {
namespace ult {
class MockNeoDrm : public NEO::Drm {
struct MockNeoDrm : public NEO::Drm {
public:
using NEO::Drm::getEngineInfo;
@@ -32,19 +32,15 @@ class MockNeoDrm : public NEO::Drm {
return mockSysmanQueryEngineInfoReturnFalse;
}
std::vector<NEO::EngineCapabilities> mockEngineInfo(6);
std::vector<NEO::EngineCapabilities> mockEngineInfo(3);
mockEngineInfo[0].engine.engineClass = EngineClass::ENGINE_CLASS_RENDER;
mockEngineInfo[0].engine.engineInstance = 0;
mockEngineInfo[1].engine.engineClass = EngineClass::ENGINE_CLASS_RENDER;
mockEngineInfo[1].engine.engineInstance = 1;
mockEngineInfo[2].engine.engineClass = EngineClass::ENGINE_CLASS_VIDEO;
mockEngineInfo[2].engine.engineInstance = 1;
mockEngineInfo[3].engine.engineClass = EngineClass::ENGINE_CLASS_COPY;
mockEngineInfo[1].engine.engineClass = EngineClass::ENGINE_CLASS_COPY;
mockEngineInfo[1].engine.engineInstance = 0;
mockEngineInfo[2].engine.engineClass = EngineClass::ENGINE_CLASS_VIDEO_ENHANCE;
mockEngineInfo[2].engine.engineInstance = 0;
mockEngineInfo[3].engine.engineClass = UINT16_MAX;
mockEngineInfo[3].engine.engineInstance = 0;
mockEngineInfo[4].engine.engineClass = EngineClass::ENGINE_CLASS_VIDEO_ENHANCE;
mockEngineInfo[4].engine.engineInstance = 0;
mockEngineInfo[5].engine.engineClass = UINT16_MAX;
mockEngineInfo[5].engine.engineInstance = 0;
StackVec<std::vector<NEO::EngineCapabilities>, 2> engineInfosPerTile{mockEngineInfo};
this->engineInfo.reset(new NEO::EngineInfo(this, engineInfosPerTile));

View File

@@ -159,7 +159,7 @@ TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleWhenCallingZesEngineGetActivi
EXPECT_EQ(handleComponentCount, handles.size());
for (auto handle : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesEngineGetActivity(handle, &stats));
}
}

View File

@@ -228,7 +228,7 @@ TEST_F(ZesEngineFixturePrelim, GivenValidEngineHandleWhenCallingZesEngineGetActi
for (auto handle : handles) {
ASSERT_NE(nullptr, handle);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesEngineGetActivity(handle, &stats));
}
}

View File

@@ -9,8 +9,6 @@
#include "shared/test/common/helpers/variable_backup.h"
#include "level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.h"
#include "level_zero/sysman/source/api/engine/sysman_engine_imp.h"
#include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h"
#include "level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h"
@@ -20,6 +18,8 @@ namespace L0 {
namespace Sysman {
namespace ult {
constexpr uint32_t mockEngineHandleCount = 3u;
class ZesEngineFixtureXe : public SysmanDeviceFixture {
protected:
L0::Sysman::SysmanDevice *device = nullptr;
@@ -80,35 +80,85 @@ class ZesEngineFixtureXe : public SysmanDeviceFixture {
}
};
TEST_F(ZesEngineFixtureXe, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenZeroCountIsReturnedAndVerifyCallSucceeds) {
TEST_F(ZesEngineFixtureXe, GivenComponentCountZeroWhenCallingZesDeviceEnumEngineGroupsThenCallSucceedsAndValidCountIsReturned) {
uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL));
EXPECT_EQ(count, 0u);
EXPECT_EQ(count, mockEngineHandleCount);
uint32_t testcount = count + 1;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL));
EXPECT_EQ(testcount, 0u);
EXPECT_EQ(testcount, mockEngineHandleCount);
count = 0;
std::vector<zes_engine_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, 0u);
EXPECT_EQ(count, mockEngineHandleCount);
}
TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndperfEventOpenFailsThenVerifyEngineGetActivityReturnsFailure) {
TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleWhenCallingZesEngineGetActivityThenCallSuccedsAndValidValuesAreReturned) {
zes_engine_stats_t stats = {};
auto handles = getEngineHandles(mockEngineHandleCount);
EXPECT_EQ(mockEngineHandleCount, handles.size());
for (auto handle : handles) {
ASSERT_NE(nullptr, handle);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime);
EXPECT_EQ(stats.timestamp, pPmuInterface->mockTimestamp);
}
}
TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleAndPmuTimeStampIsZeroWhenCallingZesEngineGetActivityThenValidTimeStampIsReturned) {
zes_engine_stats_t stats = {};
pPmuInterface->mockTimestamp = 0u;
auto handles = getEngineHandles(mockEngineHandleCount);
EXPECT_EQ(mockEngineHandleCount, handles.size());
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
uint64_t timeBeforeApiCall = std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
for (auto handle : handles) {
ASSERT_NE(nullptr, handle);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime);
EXPECT_GE(stats.timestamp, timeBeforeApiCall);
}
}
TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleAndPmuReadFailsWhenCallingZesEngineGetActivityThenErrorIsReturned) {
zes_engine_stats_t stats = {};
pPmuInterface->mockPmuReadFailureReturnValue = -1;
auto handles = getEngineHandles(mockEngineHandleCount);
EXPECT_EQ(mockEngineHandleCount, handles.size());
for (auto handle : handles) {
ASSERT_NE(nullptr, handle);
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesEngineGetActivity(handle, &stats));
}
}
TEST_F(ZesEngineFixtureXe, GivenDeviceHandleAndPmuOpenFailsDueToFileTableOverFlowWhenCallingZesDeviceEnumEngineGroupsThenZeroHandlesReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsPread)> mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
uint32_t mockReadVal = 23;
std::ostringstream oStream;
oStream << mockReadVal;
oStream << 23;
std::string value = oStream.str();
memcpy(buf, value.data(), count);
return count;
});
pPmuInterface->mockPerfEventOpenReadFail = true;
EXPECT_EQ(-1, pPmuInterface->pmuInterfaceOpen(0, -1, 0));
pPmuInterface->mockPerfEventOpenFailAtCount = 3;
pPmuInterface->mockErrorNumber = ENFILE;
pSysmanDeviceImp->pEngineHandleContext->handleList.clear();
pSysmanDeviceImp->pEngineHandleContext->init(pOsSysman->getSubDeviceCount());
uint32_t handleCount = 0;
EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &handleCount, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(handleCount, 0u);
}
} // namespace ult

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2021-2023 Intel Corporation
# Copyright (C) 2021-2025 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
@@ -8,6 +8,7 @@ if(UNIX)
target_sources(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_pmu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_pmu_xe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_pmu.h
)
endif()

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -25,6 +25,7 @@ class MockPmuInterfaceImpForSysman : public L0::Sysman::PmuInterfaceImp {
public:
using L0::Sysman::PmuInterfaceImp::getErrorNo;
using L0::Sysman::PmuInterfaceImp::perfEventOpen;
using L0::Sysman::PmuInterfaceImp::pSysmanKmdInterface;
using L0::Sysman::PmuInterfaceImp::readFunction;
using L0::Sysman::PmuInterfaceImp::syscallFunction;
MockPmuInterfaceImpForSysman(L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp) : L0::Sysman::PmuInterfaceImp(pLinuxSysmanImp) {}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/pmu/mock_pmu.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h"
#include <cmath>
namespace L0 {
namespace Sysman {
namespace ult {
struct MockFsAccess : public L0::Sysman::FsAccessInterface {
std::string mockReadValue = "";
ze_result_t engineActiveTicksReadStatus = ZE_RESULT_SUCCESS;
ze_result_t engineTotalTicksReadStatus = ZE_RESULT_SUCCESS;
ze_result_t gtFileReadStatus = ZE_RESULT_SUCCESS;
ze_result_t engineClassFileReadStatus = ZE_RESULT_SUCCESS;
ze_result_t engineInstanceFileReadStatus = ZE_RESULT_SUCCESS;
ze_result_t read(const std::string file, std::string &val) override {
if (!mockReadValue.empty()) {
val = mockReadValue;
} else if ((engineActiveTicksReadStatus == ZE_RESULT_SUCCESS) && (file.find("engine-active-ticks") != std::string::npos)) {
val = "events=0x02";
} else if ((engineTotalTicksReadStatus == ZE_RESULT_SUCCESS) && (file.find("engine-total-ticks") != std::string::npos)) {
val = "events=0x03";
} else if ((gtFileReadStatus == ZE_RESULT_SUCCESS) && (file.find("gt") != std::string::npos)) {
val = "config:0-7";
} else if ((engineClassFileReadStatus == ZE_RESULT_SUCCESS) && (file.find("engine_class") != std::string::npos)) {
val = "config:8-15";
} else if ((engineInstanceFileReadStatus == ZE_RESULT_SUCCESS) && (file.find("engine_instance") != std::string::npos)) {
val = "config:16-23";
} else {
val = mockReadValue;
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
return ZE_RESULT_SUCCESS;
}
MockFsAccess() = default;
};
struct SysmanXePmuFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<MockPmuInterface> pPmuInterface;
L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr;
MockSysmanKmdInterfaceXe *pSysmanKmdInterface = nullptr;
MockFsAccess *pFsAccess = nullptr;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pFsAccess = new MockFsAccess();
pSysmanKmdInterface = new MockSysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper());
pSysmanKmdInterface->pFsAccess.reset(pFsAccess);
pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface);
pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface;
pPmuInterface = std::make_unique<MockPmuInterface>(pLinuxSysmanImp);
pPmuInterface->pSysmanKmdInterface = pSysmanKmdInterface;
pLinuxSysmanImp->pPmuInterface = pPmuInterface.get();
}
void TearDown() override {
pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface;
SysmanDeviceFixture::TearDown();
}
};
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndValidConfigEventFileWhenCallingGetConfigFromEventFileThenValidConfigValueAndSuccessIsReturned) {
std::string eventFile = "sys/dev/xe/engine-active-ticks";
uint64_t mockEventConfig = 2u;
uint64_t config = UINT64_MAX;
EXPECT_EQ(0, pPmuInterface->getConfigFromEventFile(eventFile, config));
EXPECT_EQ(mockEventConfig, config);
eventFile = "sys/dev/xe/engine-total-ticks";
mockEventConfig = 3u;
config = UINT64_MAX;
EXPECT_EQ(0, pPmuInterface->getConfigFromEventFile(eventFile, config));
EXPECT_EQ(mockEventConfig, config);
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndInvalidConfigEventFileWhenCallingGetConfigFromEventFileThenFailureIsReturned) {
std::string eventFile = "sys/dev/xe/engine-ticks";
uint64_t config = UINT64_MAX;
EXPECT_EQ(-1, pPmuInterface->getConfigFromEventFile(eventFile, config));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndFsReadFailsForEventFileWhenCallingGetConfigFromEventFileThenFailureIsReturned) {
std::string eventFile = "sys/dev/xe/engine-active-ticks";
pFsAccess->engineActiveTicksReadStatus = ZE_RESULT_ERROR_UNKNOWN;
uint64_t config = UINT64_MAX;
EXPECT_EQ(-1, pPmuInterface->getConfigFromEventFile(eventFile, config));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndEventFileHasInvalidValueWhenCallingGetConfigFromEventFileThenFailureIsReturned) {
std::string eventFile = "sys/dev/xe/engine-active-ticks";
pFsAccess->mockReadValue = "invalidValue";
uint64_t config = UINT64_MAX;
EXPECT_EQ(-1, pPmuInterface->getConfigFromEventFile(eventFile, config));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndValidFormatConfigDirectoryNameWhenCallingGetConfigAfterFormatThenValidConfigValueAndSuccessIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
uint64_t mockConfigAfterFormat = mockConfig | mockEngineClass << 8;
EXPECT_EQ(0, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
EXPECT_EQ(mockConfigAfterFormat, mockConfig);
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndFsReadForGtFailsWhenCallingGetConfigAfterFormatThenFailureIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
pFsAccess->gtFileReadStatus = ZE_RESULT_ERROR_UNKNOWN;
EXPECT_EQ(-1, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndFsReadForEngineClassFailsWhenCallingGetConfigAfterFormatThenFailureIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
pFsAccess->engineClassFileReadStatus = ZE_RESULT_ERROR_UNKNOWN;
EXPECT_EQ(-1, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndFsReadForEngineInstanceFailsWhenCallingGetConfigAfterFormatThenFailureIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
pFsAccess->engineInstanceFileReadStatus = ZE_RESULT_ERROR_UNKNOWN;
EXPECT_EQ(-1, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndGtFileHasInvalidValueWhenCallingGetConfigAfterFormatThenFailureIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
pFsAccess->mockReadValue = "invalidValue";
EXPECT_EQ(-1, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
}
TEST_F(SysmanXePmuFixture, GivenPmuHandleAndGtFileHasInvalidConfigFormatWhenCallingGetConfigAfterFormatThenFailureIsReturned) {
std::string formatDir = "/sys/dev/xe/format";
uint64_t mockConfig = 1u;
uint32_t mockEngineClass = 1u;
uint32_t mockEngineInstance = 0u;
uint32_t mockGt = 0u;
pFsAccess->mockReadValue = "config:32";
EXPECT_EQ(-1, pPmuInterface->getConfigAfterFormat(formatDir, mockConfig, mockEngineClass, mockEngineInstance, mockGt));
}
} // namespace ult
} // namespace Sysman
} // namespace L0

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2024 Intel Corporation
# Copyright (C) 2024-2025 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
@@ -11,7 +11,6 @@ set(L0_SYSMAN_SHARED_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_kmd_interface_i915_prelim.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_kmd_interface_i915_upstream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_kmd_interface_xe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_sysman_fixture_xe.h
)
if(UNIX)

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2024-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/test/common/helpers/variable_backup.h"
#include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h"
namespace L0 {
namespace Sysman {
namespace ult {
class SysmanFixtureDeviceXe : public SysmanDeviceFixture {
protected:
std::unique_ptr<MockPmuInterfaceImp> pPmuInterface;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pPmuInterface = std::make_unique<MockPmuInterfaceImp>(pLinuxSysmanImp);
pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper()));
mockInitFsAccess();
pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
bool isIntegratedDevice = false;
pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice);
}
void TearDown() override {
SysmanDeviceFixture::TearDown();
}
void mockInitFsAccess() {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
constexpr size_t sizeofPath = sizeof("/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0");
strcpy_s(buf, sizeofPath, "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0");
return sizeofPath;
});
pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pLinuxSysmanImp->getDrm());
}
};
} // namespace ult
} // namespace Sysman
} // namespace L0

View File

@@ -10,9 +10,8 @@
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_fixture_xe.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h"
#include "level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h"
#include "gtest/gtest.h"
@@ -33,11 +32,6 @@ static int mockReadLinkSuccess(const char *path, char *buf, size_t bufsize) {
return sizeofPath;
}
static int mockReadLinkFailure(const char *path, char *buf, size_t bufsize) {
errno = ENOENT;
return -1;
}
static ssize_t mockReadSuccess(int fd, void *buf, size_t count, off_t offset) {
std::ostringstream oStream;
oStream << mockReadVal;
@@ -46,10 +40,29 @@ static ssize_t mockReadSuccess(int fd, void *buf, size_t count, off_t offset) {
return count;
}
static ssize_t mockReadFailure(int fd, void *buf, size_t count, off_t offset) {
errno = ENOENT;
return -1;
}
class SysmanFixtureDeviceXe : public SysmanDeviceFixture {
protected:
std::unique_ptr<MockPmuInterfaceImp> pPmuInterface;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pPmuInterface = std::make_unique<MockPmuInterfaceImp>(pLinuxSysmanImp);
pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper()));
mockInitFsAccess();
pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
bool isIntegratedDevice = true;
pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice);
}
void mockInitFsAccess() {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess);
pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pLinuxSysmanImp->getDrm());
}
void TearDown() override {
SysmanDeviceFixture::TearDown();
}
};
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenGettingSysfsFileNamesThenProperPathsAreReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
@@ -93,9 +106,9 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenCallingGetEngineClassSt
EXPECT_STREQ("vecs", pSysmanKmdInterface->getEngineClassString(EngineClass::ENGINE_CLASS_VIDEO_ENHANCE).value().c_str());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenIsGroupEngineInterfaceAvailableCalledThenTrueValueIsReturned) {
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenIsGroupEngineInterfaceAvailableCalledThenFalseValueIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_TRUE(pSysmanKmdInterface->isGroupEngineInterfaceAvailable());
EXPECT_FALSE(pSysmanKmdInterface->isGroupEngineInterfaceAvailable());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenCheckingAvailabilityOfBaseFrequencyFactorAndSystemPowerBalanceThenTrueValueIsReturned) {
@@ -143,38 +156,10 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndIsIntegratedDeviceInstan
VariableBackup<decltype(NEO::SysCalls::sysCallsPread)> mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess);
bool isIntegratedDevice = true;
pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice);
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndIsNotIntegratedDeviceInstanceWhenGetEventsIsCalledThenValidEventTypeIsReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkSuccess);
VariableBackup<decltype(NEO::SysCalls::sysCallsPread)> mockPread(&NEO::SysCalls::sysCallsPread, &mockReadSuccess);
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndReadSymLinkFailsWhenGetEventsIsCalledThenFailureIsReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, &mockReadLinkFailure);
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_EQ(0u, pSysmanKmdInterface->getEventType());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndFsReadFailsWhenGetEventsIsCalledThenFailureIsReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsPread)> mockPread(&NEO::SysCalls::sysCallsPread, &mockReadFailure);
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_EQ(0u, pSysmanKmdInterface->getEventType());
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenCheckingSupportForSettingSchedulerModesThenFalseValueIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_FALSE(pSysmanKmdInterface->isSettingExclusiveModeSupported());
@@ -186,24 +171,6 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenCheckingWhetherClientIn
EXPECT_TRUE(pSysmanKmdInterface->clientInfoAvailableInFdInfo());
}
TEST_F(SysmanFixtureDeviceXe, GivenEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdListIsCalledThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COPY_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_RENDER_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_MEDIA_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenReadingBusynessFromGroupFdThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
zes_engine_stats_t pStats = {};
std::pair<int64_t, int64_t> fdPair = {};
EXPECT_EQ(pSysmanKmdInterface->readBusynessFromGroupFd(pPmuInterface.get(), fdPair, &pStats), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenCheckingSupportForVfEngineUtilizationThenFalseValueIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
EXPECT_FALSE(pSysmanKmdInterface->isVfEngineUtilizationSupported());
@@ -231,6 +198,46 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenGetEnergyCounterNodeFil
EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFile(ZES_POWER_DOMAIN_UNKNOWN));
}
TEST_F(SysmanFixtureDeviceXe, GivenGroupEngineTypeAndSysmanKmdInterfaceWhenCallingGetEngineActivityFdListThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_ALL, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigFromEventFileFailsForEngineActiveTicksWhenCallingGetEngineActivityFdListThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
pPmuInterface->mockEventConfigReturnValue.push_back(-1);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigFromEventFileFailsForEngineTotalTicksWhenCallingGetEngineActivityFdListThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
pPmuInterface->mockEventConfigReturnValue.push_back(0);
pPmuInterface->mockEventConfigReturnValue.push_back(-1);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigAfterFormatFailsForEngineActiveTicksWhenCallingGetEngineActivityFdListThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
pPmuInterface->mockFormatConfigReturnValue.push_back(-1);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigAfterFormatFailsForEngineTotalTicksWhenCallingGetEngineActivityFdListThenErrorIsReturned) {
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
std::vector<std::pair<int64_t, int64_t>> fdList = {};
pPmuInterface->mockFormatConfigReturnValue.push_back(0);
pPmuInterface->mockFormatConfigReturnValue.push_back(-1);
EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdList(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
} // namespace ult
} // namespace Sysman
} // namespace L0

View File

@@ -7,9 +7,7 @@
#pragma once
#include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h"
#include "level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h"
#include "level_zero/sysman/source/shared/linux/sysman_fs_access_interface.h"
namespace L0 {
namespace Sysman {
@@ -17,17 +15,25 @@ namespace ult {
class MockPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp {
public:
using PmuInterfaceImp::perfEventOpen;
using PmuInterfaceImp::pSysmanKmdInterface;
int64_t mockPmuFd = -1;
uint64_t mockTimestamp = 0;
uint64_t mockActiveTime = 0;
int32_t mockErrorNumber = -ENOSPC;
int32_t mockPerfEventOpenFailAtCount = 1;
int32_t mockPmuReadFailureReturnValue = 0;
bool mockPerfEventOpenReadFail = false;
using PmuInterfaceImp::perfEventOpen;
using PmuInterfaceImp::pSysmanKmdInterface;
std::vector<int32_t> mockEventConfigReturnValue = {};
std::vector<int32_t> mockFormatConfigReturnValue = {};
MockPmuInterfaceImp(L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {}
int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override {
if (mockPerfEventOpenReadFail == true) {
mockPerfEventOpenFailAtCount = std::max<int32_t>(mockPerfEventOpenFailAtCount - 1, 1);
const bool shouldCheckForError = (mockPerfEventOpenFailAtCount == 1);
if (shouldCheckForError && mockPerfEventOpenReadFail == true) {
errno = mockErrorNumber;
return -1;
}
@@ -35,16 +41,33 @@ class MockPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp {
return mockPmuFd;
}
int mockPmuReadFailureReturnValue = 0;
int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override {
int32_t pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override {
if (mockPmuReadFailureReturnValue == -1) {
return mockPmuReadFailureReturnValue;
}
data[0] = mockActiveTime;
data[1] = mockTimestamp;
data[2] = mockActiveTime;
data[3] = mockTimestamp;
return 0;
}
int32_t getConfigFromEventFile(const std::string_view &eventFile, uint64_t &config) override {
int32_t returnValue = 0;
if (!mockEventConfigReturnValue.empty()) {
returnValue = mockEventConfigReturnValue.front();
mockEventConfigReturnValue.erase(mockEventConfigReturnValue.begin());
}
return returnValue;
}
int32_t getConfigAfterFormat(const std::string_view &formatDir, uint64_t &config, uint32_t engineClass, uint32_t engineInstance, uint32_t gt) override {
int32_t returnValue = 0;
if (!mockFormatConfigReturnValue.empty()) {
returnValue = mockFormatConfigReturnValue.front();
mockFormatConfigReturnValue.erase(mockFormatConfigReturnValue.begin());
}
return returnValue;
}
};
} // namespace ult