mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-30 01:35:20 +08:00
feature(sysman): feature: Add VF Engine Utilization API implementation
Related-To: NEO-11202 Signed-off-by: Pratik Bari <pratik.bari@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
819ffea90f
commit
ad881e3f2e
@@ -8,8 +8,11 @@
|
||||
#include "level_zero/sysman/source/api/vf_management/linux/sysman_os_vf_imp.h"
|
||||
|
||||
#include "shared/source/os_interface/driver_info.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
#include "shared/source/utilities/directory.h"
|
||||
|
||||
#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"
|
||||
#include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h"
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
@@ -93,8 +96,118 @@ ze_result_t LinuxVfImp::vfOsGetMemoryUtilization(uint32_t *pCount, zes_vf_util_m
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void LinuxVfImp::vfGetInstancesFromEngineInfo(NEO::EngineInfo *engineInfo, std::set<std::pair<zes_engine_group_t, uint32_t>> &engineGroupAndInstance) {
|
||||
|
||||
auto engineTileMap = engineInfo->getEngineTileInfo();
|
||||
for (const auto &engine : engineTileMap) {
|
||||
auto engineClassToEngineGroupRange = engineClassToEngineGroup.equal_range(static_cast<uint16_t>(engine.second.engineClass));
|
||||
for (auto l0EngineEntryInMap = engineClassToEngineGroupRange.first; l0EngineEntryInMap != engineClassToEngineGroupRange.second; l0EngineEntryInMap++) {
|
||||
auto l0EngineType = l0EngineEntryInMap->second;
|
||||
engineGroupAndInstance.insert({l0EngineType, static_cast<uint32_t>(engine.second.engineInstance)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxVfImp::vfEngineDataInit() {
|
||||
|
||||
const auto pDrm = pLinuxSysmanImp->getDrm();
|
||||
const auto pPmuInterface = pLinuxSysmanImp->getPmuInterface();
|
||||
const auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
|
||||
auto hwDeviceId = pLinuxSysmanImp->getSysmanHwDeviceIdInstance();
|
||||
if (hwDeviceId.getFileDescriptor() < 0) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not get Device Id Fd and returning error:0x%x \n", __FUNCTION__, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
if (pDrm->sysmanQueryEngineInfo() == false) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s():sysmanQueryEngineInfo is returning false and returning error:0x%x \n", __FUNCTION__, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
const auto engineInfo = pDrm->getEngineInfo();
|
||||
vfGetInstancesFromEngineInfo(engineInfo, engineGroupAndInstance);
|
||||
for (const auto &engine : engineGroupAndInstance) {
|
||||
auto engineClass = engineGroupToEngineClass.find(engine.first);
|
||||
std::pair<uint64_t, uint64_t> configPair{UINT64_MAX, UINT64_MAX};
|
||||
auto result = pSysmanKmdInterface->getBusyAndTotalTicksConfigs(vfId, engine.second, engineClass->second, configPair);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get the busy config and total ticks config and returning error:0x%x \n", __FUNCTION__, result);
|
||||
cleanup();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t busyTicksConfig = configPair.first;
|
||||
int64_t busyTicksFd = pPmuInterface->pmuInterfaceOpen(busyTicksConfig, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
|
||||
if (busyTicksFd < 0) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Busy Ticks Handle and returning error:0x%x \n", __FUNCTION__, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
cleanup();
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
uint64_t totalTicksConfig = configPair.second;
|
||||
int64_t totalTicksFd = pPmuInterface->pmuInterfaceOpen(totalTicksConfig, static_cast<int32_t>(busyTicksFd), PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
|
||||
if (totalTicksFd < 0) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Could not open Total Ticks Handle and returning error:0x%x \n", __FUNCTION__, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
close(static_cast<int>(busyTicksFd));
|
||||
cleanup();
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
EngineUtilsData pEngineUtilsData;
|
||||
pEngineUtilsData.engineType = engine.first;
|
||||
pEngineUtilsData.busyTicksFd = busyTicksFd;
|
||||
pEngineUtilsData.totalTicksFd = totalTicksFd;
|
||||
pEngineUtils.push_back(pEngineUtilsData);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t LinuxVfImp::vfOsGetEngineUtilization(uint32_t *pCount, zes_vf_util_engine_exp2_t *pEngineUtil) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
|
||||
const auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
if (!pSysmanKmdInterface->isVfEngineUtilizationSupported()) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
std::call_once(initEngineDataOnce, [this]() {
|
||||
this->vfEngineDataInit();
|
||||
});
|
||||
|
||||
uint32_t engineCount = static_cast<uint32_t>(pEngineUtils.size());
|
||||
if (engineCount == 0) {
|
||||
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): The Total Engine Count Is Zero and hence returning error:0x%x \n", __FUNCTION__, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
if (*pCount == 0) {
|
||||
*pCount = engineCount;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
if (*pCount > engineCount) {
|
||||
*pCount = engineCount;
|
||||
}
|
||||
|
||||
if (pEngineUtil != nullptr) {
|
||||
const auto pPmuInterface = pLinuxSysmanImp->getPmuInterface();
|
||||
uint32_t index = 0;
|
||||
for (const auto &pEngineUtilsData : pEngineUtils) {
|
||||
uint64_t pmuData[4] = {};
|
||||
auto ret = pPmuInterface->pmuRead(static_cast<int>(pEngineUtilsData.busyTicksFd), pmuData, sizeof(pmuData));
|
||||
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;
|
||||
}
|
||||
|
||||
pEngineUtil[index].vfEngineType = pEngineUtilsData.engineType;
|
||||
pEngineUtil[index].activeCounterValue = pmuData[2];
|
||||
pEngineUtil[index].samplingCounterValue = pmuData[3];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
bool LinuxVfImp::vfOsGetLocalMemoryUsed(uint64_t &lMemUsed) {
|
||||
@@ -138,6 +251,20 @@ LinuxVfImp::LinuxVfImp(
|
||||
this->vfId = vfId;
|
||||
}
|
||||
|
||||
void LinuxVfImp::cleanup() {
|
||||
for (const auto &pEngineUtilsData : pEngineUtils) {
|
||||
DEBUG_BREAK_IF(pEngineUtilsData.busyTicksFd < 0);
|
||||
close(static_cast<int>(pEngineUtilsData.busyTicksFd));
|
||||
DEBUG_BREAK_IF(pEngineUtilsData.totalTicksFd < 0);
|
||||
close(static_cast<int>(pEngineUtilsData.totalTicksFd));
|
||||
}
|
||||
pEngineUtils.clear();
|
||||
}
|
||||
|
||||
LinuxVfImp::~LinuxVfImp() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
std::unique_ptr<OsVf> OsVf::create(
|
||||
OsSysman *pOsSysman, uint32_t vfId) {
|
||||
std::unique_ptr<LinuxVfImp> pLinuxVfImp = std::make_unique<LinuxVfImp>(pOsSysman, vfId);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "level_zero/sysman/source/api/vf_management/sysman_vf_imp.h"
|
||||
#include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace L0 {
|
||||
@@ -21,9 +22,14 @@ class SysFsAccessInterface;
|
||||
|
||||
class LinuxVfImp : public OsVf, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
LinuxVfImp() = default;
|
||||
struct EngineUtilsData {
|
||||
zes_engine_group_t engineType{};
|
||||
int64_t busyTicksFd = -1;
|
||||
int64_t totalTicksFd = -1;
|
||||
};
|
||||
|
||||
LinuxVfImp(OsSysman *pOsSysman, uint32_t vfId);
|
||||
~LinuxVfImp() override = default;
|
||||
~LinuxVfImp() override;
|
||||
|
||||
ze_result_t vfOsGetCapabilities(zes_vf_exp_capabilities_t *pCapability) override;
|
||||
ze_result_t vfOsGetMemoryUtilization(uint32_t *pCount, zes_vf_util_mem_exp2_t *pMemUtil) override;
|
||||
@@ -32,11 +38,19 @@ class LinuxVfImp : public OsVf, NEO::NonCopyableOrMovableClass {
|
||||
bool vfOsGetLocalMemoryUsed(uint64_t &lMemUsed) override;
|
||||
|
||||
protected:
|
||||
ze_result_t vfEngineDataInit();
|
||||
ze_result_t getVfBDFAddress(uint32_t vfIdMinusOne, zes_pci_address_t *address);
|
||||
void vfGetInstancesFromEngineInfo(NEO::EngineInfo *engineInfo, std::set<std::pair<zes_engine_group_t, uint32_t>> &engineGroupAndInstance);
|
||||
void cleanup();
|
||||
LinuxSysmanImp *pLinuxSysmanImp = nullptr;
|
||||
SysFsAccessInterface *pSysfsAccess = nullptr;
|
||||
uint32_t vfId = 0;
|
||||
static const uint32_t maxMemoryTypes = 1; // Since only the Device Memory Utilization is Supported and not for the Host Memory, this value is 1
|
||||
|
||||
private:
|
||||
std::set<std::pair<zes_engine_group_t, uint32_t>> engineGroupAndInstance = {};
|
||||
std::vector<EngineUtilsData> pEngineUtils = {};
|
||||
std::once_flag initEngineDataOnce;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
|
||||
@@ -147,6 +147,8 @@ class SysmanKmdInterface {
|
||||
virtual bool isSettingTimeoutModeSupported() const = 0;
|
||||
virtual bool isSettingExclusiveModeSupported() const = 0;
|
||||
virtual void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual bool isVfEngineUtilizationSupported() const = 0;
|
||||
virtual ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) = 0;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<FsAccessInterface> pFsAccess;
|
||||
@@ -199,6 +201,8 @@ class SysmanKmdInterfaceI915Upstream : public SysmanKmdInterface, SysmanKmdInter
|
||||
bool isSettingTimeoutModeSupported() const override { return true; }
|
||||
bool isSettingExclusiveModeSupported() const override { return true; }
|
||||
void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
bool isVfEngineUtilizationSupported() const override { return false; }
|
||||
ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) override;
|
||||
|
||||
protected:
|
||||
std::map<SysfsName, valuePair> sysfsNameToFileMap;
|
||||
@@ -242,6 +246,8 @@ class SysmanKmdInterfaceI915Prelim : public SysmanKmdInterface, SysmanKmdInterfa
|
||||
bool isSettingTimeoutModeSupported() const override { return true; }
|
||||
bool isSettingExclusiveModeSupported() const override { return true; }
|
||||
void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
bool isVfEngineUtilizationSupported() const override { return true; }
|
||||
ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) override;
|
||||
|
||||
protected:
|
||||
std::map<SysfsName, valuePair> sysfsNameToFileMap;
|
||||
@@ -287,6 +293,8 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface {
|
||||
bool isSettingTimeoutModeSupported() const override { return false; }
|
||||
bool isSettingExclusiveModeSupported() const override { return false; }
|
||||
void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
bool isVfEngineUtilizationSupported() const override { return false; }
|
||||
ze_result_t getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) override;
|
||||
|
||||
protected:
|
||||
std::map<SysfsName, valuePair> sysfsNameToFileMap;
|
||||
|
||||
@@ -173,5 +173,12 @@ void SysmanKmdInterfaceI915Prelim::getDriverVersion(char (&driverVersion)[ZES_ST
|
||||
return;
|
||||
}
|
||||
|
||||
ze_result_t SysmanKmdInterfaceI915Prelim::getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) {
|
||||
|
||||
configPair.first = ___PRELIM_I915_PMU_FN_EVENT(PRELIM_I915_PMU_ENGINE_BUSY_TICKS(engineClass, engineInstance), fnNumber);
|
||||
configPair.second = ___PRELIM_I915_PMU_FN_EVENT(PRELIM_I915_PMU_ENGINE_TOTAL_TICKS(engineClass, engineInstance), fnNumber);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -140,5 +140,9 @@ void SysmanKmdInterfaceI915Upstream::getDriverVersion(char (&driverVersion)[ZES_
|
||||
return;
|
||||
}
|
||||
|
||||
ze_result_t SysmanKmdInterfaceI915Upstream::getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) {
|
||||
return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -146,5 +146,9 @@ void SysmanKmdInterfaceXe::getDriverVersion(char (&driverVersion)[ZES_STRING_PRO
|
||||
return;
|
||||
}
|
||||
|
||||
ze_result_t SysmanKmdInterfaceXe::getBusyAndTotalTicksConfigs(uint64_t fnNumber, uint64_t engineInstance, uint64_t engineClass, std::pair<uint64_t, uint64_t> &configPair) {
|
||||
return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -231,6 +231,11 @@ TEST_F(SysmanFixtureDeviceI915Prelim, GivenSysmanKmdInterfaceWhenCheckingWhether
|
||||
EXPECT_FALSE(pSysmanKmdInterface->clientInfoAvailableInFdInfo());
|
||||
}
|
||||
|
||||
TEST_F(SysmanFixtureDeviceI915Prelim, GivenSysmanKmdInterfaceInstanceWhenCheckingSupportForVfEngineUtilizationThenTrueValueIsReturned) {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
EXPECT_TRUE(pSysmanKmdInterface->isVfEngineUtilizationSupported());
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -237,6 +237,17 @@ TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceWhenCheckingWheth
|
||||
EXPECT_FALSE(pSysmanKmdInterface->clientInfoAvailableInFdInfo());
|
||||
}
|
||||
|
||||
TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceInstanceWhenCheckingSupportForVfEngineUtilizationThenFalseValueIsReturned) {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
EXPECT_FALSE(pSysmanKmdInterface->isVfEngineUtilizationSupported());
|
||||
}
|
||||
|
||||
TEST_F(SysmanFixtureDeviceI915Upstream, GivenSysmanKmdInterfaceInstanceWhenGettingBusyAndTotalTicksConfigsThenErrorIsReturned) {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
std::pair<uint64_t, uint64_t> configPair;
|
||||
EXPECT_EQ(pSysmanKmdInterface->getBusyAndTotalTicksConfigs(0, 0, 1, configPair), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -188,6 +188,17 @@ TEST_F(SysmanFixtureDeviceXe, GivenSingleEngineTypeAndSysmanKmdInterfaceInstance
|
||||
EXPECT_LT(pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get()), 0);
|
||||
}
|
||||
|
||||
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenCheckingSupportForVfEngineUtilizationThenFalseValueIsReturned) {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
EXPECT_FALSE(pSysmanKmdInterface->isVfEngineUtilizationSupported());
|
||||
}
|
||||
|
||||
TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenGettingBusyAndTotalTicksConfigsThenErrorIsReturned) {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
std::pair<uint64_t, uint64_t> configPair;
|
||||
EXPECT_EQ(pSysmanKmdInterface->getBusyAndTotalTicksConfigs(0, 0, 1, configPair), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -10,6 +10,7 @@ set(L0_TESTS_SYSMAN_VF_MANAGEMENT_LINUX
|
||||
|
||||
list(APPEND L0_TESTS_SYSMAN_VF_MANAGEMENT_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_sysman_vf_management.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_sysman_vf_management_prelim.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_sysfs_vf_management.h
|
||||
)
|
||||
|
||||
|
||||
@@ -7,9 +7,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/test/common/test_macros/mock_method_macros.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
#include "shared/source/os_interface/linux/i915_prelim.h"
|
||||
|
||||
#include "level_zero/sysman/source/api/vf_management/linux/sysman_os_vf_imp.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"
|
||||
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_hw_device_id.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
@@ -22,9 +26,93 @@ const std::string pathForVfBdf = "device/virtfn0";
|
||||
const std::string mockBdfdata = "pci0000:4a/0000:4a:02.0/0000:4b:00.0/0000:4c:01.0/0000:4d:00.1";
|
||||
const std::string mockInvalidBdfdata = "pci0000:4a";
|
||||
const std::string mockPathWithInvalidTokens = "pci0000:4a/0000:4a";
|
||||
const int64_t mockPmuFd = 10;
|
||||
const uint64_t mockActiveTime = 987654321;
|
||||
const uint64_t mockTimestamp = 87654321;
|
||||
const uint64_t mockLmemUsed = 65536;
|
||||
const uint64_t mockLmemQuota = 128000;
|
||||
const uint32_t mockNumberOfVfs = 1;
|
||||
const uint32_t numberMockedEngines = 2;
|
||||
|
||||
struct MockVfPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp {
|
||||
using PmuInterfaceImp::perfEventOpen;
|
||||
using PmuInterfaceImp::pSysmanKmdInterface;
|
||||
MockVfPmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {}
|
||||
~MockVfPmuInterfaceImp() override = default;
|
||||
|
||||
bool mockPmuReadFail = false;
|
||||
bool mockPerfEventOpenReadFail = false;
|
||||
int32_t mockErrorNumber = -ENOSPC;
|
||||
int32_t mockPerfEventOpenFailAtCount = 1;
|
||||
|
||||
int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override {
|
||||
|
||||
mockPerfEventOpenFailAtCount = std::max<int32_t>(mockPerfEventOpenFailAtCount - 1, 1);
|
||||
const bool shouldCheckForError = (mockPerfEventOpenFailAtCount == 1);
|
||||
if (shouldCheckForError && mockPerfEventOpenReadFail == true) {
|
||||
errno = mockErrorNumber;
|
||||
return -1;
|
||||
}
|
||||
return mockPmuFd;
|
||||
}
|
||||
|
||||
int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override {
|
||||
|
||||
if (mockPmuReadFail == true) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = mockActiveTime;
|
||||
data[1] = mockTimestamp;
|
||||
data[2] = mockActiveTime;
|
||||
data[3] = mockTimestamp;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct MockEngineSysmanHwDeviceIdDrm : public MockSysmanHwDeviceIdDrm {
|
||||
|
||||
using L0::Sysman::ult::MockSysmanHwDeviceIdDrm::MockSysmanHwDeviceIdDrm;
|
||||
int returnOpenFileDescriptor = -1;
|
||||
int returnCloseFileDescriptor = 0;
|
||||
|
||||
int openFileDescriptor() override {
|
||||
return returnOpenFileDescriptor;
|
||||
}
|
||||
|
||||
int closeFileDescriptor() override {
|
||||
return returnCloseFileDescriptor;
|
||||
}
|
||||
};
|
||||
|
||||
struct MockVfNeoDrm : public Drm {
|
||||
using Drm::engineInfo;
|
||||
using Drm::setupIoctlHelper;
|
||||
const int mockFd = 0;
|
||||
MockVfNeoDrm(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<MockSysmanHwDeviceIdDrm>(mockFd, ""), rootDeviceEnvironment) {}
|
||||
MockVfNeoDrm(RootDeviceEnvironment &rootDeviceEnvironment, int mockFileDescriptor) : Drm(std::make_unique<MockEngineSysmanHwDeviceIdDrm>(mockFileDescriptor, ""), rootDeviceEnvironment) {}
|
||||
~MockVfNeoDrm() override = default;
|
||||
|
||||
bool mockReadSysmanQueryEngineInfo = true;
|
||||
|
||||
bool sysmanQueryEngineInfo() override {
|
||||
|
||||
if (mockReadSysmanQueryEngineInfo == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<NEO::EngineCapabilities> i915QueryEngineInfo(numberMockedEngines);
|
||||
i915QueryEngineInfo[0].engine.engineClass = prelim_drm_i915_gem_engine_class::PRELIM_I915_ENGINE_CLASS_COMPUTE;
|
||||
i915QueryEngineInfo[0].engine.engineInstance = 0;
|
||||
i915QueryEngineInfo[1].engine.engineClass = drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY;
|
||||
i915QueryEngineInfo[1].engine.engineInstance = 0;
|
||||
|
||||
StackVec<std::vector<NEO::EngineCapabilities>, 2> engineInfos{i915QueryEngineInfo};
|
||||
|
||||
this->engineInfo.reset(new EngineInfo(this, engineInfos));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct MockVfSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface {
|
||||
ze_result_t mockError = ZE_RESULT_SUCCESS;
|
||||
@@ -98,10 +186,29 @@ struct MockVfSysfsAccessInterface : public L0::Sysman::SysFsAccessInterface {
|
||||
~MockVfSysfsAccessInterface() override = default;
|
||||
};
|
||||
|
||||
struct MockVfFsAccessInterface : public L0::Sysman::FsAccessInterface {
|
||||
|
||||
bool mockReadFail = false;
|
||||
|
||||
ze_result_t read(const std::string file, uint32_t &val) override {
|
||||
|
||||
if (mockReadFail == true) {
|
||||
val = 0;
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
val = 23;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
MockVfFsAccessInterface() = default;
|
||||
~MockVfFsAccessInterface() override = default;
|
||||
};
|
||||
|
||||
class PublicLinuxVfImp : public L0::Sysman::LinuxVfImp {
|
||||
public:
|
||||
PublicLinuxVfImp(L0::Sysman::OsSysman *pOsSysman, uint32_t vfId) : L0::Sysman::LinuxVfImp(pOsSysman, vfId) {}
|
||||
using L0::Sysman::LinuxVfImp::pSysfsAccess;
|
||||
using L0::Sysman::LinuxVfImp::vfEngineDataInit;
|
||||
};
|
||||
|
||||
} // namespace ult
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#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_i915.h"
|
||||
#include "level_zero/sysman/test/unit_tests/sources/vf_management/linux/mock_sysfs_vf_management.h"
|
||||
|
||||
namespace L0 {
|
||||
@@ -234,6 +235,17 @@ TEST_F(ZesVfFixture, GivenValidVfHandleWhenQueryingMemoryUtilizationAndAndZeroLo
|
||||
EXPECT_EQ(pVfImp->vfOsGetMemoryUtilization(&mockCount, memUtils.data()), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixture, GivenValidVfHandleWhenBusyAndTotalTicksConfigNotAvailableAndCallingVfEngineDataInitThenErrorIsReturned) {
|
||||
|
||||
auto pDrm = new MockVfNeoDrm(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
|
||||
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
|
||||
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
|
||||
osInterface->setDriverModel(std::unique_ptr<MockVfNeoDrm>(pDrm));
|
||||
|
||||
auto pVfImp = std::make_unique<PublicLinuxVfImp>(pOsSysman, 1);
|
||||
EXPECT_EQ(pVfImp->vfEngineDataInit(), ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#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_i915.h"
|
||||
#include "level_zero/sysman/test/unit_tests/sources/vf_management/linux/mock_sysfs_vf_management.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
namespace ult {
|
||||
|
||||
constexpr uint32_t mockHandleCount = 1u;
|
||||
|
||||
class ZesVfFixturePrelim : public SysmanDeviceFixture {
|
||||
protected:
|
||||
L0::Sysman::SysmanDevice *device = nullptr;
|
||||
MockVfSysfsAccessInterface *pSysfsAccess = nullptr;
|
||||
MockVfFsAccessInterface *pFsAccess = nullptr;
|
||||
std::unique_ptr<MockVfPmuInterfaceImp> pPmuInterface;
|
||||
PmuInterface *pOriginalPmuInterface = nullptr;
|
||||
MockVfNeoDrm *pDrm = nullptr;
|
||||
MockSysmanKmdInterfacePrelim *pSysmanKmdInterface = nullptr;
|
||||
|
||||
void SetUp() override {
|
||||
SysmanDeviceFixture::SetUp();
|
||||
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
|
||||
std::string str = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128";
|
||||
std::memcpy(buf, str.c_str(), str.size());
|
||||
return static_cast<int>(str.size());
|
||||
});
|
||||
|
||||
pFsAccess = new MockVfFsAccessInterface();
|
||||
pSysfsAccess = new MockVfSysfsAccessInterface();
|
||||
|
||||
pSysmanKmdInterface = new MockSysmanKmdInterfacePrelim(pLinuxSysmanImp->getSysmanProductHelper());
|
||||
pSysmanKmdInterface->pFsAccess.reset(pFsAccess);
|
||||
pSysmanKmdInterface->pSysfsAccess.reset(pSysfsAccess);
|
||||
pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface);
|
||||
|
||||
pLinuxSysmanImp->pFsAccess = pLinuxSysmanImp->getSysmanKmdInterface()->getFsAccess();
|
||||
pLinuxSysmanImp->pSysfsAccess = pLinuxSysmanImp->getSysmanKmdInterface()->getSysFsAccess();
|
||||
|
||||
pDrm = new MockVfNeoDrm(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
|
||||
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
|
||||
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
|
||||
osInterface->setDriverModel(std::unique_ptr<MockVfNeoDrm>(pDrm));
|
||||
|
||||
pSysmanDeviceImp->pVfManagementHandleContext->handleList.clear();
|
||||
pPmuInterface = std::make_unique<MockVfPmuInterfaceImp>(pLinuxSysmanImp);
|
||||
pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface;
|
||||
pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get();
|
||||
pLinuxSysmanImp->pPmuInterface = pPmuInterface.get();
|
||||
pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = true;
|
||||
device = pSysmanDevice;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface;
|
||||
SysmanDeviceFixture::TearDown();
|
||||
}
|
||||
|
||||
std::vector<zes_vf_handle_t> getEnabledVfHandles(uint32_t count) {
|
||||
std::vector<zes_vf_handle_t> handles(count, nullptr);
|
||||
EXPECT_EQ(zesDeviceEnumEnabledVFExp(device, &count, handles.data()), ZE_RESULT_SUCCESS);
|
||||
return handles;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidDeviceHandleWhenQueryingEnabledVfHandlesThenCorrectVfHandlesAreReturned) {
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenCallingZesVFManagementGetVFEngineUtilizationExp2AndOpenCallFailsThenErrorIsReturned) {
|
||||
|
||||
MockVfNeoDrm *pDrm = nullptr;
|
||||
int mockFd = -1;
|
||||
pDrm = new MockVfNeoDrm(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()), mockFd);
|
||||
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
|
||||
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
|
||||
osInterface->setDriverModel(std::unique_ptr<MockVfNeoDrm>(pDrm));
|
||||
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenCallingZesVFManagementGetVFEngineUtilizationExp2AndSysmanQueryEngineInfoFailsThenErrorIsReturned) {
|
||||
|
||||
pDrm->mockReadSysmanQueryEngineInfo = false;
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenCallingZesVFManagementGetVFEngineUtilizationExp2WithEngineStatsCountThenCorrectEngineStatsCountIsReturned) {
|
||||
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
EXPECT_EQ(count, numberMockedEngines);
|
||||
count = count + 5;
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
EXPECT_EQ(count, numberMockedEngines);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenQueryingEngineUtilizationMultipleTimesThenCorrectEngineStatsAreReturned) {
|
||||
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
std::vector<zes_vf_util_engine_exp2_t> engineUtils(count);
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, engineUtils.data());
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
EXPECT_EQ(engineUtils[0].vfEngineType, ZES_ENGINE_GROUP_COMPUTE_SINGLE);
|
||||
EXPECT_EQ(engineUtils[0].activeCounterValue, mockActiveTime);
|
||||
EXPECT_EQ(engineUtils[0].samplingCounterValue, mockTimestamp);
|
||||
EXPECT_EQ(engineUtils[1].vfEngineType, ZES_ENGINE_GROUP_COPY_SINGLE);
|
||||
EXPECT_EQ(engineUtils[1].activeCounterValue, mockActiveTime);
|
||||
EXPECT_EQ(engineUtils[1].samplingCounterValue, mockTimestamp);
|
||||
engineUtils.clear();
|
||||
engineUtils.resize(count);
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, engineUtils.data());
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
EXPECT_EQ(engineUtils[0].vfEngineType, ZES_ENGINE_GROUP_COMPUTE_SINGLE);
|
||||
EXPECT_EQ(engineUtils[0].activeCounterValue, mockActiveTime);
|
||||
EXPECT_EQ(engineUtils[0].samplingCounterValue, mockTimestamp);
|
||||
EXPECT_EQ(engineUtils[1].vfEngineType, ZES_ENGINE_GROUP_COPY_SINGLE);
|
||||
EXPECT_EQ(engineUtils[1].activeCounterValue, mockActiveTime);
|
||||
EXPECT_EQ(engineUtils[1].samplingCounterValue, mockTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenPmuInterfaceOpenFailsForBusyTicksConfigThenErrorIsReturned) {
|
||||
|
||||
pFsAccess->mockReadFail = true;
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenPmuInterfaceOpenFailsForTotalTicksConfigThenErrorIsReturned) {
|
||||
|
||||
pPmuInterface->mockPerfEventOpenFailAtCount = 3;
|
||||
pPmuInterface->mockPerfEventOpenReadFail = true;
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZesVfFixturePrelim, GivenValidVfHandleWhenPmuReadFailsThenErrorIsReturned) {
|
||||
|
||||
pPmuInterface->mockPmuReadFail = true;
|
||||
auto handles = getEnabledVfHandles(mockHandleCount);
|
||||
for (auto handleVf : handles) {
|
||||
ASSERT_NE(nullptr, handleVf);
|
||||
uint32_t count = 0;
|
||||
auto result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, nullptr);
|
||||
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
std::vector<zes_vf_util_engine_exp2_t> engineUtils(count);
|
||||
result = zesVFManagementGetVFEngineUtilizationExp2(handleVf, &count, engineUtils.data());
|
||||
EXPECT_EQ(result, ZE_RESULT_ERROR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
Reference in New Issue
Block a user