From 7ea22d03698a2b0905e3eec21ab0d0cec80f6fb9 Mon Sep 17 00:00:00 2001 From: Filip Hazubski Date: Sun, 30 Jul 2023 12:23:34 +0200 Subject: [PATCH] feature: Add pat index programming to gem create ext call When upstream ioctl helper is created it will try to create small allocation, adding I915_GEM_CREATE_EXT_SET_PAT extension. If it succeeds, for all resources with valid pat index value it will then explicitly program pat index value with gem create ext call. PrintBOCreateDestroyResult value can be used to: - print whether the set pat extension is supported by the kernel, when ioctl helper is created - print whether set pat extension was added for a given gem create ext call and what pat index value was programmed Note: introduced changes are disabled by defualt. Toggle DisableGemCreateExtSetPat can be used to enable new functionality. Related-To: NEO-7896 Signed-off-by: Filip Hazubski --- .../debug_settings/debug_variables_base.inl | 1 + .../os_interface/linux/drm_memory_manager.cpp | 22 +-- .../source/os_interface/linux/ioctl_helper.h | 12 +- .../linux/ioctl_helper_prelim.cpp | 2 +- .../linux/ioctl_helper_upstream.cpp | 59 ++++++- .../linux/local/dg1/ioctl_helper_dg1.cpp | 4 +- .../source/os_interface/linux/memory_info.cpp | 16 +- .../source/os_interface/linux/memory_info.h | 8 +- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 2 +- .../os_interface/linux/xe/ioctl_helper_xe.h | 2 +- .../linux/drm_memory_manager_fixture.h | 8 +- shared/test/common/test_files/igdrcl.config | 1 + .../linux/drm_memory_info_prelim_tests.cpp | 24 +-- .../linux/drm_memory_info_tests.cpp | 4 +- .../linux/drm_memory_manager_tests.cpp | 2 +- .../linux/drm_with_prelim_tests.cpp | 8 +- .../linux/ioctl_helper_tests_dg1.cpp | 6 +- .../linux/ioctl_helper_tests_upstream.cpp | 167 +++++++++++++++++- .../linux/xe/ioctl_helper_xe_tests.cpp | 6 +- 19 files changed, 284 insertions(+), 70 deletions(-) diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 88f442edbd..86ab899549 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -83,6 +83,7 @@ DECLARE_DEBUG_VARIABLE(bool, ForceMemoryPrefetchForKmdMigratedSharedAllocations, DECLARE_DEBUG_VARIABLE(bool, ClKhrExternalMemoryExtension, true, "Enable cl_khr_external_memory extension") DECLARE_DEBUG_VARIABLE(bool, WaitForMemoryRelease, false, "Wait for memory release when out of memory") DECLARE_DEBUG_VARIABLE(bool, RemoveRestrictionsOnNumberOfThreadsInGpgpuThreadGroup, 0, "0 - default disabled, 1- remove restrictions on NumberOfThreadsInGpgpuThreadGroup in INTERFACE_DESCRIPTOR_DATA") +DECLARE_DEBUG_VARIABLE(bool, DisableGemCreateExtSetPat, true, "Do not use I915_GEM_CREATE_EXT_SET_PAT extension when gem create ext is called") DECLARE_DEBUG_VARIABLE(std::string, ForceDeviceId, std::string("unk"), "Override device id in AUB/TBX mode") DECLARE_DEBUG_VARIABLE(std::string, FilterDeviceId, std::string("unk"), "Device id filter, adapter matching device id will be opened; ignored when unk") DECLARE_DEBUG_VARIABLE(std::string, FilterBdfPath, std::string("unk"), "Linux-only, BDF path filter, only matching paths will be opened; ignored when unk") diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 893e4c9e86..b56082e0de 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -1807,19 +1807,19 @@ BufferObject *DrmMemoryManager::createBufferObjectInMemoryRegion(uint32_t rootDe uint32_t handle = 0; int ret = 0; + auto patIndex = drm->getPatIndex(gmm, allocationType, CacheRegion::Default, CachePolicy::WriteBack, false); + auto banks = std::bitset<4>(memoryBanks); if (banks.count() > 1) { - ret = memoryInfo->createGemExtWithMultipleRegions(memoryBanks, size, handle); + ret = memoryInfo->createGemExtWithMultipleRegions(memoryBanks, size, handle, patIndex); } else { - ret = memoryInfo->createGemExtWithSingleRegion(memoryBanks, size, handle, pairHandle); + ret = memoryInfo->createGemExtWithSingleRegion(memoryBanks, size, handle, patIndex, pairHandle); } if (ret != 0) { return nullptr; } - auto patIndex = drm->getPatIndex(gmm, allocationType, CacheRegion::Default, CachePolicy::WriteBack, false); - auto bo = new (std::nothrow) BufferObject(rootDeviceIndex, drm, patIndex, handle, size, maxOsContextCount); if (!bo) { return nullptr; @@ -1836,13 +1836,13 @@ bool DrmMemoryManager::createDrmChunkedAllocation(Drm *drm, DrmAllocation *alloc uint32_t handle = 0; auto memoryBanks = static_cast(storageInfo.memoryBanks.to_ulong()); uint32_t numOfChunks = DebugManager.flags.NumberOfBOChunks.get(); - int ret = memoryInfo->createGemExtWithMultipleRegions(memoryBanks, boSize, handle, -1, true, numOfChunks); - if (ret != 0) { - return false; - } auto gmm = allocation->getGmm(0u); auto patIndex = drm->getPatIndex(gmm, allocation->getAllocationType(), CacheRegion::Default, CachePolicy::WriteBack, false); + int ret = memoryInfo->createGemExtWithMultipleRegions(memoryBanks, boSize, handle, patIndex, -1, true, numOfChunks); + if (ret != 0) { + return false; + } auto bo = new (std::nothrow) BufferObject(allocation->getRootDeviceIndex(), drm, patIndex, handle, boSize, maxOsContextCount); UNRECOVERABLE_IF(bo == nullptr); @@ -2247,7 +2247,9 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const auto memoryBanks = (DebugManager.flags.KMDSupportForCrossTileMigrationPolicy.get() > 0 || useChunking) ? allocationData.storageInfo.memoryBanks : DeviceBitfield(1 << memoryInstance); auto memRegions = createMemoryRegionsForSharedAllocation(*pHwInfo, *memoryInfo, allocationData, memoryBanks); - int ret = memoryInfo->createGemExt(memRegions, currentSize, handle, {}, -1, useChunking, numOfChunks); + auto patIndex = drm.getPatIndex(nullptr, allocationData.type, CacheRegion::Default, CachePolicy::WriteBack, false); + + int ret = memoryInfo->createGemExt(memRegions, currentSize, handle, patIndex, {}, -1, useChunking, numOfChunks); if (ret) { this->munmapFunction(cpuPointer, totalSizeToAlloc); @@ -2255,8 +2257,6 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const return nullptr; } - auto patIndex = drm.getPatIndex(nullptr, allocationData.type, CacheRegion::Default, CachePolicy::WriteBack, false); - std::unique_ptr bo(new BufferObject(allocationData.rootDeviceIndex, &drm, patIndex, handle, currentSize, maxOsContextCount)); if (!ioctlHelper->setVmBoAdvise(bo->peekHandle(), vmAdviseAttribute, nullptr)) { diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index 5301b1d3fc..ec4c0303fb 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -80,7 +80,7 @@ class IoctlHelper { virtual bool isSetPairAvailable() = 0; virtual bool isChunkingAvailable() = 0; virtual bool isVmBindAvailable() = 0; - virtual int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) = 0; + virtual int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) = 0; virtual CacheRegion closAlloc() = 0; virtual uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) = 0; virtual CacheRegion closFree(CacheRegion closIndex) = 0; @@ -169,7 +169,7 @@ class IoctlHelperUpstream : public IoctlHelper { bool isSetPairAvailable() override; bool isChunkingAvailable() override; bool isVmBindAvailable() override; - int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; + int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; CacheRegion closAlloc() override; uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) override; CacheRegion closFree(CacheRegion closIndex) override; @@ -215,6 +215,10 @@ class IoctlHelperUpstream : public IoctlHelper { std::string getIoctlString(DrmIoctl ioctlRequest) const override; bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override; bool isWaitBeforeBindRequired(bool bind) const override; + + protected: + MOCKABLE_VIRTUAL void detectExtSetPatSupport(); + bool isSetPatSupported = false; }; template @@ -225,7 +229,7 @@ class IoctlHelperImpl : public IoctlHelperUpstream { return std::make_unique>(drm); } - int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; + int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; std::vector translateToMemoryRegions(const std::vector ®ionInfo) override; unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; @@ -239,7 +243,7 @@ class IoctlHelperPrelim20 : public IoctlHelper { bool isSetPairAvailable() override; bool isChunkingAvailable() override; bool isVmBindAvailable() override; - int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; + int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; CacheRegion closAlloc() override; uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) override; CacheRegion closFree(CacheRegion closIndex) override; diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 34f1dc720a..6f4519355f 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -146,7 +146,7 @@ bool IoctlHelperPrelim20::isVmBindAvailable() { return vmBindSupported; } -int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { +int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { uint32_t regionsSize = static_cast(memClassInstances.size()); std::vector regions(regionsSize); for (uint32_t i = 0; i < regionsSize; i++) { diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index 94692b0cf3..b057c34833 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -7,6 +7,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/helpers/common_types.h" +#include "shared/source/helpers/constants.h" #include "shared/source/os_interface/linux/cache_info.h" #include "shared/source/os_interface/linux/drm_wrappers.h" #include "shared/source/os_interface/linux/i915_upstream.h" @@ -15,6 +16,7 @@ namespace NEO { bool IoctlHelperUpstream::initialize() { + detectExtSetPatSupport(); return true; } @@ -30,41 +32,88 @@ bool IoctlHelperUpstream::isVmBindAvailable() { return false; } -int IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { +int IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { + bool isPatIndexValid = (patIndex != CommonConstants::unsupportedPatIndex) && (patIndex <= std::numeric_limits::max()); + bool useSetPat = this->isSetPatSupported && isPatIndexValid; + uint32_t regionsSize = static_cast(memClassInstances.size()); std::vector regions(regionsSize); for (uint32_t i = 0; i < regionsSize; i++) { regions[i].memory_class = memClassInstances[i].memoryClass; regions[i].memory_instance = memClassInstances[i].memoryInstance; } + drm_i915_gem_create_ext_memory_regions memRegions{}; memRegions.num_regions = regionsSize; memRegions.regions = reinterpret_cast(regions.data()); memRegions.base.name = I915_GEM_CREATE_EXT_MEMORY_REGIONS; + drm_i915_gem_create_ext_set_pat setPat{}; + setPat.pat_index = static_cast(patIndex); + setPat.base.name = I915_GEM_CREATE_EXT_SET_PAT; + drm_i915_gem_create_ext createExt{}; createExt.size = allocSize; createExt.extensions = reinterpret_cast(&memRegions); - printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "Performing GEM_CREATE_EXT with { size: %lu", - allocSize); + if (useSetPat) { + memRegions.base.next_extension = reinterpret_cast(&setPat); + } if (DebugManager.flags.PrintBOCreateDestroyResult.get()) { + printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "Performing GEM_CREATE_EXT with { size: %lu", + allocSize); + for (uint32_t i = 0; i < regionsSize; i++) { auto region = regions[i]; printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, ", memory class: %d, memory instance: %d", region.memory_class, region.memory_instance); } + + if (useSetPat) { + printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, ", pat index: %lu", patIndex); + } + printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "%s", " }\n"); } auto ret = ioctl(DrmIoctl::GemCreateExt, &createExt); - - printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "GEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: %d BO-%u with size: %lu\n", ret, createExt.handle, createExt.size); handle = createExt.handle; + + printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "GEM_CREATE_EXT with EXT_MEMORY_REGIONS%s has returned: %d BO-%u with size: %lu\n", + (useSetPat) ? " with EXT_SET_PAT" : "", + ret, createExt.handle, createExt.size); + return ret; } +void IoctlHelperUpstream::detectExtSetPatSupport() { + drm_i915_gem_create_ext_set_pat setPat{}; + setPat.pat_index = 0; + setPat.base.name = I915_GEM_CREATE_EXT_SET_PAT; + + drm_i915_gem_create_ext createExt{}; + createExt.size = 1; + createExt.extensions = reinterpret_cast(&setPat); + + auto isSetPatDisabled = DebugManager.flags.DisableGemCreateExtSetPat.get(); + + if (!isSetPatDisabled) { + int returnValue = ioctl(DrmIoctl::GemCreateExt, &createExt); + this->isSetPatSupported = (returnValue == 0); + + if (returnValue == 0) { + GemClose close{}; + close.handle = createExt.handle; + returnValue = ioctl(DrmIoctl::GemClose, &close); + UNRECOVERABLE_IF(returnValue); + } + } + + printDebugString(DebugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "EXT_SET_PAT support is: %s\n", + this->isSetPatSupported ? "enabled" : "disabled"); +} + CacheRegion IoctlHelperUpstream::closAlloc() { return CacheRegion::None; } diff --git a/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp b/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp index 8e680fb71e..fec64cdbe0 100644 --- a/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp +++ b/shared/source/os_interface/linux/local/dg1/ioctl_helper_dg1.cpp @@ -21,8 +21,8 @@ constexpr static auto gfxProduct = IGFX_DG1; extern bool isQueryDrmTip(const std::vector &queryInfo); template <> -int IoctlHelperImpl::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { - auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle, isChunked, numOfChunks); +int IoctlHelperImpl::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { + auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, patIndex, vmId, pairHandle, isChunked, numOfChunks); if (ret == 0) { return ret; } diff --git a/shared/source/os_interface/linux/memory_info.cpp b/shared/source/os_interface/linux/memory_info.cpp index 98cca5d518..80ddb6f045 100644 --- a/shared/source/os_interface/linux/memory_info.cpp +++ b/shared/source/os_interface/linux/memory_info.cpp @@ -56,8 +56,8 @@ void MemoryInfo::assignRegionsFromDistances(const std::vector &dis } } -int MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { - return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle, isChunked, numOfChunks); +int MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { + return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, patIndex, vmId, pairHandle, isChunked, numOfChunks); } uint32_t MemoryInfo::getTileIndex(uint32_t memoryBank) { @@ -109,7 +109,7 @@ void MemoryInfo::printRegionSizes() { } } -int MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle) { +int MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle) { auto pHwInfo = this->drm.getRootDeviceEnvironment().getHardwareInfo(); auto regionClassAndInstance = getMemoryRegionClassAndInstance(memoryBanks, *pHwInfo); MemRegionsVec region = {regionClassAndInstance}; @@ -121,11 +121,11 @@ int MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocS } } uint32_t numOfChunks = 0; - auto ret = createGemExt(region, allocSize, handle, vmId, pairHandle, false, numOfChunks); + auto ret = createGemExt(region, allocSize, handle, patIndex, vmId, pairHandle, false, numOfChunks); return ret; } -int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle) { +int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex) { auto pHwInfo = this->drm.getRootDeviceEnvironment().getHardwareInfo(); auto banks = std::bitset<4>(memoryBanks); MemRegionsVec memRegions{}; @@ -140,11 +140,11 @@ int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t all currentBank++; } uint32_t numOfChunks = 0; - auto ret = createGemExt(memRegions, allocSize, handle, {}, -1, false, numOfChunks); + auto ret = createGemExt(memRegions, allocSize, handle, patIndex, {}, -1, false, numOfChunks); return ret; } -int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { +int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { auto pHwInfo = this->drm.getRootDeviceEnvironment().getHardwareInfo(); auto banks = std::bitset<4>(memoryBanks); MemRegionsVec memRegions{}; @@ -158,7 +158,7 @@ int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t all } currentBank++; } - auto ret = createGemExt(memRegions, allocSize, handle, {}, pairHandle, isChunked, numOfChunks); + auto ret = createGemExt(memRegions, allocSize, handle, patIndex, {}, pairHandle, isChunked, numOfChunks); return ret; } diff --git a/shared/source/os_interface/linux/memory_info.h b/shared/source/os_interface/linux/memory_info.h index 3d56e102c0..62a0d67d92 100644 --- a/shared/source/os_interface/linux/memory_info.h +++ b/shared/source/os_interface/linux/memory_info.h @@ -26,7 +26,7 @@ class MemoryInfo { void assignRegionsFromDistances(const std::vector &distances); - MOCKABLE_VIRTUAL int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks); + MOCKABLE_VIRTUAL int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks); MemoryClassInstance getMemoryRegionClassAndInstance(uint32_t memoryBank, const HardwareInfo &hwInfo); @@ -38,9 +38,9 @@ class MemoryInfo { uint32_t getTileIndex(uint32_t memoryBank); - MOCKABLE_VIRTUAL int createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle); - MOCKABLE_VIRTUAL int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle); - MOCKABLE_VIRTUAL int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle, bool isChunked, uint32_t numOfChunks); + MOCKABLE_VIRTUAL int createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle); + MOCKABLE_VIRTUAL int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex); + MOCKABLE_VIRTUAL int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle, bool isChunked, uint32_t numOfChunks); const RegionContainer &getDrmRegionInfos() const { return drmQueryRegions; } diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index 7be3f743d1..c9af12cd0d 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -435,7 +435,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo return true; } -int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { +int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { struct drm_xe_gem_create create = {}; uint32_t regionsSize = static_cast(memClassInstances.size()); diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index f1fe180217..50ec94c8fc 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -46,7 +46,7 @@ class IoctlHelperXe : public IoctlHelper { bool isSetPairAvailable() override; bool isChunkingAvailable() override; bool isVmBindAvailable() override; - int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; + int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override; CacheRegion closAlloc() override; uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) override; CacheRegion closFree(CacheRegion closIndex) override; diff --git a/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h b/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h index 2f5d277ec1..411f9a52cf 100644 --- a/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h +++ b/shared/test/common/os_interface/linux/drm_memory_manager_fixture.h @@ -69,14 +69,14 @@ struct MockedMemoryInfo : public NEO::MemoryInfo { size_t getMemoryRegionSize(uint32_t memoryBank) override { return 1024u; } - int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override { + int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override { if (allocSize == 0) { return EINVAL; } handle = 1u; return 0; } - int createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle) override { + int createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle) override { if (allocSize == 0) { return EINVAL; } @@ -84,7 +84,7 @@ struct MockedMemoryInfo : public NEO::MemoryInfo { pairHandlePassed = pairHandle; return 0; } - int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle) override { + int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex) override { if (allocSize == 0) { return EINVAL; } @@ -92,7 +92,7 @@ struct MockedMemoryInfo : public NEO::MemoryInfo { banks = memoryBanks; return 0; } - int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override { + int createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t allocSize, uint32_t &handle, uint64_t patIndex, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override { if (allocSize == 0) { return EINVAL; } diff --git a/shared/test/common/test_files/igdrcl.config b/shared/test/common/test_files/igdrcl.config index bc64334ffb..4fb00c61db 100644 --- a/shared/test/common/test_files/igdrcl.config +++ b/shared/test/common/test_files/igdrcl.config @@ -543,6 +543,7 @@ TrackNumCsrClientsOnSyncPoints = -1 EventTimestampRefreshIntervalInMilliSec = -1 SynchronizeEventBeforeReset = -1 RemoveRestrictionsOnNumberOfThreadsInGpgpuThreadGroup = 0 +DisableGemCreateExtSetPat = 1 SkipDcFlushOnBarrierWithoutEvents = -1 EnableAIL=1 WaitForUserFenceOnEventHostSynchronize = -1 diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp index cbc3847138..df06c8a317 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp @@ -373,7 +373,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemWithExtensionsThenRetu ASSERT_NE(nullptr, memoryInfo); uint32_t numOfChunks = 0; - auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -397,7 +397,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithSingleRegionThe auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -428,12 +428,12 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithPairHandleThenR uint32_t pairHandle = 0; auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, pairHandle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, pairHandle, 0, -1); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); uint32_t handle = 0; - ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, pairHandle); + ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, pairHandle); EXPECT_EQ(0, ret); EXPECT_EQ(2u, drm->ioctlCallsCount); } @@ -461,7 +461,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithChunkingButSize bool isChunked = true; auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - EXPECT_THROW(memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, pairHandle, isChunked, numOfChunks), std::runtime_error); + EXPECT_THROW(memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, 0, pairHandle, isChunked, numOfChunks), std::runtime_error); } TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithChunkingWithSizeGreaterThanAllowedThenAllocationIsCreatedWithChunking) { @@ -487,7 +487,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithChunkingWithSiz bool isChunked = true; auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, pairHandle, isChunked, numOfChunks); + auto ret = memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, 0, pairHandle, isChunked, numOfChunks); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); } @@ -511,7 +511,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportWhenCreatingGemExt ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -541,7 +541,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndNoPrivateBOSupportWhenCreatingGemE ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -570,7 +570,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportedAndIsPerContextV ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -603,7 +603,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithMultipleRegions ASSERT_NE(nullptr, memoryInfo); uint32_t handle = 0; uint32_t memoryRegions = 0b1011; - auto ret = memoryInfo->createGemExtWithMultipleRegions(memoryRegions, 1024, handle); + auto ret = memoryInfo->createGemExtWithMultipleRegions(memoryRegions, 1024, handle, 0); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -644,7 +644,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCallingCreatingGemExtWithMultiple uint32_t handle = 0; uint32_t memoryRegions = 0b1011; uint32_t numOfChunks = 2; - EXPECT_THROW(memoryInfo->createGemExtWithMultipleRegions(memoryRegions, MemoryConstants::chunkThreshold / (numOfChunks * 2), handle, -1, true, numOfChunks), std::runtime_error); + EXPECT_THROW(memoryInfo->createGemExtWithMultipleRegions(memoryRegions, MemoryConstants::chunkThreshold / (numOfChunks * 2), handle, 0, -1, true, numOfChunks), std::runtime_error); } TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCallingCreatingGemExtWithMultipleRegionsAndChunkingThenReturnCorrectValues) { @@ -672,7 +672,7 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCallingCreatingGemExtWithMultiple uint32_t memoryRegions = 0b1011; uint32_t numOfChunks = 2; size_t size = MemoryConstants::chunkThreshold * numOfChunks; - auto ret = memoryInfo->createGemExtWithMultipleRegions(memoryRegions, size, handle, -1, true, numOfChunks); + auto ret = memoryInfo->createGemExtWithMultipleRegions(memoryRegions, size, handle, 0, -1, true, numOfChunks); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp index e92a1ced86..2b3d70276a 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_info_tests.cpp @@ -236,7 +236,7 @@ HWTEST2_F(MemoryInfoTest, givenMemoryInfoWithRegionsWhenCreatingGemWithExtension uint32_t handle = 0; MemRegionsVec memClassInstance = {regionInfo[0].region, regionInfo[1].region}; uint32_t numOfChunks = 0; - auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); @@ -259,7 +259,7 @@ HWTEST2_F(MemoryInfoTest, givenMemoryInfoWithRegionsWhenCreatingGemExtWithSingle auto memoryInfo = std::make_unique(regionInfo, *drm); ASSERT_NE(nullptr, memoryInfo); - auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, -1); + auto ret = memoryInfo->createGemExtWithSingleRegion(1, 1024, handle, 0, -1); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); EXPECT_EQ(1u, drm->ioctlCallsCount); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index ac0de26c77..5cfef53146 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -3669,7 +3669,6 @@ TEST(DrmMemoryManagerFreeGraphicsMemoryUnreferenceTest, TEST(DrmMemoryManagerFreeGraphicsMemoryUnreferenceTest, whenPrintBOCreateDestroyResultFlagIsSetAndCallToCreateSharedAllocationThenExpectedMessageIsPrinted) { DebugManagerStateRestore stateRestore; - DebugManager.flags.PrintBOCreateDestroyResult.set(true); MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); const uint32_t rootDeviceIndex = 0u; @@ -3683,6 +3682,7 @@ TEST(DrmMemoryManagerFreeGraphicsMemoryUnreferenceTest, osHandle handle = 1u; AllocationProperties properties(rootDeviceIndex, false, MemoryConstants::pageSize, AllocationType::SHARED_BUFFER, false, {}); + DebugManager.flags.PrintBOCreateDestroyResult.set(true); testing::internal::CaptureStdout(); auto allocation = memoryManger.createGraphicsAllocationFromSharedHandle(handle, properties, false, false, false, nullptr); ASSERT_NE(nullptr, allocation); diff --git a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp index a092902d62..da94fa9bdb 100644 --- a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp @@ -137,7 +137,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtThenReturnSuccess) uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); EXPECT_EQ(1u, handle); EXPECT_EQ(0, ret); @@ -155,7 +155,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithChunkingThenGet uint32_t handle = 0; uint32_t getNumOfChunks = 2; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - ioctlHelper->createGemExt(memClassInstance, allocSize, handle, {}, -1, true, getNumOfChunks); + ioctlHelper->createGemExt(memClassInstance, allocSize, handle, 0, {}, -1, true, getNumOfChunks); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("GEM_CREATE_EXT with BOChunkingSize 65536, chunkingParamRegion.param.data 65536, numOfChunks 2\n"); EXPECT_EQ(expectedOutput, output); @@ -172,7 +172,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithChunkingAndAllo uint32_t handle = 0; uint32_t getNumOfChunks = 2; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; - EXPECT_THROW(ioctlHelper->createGemExt(memClassInstance, allocSize, handle, {}, -1, true, getNumOfChunks), std::runtime_error); + EXPECT_THROW(ioctlHelper->createGemExt(memClassInstance, allocSize, handle, 0, {}, -1, true, getNumOfChunks), std::runtime_error); } TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithDebugFlagThenPrintDebugInfo) { @@ -184,7 +184,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithDebugFlagThenPr uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, param: 0x1000000010001, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT has returned: 0 BO-1 with size: 1024\n"); diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp index ca699725a1..8c5374ee32 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_dg1.cpp @@ -28,7 +28,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtThenReturnCorrectValue) { uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); EXPECT_EQ(0, ret); EXPECT_EQ(1u, handle); @@ -50,7 +50,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WithDrmTipWhenCreateGemExtWithDebugFlagTh uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: 0 BO-1 with size: 1024\n"); @@ -72,7 +72,7 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtWithDebugFlagThenPrintDeb uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: -1 BO-0 with size: 1024\nGEM_CREATE_EXT with EXT_SETPARAM has returned: 0 BO-1 with size: 1024\n"); diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index 9a6d33bc00..f283ae9aec 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -18,6 +18,76 @@ using namespace NEO; +struct MockIoctlHelperUpstream : IoctlHelperUpstream { + using IoctlHelperUpstream::IoctlHelperUpstream; + using IoctlHelperUpstream::isSetPatSupported; + + void detectExtSetPatSupport() override { + detectExtSetPatSupportCallCount++; + IoctlHelperUpstream::detectExtSetPatSupport(); + } + + int ioctl(DrmIoctl request, void *arg) override { + ioctlCallCount++; + if (request == DrmIoctl::GemCreateExt) { + lastGemCreateContainedSetPat = checkWhetherGemCreateExtContainsSetPat(arg); + if (overrideGemCreateExtReturnValue.has_value()) { + return *overrideGemCreateExtReturnValue; + } + } + return IoctlHelperUpstream::ioctl(request, arg); + } + + bool checkWhetherGemCreateExtContainsSetPat(void *arg) { + auto &gemCreateExt = *reinterpret_cast(arg); + auto pExtensionBase = reinterpret_cast(gemCreateExt.extensions); + while (pExtensionBase != nullptr) { + if (pExtensionBase->name == I915_GEM_CREATE_EXT_SET_PAT) { + return true; + } + pExtensionBase = reinterpret_cast(pExtensionBase->next_extension); + } + return false; + } + + size_t detectExtSetPatSupportCallCount = 0; + size_t ioctlCallCount = 0; + std::optional overrideGemCreateExtReturnValue{}; + bool lastGemCreateContainedSetPat = false; +}; + +TEST(IoctlHelperUpstreamTest, whenInitializeIsCalledThenDetectExtSetPatSupportFunctionIsCalled) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.DisableGemCreateExtSetPat.set(false); + + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + MockIoctlHelperUpstream mockIoctlHelper{*drm}; + EXPECT_EQ(0u, mockIoctlHelper.detectExtSetPatSupportCallCount); + EXPECT_FALSE(mockIoctlHelper.lastGemCreateContainedSetPat); + EXPECT_EQ(0u, mockIoctlHelper.ioctlCallCount); + + mockIoctlHelper.overrideGemCreateExtReturnValue = 0; + mockIoctlHelper.initialize(); + EXPECT_EQ(1u, mockIoctlHelper.detectExtSetPatSupportCallCount); + EXPECT_TRUE(mockIoctlHelper.lastGemCreateContainedSetPat); + EXPECT_EQ(2u, mockIoctlHelper.ioctlCallCount); // create and close + EXPECT_TRUE(mockIoctlHelper.isSetPatSupported); + + mockIoctlHelper.overrideGemCreateExtReturnValue = -1; + mockIoctlHelper.initialize(); + EXPECT_EQ(2u, mockIoctlHelper.detectExtSetPatSupportCallCount); + EXPECT_TRUE(mockIoctlHelper.lastGemCreateContainedSetPat); + EXPECT_EQ(3u, mockIoctlHelper.ioctlCallCount); // only create + EXPECT_FALSE(mockIoctlHelper.isSetPatSupported); + + DebugManager.flags.DisableGemCreateExtSetPat.set(true); + mockIoctlHelper.initialize(); + EXPECT_EQ(3u, mockIoctlHelper.detectExtSetPatSupportCallCount); + EXPECT_EQ(3u, mockIoctlHelper.ioctlCallCount); // no ioctl calls + EXPECT_FALSE(mockIoctlHelper.isSetPatSupported); +} + TEST(IoctlHelperUpstreamTest, whenGettingVmBindAvailabilityThenFalseIsReturned) { auto executionEnvironment = std::make_unique(); auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); @@ -219,7 +289,7 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtThenReturnCorrectVal uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); EXPECT_EQ(0, ret); EXPECT_EQ(1u, handle); @@ -230,23 +300,112 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtThenReturnCorrectVal TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtWithDebugFlagThenPrintDebugInfo) { DebugManagerStateRestore stateRestore; - DebugManager.flags.PrintBOCreateDestroyResult.set(true); auto executionEnvironment = std::make_unique(); auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); - testing::internal::CaptureStdout(); auto ioctlHelper = drm->getIoctlHelper(); + DebugManager.flags.PrintBOCreateDestroyResult.set(true); + testing::internal::CaptureStdout(); + uint32_t handle = 0; MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; uint32_t numOfChunks = 0; - ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks); + ioctlHelper->createGemExt(memClassInstance, 1024, handle, 0, {}, -1, false, numOfChunks); std::string output = testing::internal::GetCapturedStdout(); std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS has returned: 0 BO-1 with size: 1024\n"); EXPECT_EQ(expectedOutput, output); } +TEST(IoctlHelperTestsUpstream, givenSetPatSupportedWhenCreateGemExtThenSetPatExtensionsIsAdded) { + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + MockIoctlHelperUpstream mockIoctlHelper{*drm}; + + uint32_t handle = 0; + MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; + mockIoctlHelper.isSetPatSupported = false; + auto ret = mockIoctlHelper.createGemExt(memClassInstance, 1, handle, 0, {}, -1, false, 0); + EXPECT_EQ(0, ret); + EXPECT_EQ(1u, mockIoctlHelper.ioctlCallCount); + EXPECT_FALSE(mockIoctlHelper.lastGemCreateContainedSetPat); + + mockIoctlHelper.isSetPatSupported = true; + ret = mockIoctlHelper.createGemExt(memClassInstance, 1, handle, 0, {}, -1, false, 0); + EXPECT_EQ(0, ret); + EXPECT_EQ(2u, mockIoctlHelper.ioctlCallCount); + EXPECT_TRUE(mockIoctlHelper.lastGemCreateContainedSetPat); +} + +TEST(IoctlHelperTestsUpstream, givenInvalidPatIndexWhenCreateGemExtThenSetPatExtensionsIsNotAdded) { + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + MockIoctlHelperUpstream mockIoctlHelper{*drm}; + + uint32_t handle = 0; + mockIoctlHelper.isSetPatSupported = true; + uint64_t invalidPatIndex = CommonConstants::unsupportedPatIndex; + MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; + auto ret = mockIoctlHelper.createGemExt(memClassInstance, 1, handle, invalidPatIndex, {}, -1, false, 0); + EXPECT_EQ(0, ret); + EXPECT_EQ(1u, mockIoctlHelper.ioctlCallCount); + EXPECT_FALSE(mockIoctlHelper.lastGemCreateContainedSetPat); + + invalidPatIndex = static_cast(std::numeric_limits::max()) + 1; + ret = mockIoctlHelper.createGemExt(memClassInstance, 1, handle, invalidPatIndex, {}, -1, false, 0); + EXPECT_EQ(0, ret); + EXPECT_EQ(2u, mockIoctlHelper.ioctlCallCount); + EXPECT_FALSE(mockIoctlHelper.lastGemCreateContainedSetPat); +} + +TEST(IoctlHelperTestsUpstream, givenSetPatSupportedWhenCreateGemExtWithDebugFlagThenPrintDebugInfoWithExtSetPat) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.DisableGemCreateExtSetPat.set(false); + + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + MockIoctlHelperUpstream mockIoctlHelper{*drm}; + + DebugManager.flags.PrintBOCreateDestroyResult.set(true); + testing::internal::CaptureStdout(); + + uint32_t handle = 0; + mockIoctlHelper.isSetPatSupported = true; + MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}}; + uint32_t numOfChunks = 0; + uint64_t patIndex = 5; + mockIoctlHelper.createGemExt(memClassInstance, 1024, handle, patIndex, {}, -1, false, numOfChunks); + + std::string output = testing::internal::GetCapturedStdout(); + std::string expectedOutput("Performing GEM_CREATE_EXT with { size: 1024, memory class: 1, memory instance: 0, pat index: 5 }\nGEM_CREATE_EXT with EXT_MEMORY_REGIONS with EXT_SET_PAT has returned: 0 BO-1 with size: 1024\n"); + EXPECT_EQ(expectedOutput, output); +} + +TEST(IoctlHelperUpstreamTest, whenDetectExtSetPatSupportIsCalledWithDebugFlagThenPrintCorrectDebugInfo) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.DisableGemCreateExtSetPat.set(false); + + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + MockIoctlHelperUpstream mockIoctlHelper{*drm}; + + DebugManager.flags.PrintBOCreateDestroyResult.set(true); + testing::internal::CaptureStdout(); + mockIoctlHelper.overrideGemCreateExtReturnValue = 0; + mockIoctlHelper.detectExtSetPatSupport(); + std::string output = testing::internal::GetCapturedStdout(); + std::string expectedOutput("EXT_SET_PAT support is: enabled\n"); + EXPECT_EQ(expectedOutput, output); + + testing::internal::CaptureStdout(); + mockIoctlHelper.overrideGemCreateExtReturnValue = -1; + mockIoctlHelper.detectExtSetPatSupport(); + output = testing::internal::GetCapturedStdout(); + expectedOutput = "EXT_SET_PAT support is: disabled\n"; + EXPECT_EQ(expectedOutput, output); +} + TEST(IoctlHelperTestsUpstream, givenUpstreamWhenClosAllocThenReturnNoneRegion) { auto executionEnvironment = std::make_unique(); auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index d76fe343cc..ba0a5a45e2 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -78,7 +78,7 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGemCreateExtWithRegionsThen uint32_t handle = 0u; uint32_t numOfChunks = 0; - EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, {}, -1, false, numOfChunks)); + EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, 0, {}, -1, false, numOfChunks)); } TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGemCreateExtWithRegionsAndVmIdThenDummyValueIsReturned) { @@ -97,7 +97,7 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGemCreateExtWithRegionsAndV uint32_t handle = 0u; uint32_t numOfChunks = 0; GemVmControl test = {}; - EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, test.vmId, -1, false, numOfChunks)); + EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, 0, test.vmId, -1, false, numOfChunks)); } TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsReturned) { @@ -121,7 +121,7 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe MemRegionsVec memRegions{}; uint32_t handle = 0u; uint32_t numOfChunks = 0; - EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, {}, -1, false, numOfChunks)); + EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, 0, {}, -1, false, numOfChunks)); EXPECT_TRUE(xeIoctlHelper->isVmBindAvailable());