feature: Add support for chunking in the UMD (1/N)

Read if support for chunking is available in the KMD.
If available, KMD will create a BO with 1 or more chunks,
depending on the chunk size selected.

Related-To: NEO-7695

Sync to
https://github.com/intel-gpu/drm-uapi-helper/releases/tag/v2.0-rc18

Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
Signed-off-by: John Falkowski <john.falkowski@intel.com>
This commit is contained in:
Jaime Arteaga
2023-03-08 04:06:00 +00:00
committed by Compute-Runtime-Automation
parent 16d6ee735a
commit 2efd6e547a
38 changed files with 961 additions and 36 deletions

View File

@@ -502,6 +502,10 @@ DECLARE_DEBUG_VARIABLE(bool, ForceLargeGrfCompilationMode, false, "Adds build op
DECLARE_DEBUG_VARIABLE(bool, EnableConcurrentSharedCrossP2PDeviceAccess, false, "Enables the concurrent use between host and peer devices of shared-allocations ")
DECLARE_DEBUG_VARIABLE(bool, AllocateSharedAllocationsInHeapExtendedHost, false, "When enabled driver can allocate shared unified memory allocation in heap extended host. (0 - disable, 1 - enable)")
DECLARE_DEBUG_VARIABLE(bool, AllocateHostAllocationsInHeapExtendedHost, true, "When enabled driver can allocate host unified memory allocation in heap extended host. (0 - disable, 1 - enable)")
DECLARE_DEBUG_VARIABLE(bool, PrintBOChunkingLogs, false, "Print some logs on BO chunking")
DECLARE_DEBUG_VARIABLE(bool, EnableBOChunking, false, "Enables use of chunking of BOs in the KMD.")
DECLARE_DEBUG_VARIABLE(bool, EnableBOChunkingPreferredLocationHint, false, "Enables preferred location advise on chunks")
DECLARE_DEBUG_VARIABLE(int32_t, NumberOfBOChunks, 2, "Number of chunks to use. Must be a power of two)")
DECLARE_DEBUG_VARIABLE(int32_t, ForceAutoGrfCompilationMode, -1, "Adds build option -*-intel-enable-auto-large-GRF-mode to force kernel compilation")
DECLARE_DEBUG_VARIABLE(int32_t, ForceOCLVersion, 0, "Force specific OpenCL API version")
DECLARE_DEBUG_VARIABLE(int32_t, ForceOCL21FeaturesSupport, -1, "-1: default, 0: disable, 1:enable. Force support of OpenCL 2.0 and OpenCL 2.1 API features")

View File

@@ -116,6 +116,7 @@ Drm *Drm::create(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceId, RootDeviceEnvironm
}
drm->isSetPairAvailable();
drm->isChunkingAvailable();
if (!drm->isPerContextVMRequired()) {
if (!drm->createVirtualMemoryAddressSpace(GfxCoreHelper::getSubDevicesCount(rootDeviceEnvironment.getHardwareInfo()))) {

View File

@@ -54,6 +54,7 @@ inline constexpr uintptr_t page4kEntryMask = std::numeric_limits<uintptr_t>::max
inline constexpr uintptr_t page64kEntryMask = std::numeric_limits<uintptr_t>::max() & ~MemoryConstants::page64kMask;
inline constexpr int GfxAddressBits = is64bit ? 48 : 32;
inline constexpr uint64_t maxSvmAddress = is64bit ? maxNBitValue(47) : maxNBitValue(32);
inline constexpr size_t chunkThreshold = MemoryConstants::pageSize64k;
} // namespace MemoryConstants

View File

@@ -33,5 +33,7 @@ struct StorageInfo {
char resourceTag[AppResourceDefines::maxStrLen + 1] = "";
uint32_t getMemoryBanks() const { return static_cast<uint32_t>(memoryBanks.to_ulong()); }
uint32_t getTotalBanksCnt() const;
bool isChunked = false;
uint32_t numOfChunks = 0;
};
} // namespace NEO

View File

@@ -10,12 +10,15 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/memory_manager/residency.h"
#include "shared/source/os_interface/linux/cache_info.h"
#include "shared/source/os_interface/linux/drm_buffer_object.h"
#include "shared/source/os_interface/linux/drm_memory_manager.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/i915_prelim.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/source/os_interface/linux/memory_info.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/source/os_interface/os_context.h"
#include "shared/source/os_interface/product_helper.h"
@@ -82,6 +85,44 @@ bool DrmAllocation::setPreferredLocation(Drm *drm, PreferredLocation memoryLocat
auto ioctlHelper = drm->getIoctlHelper();
auto remainingMemoryBanks = storageInfo.memoryBanks;
bool success = true;
auto pHwInfo = drm->getRootDeviceEnvironment().getHardwareInfo();
if (this->storageInfo.isChunked && DebugManager.flags.EnableBOChunkingPreferredLocationHint.get() == 1) {
prelim_drm_i915_gem_memory_class_instance region{};
region.memory_class = NEO::PrelimI915::PRELIM_I915_MEMORY_CLASS_DEVICE;
auto banks = std::bitset<4>(remainingMemoryBanks);
MemRegionsVec memRegions{};
size_t currentBank = 0;
size_t i = 0;
while (i < banks.count()) {
if (banks.test(currentBank)) {
auto regionClassAndInstance = drm->getMemoryInfo()->getMemoryRegionClassAndInstance(1u << currentBank, *pHwInfo);
memRegions.push_back(regionClassAndInstance);
i++;
}
currentBank++;
}
for (uint32_t i = 0; i < this->storageInfo.numOfChunks; i++) {
// Depth-first
region.memory_instance = memRegions[i / (this->storageInfo.numOfChunks / memRegions.size())].memoryInstance;
uint64_t chunkLength = (bufferObjects[0]->peekSize() / this->storageInfo.numOfChunks);
uint64_t chunkStart = i * chunkLength;
printDebugString(DebugManager.flags.PrintBOChunkingLogs.get(), stdout,
"Setting PRELIM_DRM_I915_GEM_VM_ADVISE for BO-%d chunk 0x%lx chunkLength %ld memory_class %d, memory_region %d\n",
bufferObjects[0]->peekHandle(),
chunkStart,
chunkLength,
region.memory_class,
region.memory_instance);
success &= ioctlHelper->setVmBoAdviseForChunking(bufferObjects[0]->peekHandle(),
chunkStart,
chunkLength,
ioctlHelper->getPreferredLocationAdvise(),
&region);
}
return success;
}
for (uint8_t handleId = 0u; handleId < numHandles; handleId++) {
auto memoryInstance = Math::getMinLsbSet(static_cast<uint32_t>(remainingMemoryBanks.to_ulong()));

View File

@@ -211,6 +211,8 @@ class BufferObject {
uint32_t getOsContextId(OsContext *osContext);
std::vector<std::array<bool, EngineLimits::maxHandleCount>> bindInfo;
bool isChunked = false;
protected:
MOCKABLE_VIRTUAL MemoryOperationsStatus evictUnusedAllocations(bool waitForCompletion, bool isLockNeeded);

View File

@@ -38,6 +38,7 @@
#include "shared/source/os_interface/linux/drm_memory_operations_handler.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/i915_prelim.h"
#include "shared/source/os_interface/linux/memory_info.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/source/os_interface/os_interface.h"
@@ -1826,6 +1827,34 @@ BufferObject *DrmMemoryManager::createBufferObjectInMemoryRegion(uint32_t rootDe
return bo;
}
bool DrmMemoryManager::createDrmChunkedAllocation(Drm *drm, DrmAllocation *allocation, uint64_t boAddress, size_t boSize, size_t maxOsContextCount) {
auto &storageInfo = allocation->storageInfo;
auto memoryInfo = drm->getMemoryInfo();
uint32_t handle = 0;
auto memoryBanks = static_cast<uint32_t>(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);
auto bo = new (std::nothrow) BufferObject(allocation->getRootDeviceIndex(), drm, patIndex, handle, boSize, maxOsContextCount);
UNRECOVERABLE_IF(bo == nullptr);
bo->setAddress(boAddress);
allocation->getBufferObjectToModify(0) = bo;
bo->isChunked = 1;
storageInfo.isChunked = true;
storageInfo.numOfChunks = numOfChunks;
return true;
}
bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, uint64_t gpuAddress, size_t maxOsContextCount) {
BufferObjects bos{};
auto &storageInfo = allocation->storageInfo;
@@ -1836,7 +1865,25 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation,
auto useKmdMigrationForBuffers = (AllocationType::BUFFER == allocation->getAllocationType() && (DebugManager.flags.UseKmdMigrationForBuffers.get() > 0));
auto handles = storageInfo.getNumBanks();
if (storageInfo.colouringPolicy == ColouringPolicy::ChunkSizeBased) {
bool useChunking = false;
size_t boTotalChunkSize = 0;
if (AllocationType::BUFFER == allocation->getAllocationType() &&
drm->getChunkingAvailable()) {
boTotalChunkSize = allocation->getUnderlyingBufferSize();
uint32_t numOfChunks = DebugManager.flags.NumberOfBOChunks.get();
size_t chunkingSize = boTotalChunkSize / numOfChunks;
// Dont chunk for sizes less than chunkThreshold
if (!(chunkingSize & (MemoryConstants::chunkThreshold - 1))) {
handles = 1;
allocation->resizeBufferObjects(handles);
bos.resize(handles);
useChunking = true;
}
} else if (storageInfo.colouringPolicy == ColouringPolicy::ChunkSizeBased) {
handles = allocation->getNumGmms();
allocation->resizeBufferObjects(handles);
bos.resize(handles);
@@ -1845,6 +1892,10 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation,
int32_t pairHandle = -1;
if (useChunking) {
return createDrmChunkedAllocation(drm, allocation, gpuAddress, boTotalChunkSize, maxOsContextCount);
}
for (auto handleId = 0u; handleId < handles; handleId++, currentBank++) {
if (currentBank == banksCnt) {
currentBank = 0;
@@ -2163,6 +2214,16 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const
auto remainingMemoryBanks = allocationData.storageInfo.memoryBanks;
auto numHandles = GraphicsAllocation::getNumHandlesForKmdSharedAllocation(allocationData.storageInfo.getNumBanks());
bool useChunking = false;
uint32_t numOfChunks = DebugManager.flags.NumberOfBOChunks.get();
size_t chunkingSize = size / numOfChunks;
// Dont chunk for sizes less than chunkThreshold
if (drm.getChunkingAvailable() && !(chunkingSize & (MemoryConstants::chunkThreshold - 1))) {
numHandles = 1;
useChunking = true;
}
for (auto handleId = 0u; handleId < numHandles; handleId++) {
uint32_t handle = 0;
@@ -2172,10 +2233,10 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const
}
auto memoryInstance = Math::getMinLsbSet(static_cast<uint32_t>(remainingMemoryBanks.to_ulong()));
auto memoryBanks = DebugManager.flags.KMDSupportForCrossTileMigrationPolicy.get() > 0 ? allocationData.storageInfo.memoryBanks : DeviceBitfield(1 << memoryInstance);
auto memoryBanks = (DebugManager.flags.KMDSupportForCrossTileMigrationPolicy.get() > 0 || useChunking) ? allocationData.storageInfo.memoryBanks : DeviceBitfield(1 << memoryInstance);
auto memRegions = createMemoryRegionsForSharedAllocation(*pHwInfo, *memoryInfo, allocationData, memoryBanks);
auto ret = memoryInfo->createGemExt(memRegions, currentSize, handle, {}, -1);
int ret = memoryInfo->createGemExt(memRegions, currentSize, handle, {}, -1, useChunking, numOfChunks);
if (ret) {
this->munmapFunction(cpuPointer, totalSizeToAlloc);
@@ -2205,6 +2266,8 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const
bo->setAddress(castToUint64(currentAddress));
bo->isChunked = useChunking;
bos.push_back(bo.release());
currentAddress = reinterpret_cast<void *>(castToUint64(currentAddress) + currentSize);
@@ -2220,6 +2283,8 @@ GraphicsAllocation *DrmMemoryManager::createSharedUnifiedMemoryAllocation(const
allocation->setReservedAddressRange(reinterpret_cast<void *>(preferredAddress), totalSizeToAlloc);
allocation->setNumHandles(static_cast<uint32_t>(bos.size()));
allocation->storageInfo = allocationData.storageInfo;
allocation->storageInfo.isChunked = useChunking;
allocation->storageInfo.numOfChunks = numOfChunks;
if (!allocation->setCacheRegion(&drm, static_cast<CacheRegion>(allocationData.cacheRegion))) {
this->munmapFunction(cpuBasePointer, totalSizeToAlloc);
for (auto bo : bos) {

View File

@@ -137,6 +137,7 @@ class DrmMemoryManager : public MemoryManager {
GraphicsAllocation *allocate32BitGraphicsMemoryImpl(const AllocationData &allocationData, bool useLocalMemory) override;
void cleanupBeforeReturn(const AllocationData &allocationData, GfxPartition *gfxPartition, DrmAllocation *drmAllocation, GraphicsAllocation *graphicsAllocation, uint64_t &gpuAddress, size_t &sizeAllocated);
GraphicsAllocation *allocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) override;
bool createDrmChunkedAllocation(Drm *drm, DrmAllocation *allocation, uint64_t boAddress, size_t boSize, size_t maxOsContextCount);
bool createDrmAllocation(Drm *drm, DrmAllocation *allocation, uint64_t gpuAddress, size_t maxOsContextCount);
void registerAllocationInOs(GraphicsAllocation *allocation) override;
void waitOnCompletionFence(GraphicsAllocation *allocation);

View File

@@ -54,6 +54,10 @@ MemoryOperationsStatus DrmMemoryOperationsHandlerBind::makeResidentWithinOsConte
auto drmAllocation = static_cast<DrmAllocation *>(*gfxAllocation);
auto bo = drmAllocation->storageInfo.getNumBanks() > 1 ? drmAllocation->getBOs()[drmIterator] : drmAllocation->getBO();
if (drmAllocation->storageInfo.isChunked) {
bo = drmAllocation->getBO();
}
if (!bo->bindInfo[bo->getOsContextId(osContext)][drmIterator]) {
int result = drmAllocation->makeBOsResident(osContext, drmIterator, nullptr, true);
if (result) {

View File

@@ -1270,6 +1270,20 @@ bool Drm::isSetPairAvailable() {
return setPairAvailable;
}
bool Drm::isChunkingAvailable() {
if (DebugManager.flags.EnableBOChunking.get()) {
std::call_once(checkChunkingOnce, [this]() {
int ret = ioctlHelper->isChunkingAvailable();
if (ret) {
chunkingAvailable = true;
}
printDebugString(DebugManager.flags.PrintBOChunkingLogs.get(), stdout,
"Chunking available: %d\n", chunkingAvailable);
});
}
return chunkingAvailable;
}
bool Drm::isVmBindAvailable() {
std::call_once(checkBindOnce, [this]() {
int ret = ioctlHelper->isVmBindAvailable();
@@ -1350,7 +1364,7 @@ int changeBufferObjectBinding(Drm *drm, OsContext *osContext, uint32_t vmHandleI
bool bindImmediate = bo->isImmediateBindingRequired();
bool bindMakeResident = false;
if (drm->useVMBindImmediate()) {
bindMakeResident = bo->isExplicitResidencyRequired();
bindMakeResident = bo->isExplicitResidencyRequired() && !bo->isChunked;
bindImmediate = true;
}
flags |= ioctlHelper->getFlagsForVmBind(bindCapture, bindImmediate, bindMakeResident);

View File

@@ -161,6 +161,8 @@ class Drm : public DriverModel {
MOCKABLE_VIRTUAL bool isSetPairAvailable();
MOCKABLE_VIRTUAL bool getSetPairAvailable() { return setPairAvailable; }
MOCKABLE_VIRTUAL bool isChunkingAvailable();
MOCKABLE_VIRTUAL bool getChunkingAvailable() { return chunkingAvailable; }
MOCKABLE_VIRTUAL bool useVMBindImmediate() const;
@@ -334,6 +336,7 @@ class Drm : public DriverModel {
std::once_flag checkBindOnce;
std::once_flag checkSetPairOnce;
std::once_flag checkChunkingOnce;
std::once_flag checkCompletionFenceOnce;
RootDeviceEnvironment &rootDeviceEnvironment;
@@ -346,6 +349,7 @@ class Drm : public DriverModel {
bool bindAvailable = false;
bool directSubmissionActive = false;
bool setPairAvailable = false;
bool chunkingAvailable = false;
bool contextDebugSupported = false;
bool pageFaultSupported = false;
bool completionFenceSupported = false;

View File

@@ -75,8 +75,9 @@ class IoctlHelper {
virtual bool initialize() = 0;
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<uint32_t> vmId, int32_t pairHandle) = 0;
virtual int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> 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;
@@ -86,6 +87,7 @@ class IoctlHelper {
virtual uint32_t getPreferredLocationAdvise() = 0;
virtual std::optional<MemoryClassInstance> getPreferredLocationRegion(PreferredLocation memoryLocation, uint32_t memoryInstance) = 0;
virtual bool setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) = 0;
virtual bool setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) = 0;
virtual bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) = 0;
virtual uint32_t getDirectSubmissionFlag() = 0;
virtual std::unique_ptr<uint8_t[]> prepareVmBindExt(const StackVec<uint32_t, 2> &bindExtHandles) = 0;
@@ -159,8 +161,9 @@ class IoctlHelperUpstream : public IoctlHelper {
bool initialize() override;
bool isSetPairAvailable() override;
bool isChunkingAvailable() override;
bool isVmBindAvailable() override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> 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;
@@ -170,6 +173,7 @@ class IoctlHelperUpstream : public IoctlHelper {
uint32_t getPreferredLocationAdvise() override;
std::optional<MemoryClassInstance> getPreferredLocationRegion(PreferredLocation memoryLocation, uint32_t memoryInstance) override;
bool setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) override;
bool setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) override;
bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) override;
uint32_t getDirectSubmissionFlag() override;
std::unique_ptr<uint8_t[]> prepareVmBindExt(const StackVec<uint32_t, 2> &bindExtHandles) override;
@@ -215,7 +219,7 @@ class IoctlHelperImpl : public IoctlHelperUpstream {
return std::make_unique<IoctlHelperImpl<gfxProduct>>(drm);
}
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override;
std::vector<MemoryRegion> translateToMemoryRegions(const std::vector<uint8_t> &regionInfo) override;
unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest) const override;
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
@@ -227,8 +231,9 @@ class IoctlHelperPrelim20 : public IoctlHelper {
bool initialize() override;
bool isSetPairAvailable() override;
bool isChunkingAvailable() override;
bool isVmBindAvailable() override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> 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;
@@ -238,6 +243,7 @@ class IoctlHelperPrelim20 : public IoctlHelper {
uint32_t getPreferredLocationAdvise() override;
std::optional<MemoryClassInstance> getPreferredLocationRegion(PreferredLocation memoryLocation, uint32_t memoryInstance) override;
bool setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) override;
bool setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) override;
bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) override;
uint32_t getDirectSubmissionFlag() override;
std::unique_ptr<uint8_t[]> prepareVmBindExt(const StackVec<uint32_t, 2> &bindExtHandles) override;

View File

@@ -7,6 +7,7 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/helpers/constants.h"
#include "shared/source/helpers/debug_helpers.h"
@@ -56,6 +57,19 @@ bool IoctlHelperPrelim20::isSetPairAvailable() {
return setPairSupported;
}
bool IoctlHelperPrelim20::isChunkingAvailable() {
int chunkSupported = 0;
GetParam getParam{};
getParam.param = PRELIM_I915_PARAM_HAS_CHUNK_SIZE;
getParam.value = &chunkSupported;
int retVal = IoctlHelper::ioctl(DrmIoctl::Getparam, &getParam);
if (retVal) {
return false;
}
return chunkSupported;
}
bool IoctlHelperPrelim20::isVmBindAvailable() {
int vmBindSupported = 0;
GetParam getParam{};
@@ -68,7 +82,7 @@ bool IoctlHelperPrelim20::isVmBindAvailable() {
return vmBindSupported;
}
int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) {
int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
uint32_t regionsSize = static_cast<uint32_t>(memClassInstances.size());
std::vector<prelim_drm_i915_gem_memory_class_instance> regions(regionsSize);
for (uint32_t i = 0; i < regionsSize; i++) {
@@ -86,6 +100,7 @@ int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, si
prelim_drm_i915_gem_create_ext_vm_private vmPrivate{};
prelim_drm_i915_gem_create_ext_setparam pairSetparamRegion{};
prelim_drm_i915_gem_create_ext_setparam chunkingParamRegion{};
if (vmId != std::nullopt) {
vmPrivate.base.name = PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE;
@@ -98,11 +113,25 @@ int IoctlHelperPrelim20::createGemExt(const MemRegionsVec &memClassInstances, si
pairSetparamRegion.param.data = pairHandle;
}
if (vmId != std::nullopt) {
vmPrivate.base.next_extension = reinterpret_cast<uintptr_t>(&pairSetparamRegion);
setparamRegion.base.next_extension = reinterpret_cast<uintptr_t>(&vmPrivate);
} else if (pairHandle != -1) {
setparamRegion.base.next_extension = reinterpret_cast<uintptr_t>(&pairSetparamRegion);
if (isChunked) {
size_t chunkingSize = allocSize / numOfChunks;
chunkingParamRegion.base.name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM;
chunkingParamRegion.param.param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_SET_CHUNK_SIZE;
UNRECOVERABLE_IF(chunkingSize & (MemoryConstants::pageSize64k - 1));
chunkingParamRegion.param.data = chunkingSize;
printDebugString(DebugManager.flags.PrintBOChunkingLogs.get(), stdout,
"GEM_CREATE_EXT with BOChunkingSize %d, chunkingParamRegion.param.data %d, numOfChunks %d\n",
chunkingSize,
chunkingParamRegion.param.data,
numOfChunks);
setparamRegion.base.next_extension = reinterpret_cast<uintptr_t>(&chunkingParamRegion);
} else {
if (vmId != std::nullopt) {
vmPrivate.base.next_extension = reinterpret_cast<uintptr_t>(&pairSetparamRegion);
setparamRegion.base.next_extension = reinterpret_cast<uintptr_t>(&vmPrivate);
} else if (pairHandle != -1) {
setparamRegion.base.next_extension = reinterpret_cast<uintptr_t>(&pairSetparamRegion);
}
}
prelim_drm_i915_gem_create_ext createExt{};
@@ -238,6 +267,25 @@ std::optional<MemoryClassInstance> IoctlHelperPrelim20::getPreferredLocationRegi
return region;
}
bool IoctlHelperPrelim20::setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) {
prelim_drm_i915_gem_vm_advise vmAdvise{};
vmAdvise.handle = handle;
vmAdvise.start = start;
vmAdvise.length = length;
vmAdvise.attribute = attribute;
UNRECOVERABLE_IF(region == nullptr);
vmAdvise.region = *reinterpret_cast<prelim_drm_i915_gem_memory_class_instance *>(region);
int ret = IoctlHelper::ioctl(DrmIoctl::GemVmAdvise, &vmAdvise);
if (ret != 0) {
int err = errno;
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err));
DEBUG_BREAK_IF(true);
return false;
}
return true;
}
bool IoctlHelperPrelim20::setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) {
prelim_drm_i915_gem_vm_advise vmAdvise{};

View File

@@ -22,11 +22,15 @@ bool IoctlHelperUpstream::isSetPairAvailable() {
return false;
}
bool IoctlHelperUpstream::isChunkingAvailable() {
return false;
}
bool IoctlHelperUpstream::isVmBindAvailable() {
return false;
}
int IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) {
int IoctlHelperUpstream::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
uint32_t regionsSize = static_cast<uint32_t>(memClassInstances.size());
std::vector<drm_i915_gem_memory_class_instance> regions(regionsSize);
for (uint32_t i = 0; i < regionsSize; i++) {
@@ -94,6 +98,10 @@ bool IoctlHelperUpstream::setVmBoAdvise(int32_t handle, uint32_t attribute, void
return true;
}
bool IoctlHelperUpstream::setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) {
return true;
}
bool IoctlHelperUpstream::setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) {
return true;
}

View File

@@ -21,8 +21,8 @@ constexpr static auto gfxProduct = IGFX_DG1;
extern bool isQueryDrmTip(const std::vector<uint8_t> &queryInfo);
template <>
int IoctlHelperImpl<gfxProduct>::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) {
auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle);
int IoctlHelperImpl<gfxProduct>::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
auto ret = IoctlHelperUpstream::createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle, isChunked, numOfChunks);
if (ret == 0) {
return ret;
}

View File

@@ -56,8 +56,8 @@ void MemoryInfo::assignRegionsFromDistances(const std::vector<DistanceInfo> &dis
}
}
int MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) {
return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle);
int MemoryInfo::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
return this->drm.getIoctlHelper()->createGemExt(memClassInstances, allocSize, handle, vmId, pairHandle, isChunked, numOfChunks);
}
uint32_t MemoryInfo::getTileIndex(uint32_t memoryBank) {
@@ -120,7 +120,8 @@ int MemoryInfo::createGemExtWithSingleRegion(uint32_t memoryBanks, size_t allocS
vmId = this->drm.getVirtualMemoryAddressSpace(tileIndex);
}
}
auto ret = createGemExt(region, allocSize, handle, vmId, pairHandle);
uint32_t numOfChunks = 0;
auto ret = createGemExt(region, allocSize, handle, vmId, pairHandle, false, numOfChunks);
return ret;
}
@@ -138,7 +139,26 @@ int MemoryInfo::createGemExtWithMultipleRegions(uint32_t memoryBanks, size_t all
}
currentBank++;
}
auto ret = createGemExt(memRegions, allocSize, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = createGemExt(memRegions, allocSize, handle, {}, -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) {
auto pHwInfo = this->drm.getRootDeviceEnvironment().getHardwareInfo();
auto banks = std::bitset<4>(memoryBanks);
MemRegionsVec memRegions{};
size_t currentBank = 0;
size_t i = 0;
while (i < banks.count()) {
if (banks.test(currentBank)) {
auto regionClassAndInstance = getMemoryRegionClassAndInstance(1u << currentBank, *pHwInfo);
memRegions.push_back(regionClassAndInstance);
i++;
}
currentBank++;
}
auto ret = createGemExt(memRegions, allocSize, handle, {}, pairHandle, isChunked, numOfChunks);
return ret;
}

View File

@@ -26,7 +26,7 @@ class MemoryInfo {
void assignRegionsFromDistances(const std::vector<DistanceInfo> &distances);
MOCKABLE_VIRTUAL int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle);
MOCKABLE_VIRTUAL int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks);
MemoryClassInstance getMemoryRegionClassAndInstance(uint32_t memoryBank, const HardwareInfo &hwInfo);
@@ -40,6 +40,7 @@ class MemoryInfo {
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);
const RegionContainer &getDrmRegionInfos() const { return drmQueryRegions; }

View File

@@ -252,6 +252,10 @@ bool IoctlHelperXe::isSetPairAvailable() {
return false;
}
bool IoctlHelperXe::isChunkingAvailable() {
return false;
}
bool IoctlHelperXe::isVmBindAvailable() {
return true;
}
@@ -365,7 +369,7 @@ std::unique_ptr<MemoryInfo> IoctlHelperXe::createMemoryInfo() {
return std::make_unique<MemoryInfo>(regionsContainer, drm);
}
int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) {
int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) {
struct drm_xe_gem_create create = {};
uint32_t regionsSize = static_cast<uint32_t>(memClassInstances.size());
@@ -483,6 +487,10 @@ bool IoctlHelperXe::setVmBoAdvise(int32_t handle, uint32_t attribute, void *regi
return false;
}
bool IoctlHelperXe::setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) {
return false;
}
bool IoctlHelperXe::setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) {
xeLog(" -> IoctlHelperXe::%s\n", __FUNCTION__);
return false;

View File

@@ -44,8 +44,9 @@ class IoctlHelperXe : public IoctlHelper {
bool initialize() override;
bool isSetPairAvailable() override;
bool isChunkingAvailable() override;
bool isVmBindAvailable() override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle) override;
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> 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;
@@ -55,6 +56,7 @@ class IoctlHelperXe : public IoctlHelper {
uint32_t getPreferredLocationAdvise() override;
std::optional<MemoryClassInstance> getPreferredLocationRegion(PreferredLocation memoryLocation, uint32_t memoryInstance) override;
bool setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) override;
bool setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) override;
bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) override;
uint32_t getDirectSubmissionFlag() override;
std::unique_ptr<uint8_t[]> prepareVmBindExt(const StackVec<uint32_t, 2> &bindExtHandles) override;

View File

@@ -27,6 +27,7 @@ class DrmMock : public Drm {
using Drm::bindAvailable;
using Drm::cacheInfo;
using Drm::checkQueueSliceSupport;
using Drm::chunkingAvailable;
using Drm::classHandles;
using Drm::completionFenceSupported;
using Drm::contextDebugSupported;
@@ -141,6 +142,13 @@ class DrmMock : public Drm {
return setPairAvailable;
}
bool isChunkingAvailable() override {
if (callBaseIsChunkingAvailable) {
return Drm::isChunkingAvailable();
}
return chunkingAvailable;
}
bool getSetPairAvailable() override {
if (callBaseGetSetPairAvailable) {
return Drm::getSetPairAvailable();
@@ -197,6 +205,7 @@ class DrmMock : public Drm {
bool callBaseCreateDrmContext = true;
bool callBaseIsVmBindAvailable = false;
bool callBaseIsSetPairAvailable = false;
bool callBaseIsChunkingAvailable = false;
bool callBaseGetSetPairAvailable = false;
bool unrecoverableContextSet = false;
bool failRetHwIpVersion = false;

View File

@@ -52,6 +52,10 @@ int DrmMockPrelimContext::handlePrelimRequest(DrmIoctl request, void *arg) {
setPairQueryCalled++;
*gp->value = setPairQueryValue;
return setPairQueryReturn;
} else if (gp->param == PRELIM_I915_PARAM_HAS_CHUNK_SIZE) {
chunkingQueryCalled++;
*gp->value = chunkingQueryValue;
return chunkingQueryReturn;
}
} break;
case DrmIoctl::GemContextGetparam: {

View File

@@ -112,6 +112,10 @@ struct DrmMockPrelimContext {
int vmBindQueryValue{0};
int vmBindQueryReturn{0};
size_t chunkingQueryCalled{0};
int chunkingQueryValue{0};
int chunkingQueryReturn{0};
size_t vmBindCalled{0};
std::optional<VmBindParams> receivedVmBind{};
std::optional<UserFenceVmBindExt> receivedVmBindUserFence{};

View File

@@ -193,6 +193,9 @@ int DrmMockCustom::ioctl(DrmIoctl request, void *arg) {
createExtHandle = createExtParams->handle;
createExtExtensions = createExtParams->extensions;
ioctlCnt.gemCreateExt++;
if (failOnCreateExt == true) {
return -1;
}
} break;
case DrmIoctl::GemVmBind: {
} break;
@@ -258,3 +261,21 @@ bool DrmMockCustom::getSetPairAvailable() {
return getSetPairAvailableCall.returnValue;
}
}
bool DrmMockCustom::isChunkingAvailable() {
isChunkingAvailableCall.called++;
if (isChunkingAvailableCall.callParent) {
return Drm::isChunkingAvailable();
} else {
return isChunkingAvailableCall.returnValue;
}
}
bool DrmMockCustom::getChunkingAvailable() {
getChunkingAvailableCall.called++;
if (getChunkingAvailableCall.callParent) {
return Drm::getChunkingAvailable();
} else {
return getChunkingAvailableCall.returnValue;
}
}

View File

@@ -121,12 +121,21 @@ class DrmMockCustom : public Drm {
uint32_t called = 0u;
};
struct IsChunkingAvailableCall {
bool callParent = true;
bool returnValue = true;
uint32_t called = 0u;
};
DrmMockCustom(RootDeviceEnvironment &rootDeviceEnvironment);
int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) override;
bool getSetPairAvailable() override;
bool getChunkingAvailable() override;
bool isChunkingAvailable() override;
bool isVmBindAvailable() override;
bool completionFenceSupport() override {
@@ -171,6 +180,9 @@ class DrmMockCustom : public Drm {
IsVmBindAvailableCall getSetPairAvailableCall{};
IsVmBindAvailableCall isVmBindAvailableCall{};
IsChunkingAvailableCall getChunkingAvailableCall{};
IsChunkingAvailableCall isChunkingAvailableCall{};
std::atomic<int> ioctlRes;
std::atomic<IoctlResExt *> ioctlResExt;
@@ -224,6 +236,7 @@ class DrmMockCustom : public Drm {
uint64_t createExtSize = 0;
uint32_t createExtHandle = 0;
uint64_t createExtExtensions = 0;
bool failOnCreateExt = false;
uint32_t vmIdToCreate = 0;

View File

@@ -69,7 +69,7 @@ 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<uint32_t> vmId, int32_t pairHandle) override {
int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) override {
if (allocSize == 0) {
return EINVAL;
}
@@ -92,8 +92,23 @@ 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 {
if (allocSize == 0) {
return EINVAL;
}
if (failOnCreateGemExtWithMultipleRegions == true) {
return -1;
}
handle = 1u;
banks = memoryBanks;
isChunkedUsed = isChunked;
return 0;
}
uint32_t banks = 0;
int32_t pairHandlePassed = -1;
bool isChunkedUsed = false;
bool failOnCreateGemExtWithMultipleRegions = false;
};
class DrmMemoryManagerFixtureWithoutQuietIoctlExpectation {

View File

@@ -518,6 +518,10 @@ DetectIndirectAccessInKernel = -1
OptimizeIoqBarriersHandling = -1
AllocateSharedAllocationsInHeapExtendedHost = 0
AllocateHostAllocationsInHeapExtendedHost = 1
PrintBOChunkingLogs = 0
EnableBOChunking = 0
EnableBOChunkingPreferredLocationHint = 0
NumberOfBOChunks = 2
DirectSubmissionControllerMaxTimeout = -1
ExitOnSubmissionNumber = -1
ExitOnSubmissionMode = 0

View File

@@ -70,3 +70,11 @@ TEST(DrmBindTest, whenCheckingSetPairAvailabilityThenIoctlHelperSupportIsUsed) {
EXPECT_EQ(drm.isSetPairAvailable(), drm.getIoctlHelper()->isSetPairAvailable());
}
TEST(DrmBindTest, whenCheckingChunkingAvailabilityThenIoctlHelperSupportIsUsed) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.callBaseIsChunkingAvailable = true;
EXPECT_EQ(drm.isChunkingAvailable(), drm.getIoctlHelper()->isChunkingAvailable());
}

View File

@@ -372,7 +372,8 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemWithExtensionsThenRetu
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo, *drm);
ASSERT_NE(nullptr, memoryInfo);
auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks);
EXPECT_EQ(1u, handle);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, drm->ioctlCallsCount);
@@ -437,6 +438,60 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithPairHandleThenR
EXPECT_EQ(2u, drm->ioctlCallsCount);
}
TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithChunkingButSizeLessThanAllowedThenExceptionIsThrown) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(1);
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
auto drm = std::make_unique<DrmQueryMock>(*executionEnvironment->rootDeviceEnvironments[0]);
drm->context.chunkingQueryValue = 1;
drm->context.chunkingQueryReturn = 1;
uint32_t numOfChunks = 2;
size_t allocSize = MemoryConstants::chunkThreshold / (numOfChunks * 2);
uint32_t pairHandle = -1;
uint32_t handle = 0;
bool isChunked = true;
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo, *drm);
ASSERT_NE(nullptr, memoryInfo);
EXPECT_THROW(memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, pairHandle, isChunked, numOfChunks), std::runtime_error);
}
TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithChunkingWithSizeGreaterThanAllowedThenAllocationIsCreatedWithChunking) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(1);
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
auto drm = std::make_unique<DrmQueryMock>(*executionEnvironment->rootDeviceEnvironments[0]);
drm->context.chunkingQueryValue = 1;
drm->context.chunkingQueryReturn = 1;
uint32_t numOfChunks = 2;
size_t allocSize = MemoryConstants::chunkThreshold * numOfChunks * 2;
uint32_t pairHandle = -1;
uint32_t handle = 0;
bool isChunked = true;
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo, *drm);
ASSERT_NE(nullptr, memoryInfo);
auto ret = memoryInfo->createGemExtWithMultipleRegions(1, allocSize, handle, pairHandle, isChunked, numOfChunks);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, drm->ioctlCallsCount);
}
TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportWhenCreatingGemExtWithSingleRegionThenValidVmIdIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(1);
@@ -564,3 +619,72 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithMultipleRegions
EXPECT_EQ(3u, createExt->memoryRegions[2].memoryInstance);
EXPECT_EQ(1024u, drm->context.receivedCreateGemExt->size);
}
TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCallingCreatingGemExtWithMultipleRegionsAndNotAllowedSizeThenExceptionIsThrown) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(1);
std::vector<MemoryRegion> regionInfo(5);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
regionInfo[2].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 1};
regionInfo[2].probedSize = 16 * GB;
regionInfo[3].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 2};
regionInfo[3].probedSize = 16 * GB;
regionInfo[4].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 3};
regionInfo[4].probedSize = 16 * GB;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmQueryMock>(*executionEnvironment->rootDeviceEnvironments[0]);
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo, *drm);
ASSERT_NE(nullptr, memoryInfo);
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);
}
TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCallingCreatingGemExtWithMultipleRegionsAndChunkingThenReturnCorrectValues) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(1);
std::vector<MemoryRegion> regionInfo(5);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
regionInfo[2].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 1};
regionInfo[2].probedSize = 16 * GB;
regionInfo[3].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 2};
regionInfo[3].probedSize = 16 * GB;
regionInfo[4].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 3};
regionInfo[4].probedSize = 16 * GB;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto drm = std::make_unique<DrmQueryMock>(*executionEnvironment->rootDeviceEnvironments[0]);
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo, *drm);
ASSERT_NE(nullptr, memoryInfo);
uint32_t handle = 0;
uint32_t memoryRegions = 0b1011;
uint32_t numOfChunks = 2;
size_t size = MemoryConstants::chunkThreshold * numOfChunks;
auto ret = memoryInfo->createGemExtWithMultipleRegions(memoryRegions, size, handle, -1, true, numOfChunks);
EXPECT_EQ(1u, handle);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, drm->ioctlCallsCount);
const auto &createExt = drm->context.receivedCreateGemExt;
ASSERT_TRUE(createExt);
ASSERT_EQ(3u, createExt->memoryRegions.size());
EXPECT_EQ(drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[0].memoryClass);
EXPECT_EQ(0u, createExt->memoryRegions[0].memoryInstance);
EXPECT_EQ(drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[1].memoryClass);
EXPECT_EQ(1u, createExt->memoryRegions[1].memoryInstance);
EXPECT_EQ(drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[2].memoryClass);
EXPECT_EQ(3u, createExt->memoryRegions[2].memoryInstance);
EXPECT_EQ(size, drm->context.receivedCreateGemExt->size);
}

View File

@@ -235,7 +235,8 @@ HWTEST2_F(MemoryInfoTest, givenMemoryInfoWithRegionsWhenCreatingGemWithExtension
uint32_t handle = 0;
MemRegionsVec memClassInstance = {regionInfo[0].region, regionInfo[1].region};
auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = memoryInfo->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks);
EXPECT_EQ(1u, handle);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, drm->ioctlCallsCount);

View File

@@ -324,6 +324,86 @@ TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, whenCreateUnifiedMemoryAllocationT
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerLocalMemoryPrelimTest,
whenCreateUnifiedMemoryAllocationWithChunkingThenGemCreateExtAndPreferredLocationAreUsed) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(1);
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 1};
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, DrmMockHelper::getEngineOrMemoryInstanceValue(0, 0)};
mock->memoryInfo.reset(new MemoryInfo(regionInfo, *mock));
mock->queryEngineInfo();
mock->ioctlCallsCount = 0;
mock->chunkingAvailable = true;
mock->callBaseIsChunkingAvailable = true;
AllocationProperties gpuProperties{0u,
MemoryConstants::chunkThreshold,
AllocationType::UNIFIED_SHARED_MEMORY,
1u};
gpuProperties.alignment = 2 * MemoryConstants::megaByte;
gpuProperties.usmInitialPlacement = GraphicsAllocation::UsmInitialPlacement::CPU;
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(gpuProperties);
ASSERT_NE(allocation, nullptr);
EXPECT_NE(static_cast<DrmAllocation *>(allocation)->getMmapPtr(), nullptr);
EXPECT_NE(static_cast<DrmAllocation *>(allocation)->getMmapSize(), 0u);
EXPECT_EQ(allocation->getAllocationOffset(), 0u);
const auto &createExt = mock->context.receivedCreateGemExt.value();
EXPECT_EQ(1u, createExt.handle);
const auto &memRegions = createExt.memoryRegions;
ASSERT_EQ(memRegions.size(), 2u);
EXPECT_EQ(memRegions[0].memoryClass, drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM);
EXPECT_EQ(memRegions[0].memoryInstance, 1u);
EXPECT_EQ(memRegions[1].memoryClass, drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE);
EXPECT_EQ(memRegions[1].memoryInstance, regionInfo[1].region.memoryInstance);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerLocalMemoryPrelimTest,
whenCreateUnifiedMemoryAllocationWithChunkingAndNoEnableBOChunkingPreferredLocationHintSetThenGemCreateExtIsUsedWithoutPreferredLocation) {
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 1};
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, DrmMockHelper::getEngineOrMemoryInstanceValue(0, 0)};
mock->memoryInfo.reset(new MemoryInfo(regionInfo, *mock));
mock->queryEngineInfo();
mock->ioctlCallsCount = 0;
mock->chunkingAvailable = true;
mock->callBaseIsChunkingAvailable = true;
AllocationProperties gpuProperties{0u,
MemoryConstants::chunkThreshold,
AllocationType::UNIFIED_SHARED_MEMORY,
1u};
gpuProperties.alignment = 2 * MemoryConstants::megaByte;
gpuProperties.usmInitialPlacement = GraphicsAllocation::UsmInitialPlacement::CPU;
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(gpuProperties);
ASSERT_NE(allocation, nullptr);
EXPECT_NE(static_cast<DrmAllocation *>(allocation)->getMmapPtr(), nullptr);
EXPECT_NE(static_cast<DrmAllocation *>(allocation)->getMmapSize(), 0u);
EXPECT_EQ(allocation->getAllocationOffset(), 0u);
const auto &createExt = mock->context.receivedCreateGemExt.value();
EXPECT_EQ(1u, createExt.handle);
const auto &memRegions = createExt.memoryRegions;
ASSERT_EQ(memRegions.size(), 2u);
EXPECT_EQ(memRegions[0].memoryClass, drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM);
EXPECT_EQ(memRegions[0].memoryInstance, 1u);
EXPECT_EQ(memRegions[1].memoryClass, drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE);
EXPECT_EQ(memRegions[1].memoryInstance, regionInfo[1].region.memoryInstance);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, whenCreateUnifiedMemoryAllocationWithMultiMemoryRegionsThenGemCreateExtIsUsedWithSingleLmemRegions) {
std::vector<MemoryRegion> regionInfo(3);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 1};

View File

@@ -5259,6 +5259,68 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAl
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest,
givenMemoryAllocationWithLessThanChunkingSizeAllowedThenChunkingIsNotUsed) {
VariableBackup<bool> backupChunkingCallParent{&mock->getChunkingAvailableCall.callParent, false};
VariableBackup<bool> backupChunkingReturnValue{&mock->getChunkingAvailableCall.returnValue, true};
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = MemoryConstants::chunkThreshold / 4;
allocData.type = AllocationType::BUFFER;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks = 0b11;
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
EXPECT_NE(nullptr, allocation);
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
EXPECT_EQ(false, static_cast<MockedMemoryInfo *>(mock->getMemoryInfo())->isChunkedUsed);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest,
givenMemoryAllocationWithMoreThanChunkingSizeAllowedThenChunkingIsUsed) {
VariableBackup<bool> backupChunkingCallParent{&mock->getChunkingAvailableCall.callParent, false};
VariableBackup<bool> backupChunkingReturnValue{&mock->getChunkingAvailableCall.returnValue, true};
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = MemoryConstants::chunkThreshold * 2;
allocData.type = AllocationType::BUFFER;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks = 0b11;
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
EXPECT_NE(nullptr, allocation);
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
EXPECT_EQ(true, static_cast<MockedMemoryInfo *>(mock->getMemoryInfo())->isChunkedUsed);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest,
givenMemoryAllocationWithMoreThanChunkingSizeAllowedAndFailGemCreateExtThenNullptrIsReturned) {
VariableBackup<bool> backupChunkingCallParent{&mock->getChunkingAvailableCall.callParent, false};
VariableBackup<bool> backupChunkingReturnValue{&mock->getChunkingAvailableCall.returnValue, true};
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = MemoryConstants::chunkThreshold * 2;
allocData.type = AllocationType::BUFFER;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks = 0b11;
static_cast<MockedMemoryInfo *>(mock->getMemoryInfo())->failOnCreateGemExtWithMultipleRegions = true;
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
EXPECT_EQ(nullptr, allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMemoryAllocationWithNoSetPairAndTwoHandlesThenPairHandleIsPassed) {
VariableBackup<bool> backupSetPairCallParent{&mock->getSetPairAvailableCall.callParent, false};
VariableBackup<bool> backupSetPairReturnValue{&mock->getSetPairAvailableCall.returnValue, false};

View File

@@ -567,6 +567,37 @@ TEST_F(DrmMemoryOperationsHandlerBindTest, givenDrmMemoryOperationBindWhenMakeRe
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryOperationsHandlerBindTest, givenDrmMemoryOperationBindWhenMakeResidentWithChunkingWithinOsContextEvictableAllocationThenAllocationIsNotMarkedAsAlwaysResident) {
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), MemoryConstants::pageSize});
allocation->storageInfo.isChunked = true;
EXPECT_EQ(operationHandler->makeResidentWithinOsContext(device->getDefaultEngine().osContext, ArrayRef<GraphicsAllocation *>(&allocation, 1), false), MemoryOperationsStatus::SUCCESS);
EXPECT_TRUE(allocation->isAlwaysResident(device->getDefaultEngine().osContext->getContextId()));
EXPECT_EQ(operationHandler->evict(device, *allocation), MemoryOperationsStatus::SUCCESS);
EXPECT_EQ(operationHandler->makeResidentWithinOsContext(device->getDefaultEngine().osContext, ArrayRef<GraphicsAllocation *>(&allocation, 1), true), MemoryOperationsStatus::SUCCESS);
EXPECT_FALSE(allocation->isAlwaysResident(device->getDefaultEngine().osContext->getContextId()));
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryOperationsHandlerBindTest, givenDrmMemoryOperationBindWhenMakeResidentWithChunkingAndMultipleBanksWithinOsContextEvictableAllocationThenAllocationIsNotMarkedAsAlwaysResident) {
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), MemoryConstants::pageSize});
allocation->storageInfo.isChunked = true;
allocation->storageInfo.memoryBanks = 0x5;
EXPECT_EQ(operationHandler->makeResidentWithinOsContext(device->getDefaultEngine().osContext, ArrayRef<GraphicsAllocation *>(&allocation, 1), false), MemoryOperationsStatus::SUCCESS);
EXPECT_TRUE(allocation->isAlwaysResident(device->getDefaultEngine().osContext->getContextId()));
EXPECT_EQ(operationHandler->evict(device, *allocation), MemoryOperationsStatus::SUCCESS);
EXPECT_EQ(operationHandler->makeResidentWithinOsContext(device->getDefaultEngine().osContext, ArrayRef<GraphicsAllocation *>(&allocation, 1), true), MemoryOperationsStatus::SUCCESS);
EXPECT_FALSE(allocation->isAlwaysResident(device->getDefaultEngine().osContext->getContextId()));
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryOperationsHandlerBindTest, givenDrmMemoryOperationBindWhenChangingResidencyThenOperationIsHandledProperly) {
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), MemoryConstants::pageSize});
@@ -1358,6 +1389,20 @@ TEST(DrmSetPairTests, whenQueryingForSetPairAvailableAndNoDebugKeyThenFalseIsRet
EXPECT_EQ(0u, drm.context.setPairQueryCalled);
}
TEST(DrmChunkingTests, whenQueryingForChunkingAvailableAndNoDebugKeyThenFalseIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.context.chunkingQueryValue = 0;
drm.context.chunkingQueryReturn = 0;
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
drm.callBaseIsChunkingAvailable = true;
EXPECT_FALSE(drm.isChunkingAvailable());
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
}
TEST(DrmSetPairTests, whenQueryingForSetPairAvailableAndDebugKeySetAndNoSupportAvailableThenFalseIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableSetPair.set(1);
@@ -1472,3 +1517,54 @@ TEST(DrmResidencyHandlerTests, whenQueryingForSetPairAvailableWithDebugKeySetToZ
EXPECT_FALSE(drm.setPairAvailable);
EXPECT_EQ(0u, drm.context.setPairQueryCalled);
}
TEST(DrmResidencyHandlerTests, whenQueryingForChunkingAvailableAndSupportAvailableThenExpectedValueIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableBOChunking.set(1);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.context.chunkingQueryValue = 1;
drm.context.chunkingQueryReturn = 0;
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
drm.callBaseIsChunkingAvailable = true;
EXPECT_TRUE(drm.isChunkingAvailable());
EXPECT_TRUE(drm.chunkingAvailable);
EXPECT_EQ(1u, drm.context.chunkingQueryCalled);
}
TEST(DrmResidencyHandlerTests, whenQueryingForChunkingAvailableAndFailureInQueryThenFalseIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableBOChunking.set(1);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.context.chunkingQueryValue = 1;
drm.context.chunkingQueryReturn = 1;
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
drm.callBaseIsChunkingAvailable = true;
EXPECT_FALSE(drm.isChunkingAvailable());
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(1u, drm.context.chunkingQueryCalled);
}
TEST(DrmResidencyHandlerTests, whenQueryingForChunkingAvailableWithDebugKeySetToZeroThenFalseIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableBOChunking.set(0);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.context.chunkingQueryValue = 1;
drm.context.chunkingQueryReturn = 1;
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
drm.callBaseIsChunkingAvailable = true;
EXPECT_FALSE(drm.isChunkingAvailable());
EXPECT_FALSE(drm.chunkingAvailable);
EXPECT_EQ(0u, drm.context.chunkingQueryCalled);
}

View File

@@ -61,6 +61,35 @@ TEST(DrmVmBindTest, givenBoRequiringExplicitResidencyWhenBindingThenMakeResident
}
}
TEST(DrmVmBindTest,
givenBoWithChunkingRequiringExplicitResidencyWhenBindingThenMakeResidentFlagIsNotPassedAndUserFenceIsSetup) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->initializeMemoryManager();
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
drm.pageFaultSupported = true;
for (auto requireResidency : {false, true}) {
MockBufferObject bo(0, &drm, 3, 0, 0, 1);
bo.isChunked = true;
bo.requireExplicitResidency(requireResidency);
OsContextLinux osContext(drm, 0, 0u, EngineDescriptorHelper::getDefaultDescriptor());
osContext.ensureContextInitialized();
uint32_t vmHandleId = 0;
bo.bind(&osContext, vmHandleId);
if (requireResidency) {
EXPECT_EQ(DrmPrelimHelper::getImmediateVmBindFlag(), drm.context.receivedVmBind->flags);
ASSERT_TRUE(drm.context.receivedVmBindUserFence);
EXPECT_EQ(castToUint64(drm.getFenceAddr(vmHandleId)), drm.context.receivedVmBindUserFence->addr);
EXPECT_EQ(drm.fenceVal[vmHandleId], drm.context.receivedVmBindUserFence->val);
} else {
EXPECT_EQ(DrmPrelimHelper::getImmediateVmBindFlag(), drm.context.receivedVmBind->flags);
}
}
}
TEST(DrmVmBindTest, givenPerContextVmsAndBoRequiringExplicitResidencyWhenBindingThenPagingFenceFromContextIsUsed) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->rootDeviceEnvironments[0]->initGmm();

View File

@@ -136,13 +136,45 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtThenReturnSuccess)
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks);
EXPECT_EQ(1u, handle);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, drm->ioctlCallsCount);
}
TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithChunkingThenGetNumOfChunks) {
DebugManagerStateRestore stateRestore;
DebugManager.flags.PrintBOChunkingLogs.set(true);
DebugManager.flags.NumberOfBOChunks.set(2);
size_t allocSize = 2 * MemoryConstants::pageSize64k;
testing::internal::CaptureStdout();
auto ioctlHelper = drm->getIoctlHelper();
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);
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);
EXPECT_EQ(2u, getNumOfChunks);
}
TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithChunkingAndAllocTooSmallThenExceptionThrown) {
DebugManagerStateRestore stateRestore;
DebugManager.flags.PrintBOChunkingLogs.set(false);
DebugManager.flags.NumberOfBOChunks.set(2);
size_t allocSize = MemoryConstants::pageSize64k;
auto ioctlHelper = drm->getIoctlHelper();
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);
}
TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithDebugFlagThenPrintDebugInfo) {
DebugManagerStateRestore stateRestore;
DebugManager.flags.PrintBOCreateDestroyResult.set(true);
@@ -151,7 +183,8 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithDebugFlagThenPr
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -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");
@@ -252,6 +285,28 @@ TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseFailsThenDont
EXPECT_NE(memAdviseFlags.allFlags, allocation.enabledMemAdviseFlags.allFlags);
}
TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseForChunkingFailsThenDontUpdateMemAdviceFlags) {
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
drm->ioctlCallsCount = 0;
drm->ioctlRetVal = -1;
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);
MockDrmAllocation allocation(0u, AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
MemAdviseFlags memAdviseFlags{};
memAdviseFlags.nonAtomic = 1;
allocation.storageInfo.isChunked = 1;
allocation.setMemAdvise(drm.get(), memAdviseFlags);
EXPECT_EQ(1u, drm->ioctlCallsCount);
EXPECT_NE(memAdviseFlags.allFlags, allocation.enabledMemAdviseFlags.allFlags);
}
TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseWithNonAtomicIsCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);
drm->ioctlCallsCount = 0;
@@ -288,6 +343,102 @@ TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseWithDevicePre
EXPECT_EQ(2u, drm->ioctlCallsCount);
}
TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseWithChunkingPreferredLocationIsCalledThenUpdateTheCorrespondingVmAdviceForBufferChunks) {
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
std::vector<MemoryRegion> memRegions{
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 1}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 2}, MemoryConstants::chunkThreshold * 4, 0}};
drm->memoryInfo.reset(new MemoryInfo(memRegions, *drm));
drm->ioctlCallsCount = 0;
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);
MockDrmAllocation allocation(0u, AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
allocation.storageInfo.memoryBanks = 0x1;
allocation.setNumHandles(1);
allocation.storageInfo.isChunked = 1;
allocation.storageInfo.numOfChunks = 4;
MemAdviseFlags memAdviseFlags{};
for (auto devicePreferredLocation : {true, false}) {
memAdviseFlags.devicePreferredLocation = devicePreferredLocation;
EXPECT_TRUE(allocation.setMemAdvise(drm.get(), memAdviseFlags));
EXPECT_EQ(memAdviseFlags.allFlags, allocation.enabledMemAdviseFlags.allFlags);
}
EXPECT_EQ(allocation.storageInfo.numOfChunks * 2, drm->ioctlCallsCount);
}
TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemAdviseWithChunkingButWithoutEnableBOChunkingPreferredLocationHintCalledThenUpdateTheCorrespondingVmAdviceForBufferObject) {
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(0);
std::vector<MemoryRegion> memRegions{
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 1}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 2}, MemoryConstants::chunkThreshold * 4, 0}};
drm->memoryInfo.reset(new MemoryInfo(memRegions, *drm));
drm->ioctlCallsCount = 0;
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);
MockDrmAllocation allocation(0u, AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
allocation.storageInfo.memoryBanks = 0x1;
allocation.setNumHandles(1);
allocation.storageInfo.isChunked = 1;
allocation.storageInfo.numOfChunks = 4;
MemAdviseFlags memAdviseFlags{};
for (auto devicePreferredLocation : {true, false}) {
memAdviseFlags.devicePreferredLocation = devicePreferredLocation;
EXPECT_TRUE(allocation.setMemAdvise(drm.get(), memAdviseFlags));
EXPECT_EQ(memAdviseFlags.allFlags, allocation.enabledMemAdviseFlags.allFlags);
}
EXPECT_EQ(2u, drm->ioctlCallsCount);
}
TEST_F(IoctlHelperPrelimFixture,
givenDrmAllocationWhenSetMemAdviseWithChunkingPreferredLocationIsCalledWithFailureThenReturnFalse) {
drm->ioctlRetVal = -1;
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
std::vector<MemoryRegion> memRegions{
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 1}, MemoryConstants::chunkThreshold * 4, 0},
{{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 2}, MemoryConstants::chunkThreshold * 4, 0}};
drm->memoryInfo.reset(new MemoryInfo(memRegions, *drm));
drm->ioctlCallsCount = 0;
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);
MockDrmAllocation allocation(0u, AllocationType::BUFFER, MemoryPool::LocalMemory);
allocation.bufferObjects[0] = &bo;
allocation.storageInfo.memoryBanks = 0x5;
allocation.setNumHandles(1);
allocation.storageInfo.isChunked = 1;
allocation.storageInfo.numOfChunks = 4;
MemAdviseFlags memAdviseFlags{};
memAdviseFlags.devicePreferredLocation = true;
EXPECT_FALSE(allocation.setMemAdvise(drm.get(), memAdviseFlags));
EXPECT_EQ(allocation.storageInfo.numOfChunks, drm->ioctlCallsCount);
}
TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemPrefetchSucceedsThenReturnTrue) {
SubDeviceIdsVec subDeviceIds{0};
MockBufferObject bo(0u, drm.get(), 3, 0, 0, 1);

View File

@@ -27,7 +27,8 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtThenReturnCorrectValue) {
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, handle);
@@ -48,7 +49,8 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WithDrmTipWhenCreateGemExtWithDebugFlagTh
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -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");
@@ -69,7 +71,8 @@ DG1TEST_F(IoctlHelperTestsDg1, givenDg1WhenCreateGemExtWithDebugFlagThenPrintDeb
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -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");

View File

@@ -218,7 +218,8 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtThenReturnCorrectVal
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
auto ret = ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1, false, numOfChunks);
EXPECT_EQ(0, ret);
EXPECT_EQ(1u, handle);
@@ -238,7 +239,8 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenCreateGemExtWithDebugFlagThenPri
auto ioctlHelper = drm->getIoctlHelper();
uint32_t handle = 0;
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -1);
uint32_t numOfChunks = 0;
ioctlHelper->createGemExt(memClassInstance, 1024, handle, {}, -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");

View File

@@ -62,6 +62,43 @@ TEST(IoctlHelperXeTest, whenChangingBufferBindingThenWaitIsNeededAlways) {
EXPECT_TRUE(ioctlHelper.isWaitBeforeBindRequired(false));
}
TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGemCreateExtWithRegionsThenDummyValueIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<IoctlHelperXe>(drm);
ASSERT_NE(nullptr, xeIoctlHelper);
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
MemRegionsVec memRegions = {regionInfo[0].region, regionInfo[1].region};
uint32_t handle = 0u;
uint32_t numOfChunks = 0;
EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, {}, -1, false, numOfChunks));
}
TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingGemCreateExtWithRegionsAndVmIdThenDummyValueIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
auto xeIoctlHelper = std::make_unique<IoctlHelperXe>(drm);
ASSERT_NE(nullptr, xeIoctlHelper);
std::vector<MemoryRegion> regionInfo(2);
regionInfo[0].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM, 0};
regionInfo[0].probedSize = 8 * GB;
regionInfo[1].region = {drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0};
regionInfo[1].probedSize = 16 * GB;
MemRegionsVec memRegions = {regionInfo[0].region, regionInfo[1].region};
uint32_t handle = 0u;
uint32_t numOfChunks = 0;
GemVmControl test = {};
EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, test.vmId, -1, false, numOfChunks));
}
TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
@@ -82,7 +119,8 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe
MemRegionsVec memRegions{};
uint32_t handle = 0u;
EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, {}, -1));
uint32_t numOfChunks = 0;
EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, 0u, handle, {}, -1, false, numOfChunks));
EXPECT_TRUE(xeIoctlHelper->isVmBindAvailable());
@@ -104,6 +142,10 @@ TEST(IoctlHelperXeTest, givenIoctlHelperXeWhenCallingAnyMethodThenDummyValueIsRe
EXPECT_FALSE(xeIoctlHelper->setVmBoAdvise(0, 0, nullptr));
EXPECT_FALSE(xeIoctlHelper->setVmBoAdviseForChunking(0, 0, 0, 0, nullptr));
EXPECT_FALSE(xeIoctlHelper->isChunkingAvailable());
EXPECT_FALSE(xeIoctlHelper->setVmPrefetch(0, 0, 0, 0));
EXPECT_EQ(0u, xeIoctlHelper->getDirectSubmissionFlag());