From 246a143d0f8a7022080db20171ebb3c1ef150b73 Mon Sep 17 00:00:00 2001 From: "Bari, Pratik" Date: Mon, 30 Oct 2023 07:01:53 +0000 Subject: [PATCH] feature: Xe porting of Group Engine Interface Related-To: NEO-8629 Signed-off-by: Bari, Pratik --- .../api/engine/linux/sysman_os_engine_imp.cpp | 52 +-- .../linux/sysman_os_engine_imp_prelim.cpp | 24 +- .../api/power/linux/sysman_os_power_imp.cpp | 2 +- .../shared/linux/pmu/sysman_pmu_imp.cpp | 37 +-- .../source/shared/linux/pmu/sysman_pmu_imp.h | 6 +- .../shared/linux/sysman_kmd_interface.cpp | 105 ++++-- .../shared/linux/sysman_kmd_interface.h | 10 +- .../source/shared/linux/zes_os_sysman_imp.cpp | 1 + .../sources/engine/linux/CMakeLists.txt | 7 + .../sources/engine/linux/mock_engine.h | 45 +-- .../sources/engine/linux/mock_engine_xe.h | 87 +++++ .../sources/engine/linux/test_zes_engine.cpp | 107 +++--- .../engine/linux/test_zes_engine_prelim.cpp | 46 ++- .../engine/linux/test_zes_engine_xe.cpp | 163 ++++++++++ .../sources/events/linux/test_zes_events.cpp | 76 +++++ .../unit_tests/sources/linux/pmu/mock_pmu.h | 7 - .../unit_tests/sources/linux/pmu/test_pmu.cpp | 54 +++- .../sources/ras/linux/test_zes_ras.cpp | 42 +++ .../unit_tests/sources/shared/CMakeLists.txt | 10 + .../sources/shared/linux/CMakeLists.txt | 19 ++ .../linux/sysman_kmd_interface_tests.cpp | 306 ++++++++++++++++++ .../shared/linux/sysman_kmd_interface_tests.h | 70 ++++ 22 files changed, 1062 insertions(+), 214 deletions(-) create mode 100644 level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h create mode 100644 level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/shared/CMakeLists.txt create mode 100644 level_zero/sysman/test/unit_tests/sources/shared/linux/CMakeLists.txt create mode 100644 level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.cpp create mode 100644 level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.h diff --git a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp index c11978906a..a1341650e3 100644 --- a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp +++ b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp @@ -13,30 +13,33 @@ #include "level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h" #include "level_zero/sysman/source/shared/linux/sysman_hw_device_id_linux.h" +#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h" #include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h" #include "level_zero/sysman/source/sysman_const.h" namespace L0 { namespace Sysman { -constexpr auto I915_SAMPLE_BUSY = NEO::I915::drm_i915_pmu_engine_sample::I915_SAMPLE_BUSY; -static const std::multimap<__u16, zes_engine_group_t> i915ToEngineMap = { - {static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER), ZES_ENGINE_GROUP_RENDER_SINGLE}, - {static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO), ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE}, - {static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO), ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE}, - {static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY), ZES_ENGINE_GROUP_COPY_SINGLE}, - {static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE), ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE}}; - -static const std::multimap engineToI915Map = { - {ZES_ENGINE_GROUP_RENDER_SINGLE, static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER)}, - {ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO)}, - {ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO)}, - {ZES_ENGINE_GROUP_COPY_SINGLE, static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY)}, - {ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE, static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE)}}; +zes_engine_group_t LinuxEngineImp::getGroupFromEngineType(zes_engine_group_t type) { + if (type == ZES_ENGINE_GROUP_RENDER_SINGLE) { + return ZES_ENGINE_GROUP_RENDER_ALL; + } + if (type == ZES_ENGINE_GROUP_COMPUTE_SINGLE) { + return ZES_ENGINE_GROUP_COMPUTE_ALL; + } + if (type == ZES_ENGINE_GROUP_COPY_SINGLE) { + return ZES_ENGINE_GROUP_COPY_ALL; + } + if (type == ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE || type == ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE || type == ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE) { + return ZES_ENGINE_GROUP_MEDIA_ALL; + } + return ZES_ENGINE_GROUP_ALL; +} ze_result_t OsEngine::getNumEngineTypeAndInstances(std::set> &engineGroupInstance, OsSysman *pOsSysman) { LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); NEO::Drm *pDrm = pLinuxSysmanImp->getDrm(); + auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); bool status = false; { @@ -45,15 +48,21 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::setgetEngineInfo(); - for (auto itr = engineInfo->engines.begin(); itr != engineInfo->engines.end(); ++itr) { - auto i915ToEngineMapRange = i915ToEngineMap.equal_range(static_cast<__u16>(itr->engine.engineClass)); - for (auto l0EngineEntryInMap = i915ToEngineMapRange.first; l0EngineEntryInMap != i915ToEngineMapRange.second; l0EngineEntryInMap++) { + auto engineTileMap = engineInfo->getEngineTileInfo(); + for (auto itr = engineTileMap.begin(); itr != engineTileMap.end(); ++itr) { + uint32_t subDeviceId = itr->first; + auto engineGroupRange = engineClassToEngineGroup.equal_range(static_cast(itr->second.engineClass)); + for (auto l0EngineEntryInMap = engineGroupRange.first; l0EngineEntryInMap != engineGroupRange.second; l0EngineEntryInMap++) { auto l0EngineType = l0EngineEntryInMap->second; - engineGroupInstance.insert({l0EngineType, {static_cast(itr->engine.engineInstance), 0}}); + engineGroupInstance.insert({l0EngineType, {static_cast(itr->second.engineInstance), subDeviceId}}); + if (pSysmanKmdInterface->isGroupEngineInterfaceAvailable()) { + engineGroupInstance.insert({LinuxEngineImp::getGroupFromEngineType(l0EngineType), {0u, subDeviceId}}); + engineGroupInstance.insert({ZES_ENGINE_GROUP_ALL, {0u, subDeviceId}}); + } } } return ZE_RESULT_SUCCESS; @@ -84,9 +93,7 @@ ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) { } void LinuxEngineImp::init() { - auto i915EngineClass = engineToI915Map.find(engineGroup); - // I915_PMU_ENGINE_BUSY macro provides the perf type config which we want to listen to get the engine busyness. - fd = pPmuInterface->pmuInterfaceOpen(I915_PMU_ENGINE_BUSY(i915EngineClass->second, engineInstance), -1, PERF_FORMAT_TOTAL_TIME_ENABLED); + fd = pSysmanKmdInterface->getEngineActivityFd(engineGroup, engineInstance, subDeviceId, pPmuInterface); } bool LinuxEngineImp::isEngineModuleSupported() { @@ -102,6 +109,7 @@ LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uin pDrm = pLinuxSysmanImp->getDrm(); pDevice = pLinuxSysmanImp->getSysmanDeviceImp(); pPmuInterface = pLinuxSysmanImp->getPmuInterface(); + pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); init(); } diff --git a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp_prelim.cpp b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp_prelim.cpp index 607bb14c31..a5918dc4d5 100644 --- a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp_prelim.cpp +++ b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp_prelim.cpp @@ -18,6 +18,8 @@ namespace L0 { namespace Sysman { +using NEO::PrelimI915::I915_SAMPLE_BUSY; + zes_engine_group_t LinuxEngineImp::getGroupFromEngineType(zes_engine_group_t type) { if (type == ZES_ENGINE_GROUP_RENDER_SINGLE) { return ZES_ENGINE_GROUP_RENDER_ALL; @@ -88,7 +90,27 @@ ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) { } void LinuxEngineImp::init() { - fd = pSysmanKmdInterface->getEngineActivityFd(engineGroup, engineInstance, subDeviceId, pPmuInterface); + uint64_t config = UINT64_MAX; + switch (engineGroup) { + case ZES_ENGINE_GROUP_ALL: + config = __PRELIM_I915_PMU_ANY_ENGINE_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_COMPUTE_ALL: + case ZES_ENGINE_GROUP_RENDER_ALL: + config = __PRELIM_I915_PMU_RENDER_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_COPY_ALL: + config = __PRELIM_I915_PMU_COPY_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_MEDIA_ALL: + config = __PRELIM_I915_PMU_MEDIA_GROUP_BUSY(subDeviceId); + break; + default: + auto engineClass = engineGroupToEngineClass.find(engineGroup); + config = I915_PMU_ENGINE_BUSY(engineClass->second, engineInstance); + break; + } + fd = pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED); } bool LinuxEngineImp::isEngineModuleSupported() { diff --git a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp index e4c6afc7c9..8f10a28a8a 100644 --- a/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp +++ b/level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp @@ -253,7 +253,7 @@ LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_ LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); pPmt = pLinuxSysmanImp->getPlatformMonitoringTechAccess(subdeviceId); pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); - pSysfsAccess = pSysmanKmdInterface->getSysFsAccess(pLinuxSysmanImp->getDeviceName()); + pSysfsAccess = pSysmanKmdInterface->getSysFsAccess(); } OsPower *OsPower::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) { diff --git a/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.cpp b/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.cpp index d7655f2097..5100384882 100644 --- a/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.cpp +++ b/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.cpp @@ -9,41 +9,14 @@ #include "shared/source/memory_manager/memory_manager.h" +#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h" + namespace L0 { namespace Sysman { const std::string PmuInterfaceImp::deviceDir("device"); const std::string PmuInterfaceImp::sysDevicesDir("/sys/devices/"); static constexpr int64_t perfEventOpenSyscallNumber = 298; -// Get event id -uint32_t PmuInterfaceImp::getEventType() { - std::string i915DirName("i915"); - const bool isIntegratedDevice = pDevice->getRootDeviceEnvironment().getHardwareInfo()->capabilityTable.isIntegratedDevice; - if (!isIntegratedDevice) { - std::string bdfDir; - // ID or type of Pmu driver for discrete graphics is obtained by reading sysfs node as explained below: - // For instance DG1 in PCI slot 0000:03:00.0: - // $ cat /sys/devices/i915_0000_03_00.0/type - // 23 - ze_result_t result = pSysfsAccess->readSymLink(deviceDir, bdfDir); - if (ZE_RESULT_SUCCESS != result) { - return 0; - } - const auto loc = bdfDir.find_last_of('/'); - auto bdf = bdfDir.substr(loc + 1); - std::replace(bdf.begin(), bdf.end(), ':', '_'); - i915DirName = "i915_" + bdf; - } - // For integrated graphics type of PMU driver is obtained by reading /sys/devices/i915/type node - // # cat /sys/devices/i915/type - // 18 - const std::string eventTypeSysfsNode = sysDevicesDir + i915DirName + "/" + "type"; - auto eventTypeVal = 0u; - if (ZE_RESULT_SUCCESS != pFsAccess->read(eventTypeSysfsNode, eventTypeVal)) { - return 0; - } - return eventTypeVal; -} int PmuInterfaceImp::getErrorNo() { return errno; @@ -55,12 +28,13 @@ inline int64_t PmuInterfaceImp::perfEventOpen(perf_event_attr *attr, pid_t pid, } int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint32_t format) { + const bool isIntegratedDevice = pDevice->getRootDeviceEnvironment().getHardwareInfo()->capabilityTable.isIntegratedDevice; struct perf_event_attr attr = {}; int nrCpus = get_nprocs_conf(); int cpu = 0; int64_t ret = 0; - attr.type = getEventType(); + attr.type = pSysmanKmdInterface->getEventType(isIntegratedDevice); if (attr.type == 0) { return -ENOENT; } @@ -89,9 +63,8 @@ int PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) { } PmuInterfaceImp::PmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) { - pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess(); - pFsAccess = &pLinuxSysmanImp->getFsAccess(); pDevice = pLinuxSysmanImp->getSysmanDeviceImp(); + pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); } PmuInterface *PmuInterface::create(LinuxSysmanImp *pLinuxSysmanImp) { diff --git a/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h b/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h index ea94d64b6b..a93e3862ae 100644 --- a/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h +++ b/level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h @@ -18,6 +18,8 @@ namespace L0 { namespace Sysman { +class SysmanKmdInterface; + class PmuInterfaceImp : public PmuInterface, NEO::NonCopyableOrMovableClass { public: PmuInterfaceImp() = delete; @@ -31,11 +33,9 @@ class PmuInterfaceImp : public PmuInterface, NEO::NonCopyableOrMovableClass { 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; + SysmanKmdInterface *pSysmanKmdInterface = nullptr; private: - uint32_t getEventType(); - FsAccess *pFsAccess = nullptr; - SysfsAccess *pSysfsAccess = nullptr; SysmanDeviceImp *pDevice = nullptr; static const std::string deviceDir; static const std::string sysDevicesDir; diff --git a/level_zero/sysman/source/shared/linux/sysman_kmd_interface.cpp b/level_zero/sysman/source/shared/linux/sysman_kmd_interface.cpp index 84a94be555..557c056e86 100644 --- a/level_zero/sysman/source/shared/linux/sysman_kmd_interface.cpp +++ b/level_zero/sysman/source/shared/linux/sysman_kmd_interface.cpp @@ -12,16 +12,18 @@ #include "shared/source/helpers/hw_info.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/engine_info.h" -#include "shared/source/os_interface/linux/i915_prelim.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 "drm/i915_drm.h" #include "drm/xe_drm.h" namespace L0 { namespace Sysman { -using NEO::PrelimI915::I915_SAMPLE_BUSY; + +const std::string deviceDir("device"); +const std::string sysDevicesDir("/sys/devices/"); SysmanKmdInterface::SysmanKmdInterface() = default; @@ -78,29 +80,25 @@ std::unique_ptr SysmanKmdInterface::create(const NEO::Drm &d return pSysmanKmdInterface; } -FsAccessInterface *SysmanKmdInterface::getFsAccess() { +void SysmanKmdInterface::initFsAccessInterface(const NEO::Drm &drm) { + pFsAccess = FsAccessInterface::create(); + pProcfsAccess = ProcFsAccessInterface::create(); + std::string deviceName; + pProcfsAccess->getFileName(pProcfsAccess->myProcessId(), drm.getFileDescriptor(), deviceName); + pSysfsAccess = SysFsAccessInterface::create(deviceName); +} - if (nullptr == pFsAccess.get()) { - pFsAccess = FsAccessInterface::create(); - } +FsAccessInterface *SysmanKmdInterface::getFsAccess() { 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); - } +SysFsAccessInterface *SysmanKmdInterface::getSysFsAccess() { UNRECOVERABLE_IF(nullptr == pSysfsAccess.get()); return pSysfsAccess.get(); } @@ -209,30 +207,33 @@ std::string SysmanKmdInterfaceXe::getSysfsFilePathForPhysicalMemorySize(uint32_t int64_t SysmanKmdInterfaceI915::getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface) { uint64_t config = UINT64_MAX; - switch (engineGroup) { - case ZES_ENGINE_GROUP_ALL: - config = __PRELIM_I915_PMU_ANY_ENGINE_GROUP_BUSY(subDeviceId); - break; - case ZES_ENGINE_GROUP_COMPUTE_ALL: - case ZES_ENGINE_GROUP_RENDER_ALL: - config = __PRELIM_I915_PMU_RENDER_GROUP_BUSY(subDeviceId); - break; - case ZES_ENGINE_GROUP_COPY_ALL: - config = __PRELIM_I915_PMU_COPY_GROUP_BUSY(subDeviceId); - break; - case ZES_ENGINE_GROUP_MEDIA_ALL: - config = __PRELIM_I915_PMU_MEDIA_GROUP_BUSY(subDeviceId); - break; - default: - auto engineClass = engineGroupToEngineClass.find(engineGroup); - config = I915_PMU_ENGINE_BUSY(engineClass->second, engineInstance); - break; - } + auto engineClass = engineGroupToEngineClass.find(engineGroup); + config = I915_PMU_ENGINE_BUSY(engineClass->second, engineInstance); return pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED); } int64_t SysmanKmdInterfaceXe::getEngineActivityFd(zes_engine_group_t engineGroup, uint32_t engineInstance, uint32_t subDeviceId, PmuInterface *const &pPmuInterface) { - return -1; + uint64_t config = UINT64_MAX; + + switch (engineGroup) { + case ZES_ENGINE_GROUP_ALL: + config = XE_PMU_ANY_ENGINE_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_COMPUTE_ALL: + case ZES_ENGINE_GROUP_RENDER_ALL: + config = XE_PMU_RENDER_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_COPY_ALL: + config = XE_PMU_COPY_GROUP_BUSY(subDeviceId); + break; + case ZES_ENGINE_GROUP_MEDIA_ALL: + config = XE_PMU_MEDIA_GROUP_BUSY(subDeviceId); + break; + default: + break; + } + + return pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED); } std::string SysmanKmdInterfaceI915::getHwmonName(uint32_t subDeviceId, bool isSubdevice) const { @@ -378,5 +379,39 @@ void SysmanKmdInterface::convertSysfsValueUnit(const SysfsValueUnit dstUnit, con } } +uint32_t SysmanKmdInterface::getEventTypeImpl(std::string &dirName, const bool isIntegratedDevice) { + auto pSysFsAccess = getSysFsAccess(); + auto pFsAccess = getFsAccess(); + + if (!isIntegratedDevice) { + std::string bdfDir; + ze_result_t result = pSysFsAccess->readSymLink(deviceDir, bdfDir); + if (ZE_RESULT_SUCCESS != result) { + return 0; + } + const auto loc = bdfDir.find_last_of('/'); + auto bdf = bdfDir.substr(loc + 1); + std::replace(bdf.begin(), bdf.end(), ':', '_'); + dirName = dirName + "_" + bdf; + } + + const std::string eventTypeSysfsNode = sysDevicesDir + dirName + "/" + "type"; + auto eventTypeVal = 0u; + if (ZE_RESULT_SUCCESS != pFsAccess->read(eventTypeSysfsNode, eventTypeVal)) { + return 0; + } + return eventTypeVal; +} + +uint32_t SysmanKmdInterfaceI915::getEventType(const bool isIntegratedDevice) { + std::string i915DirName = "i915"; + return getEventTypeImpl(i915DirName, isIntegratedDevice); +} + +uint32_t SysmanKmdInterfaceXe::getEventType(const bool isIntegratedDevice) { + std::string xeDirName = "xe"; + return getEventTypeImpl(xeDirName, isIntegratedDevice); +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/source/shared/linux/sysman_kmd_interface.h b/level_zero/sysman/source/shared/linux/sysman_kmd_interface.h index c6a8f58c1b..e75aca086d 100644 --- a/level_zero/sysman/source/shared/linux/sysman_kmd_interface.h +++ b/level_zero/sysman/source/shared/linux/sysman_kmd_interface.h @@ -108,9 +108,11 @@ class SysmanKmdInterface { virtual std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const = 0; virtual bool isStandbyModeControlAvailable() const = 0; virtual bool clientInfoAvailableInFdInfo() = 0; + virtual bool isGroupEngineInterfaceAvailable() const = 0; + void initFsAccessInterface(const NEO::Drm &drm); FsAccessInterface *getFsAccess(); ProcFsAccessInterface *getProcFsAccess(); - SysFsAccessInterface *getSysFsAccess(std::string deviceName); + SysFsAccessInterface *getSysFsAccess(); virtual std::string getEngineBasePath(uint32_t subDeviceId) const = 0; virtual bool useDefaultMaximumWatchdogTimeoutForExclusiveMode() = 0; virtual ze_result_t getNumEngineTypeAndInstances(std::map> &mapOfEngines, @@ -122,12 +124,14 @@ class SysmanKmdInterface { void convertSysfsValueUnit(const SysfsValueUnit dstUnit, const SysfsValueUnit srcUnit, const uint64_t srcValue, uint64_t &dstValue) const; virtual std::optional getEngineClassString(uint16_t engineClass) = 0; + virtual uint32_t getEventType(const bool isIntegratedDevice) = 0; protected: std::unique_ptr pFsAccess; std::unique_ptr pProcfsAccess; std::unique_ptr pSysfsAccess; virtual const std::map &getSysfsNameToNativeUnitMap() = 0; + uint32_t getEventTypeImpl(std::string &dirName, const bool isIntegratedDevice); }; class SysmanKmdInterfaceI915 : public SysmanKmdInterface { @@ -142,6 +146,7 @@ class SysmanKmdInterfaceI915 : public SysmanKmdInterface { std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override; bool isStandbyModeControlAvailable() const override { return true; } bool clientInfoAvailableInFdInfo() override; + bool isGroupEngineInterfaceAvailable() const override { return false; } std::string getEngineBasePath(uint32_t subDeviceId) const override { return "engine"; }; bool useDefaultMaximumWatchdogTimeoutForExclusiveMode() override { return false; }; ze_result_t getNumEngineTypeAndInstances(std::map> &mapOfEngines, @@ -150,6 +155,7 @@ class SysmanKmdInterfaceI915 : public SysmanKmdInterface { ze_bool_t onSubdevice, uint32_t subdeviceId) override; std::optional getEngineClassString(uint16_t engineClass) override; + uint32_t getEventType(const bool isIntegratedDevice) override; protected: std::map sysfsNameToFileMap; @@ -177,6 +183,7 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface { std::string getHwmonName(uint32_t subDeviceId, bool isSubdevice) const override; bool isStandbyModeControlAvailable() const override { return false; } bool clientInfoAvailableInFdInfo() override; + bool isGroupEngineInterfaceAvailable() const override { return true; } bool useDefaultMaximumWatchdogTimeoutForExclusiveMode() override { return true; }; ze_result_t getNumEngineTypeAndInstances(std::map> &mapOfEngines, LinuxSysmanImp *pLinuxSysmanImp, @@ -184,6 +191,7 @@ class SysmanKmdInterfaceXe : public SysmanKmdInterface { ze_bool_t onSubdevice, uint32_t subdeviceId) override; std::optional getEngineClassString(uint16_t engineClass) override; + uint32_t getEventType(const bool isIntegratedDevice) override; protected: std::map sysfsNameToFileMap; diff --git a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp index 4ad043530e..17424e1f4e 100644 --- a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp +++ b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp @@ -66,6 +66,7 @@ ze_result_t LinuxSysmanImp::init() { pSysfsAccess->getRealPath(deviceDir, gtDevicePath); pSysmanKmdInterface = SysmanKmdInterface::create(*getDrm()); + pSysmanKmdInterface->initFsAccessInterface(*getDrm()); pSysmanProductHelper = SysmanProductHelper::create(getProductFamily()); osInterface.getDriverModel()->as()->cleanup(); diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt index 9fbd352a52..0cda7f9742 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt @@ -21,6 +21,13 @@ else() ) endif() +if(NEO_ENABLE_XE_DRM_DETECTION) + list(APPEND L0_TESTS_SYSMAN_ENGINE_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_engine_xe.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_engine_xe.h + ) +endif() + if(UNIX) target_sources(${TARGET_NAME} PRIVATE diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine.h b/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine.h index 0dd6c671d9..cbfd7f0eb8 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine.h +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine.h @@ -23,13 +23,6 @@ namespace L0 { namespace Sysman { namespace ult { -constexpr int64_t mockPmuFd = 10; -constexpr uint64_t mockTimestamp = 87654321; -constexpr uint64_t mockActiveTime = 987654321; -const uint32_t microSecondsToNanoSeconds = 1000u; -constexpr uint16_t I915_INVALID_ENGINE_CLASS = UINT16_MAX; -const std::string deviceDir("device"); - struct MockEngineNeoDrm : public Drm { using Drm::getEngineInfo; using Drm::setupIoctlHelper; @@ -53,7 +46,7 @@ struct MockEngineNeoDrm : public Drm { i915engineInfo[3].engine.engineInstance = 0; i915engineInfo[4].engine.engineClass = drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE; i915engineInfo[4].engine.engineInstance = 0; - i915engineInfo[5].engine.engineClass = I915_INVALID_ENGINE_CLASS; + i915engineInfo[5].engine.engineClass = UINT16_MAX; i915engineInfo[5].engine.engineInstance = 0; this->engineInfo.reset(new EngineInfo(this, i915engineInfo)); @@ -63,6 +56,9 @@ struct MockEngineNeoDrm : public Drm { struct MockEnginePmuInterfaceImp : public L0::Sysman::PmuInterfaceImp { using PmuInterfaceImp::perfEventOpen; + int64_t mockPmuFd = 0; + uint64_t mockTimestamp = 0; + uint64_t mockActiveTime = 0; MockEnginePmuInterfaceImp(L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {} int64_t mockPerfEventFailureReturnValue = 0; @@ -86,39 +82,6 @@ struct MockEnginePmuInterfaceImp : public L0::Sysman::PmuInterfaceImp { } }; -struct MockEngineFsAccess : public L0::Sysman::FsAccess { - uint32_t mockReadVal = 23; - ze_result_t mockReadErrorVal = ZE_RESULT_SUCCESS; - ze_result_t readResult = ZE_RESULT_SUCCESS; - ze_result_t read(const std::string file, uint32_t &val) override { - val = mockReadVal; - if (mockReadErrorVal != ZE_RESULT_SUCCESS) { - readResult = mockReadErrorVal; - } - - return readResult; - } -}; - -struct MockEngineSysfsAccess : public L0::Sysman::SysfsAccess { - ze_result_t mockReadSymLinkError = ZE_RESULT_SUCCESS; - ze_result_t readSymLinkResult = ZE_RESULT_SUCCESS; - uint32_t readSymLinkCalled = 0u; - ze_result_t readSymLink(const std::string file, std::string &val) override { - readSymLinkCalled++; - if ((mockReadSymLinkError != ZE_RESULT_SUCCESS) && (readSymLinkCalled == 1)) { - return mockReadSymLinkError; - } - - if (file.compare(deviceDir) == 0) { - val = "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0"; - } - return readSymLinkResult; - } - - MockEngineSysfsAccess() = default; -}; - using DrmMockEngineInfoFailing = DrmMock; } // namespace ult diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h b/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h new file mode 100644 index 0000000000..f2ec45ead9 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/os_interface/linux/drm_neo.h" +#include "shared/source/os_interface/linux/engine_info.h" + +#include "level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h" +#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_hw_device_id.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +class MockNeoDrm : public NEO::Drm { + + public: + using NEO::Drm::getEngineInfo; + using NEO::Drm::ioctlHelper; + const int mockFd = 0; + + MockNeoDrm(NEO::RootDeviceEnvironment &rootDeviceEnvironment) : NEO::Drm(std::make_unique(mockFd, ""), rootDeviceEnvironment) {} + + bool mockSysmanQueryEngineInfoReturnFalse = true; + bool sysmanQueryEngineInfo() override { + if (mockSysmanQueryEngineInfoReturnFalse != true) { + return mockSysmanQueryEngineInfoReturnFalse; + } + + std::vector mockEngineInfo(6); + 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[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; + + this->engineInfo.reset(new NEO::EngineInfo(this, mockEngineInfo)); + return true; + } +}; + +class MockPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp { + public: + int64_t mockPmuFd = -1; + uint64_t mockTimestamp = 0; + uint64_t mockActiveTime = 0; + using PmuInterfaceImp::perfEventOpen; + using PmuInterfaceImp::pSysmanKmdInterface; + MockPmuInterfaceImp(L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {} + + int64_t mockPerfEventFailureReturnValue = 0; + int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override { + if (mockPerfEventFailureReturnValue == -1) { + return mockPerfEventFailureReturnValue; + } + + return mockPmuFd; + } + + int mockPmuReadFailureReturnValue = 0; + int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override { + if (mockPmuReadFailureReturnValue == -1) { + return mockPmuReadFailureReturnValue; + } + + data[0] = mockActiveTime; + data[1] = mockTimestamp; + return 0; + } +}; + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp index 5dcb1e43f8..63a0545de0 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp @@ -7,45 +7,40 @@ #include "shared/source/os_interface/linux/memory_info.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/engine/linux/mock_engine.h" #include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" -#include "mock_engine.h" - namespace L0 { namespace Sysman { namespace ult { constexpr uint32_t handleComponentCount = 6u; +constexpr uint32_t microSecondsToNanoSeconds = 1000u; + class ZesEngineFixture : public SysmanDeviceFixture { protected: - std::unique_ptr pPmuInterface; - L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr; - std::unique_ptr pSysfsAccess; - L0::Sysman::SysfsAccess *pSysfsAccessOriginal = nullptr; - std::unique_ptr pFsAccess; - L0::Sysman::FsAccess *pFsAccessOriginal = nullptr; L0::Sysman::SysmanDevice *device = nullptr; +}; + +class ZesEngineFixtureI915 : public ZesEngineFixture { + protected: + std::unique_ptr pPmuInterface; void SetUp() override { SysmanDeviceFixture::SetUp(); - - pSysfsAccessOriginal = pLinuxSysmanImp->pSysfsAccess; - pSysfsAccess = std::make_unique(); - pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get(); - - pFsAccessOriginal = pLinuxSysmanImp->pFsAccess; - pFsAccess = std::make_unique(); - pLinuxSysmanImp->pFsAccess = pFsAccess.get(); - MockEngineNeoDrm *pDrm = new MockEngineNeoDrm(const_cast(pSysmanDeviceImp->getRootDeviceEnvironment())); pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily); auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; osInterface->setDriverModel(std::unique_ptr(pDrm)); pPmuInterface = std::make_unique(pLinuxSysmanImp); - pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; + pPmuInterface->mockPmuFd = 10; + pPmuInterface->mockActiveTime = 987654321; + pPmuInterface->mockTimestamp = 87654321; + VariableBackup pmuBackup(&pLinuxSysmanImp->pPmuInterface); pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); - pFsAccess->mockReadVal = 23; pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = true; @@ -54,21 +49,28 @@ class ZesEngineFixture : public SysmanDeviceFixture { } void TearDown() override { - pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; - pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal; - pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; - SysmanDeviceFixture::TearDown(); } std::vector getEngineHandles(uint32_t count) { + + VariableBackup 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; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); return handles; } }; -TEST_F(ZesEngineFixture, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenNonZeroCountIsReturnedAndVerifyCallSucceeds) { +TEST_F(ZesEngineFixtureI915, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenNonZeroCountIsReturnedAndVerifyCallSucceeds) { + uint32_t count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); EXPECT_EQ(count, handleComponentCount); @@ -83,7 +85,7 @@ TEST_F(ZesEngineFixture, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGr EXPECT_EQ(count, handleComponentCount); } -TEST_F(ZesEngineFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { +TEST_F(ZesEngineFixtureI915, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { zes_engine_properties_t properties; auto handle = getEngineHandles(handleComponentCount); @@ -112,19 +114,19 @@ TEST_F(ZesEngineFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertie EXPECT_FALSE(properties.onSubdevice); } -TEST_F(ZesEngineFixture, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { +TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { zes_engine_stats_t stats = {}; auto handles = getEngineHandles(handleComponentCount); EXPECT_EQ(handleComponentCount, handles.size()); for (auto handle : handles) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats)); - EXPECT_EQ(mockActiveTime / microSecondsToNanoSeconds, stats.activeTime); - EXPECT_EQ(mockTimestamp / microSecondsToNanoSeconds, stats.timestamp); + EXPECT_EQ(pPmuInterface->mockActiveTime / microSecondsToNanoSeconds, stats.activeTime); + EXPECT_EQ(pPmuInterface->mockTimestamp / microSecondsToNanoSeconds, stats.timestamp); } } -TEST_F(ZesEngineFixture, GivenValidEngineHandleAndDiscreteDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { +TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleAndDiscreteDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = false; zes_engine_stats_t stats = {}; auto handles = getEngineHandles(handleComponentCount); @@ -132,35 +134,39 @@ TEST_F(ZesEngineFixture, GivenValidEngineHandleAndDiscreteDeviceWhenCallingZesEn for (auto handle : handles) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats)); - EXPECT_EQ(mockActiveTime / microSecondsToNanoSeconds, stats.activeTime); - EXPECT_EQ(mockTimestamp / microSecondsToNanoSeconds, stats.timestamp); + EXPECT_EQ(pPmuInterface->mockActiveTime / microSecondsToNanoSeconds, stats.activeTime); + EXPECT_EQ(pPmuInterface->mockTimestamp / microSecondsToNanoSeconds, stats.timestamp); } } -TEST_F(ZesEngineFixture, GivenTestDiscreteDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { +TEST_F(ZesEngineFixtureI915, GivenTestDiscreteDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { + + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { + return -1; + }); + pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = false; - pSysfsAccess->mockReadSymLinkError = ZE_RESULT_ERROR_NOT_AVAILABLE; auto pOsEngineTest1 = L0::Sysman::OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); zes_engine_stats_t stats = {}; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats)); - pFsAccess->mockReadVal = 0; - pFsAccess->mockReadErrorVal = ZE_RESULT_ERROR_NOT_AVAILABLE; auto pOsEngineTest2 = L0::Sysman::OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest2->getActivity(&stats)); } -TEST_F(ZesEngineFixture, GivenTestIntegratedDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { - zes_engine_stats_t stats = {}; - pFsAccess->mockReadVal = 0; - pFsAccess->mockReadErrorVal = ZE_RESULT_ERROR_NOT_AVAILABLE; +TEST_F(ZesEngineFixtureI915, GivenTestIntegratedDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) { + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + return -1; + }); + + zes_engine_stats_t stats = {}; auto pOsEngineTest1 = L0::Sysman::OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u, 0u, false); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats)); } -TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndPmuReadFailsThenVerifyEngineGetActivityReturnsFailure) { +TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndPmuReadFailsThenVerifyEngineGetActivityReturnsFailure) { pPmuInterface->mockPmuReadFailureReturnValue = -1; zes_engine_stats_t stats = {}; auto handles = getEngineHandles(handleComponentCount); @@ -171,13 +177,22 @@ TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAn } } -TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndperfEventOpenFailsThenVerifyEngineGetActivityReturnsFailure) { +TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndperfEventOpenFailsThenVerifyEngineGetActivityReturnsFailure) { + + VariableBackup 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; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->mockPerfEventFailureReturnValue = -1; - MockEnginePmuInterfaceImp pPmuInterfaceImp(pLinuxSysmanImp); EXPECT_EQ(-1, pPmuInterface->pmuInterfaceOpen(0, -1, 0)); } -TEST_F(ZesEngineFixture, GivenValidOsSysmanPointerWhenRetrievingEngineTypeAndInstancesAndIfEngineInfoQueryFailsThenErrorIsReturned) { +TEST_F(ZesEngineFixtureI915, GivenValidOsSysmanPointerWhenRetrievingEngineTypeAndInstancesAndIfEngineInfoQueryFailsThenErrorIsReturned) { std::set> engineGroupInstance; auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; @@ -187,7 +202,7 @@ TEST_F(ZesEngineFixture, GivenValidOsSysmanPointerWhenRetrievingEngineTypeAndIns EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, L0::Sysman::OsEngine::getNumEngineTypeAndInstances(engineGroupInstance, pOsSysman)); } -TEST_F(ZesEngineFixture, givenEngineInfoQuerySupportedWhenQueryingEngineInfoThenEngineInfoIsCreatedWithEngines) { +TEST_F(ZesEngineFixtureI915, givenEngineInfoQuerySupportedWhenQueryingEngineInfoThenEngineInfoIsCreatedWithEngines) { auto drm = std::make_unique((const_cast(pSysmanDeviceImp->getRootDeviceEnvironment()))); ASSERT_NE(nullptr, drm); std::vector memRegions{ @@ -199,7 +214,7 @@ TEST_F(ZesEngineFixture, givenEngineInfoQuerySupportedWhenQueryingEngineInfoThen EXPECT_EQ(2u, engineInfo->engines.size()); } -TEST_F(ZesEngineFixture, GivenEngineInfoWithVideoQuerySupportedWhenQueryingEngineInfoWithVideoThenEngineInfoIsCreatedWithEngines) { +TEST_F(ZesEngineFixtureI915, GivenEngineInfoWithVideoQuerySupportedWhenQueryingEngineInfoWithVideoThenEngineInfoIsCreatedWithEngines) { auto drm = std::make_unique((const_cast(pSysmanDeviceImp->getRootDeviceEnvironment()))); ASSERT_NE(nullptr, drm); std::vector memRegions{ @@ -211,7 +226,7 @@ TEST_F(ZesEngineFixture, GivenEngineInfoWithVideoQuerySupportedWhenQueryingEngin EXPECT_EQ(2u, engineInfo->engines.size()); } -TEST_F(ZesEngineFixture, GivenEngineInfoWithVideoQueryFailsThenFailureIsReturned) { +TEST_F(ZesEngineFixtureI915, GivenEngineInfoWithVideoQueryFailsThenFailureIsReturned) { auto drm = std::make_unique((const_cast(pSysmanDeviceImp->getRootDeviceEnvironment()))); ASSERT_NE(nullptr, drm); EXPECT_FALSE(drm->sysmanQueryEngineInfo()); diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp index fea1fc8415..03bcff712e 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp @@ -28,7 +28,6 @@ class ZesEngineFixture : public SysmanDeviceFixture { L0::Sysman::SysfsAccess *pSysfsAccessOriginal = nullptr; std::unique_ptr pFsAccess; L0::Sysman::FsAccess *pFsAccessOriginal = nullptr; - std::unique_ptr pSysmanKmdInterface; L0::Sysman::SysmanDevice *device = nullptr; @@ -51,8 +50,6 @@ class ZesEngineFixture : public SysmanDeviceFixture { pPmuInterface = std::make_unique(pLinuxSysmanImp); pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); - pSysmanKmdInterface = std::make_unique(productFamily); - std::swap(pLinuxSysmanImp->pSysmanKmdInterface, pSysmanKmdInterface); pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = true; @@ -64,12 +61,19 @@ class ZesEngineFixture : public SysmanDeviceFixture { pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal; pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; - std::swap(pLinuxSysmanImp->pSysmanKmdInterface, pSysmanKmdInterface); - SysmanDeviceFixture::TearDown(); } std::vector getEngineHandles(uint32_t count) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); return handles; @@ -236,9 +240,15 @@ TEST_F(ZesEngineFixture, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZes TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndperfEventOpenFailsThenVerifyEngineGetActivityReturnsFailure) { - pPmuInterface->mockPerfEventOpenRead = true; + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); - MockEnginePmuInterfaceImp pPmuInterfaceImp(pLinuxSysmanImp); + pPmuInterface->mockPerfEventOpenRead = true; EXPECT_EQ(-1, pPmuInterface->pmuInterfaceOpen(0, -1, 0)); } @@ -279,6 +289,15 @@ TEST_F(ZesEngineFixture, GivenValidDrmObjectWhenCallingsysmanQueryEngineInfoMeth } TEST_F(ZesEngineFixture, GivenValidEngineHandleAndHandleCountZeroWhenCallingReInitThenValidCountIsReturnedAndVerifyzesDeviceEnumEngineGroupsSucceeds) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + uint32_t count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); EXPECT_EQ(count, handleComponentCount); @@ -300,7 +319,6 @@ class ZesEngineMultiFixture : public SysmanMultiDeviceFixture { std::unique_ptr pFsAccess; L0::Sysman::FsAccess *pFsAccessOriginal = nullptr; L0::Sysman::SysmanDevice *device = nullptr; - std::unique_ptr pSysmanKmdInterface; void SetUp() override { SysmanMultiDeviceFixture::SetUp(); @@ -320,8 +338,6 @@ class ZesEngineMultiFixture : public SysmanMultiDeviceFixture { pPmuInterface = std::make_unique(pLinuxSysmanImp); pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); - pSysmanKmdInterface = std::make_unique(productFamily); - std::swap(pLinuxSysmanImp->pSysmanKmdInterface, pSysmanKmdInterface); pDrm->mockReadSysmanQueryEngineInfoMultiDevice = true; pSysfsAccess->mockReadSymLinkSuccess = true; @@ -337,10 +353,18 @@ class ZesEngineMultiFixture : public SysmanMultiDeviceFixture { pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal; pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; - std::swap(pLinuxSysmanImp->pSysmanKmdInterface, pSysmanKmdInterface); } std::vector getEngineHandles(uint32_t count) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); return handles; diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp new file mode 100644 index 0000000000..de751d2f67 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" +#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" + +namespace L0 { +namespace Sysman { +namespace ult { + +constexpr uint32_t handleEngineCount = 10u; + +class ZesEngineFixtureXe : public SysmanDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + std::unique_ptr pPmuInterface; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + device = pSysmanDevice; + MockNeoDrm *pDrm = new MockNeoDrm(const_cast(pSysmanDeviceImp->getRootDeviceEnvironment())); + pDrm->ioctlHelper = std::make_unique(*pDrm); + auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; + osInterface->setDriverModel(std::unique_ptr(pDrm)); + + pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceXe(pLinuxSysmanImp->getProductFamily())); + pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pDrm); + pPmuInterface = std::make_unique(pLinuxSysmanImp); + pPmuInterface->mockPmuFd = 10; + pPmuInterface->mockActiveTime = 987654321; + pPmuInterface->mockTimestamp = 87654321; + pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + VariableBackup pmuBackup(&pLinuxSysmanImp->pPmuInterface); + pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); + + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.isIntegratedDevice = true; + + getEngineHandles(0); + } + + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } + + std::vector getEngineHandles(uint32_t count) { + + VariableBackup 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; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } +}; + +TEST_F(ZesEngineFixtureXe, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenNonZeroCountIsReturnedAndVerifyCallSucceeds) { + + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); + EXPECT_EQ(count, handleEngineCount); + + uint32_t testcount = count + 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); + EXPECT_EQ(testcount, count); + + count = 0; + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, handleEngineCount); +} + +TEST_F(ZesEngineFixtureXe, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { + zes_engine_properties_t properties; + auto handle = getEngineHandles(handleEngineCount); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[0], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_ALL, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[1], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ALL, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[2], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_COPY_ALL, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[3], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[4], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[5], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[6], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[7], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_COPY_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[8], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE, properties.type); + EXPECT_FALSE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[9], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_ALL, properties.type); + EXPECT_FALSE(properties.onSubdevice); +} + +TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { + zes_engine_stats_t stats = {}; + auto handles = getEngineHandles(handleEngineCount); + EXPECT_EQ(handleEngineCount, handles.size()); + + for (auto handle : handles) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats)); + EXPECT_EQ(pPmuInterface->mockActiveTime / microSecondsToNanoSeconds, stats.activeTime); + EXPECT_EQ(pPmuInterface->mockTimestamp / microSecondsToNanoSeconds, stats.timestamp); + } +} + +TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndperfEventOpenFailsThenVerifyEngineGetActivityReturnsFailure) { + + VariableBackup 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; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + pPmuInterface->mockPerfEventFailureReturnValue = -1; + EXPECT_EQ(-1, pPmuInterface->pmuInterfaceOpen(0, -1, 0)); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/events/linux/test_zes_events.cpp b/level_zero/sysman/test/unit_tests/sources/events/linux/test_zes_events.cpp index 309e34db6e..848a705eb1 100644 --- a/level_zero/sysman/test/unit_tests/sources/events/linux/test_zes_events.cpp +++ b/level_zero/sysman/test/unit_tests/sources/events/linux/test_zes_events.cpp @@ -17,6 +17,7 @@ namespace ult { constexpr uint32_t mockHandleCount = 2u; constexpr int mockReadPipeFd = 8; constexpr int mockWritePipeFd = 9; +constexpr uint32_t pmuDriverType = 16u; class SysmanEventsFixture : public SysmanDeviceFixture { protected: std::unique_ptr pFsAccess; @@ -1752,6 +1753,21 @@ TEST_F(SysmanEventsFixture, } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectableErrorsCrossingTotalThresholdEventAndTotalErrorsCrossesThresholdThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS)); auto handles = getRasHandles(mockHandleCount); for (auto handle : handles) { @@ -1777,6 +1793,21 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectab } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectableErrorsCrossingTotalThresholdEventAndTotalErrorsCrossesThresholdThenEventListenAPIReturnsAfterReceivingEventThenAfterReceivingEventRegisterEventAgainToReceiveEvent) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS)); auto handles = getRasHandles(mockHandleCount); for (auto handle : handles) { @@ -1807,6 +1838,21 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectab } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasCorrectableErrorsCrossingTotalThresholdEventAndTotalErrorsCrossesThresholdThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS)); auto handles = getRasHandles(mockHandleCount); for (auto handle : handles) { @@ -1832,6 +1878,21 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasCorrectable } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectableErrorsCrossingCategoryThresholdEventAndCategoryErrorsCrossesThresholdThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS)); auto handles = getRasHandles(mockHandleCount); for (auto handle : handles) { @@ -1858,6 +1919,21 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasUncorrectab } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForRasCorrectableErrorsCrossingCategoryThresholdEventAndCategoryErrorsCrossesThresholdThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS)); auto handles = getRasHandles(mockHandleCount); for (auto handle : handles) { diff --git a/level_zero/sysman/test/unit_tests/sources/linux/pmu/mock_pmu.h b/level_zero/sysman/test/unit_tests/sources/linux/pmu/mock_pmu.h index 94aaf04d48..e6b0f8b892 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/pmu/mock_pmu.h +++ b/level_zero/sysman/test/unit_tests/sources/linux/pmu/mock_pmu.h @@ -45,13 +45,6 @@ struct MockPmuInterface : public MockPmuInterfaceImpForSysman { ADDMETHOD_NOBASE(getErrorNo, int, EINVAL, ()); }; -struct MockPmuFsAccess : public L0::Sysman::FsAccess { - ze_result_t read(const std::string file, uint32_t &val) override { - val = 18; - return ZE_RESULT_SUCCESS; - } -}; - } // namespace ult } // namespace Sysman } // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/linux/pmu/test_pmu.cpp b/level_zero/sysman/test/unit_tests/sources/linux/pmu/test_pmu.cpp index 9223309296..c2888c08c0 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/pmu/test_pmu.cpp +++ b/level_zero/sysman/test/unit_tests/sources/linux/pmu/test_pmu.cpp @@ -18,21 +18,15 @@ struct SysmanPmuFixture : public SysmanDeviceFixture { protected: std::unique_ptr pPmuInterface; L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr; - std::unique_ptr pFsAccess; - L0::Sysman::FsAccess *pFsAccessOriginal = nullptr; void SetUp() override { SysmanDeviceFixture::SetUp(); - pFsAccessOriginal = pLinuxSysmanImp->pFsAccess; - pFsAccess = std::make_unique(); - pLinuxSysmanImp->pFsAccess = pFsAccess.get(); pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; pPmuInterface = std::make_unique(pLinuxSysmanImp); pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); } void TearDown() override { pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; - pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; SysmanDeviceFixture::TearDown(); } }; @@ -52,37 +46,43 @@ inline static long int syscallReturnSuccess(long int sysNo, ...) noexcept { } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuReadThenSuccessIsReturned) { - MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); + auto pmuInterface = std::make_unique(pLinuxSysmanImp); pmuInterface->readFunction = openReadReturnSuccess; uint64_t data[2]; int validFd = 10; EXPECT_EQ(0, pmuInterface->pmuRead(validFd, data, sizeof(data))); EXPECT_EQ(mockEventVal, data[0]); EXPECT_EQ(mockTimeStamp, data[1]); - delete pmuInterface; } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPerEventOpenThenSuccessIsReturned) { - MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); + auto pmuInterface = std::make_unique(pLinuxSysmanImp); pmuInterface->syscallFunction = syscallReturnSuccess; struct perf_event_attr attr = {}; int cpu = 0; attr.read_format = static_cast(PERF_FORMAT_TOTAL_TIME_ENABLED); attr.config = 11; EXPECT_EQ(mockPmuFd, pmuInterface->perfEventOpen(&attr, -1, cpu, -1, 0)); - delete pmuInterface; } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingThenFailureIsReturned) { - MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); + auto pmuInterface = std::make_unique(pLinuxSysmanImp); pmuInterface->readFunction = openReadReturnFailure; int validFd = 10; uint64_t data[2]; EXPECT_EQ(-1, pmuInterface->pmuRead(validFd, data, sizeof(data))); - delete pmuInterface; } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEventOpenSucceedsThenVaildFdIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 18; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + uint64_t config = 10; auto &rootDeviceEnvironment = pLinuxSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironment(); auto mutableHwInfo = rootDeviceEnvironment.getMutableHardwareInfo(); @@ -91,6 +91,15 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEv } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenReadingGroupOfEventsUsingGroupFdThenSuccessIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 18; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + uint64_t configForEvent1 = 10; int64_t groupFd = pLinuxSysmanImp->pPmuInterface->pmuInterfaceOpen(configForEvent1, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); // To get group leader uint64_t configForEvent2 = 15; @@ -104,6 +113,15 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenReadingGroupOfEventsUsingGroupFd } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEventOpenFailsThenFailureIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 18; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->perfEventOpenResult = -1; uint64_t config = 10; auto &rootDeviceEnvironment = pLinuxSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironment(); @@ -113,6 +131,15 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEv } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEventOpenFailsAndErrNoSetBySyscallIsNotInvalidArgumentThenFailureIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 18; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->perfEventOpenResult = -1; pPmuInterface->getErrorNoResult = EBADF; uint64_t config = 10; @@ -123,10 +150,9 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEv } TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenAndDomainErrorOccursThenDomainErrorIsReturnedBygetErrorNoFunction) { - MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); + auto pmuInterface = std::make_unique(pLinuxSysmanImp); log(-1.0); // Domain error injected EXPECT_EQ(EDOM, pmuInterface->getErrorNo()); - delete pmuInterface; } } // namespace ult diff --git a/level_zero/sysman/test/unit_tests/sources/ras/linux/test_zes_ras.cpp b/level_zero/sysman/test/unit_tests/sources/ras/linux/test_zes_ras.cpp index 2e29107ae0..51c70c4c26 100644 --- a/level_zero/sysman/test/unit_tests/sources/ras/linux/test_zes_ras.cpp +++ b/level_zero/sysman/test/unit_tests/sources/ras/linux/test_zes_ras.cpp @@ -190,6 +190,20 @@ TEST_F(SysmanRasFixture, GivenValidSysmanHandleWhenRetrievingRasHandlesIfRasEven TEST_F(SysmanRasFixture, GivenValidRasHandleWhenCallingzesRasGetStateForGtThenSuccessIsReturned) { + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->mockPmuReadCorrectable = true; pRasFwUtilInterface->mockMemorySuccess = false; @@ -222,6 +236,20 @@ TEST_F(SysmanRasFixture, GivenValidRasHandleWhenCallingzesRasGetStateForGtThenSu TEST_F(SysmanRasFixture, GivenValidRasHandleWhenCallingRasGetStateForGtAfterClearThenSuccessIsReturned) { + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->mockPmuReadAfterClear = true; auto handles = getRasHandles(mockHandleCount); @@ -596,6 +624,20 @@ TEST_F(SysmanRasMultiDeviceFixture, GivenValidHandleWhenGettingRasPropertiesThen TEST_F(SysmanRasMultiDeviceFixture, GivenValidRasHandleWhenCallingzesRasGetStateForGtThenSuccessIsReturned) { + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << pmuDriverType; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + pPmuInterface->mockPmuReadTile = true; pSysfsAccess->isMultiTileArch = true; diff --git a/level_zero/sysman/test/unit_tests/sources/shared/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/shared/CMakeLists.txt new file mode 100644 index 0000000000..9704dc6ade --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/shared/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) +add_subdirectories() diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/shared/linux/CMakeLists.txt new file mode 100644 index 0000000000..b0e18d3c7e --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SYSMAN_SHARED_TESTS + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_kmd_interface_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_kmd_interface_tests.h +) + +if(UNIX) + target_sources(${TARGET_NAME} + PRIVATE + ${L0_SYSMAN_SHARED_TESTS} + ) +endif() + diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.cpp new file mode 100644 index 0000000000..59c3f55b34 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.h" + +#include "shared/source/helpers/hw_info.h" +#include "shared/source/helpers/string.h" +#include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/helpers/variable_backup.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" + +#include "gtest/gtest.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +using namespace NEO; + +const uint32_t mockReadVal = 23; + +class SysmanFixtureDeviceI915 : public SysmanDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + std::unique_ptr pPmuInterface; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + device = pSysmanDevice; + pPmuInterface = std::make_unique(pLinuxSysmanImp); + pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + VariableBackup pmuBackup(&pLinuxSysmanImp->pPmuInterface); + pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); + } + + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } +}; + +TEST_F(SysmanFixtureDeviceI915, GivenSysmanKmdInterfaceInstanceWhenIsGroupEngineInterfaceAvailableCalledThenFalseValueIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_FALSE(pSysmanKmdInterface->isGroupEngineInterfaceAvailable()); +} + +TEST_F(SysmanFixtureDeviceI915, GivenGroupEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdIsCalledThenInvalidFdIsReturned) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COMPUTE_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COPY_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_RENDER_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_MEDIA_ALL, 0, 0, pPmuInterface.get())); +} + +TEST_F(SysmanFixtureDeviceI915, GivenSingleEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdIsCalledThenValidFdIsReturned) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + pPmuInterface->mockPmuFd = 10; + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get())); +} + +TEST_F(SysmanFixtureDeviceI915, GivenSysmanKmdInterfaceInstanceAndIsIntegratedDeviceWhenGetEventsIsCalledThenValidEventTypeIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + bool isIntegratedDevice = true; + EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceI915, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceWhenGetEventsIsCalledThenValidEventTypeIsReturned) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + bool isIntegratedDevice = false; + EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceI915, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndReadSymLinkFailsWhenGetEventsIsCalledThenFailureIsReturned) { + + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { + errno = ENOENT; + return -1; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + bool isIntegratedDevice = false; + EXPECT_EQ(0u, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceI915, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndFsReadFailsWhenGetEventsIsCalledThenFailureIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + errno = ENOENT; + return -1; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + bool isIntegratedDevice = false; + EXPECT_EQ(0u, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +class SysmanFixtureDeviceXe : public SysmanDeviceFixture { + protected: + L0::Sysman::SysmanDevice *device = nullptr; + std::unique_ptr pPmuInterface; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + device = pSysmanDevice; + pPmuInterface = std::make_unique(pLinuxSysmanImp); + pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceXe(pLinuxSysmanImp->getProductFamily())); + pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + + VariableBackup pmuBackup(&pLinuxSysmanImp->pPmuInterface); + pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); + } + + void TearDown() override { + SysmanDeviceFixture::TearDown(); + } +}; + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceWhenIsGroupEngineInterfaceAvailableCalledThenTrueValueIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + EXPECT_TRUE(pSysmanKmdInterface->isGroupEngineInterfaceAvailable()); +} + +TEST_F(SysmanFixtureDeviceXe, GivenGroupEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdIsCalledThenValidFdIsReturned) { + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + pPmuInterface->mockPmuFd = 10; + pPmuInterface->pSysmanKmdInterface = pSysmanKmdInterface.get(); + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COMPUTE_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COPY_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_RENDER_ALL, 0, 0, pPmuInterface.get())); + EXPECT_EQ(pPmuInterface->mockPmuFd, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_MEDIA_ALL, 0, 0, pPmuInterface.get())); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSingleEngineTypeAndSysmanKmdInterfaceInstanceWhenGetEngineActivityFdIsCalledThenInvalidFdIsReturned) { + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + pPmuInterface->pSysmanKmdInterface = pSysmanKmdInterface.get(); + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + EXPECT_EQ(-1, pSysmanKmdInterface->getEngineActivityFd(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get())); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndIsIntegratedDeviceInstanceWhenGetEventsIsCalledThenValidEventTypeIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + bool isIntegratedDevice = true; + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndIsNotIntegratedDeviceInstanceWhenGetEventsIsCalledThenValidEventTypeIsReturned) { + + VariableBackup 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; + }); + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + bool isIntegratedDevice = false; + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + EXPECT_EQ(mockReadVal, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndReadSymLinkFailsWhenGetEventsIsCalledThenFailureIsReturned) { + + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { + errno = ENOENT; + return -1; + }); + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + bool isIntegratedDevice = false; + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + EXPECT_EQ(0u, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceInstanceAndIsNotIntegratedDeviceAndFsReadFailsWhenGetEventsIsCalledThenFailureIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + errno = ENOENT; + return -1; + }); + + auto pSysmanKmdInterface = std::make_unique(pLinuxSysmanImp->getProductFamily()); + bool isIntegratedDevice = false; + pSysmanKmdInterface->pFsAccess = std::make_unique(); + pSysmanKmdInterface->pSysfsAccess = std::make_unique(); + EXPECT_EQ(0u, pSysmanKmdInterface->getEventType(isIntegratedDevice)); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.h b/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.h new file mode 100644 index 0000000000..18b5102459 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/sysman_kmd_interface_tests.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#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/sysman_kmd_interface.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +class MockPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp { + public: + int64_t mockPmuFd = -1; + uint64_t mockTimestamp = 0; + uint64_t mockActiveTime = 0; + using PmuInterfaceImp::perfEventOpen; + using PmuInterfaceImp::pSysmanKmdInterface; + MockPmuInterfaceImp(L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {} + + int64_t mockPerfEventFailureReturnValue = 0; + int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) override { + if (mockPerfEventFailureReturnValue == -1) { + return mockPerfEventFailureReturnValue; + } + + return mockPmuFd; + } + + int mockPmuReadFailureReturnValue = 0; + int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override { + if (mockPmuReadFailureReturnValue == -1) { + return mockPmuReadFailureReturnValue; + } + + data[0] = mockActiveTime; + data[1] = mockTimestamp; + return 0; + } +}; + +class MockSysmanKmdInterfaceXe : public L0::Sysman::SysmanKmdInterfaceXe { + public: + using L0::Sysman::SysmanKmdInterface::pFsAccess; + using L0::Sysman::SysmanKmdInterface::pSysfsAccess; + MockSysmanKmdInterfaceXe(const PRODUCT_FAMILY productFamily) : SysmanKmdInterfaceXe(productFamily) {} + ~MockSysmanKmdInterfaceXe() override = default; +}; + +class MockFsAccessInterface : public L0::Sysman::FsAccessInterface { + public: + MockFsAccessInterface() = default; + ~MockFsAccessInterface() override = default; +}; + +class MockSysFsAccessInterface : public L0::Sysman::SysFsAccessInterface { + public: + MockSysFsAccessInterface() = default; + ~MockSysFsAccessInterface() override = default; +}; + +} // namespace ult +} // namespace Sysman +} // namespace L0 \ No newline at end of file