Restrict system memory allocations to certain address range

Change-Id: Ibe8c1183368ce48f2c820d0f1a71f0b15703ffcd
This commit is contained in:
Zdanowicz, Zbigniew
2018-01-22 16:43:26 +01:00
parent 3532c6373f
commit e42d43953d
19 changed files with 297 additions and 27 deletions

View File

@@ -564,6 +564,7 @@ if (WIN32)
os_interface/windows/wddm_engine_mapper.inl os_interface/windows/wddm_engine_mapper.inl
os_interface/windows/wddm_memory_manager.cpp os_interface/windows/wddm_memory_manager.cpp
os_interface/windows/wddm_memory_manager.h os_interface/windows/wddm_memory_manager.h
os_interface/windows/windows_defs.h
os_interface/windows/windows_inc.cpp os_interface/windows/windows_inc.cpp
os_interface/windows/windows_wrapper.h os_interface/windows/windows_wrapper.h
os_interface/windows/performance_counters_win.cpp os_interface/windows/performance_counters_win.cpp

View File

@@ -94,14 +94,13 @@ Device::~Device() {
preemptionAllocation = nullptr; preemptionAllocation = nullptr;
} }
memoryManager->waitForDeletions(); memoryManager->waitForDeletions();
}
if (memoryManager) {
memoryManager->freeGraphicsMemory(tagAllocation); memoryManager->freeGraphicsMemory(tagAllocation);
alignedFree(this->slmWindowStartAddress);
} }
tagAllocation = nullptr; tagAllocation = nullptr;
delete memoryManager; delete memoryManager;
memoryManager = nullptr; memoryManager = nullptr;
alignedFree(this->slmWindowStartAddress);
} }
bool Device::createDeviceImpl(const HardwareInfo *pHwInfo, bool Device::createDeviceImpl(const HardwareInfo *pHwInfo,

View File

@@ -52,6 +52,10 @@ class GmmMemoryBase {
: false; : false;
} }
MOCKABLE_VIRTUAL uintptr_t getInternalGpuVaRangeLimit() {
return static_cast<uintptr_t>(pGmmGlobalContext->GetInternalGpuVaRangeLimit());
}
protected: protected:
GmmMemoryBase() = default; GmmMemoryBase() = default;
}; };

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,7 @@
#include "runtime/gmm_helper/gmm_helper.h" #include "runtime/gmm_helper/gmm_helper.h"
#include "runtime/gmm_helper/resource_info.h" #include "runtime/gmm_helper/resource_info.h"
#include "runtime/memory_manager/deferred_deleter.h" #include "runtime/memory_manager/deferred_deleter.h"
#include "runtime/memory_manager/memory_manager.h"
#include "runtime/event/event.h" #include "runtime/event/event.h"
#include "runtime/helpers/aligned_memory.h" #include "runtime/helpers/aligned_memory.h"
#include "runtime/helpers/basic_math.h" #include "runtime/helpers/basic_math.h"
@@ -73,8 +74,35 @@ MemoryManager::~MemoryManager() {
void *MemoryManager::allocateSystemMemory(size_t size, size_t alignment) { void *MemoryManager::allocateSystemMemory(size_t size, size_t alignment) {
// Establish a minimum alignment of 16bytes. // Establish a minimum alignment of 16bytes.
const size_t minAlignment = 16; constexpr size_t minAlignment = 16;
return alignedMalloc(size, std::max(alignment, minAlignment)); alignment = std::max(alignment, minAlignment);
auto restrictions = getAlignedMallocRestrictions();
void *ptr = nullptr;
ptr = alignedMallocWrapper(size, alignment);
if (restrictions == nullptr) {
return ptr;
} else if (restrictions->minAddress == 0) {
return ptr;
} else {
if (restrictions->minAddress > reinterpret_cast<uintptr_t>(ptr) && ptr != nullptr) {
StackVec<void *, 100> invalidMemVector;
invalidMemVector.push_back(ptr);
do {
ptr = alignedMallocWrapper(size, alignment);
if (restrictions->minAddress > reinterpret_cast<uintptr_t>(ptr) && ptr != nullptr) {
invalidMemVector.push_back(ptr);
} else {
break;
}
} while (1);
for (auto &it : invalidMemVector) {
alignedFreeWrapper(it);
}
}
}
return ptr;
} }
GraphicsAllocation *MemoryManager::allocateGraphicsMemoryForSVM(size_t size, bool coherent) { GraphicsAllocation *MemoryManager::allocateGraphicsMemoryForSVM(size_t size, bool coherent) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -25,7 +25,7 @@
#include "runtime/memory_manager/host_ptr_manager.h" #include "runtime/memory_manager/host_ptr_manager.h"
#include "runtime/memory_manager/graphics_allocation.h" #include "runtime/memory_manager/graphics_allocation.h"
#include "runtime/os_interface/32bit_memory.h" #include "runtime/os_interface/32bit_memory.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/utilities/tag_allocator_base.h" #include "runtime/utilities/tag_allocator_base.h"
#include <cstdint> #include <cstdint>
@@ -56,6 +56,10 @@ enum allocationType {
REUSABLE_ALLOCATION REUSABLE_ALLOCATION
}; };
struct AlignedMallocRestrictions {
uintptr_t minAddress;
};
constexpr size_t paddingBufferSize = 2 * MemoryConstants::megaByte; constexpr size_t paddingBufferSize = 2 * MemoryConstants::megaByte;
class AllocationsList : public IDList<GraphicsAllocation, true, true> { class AllocationsList : public IDList<GraphicsAllocation, true, true> {
@@ -207,6 +211,18 @@ class MemoryManager {
bool isAsyncDeleterEnabled() const; bool isAsyncDeleterEnabled() const;
virtual bool isMemoryBudgetExhausted() const; virtual bool isMemoryBudgetExhausted() const;
virtual AlignedMallocRestrictions *getAlignedMallocRestrictions() {
return nullptr;
}
MOCKABLE_VIRTUAL void *alignedMallocWrapper(size_t bytes, size_t alignment) {
return ::alignedMalloc(bytes, alignment);
}
MOCKABLE_VIRTUAL void alignedFreeWrapper(void *ptr) {
::alignedFree(ptr);
}
protected: protected:
std::recursive_mutex mtx; std::recursive_mutex mtx;
std::unique_ptr<TagAllocatorBase> profilingTimeStampAllocator; std::unique_ptr<TagAllocatorBase> profilingTimeStampAllocator;

View File

@@ -57,7 +57,7 @@ GraphicsAllocation *OsAgnosticMemoryManager::allocateGraphicsMemory(size_t size,
if (ptr != nullptr) { if (ptr != nullptr) {
memoryAllocation = new MemoryAllocation(true, 1, ptr, reinterpret_cast<uint64_t>(ptr), size, counter); memoryAllocation = new MemoryAllocation(true, 1, ptr, reinterpret_cast<uint64_t>(ptr), size, counter);
if (!memoryAllocation) { if (!memoryAllocation) {
alignedFree(ptr); alignedFreeWrapper(ptr);
return nullptr; return nullptr;
} }
memoryAllocation->uncacheable = uncacheable; memoryAllocation->uncacheable = uncacheable;
@@ -93,7 +93,7 @@ GraphicsAllocation *OsAgnosticMemoryManager::allocate32BitGraphicsMemory(size_t
void *ptrAlloc = nullptr; void *ptrAlloc = nullptr;
if (size < 0xfffff000) if (size < 0xfffff000)
ptrAlloc = alignedMalloc(allocationSize, MemoryConstants::allocationAlignment); ptrAlloc = alignedMallocWrapper(allocationSize, MemoryConstants::allocationAlignment);
void *gpuPointer = allocator32Bit->allocate(allocationSize); void *gpuPointer = allocator32Bit->allocate(allocationSize);
DEBUG_BREAK_IF(allocationMap.find(ptrAlloc) != allocationMap.end()); DEBUG_BREAK_IF(allocationMap.find(ptrAlloc) != allocationMap.end());
@@ -153,10 +153,10 @@ void OsAgnosticMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllo
if (is32BitAllocation) { if (is32BitAllocation) {
allocator32Bit->free(gpuPtrToFree, sizeToFree); allocator32Bit->free(gpuPtrToFree, sizeToFree);
if (freeMemory) { if (freeMemory) {
::alignedFree(ptr); alignedFreeWrapper(ptr);
} }
} else if (freeMemory) { } else if (freeMemory) {
::alignedFree(ptr); alignedFreeWrapper(ptr);
} }
delete gfxAllocation; delete gfxAllocation;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -21,7 +21,6 @@
*/ */
#include "runtime/device/device.h" #include "runtime/device/device.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/helpers/ptr_math.h" #include "runtime/helpers/ptr_math.h"
#include "runtime/helpers/options.h" #include "runtime/helpers/options.h"
#include "runtime/os_interface/32bit_memory.h" #include "runtime/os_interface/32bit_memory.h"
@@ -50,13 +49,13 @@ DrmMemoryManager::DrmMemoryManager(Drm *drm, gemCloseWorkerMode mode, bool force
} }
if (forcePinAllowed) { if (forcePinAllowed) {
auto mem = ::alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize); auto mem = alignedMallocWrapper(MemoryConstants::pageSize, MemoryConstants::pageSize);
DEBUG_BREAK_IF(mem == nullptr); DEBUG_BREAK_IF(mem == nullptr);
pinBB = allocUserptr(reinterpret_cast<uintptr_t>(mem), MemoryConstants::pageSize, 0, true); pinBB = allocUserptr(reinterpret_cast<uintptr_t>(mem), MemoryConstants::pageSize, 0, true);
if (!pinBB) { if (!pinBB) {
::alignedFree(mem); alignedFreeWrapper(mem);
} else { } else {
pinBB->isAllocated = true; pinBB->isAllocated = true;
} }
@@ -129,7 +128,7 @@ uint32_t DrmMemoryManager::unreference(OCLRT::BufferObject *bo, bool synchronous
} }
} else { } else {
::alignedFree(address); alignedFreeWrapper(address);
} }
} }
} }
@@ -174,7 +173,7 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemory(size_t size, size_t alig
// It's needed to prevent overlapping pages with user pointers // It's needed to prevent overlapping pages with user pointers
size_t cSize = std::max(alignUp(size, minAlignment), minAlignment); size_t cSize = std::max(alignUp(size, minAlignment), minAlignment);
auto res = ::alignedMalloc(cSize, cAlignment); auto res = alignedMallocWrapper(cSize, cAlignment);
if (!res) if (!res)
return nullptr; return nullptr;
@@ -182,7 +181,7 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemory(size_t size, size_t alig
BufferObject *bo = allocUserptr(reinterpret_cast<uintptr_t>(res), cSize, 0, true); BufferObject *bo = allocUserptr(reinterpret_cast<uintptr_t>(res), cSize, 0, true);
if (!bo) { if (!bo) {
::alignedFree(res); alignedFreeWrapper(res);
return nullptr; return nullptr;
} }

View File

@@ -67,6 +67,7 @@ Wddm::Wddm(Gdi *gdi) : initialized(false),
maximumApplicationAddress = 0; maximumApplicationAddress = 0;
node = GPUNODE_3D; node = GPUNODE_3D;
gmmMemory = std::unique_ptr<GmmMemory>(GmmMemory::create()); gmmMemory = std::unique_ptr<GmmMemory>(GmmMemory::create());
minAddress = 0;
} }
Wddm::Wddm() : Wddm(new Gdi()) { Wddm::Wddm() : Wddm(new Gdi()) {

View File

@@ -22,6 +22,7 @@
#pragma once #pragma once
#include "runtime/os_interface/windows/windows_wrapper.h" #include "runtime/os_interface/windows/windows_wrapper.h"
#include "runtime/os_interface/windows/windows_defs.h"
#include "umKmInc/sharedata.h" #include "umKmInc/sharedata.h"
#include "runtime/helpers/debug_helpers.h" #include "runtime/helpers/debug_helpers.h"
#include <d3d9types.h> #include <d3d9types.h>
@@ -183,6 +184,10 @@ class Wddm {
void initPageTableManagerRegisters(LinearStream &stream); void initPageTableManagerRegisters(LinearStream &stream);
bool updateAuxTable(D3DGPU_VIRTUAL_ADDRESS gpuVa, Gmm *gmm, bool map); bool updateAuxTable(D3DGPU_VIRTUAL_ADDRESS gpuVa, Gmm *gmm, bool map);
uintptr_t getWddmMinAddress() {
return this->minAddress;
}
protected: protected:
bool initialized; bool initialized;
bool gdiAllocated; bool gdiAllocated;
@@ -208,6 +213,7 @@ class Wddm {
uintptr_t maximumApplicationAddress; uintptr_t maximumApplicationAddress;
GPUNODE_ORDINAL node; GPUNODE_ORDINAL node;
std::unique_ptr<GmmMemory> gmmMemory; std::unique_ptr<GmmMemory> gmmMemory;
uintptr_t minAddress;
MOCKABLE_VIRTUAL bool mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, uint64_t size, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32bit, bool use64kbPages); MOCKABLE_VIRTUAL bool mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, uint64_t size, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32bit, bool use64kbPages);
MOCKABLE_VIRTUAL bool openAdapter(); MOCKABLE_VIRTUAL bool openAdapter();

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -30,6 +30,7 @@ bool Wddm::configureDeviceAddressSpace() {
SYSTEM_INFO sysInfo; SYSTEM_INFO sysInfo;
Wddm::getSystemInfo(&sysInfo); Wddm::getSystemInfo(&sysInfo);
maximumApplicationAddress = reinterpret_cast<uintptr_t>(sysInfo.lpMaximumApplicationAddress); maximumApplicationAddress = reinterpret_cast<uintptr_t>(sysInfo.lpMaximumApplicationAddress);
minAddress = windowsMinAddress;
return gmmMemory->configureDeviceAddressSpace(adapter, device, gdi->escape, return gmmMemory->configureDeviceAddressSpace(adapter, device, gdi->escape,
maximumApplicationAddress + 1u, maximumApplicationAddress + 1u,
0, 0, adapterInfo->SkuTable.FtrL3IACoherency, 0, 0); 0, 0, adapterInfo->SkuTable.FtrL3IACoherency, 0, 0);

View File

@@ -55,6 +55,7 @@ WddmMemoryManager::WddmMemoryManager(bool enable64kbPages, Wddm *wddm) : MemoryM
asyncDeleterEnabled = DebugManager.flags.EnableDeferredDeleter.get(); asyncDeleterEnabled = DebugManager.flags.EnableDeferredDeleter.get();
if (asyncDeleterEnabled) if (asyncDeleterEnabled)
deferredDeleter = createDeferredDeleter(); deferredDeleter = createDeferredDeleter();
mallocRestrictions.minAddress = wddm->getWddmMinAddress();
} }
void APIENTRY WddmMemoryManager::trimCallback(_Inout_ D3DKMT_TRIMNOTIFICATION *trimNotification) { void APIENTRY WddmMemoryManager::trimCallback(_Inout_ D3DKMT_TRIMNOTIFICATION *trimNotification) {
@@ -309,7 +310,7 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
} }
auto status = tryDeferDeletions(allocationHandles, allocationCount, input->getResidencyData().lastFence, resourceHandle); auto status = tryDeferDeletions(allocationHandles, allocationCount, input->getResidencyData().lastFence, resourceHandle);
DEBUG_BREAK_IF(!status); DEBUG_BREAK_IF(!status);
::alignedFree(cpuPtr); alignedFreeWrapper(cpuPtr);
wddm->releaseGpuPtr(gpuPtr); wddm->releaseGpuPtr(gpuPtr);
} }
delete gfxAllocation; delete gfxAllocation;
@@ -747,4 +748,9 @@ bool WddmMemoryManager::trimResidencyToBudget(uint64_t bytes) {
bool WddmMemoryManager::mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) { bool WddmMemoryManager::mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) {
return wddm->updateAuxTable(graphicsAllocation->getGpuAddress(), graphicsAllocation->gmm, true); return wddm->updateAuxTable(graphicsAllocation->getGpuAddress(), graphicsAllocation->gmm, true);
} }
AlignedMallocRestrictions *WddmMemoryManager::getAlignedMallocRestrictions() {
return &mallocRestrictions;
}
} // namespace OCLRT } // namespace OCLRT

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -85,6 +85,8 @@ class WddmMemoryManager : public MemoryManager {
bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) override; bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) override;
AlignedMallocRestrictions *getAlignedMallocRestrictions() override;
protected: protected:
GraphicsAllocation *createAllocationFromHandle(osHandle handle, bool requireSpecificBitness, bool ntHandle); GraphicsAllocation *createAllocationFromHandle(osHandle handle, bool requireSpecificBitness, bool ntHandle);
WddmAllocation *getTrimCandidateHead() { WddmAllocation *getTrimCandidateHead() {
@@ -113,6 +115,7 @@ class WddmMemoryManager : public MemoryManager {
uint64_t lastPeriodicTrimFenceValue = 0; uint64_t lastPeriodicTrimFenceValue = 0;
uint32_t trimCandidatesCount = 0; uint32_t trimCandidatesCount = 0;
bool memoryBudgetExhausted = false; bool memoryBudgetExhausted = false;
AlignedMallocRestrictions mallocRestrictions;
private: private:
Wddm *wddm; Wddm *wddm;

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
namespace OCLRT {
constexpr uintptr_t windowsMinAddress = 0x200000;
} // namespace OCLRT

View File

@@ -1431,3 +1431,140 @@ TEST_F(MemoryManagerWithCsrTest, givenAllocationThatWasUsedAndIsNotCompletedWhen
//change task count so cleanup will not clear alloc in use //change task count so cleanup will not clear alloc in use
usedAllocationAndNotGpuCompleted->taskCount = ObjectNotUsed; usedAllocationAndNotGpuCompleted->taskCount = ObjectNotUsed;
} }
class MockAlignMallocMemoryManager : public MockMemoryManager {
public:
MockAlignMallocMemoryManager() : MockMemoryManager() {
testMallocRestrictions.minAddress = 0;
alignMallocRestrictions = nullptr;
alignMallocCount = 0;
alignMallocMaxIter = 3;
returnNullBad = false;
returnNullGood = false;
}
AlignedMallocRestrictions testMallocRestrictions;
AlignedMallocRestrictions *alignMallocRestrictions;
static const uintptr_t alignMallocMinAddress = 0x100000;
static const uintptr_t alignMallocStep = 10;
int alignMallocMaxIter;
int alignMallocCount;
bool returnNullBad;
bool returnNullGood;
void *alignedMallocWrapper(size_t size, size_t align) override {
if (alignMallocCount < alignMallocMaxIter) {
alignMallocCount++;
if (!returnNullBad) {
return reinterpret_cast<void *>(alignMallocMinAddress - alignMallocStep);
} else {
return nullptr;
}
}
alignMallocCount = 0;
if (!returnNullGood) {
return reinterpret_cast<void *>(alignMallocMinAddress + alignMallocStep);
} else {
return nullptr;
}
};
void alignedFreeWrapper(void *) override {
alignMallocCount = 0;
}
AlignedMallocRestrictions *getAlignedMallocRestrictions() override {
return alignMallocRestrictions;
}
};
class MockAlignMallocMemoryManagerTest : public MemoryAllocatorTest {
public:
MockAlignMallocMemoryManager *alignedMemoryManager = nullptr;
void SetUp() override {
MemoryAllocatorTest::SetUp();
alignedMemoryManager = new (std::nothrow) MockAlignMallocMemoryManager();
//assert we have memory manager
ASSERT_NE(nullptr, memoryManager);
}
void TearDown() override {
alignedMemoryManager->alignedFreeWrapper(nullptr);
delete alignedMemoryManager;
MemoryAllocatorTest::TearDown();
}
};
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWhenNullAlignRestrictionsThenNotUseRestrictions) {
EXPECT_EQ(nullptr, memoryManager->getAlignedMallocRestrictions());
EXPECT_EQ(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
uintptr_t expectedVal = MockAlignMallocMemoryManager::alignMallocMinAddress - MockAlignMallocMemoryManager::alignMallocStep;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWhenZeroAlignRestrictionsThenNotUseRestrictions) {
alignedMemoryManager->alignMallocRestrictions = &alignedMemoryManager->testMallocRestrictions;
EXPECT_NE(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
alignedMemoryManager->alignMallocCount = 0;
uintptr_t expectedVal = MockAlignMallocMemoryManager::alignMallocMinAddress - MockAlignMallocMemoryManager::alignMallocStep;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
alignedMemoryManager->alignMallocCount = alignedMemoryManager->alignMallocMaxIter + 1;
expectedVal = MockAlignMallocMemoryManager::alignMallocMinAddress + MockAlignMallocMemoryManager::alignMallocStep;
memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWitNonZeroAlignRestrictionsWhenFirstGoodAddressThenUseRestrictionsAndReturnFirst) {
alignedMemoryManager->alignMallocRestrictions = &alignedMemoryManager->testMallocRestrictions;
alignedMemoryManager->testMallocRestrictions.minAddress = MockAlignMallocMemoryManager::alignMallocMinAddress;
EXPECT_NE(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
alignedMemoryManager->alignMallocCount = alignedMemoryManager->alignMallocMaxIter + 1;
uintptr_t expectedVal = MockAlignMallocMemoryManager::alignMallocMinAddress + MockAlignMallocMemoryManager::alignMallocStep;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWitNonZeroAlignRestrictionsWhenFirstNullAddressThenUseRestrictionsAndReturnFirstNull) {
alignedMemoryManager->alignMallocRestrictions = &alignedMemoryManager->testMallocRestrictions;
alignedMemoryManager->testMallocRestrictions.minAddress = MockAlignMallocMemoryManager::alignMallocMinAddress;
EXPECT_NE(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
alignedMemoryManager->alignMallocCount = alignedMemoryManager->alignMallocMaxIter + 1;
alignedMemoryManager->returnNullGood = true;
uintptr_t expectedVal = 0;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWitNonZeroAlignRestrictionsWhenFirstBadAnotherGoodAddressThenUseRestrictionsAndReturnAnother) {
alignedMemoryManager->alignMallocRestrictions = &alignedMemoryManager->testMallocRestrictions;
alignedMemoryManager->testMallocRestrictions.minAddress = MockAlignMallocMemoryManager::alignMallocMinAddress;
EXPECT_NE(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
alignedMemoryManager->alignMallocCount = 0;
uintptr_t expectedVal = MockAlignMallocMemoryManager::alignMallocMinAddress + MockAlignMallocMemoryManager::alignMallocStep;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}
TEST_F(MockAlignMallocMemoryManagerTest, givenMemoryManagerWitNonZeroAlignRestrictionsWhenFirstBadAnotherNullAddressThenUseRestrictionsAndReturnNull) {
alignedMemoryManager->alignMallocRestrictions = &alignedMemoryManager->testMallocRestrictions;
alignedMemoryManager->testMallocRestrictions.minAddress = MockAlignMallocMemoryManager::alignMallocMinAddress;
EXPECT_NE(nullptr, alignedMemoryManager->getAlignedMallocRestrictions());
alignedMemoryManager->alignMallocCount = 0;
alignedMemoryManager->returnNullGood = true;
uintptr_t expectedVal = 0;
uintptr_t memVal = reinterpret_cast<uintptr_t>(alignedMemoryManager->allocateSystemMemory(0x1000, 0x1000));
EXPECT_EQ(expectedVal, memVal);
}

View File

@@ -21,6 +21,7 @@
*/ */
#include "mock_gmm_memory.h" #include "mock_gmm_memory.h"
#include "runtime/os_interface/windows/windows_defs.h"
using namespace ::testing; using namespace ::testing;
@@ -34,7 +35,9 @@ GmmMemory *GmmMemory::create() {
if (MockGmmMemory::MockGmmMemoryFlag == MockGmmMemory::MockType::MockDummy) { if (MockGmmMemory::MockGmmMemoryFlag == MockGmmMemory::MockType::MockDummy) {
return new MockGmmMemoryDummy(); return new MockGmmMemoryDummy();
} else { } else {
return new NiceMock<GmockGmmMemory>(); GmockGmmMemory *gmmMemory = new NiceMock<GmockGmmMemory>();
ON_CALL(*gmmMemory, getInternalGpuVaRangeLimit()).WillByDefault(::testing::Return(OCLRT::windowsMinAddress));
return gmmMemory;
} }
} }

View File

@@ -22,6 +22,7 @@
#pragma once #pragma once
#include "gmm_memory.h" #include "gmm_memory.h"
#include "runtime/os_interface/windows/windows_defs.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
namespace OCLRT { namespace OCLRT {
@@ -52,6 +53,10 @@ class MockGmmMemoryDummy : public GmmMemory {
GMM_GFX_SIZE_T SlmGfxSpaceReserve) { GMM_GFX_SIZE_T SlmGfxSpaceReserve) {
return true; return true;
} }
uintptr_t getInternalGpuVaRangeLimit() {
return OCLRT::windowsMinAddress;
}
}; };
class GmockGmmMemory : public GmmMemory { class GmockGmmMemory : public GmmMemory {
@@ -70,5 +75,7 @@ class GmockGmmMemory : public GmmMemory {
BOOLEAN BDWL3Coherency, BOOLEAN BDWL3Coherency,
GMM_GFX_SIZE_T SizeOverride, GMM_GFX_SIZE_T SizeOverride,
GMM_GFX_SIZE_T SlmGfxSpaceReserve)); GMM_GFX_SIZE_T SlmGfxSpaceReserve));
MOCK_METHOD0(getInternalGpuVaRangeLimit, uintptr_t());
}; };
} // namespace OCLRT } // namespace OCLRT

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -139,8 +139,6 @@ class DrmMemoryManagerFixture : public MemoryManagementFixture {
typedef Test<DrmMemoryManagerFixture> DrmMemoryManagerTest; typedef Test<DrmMemoryManagerFixture> DrmMemoryManagerTest;
/* ---- */
TEST_F(DrmMemoryManagerTest, pinBBnotCreated) { TEST_F(DrmMemoryManagerTest, pinBBnotCreated) {
mock->ioctl_expected = 0; mock->ioctl_expected = 0;
EXPECT_EQ(nullptr, memoryManager->getPinBB()); EXPECT_EQ(nullptr, memoryManager->getPinBB());
@@ -1494,6 +1492,10 @@ TEST_F(DrmMemoryManagerTest, givenDefaultDrmMemoryManagerWhenAskedForVirtualPadd
EXPECT_TRUE(memoryManager->peekVirtualPaddingSupport()); EXPECT_TRUE(memoryManager->peekVirtualPaddingSupport());
} }
TEST_F(DrmMemoryManagerTest, givenDefaultDrmMemoryManagerWhenAskedForAlignedMallocRestrictionsThenNullPtrIsReturned) {
EXPECT_EQ(nullptr, memoryManager->getAlignedMallocRestrictions());
}
TEST(Allocator32BitUsingHeapAllocator, given32BitAllocatorWhenMMapFailsThenNullptrIsReturned) { TEST(Allocator32BitUsingHeapAllocator, given32BitAllocatorWhenMMapFailsThenNullptrIsReturned) {
bool flagToRestore = DebugManager.flags.UseNewHeapAllocator.get(); bool flagToRestore = DebugManager.flags.UseNewHeapAllocator.get();
DebugManager.flags.UseNewHeapAllocator.set(true); DebugManager.flags.UseNewHeapAllocator.set(true);

View File

@@ -550,6 +550,13 @@ HWTEST_F(WddmMemoryManagerTest, freeNullAllocationNoCrash) {
mm->freeGraphicsMemory(nullptr); mm->freeGraphicsMemory(nullptr);
} }
HWTEST_F(WddmMemoryManagerTest, givenDefaultWddmMemoryManagerWhenAskedForAlignedMallocRestrictionsThenValueIsReturned) {
SetUpMm<FamilyType>();
AlignedMallocRestrictions *mallocRestrictions = mm->getAlignedMallocRestrictions();
ASSERT_NE(nullptr, mallocRestrictions);
EXPECT_EQ(OCLRT::windowsMinAddress, mallocRestrictions->minAddress);
}
HWTEST_F(WddmMemoryManagerResidencyTest, addToTrimCandidateListPlacesAllocationInContainerAndAssignsPosition) { HWTEST_F(WddmMemoryManagerResidencyTest, addToTrimCandidateListPlacesAllocationInContainerAndAssignsPosition) {
SetUpMm<FamilyType>(); SetUpMm<FamilyType>();
WddmAllocation allocation; WddmAllocation allocation;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 2017 - 2018, Intel Corporation
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -391,6 +391,27 @@ HWTEST_F(WddmTest, givenSharedHandleWhenCreateGraphicsAllocationFromSharedHandle
mm.freeGraphicsMemory(graphicsAllocation); mm.freeGraphicsMemory(graphicsAllocation);
} }
HWTEST_F(WddmTest, givenWddmCreatedWhenNotInitedThenMinAddressZero) {
Wddm *wddm = Wddm::createWddm();
uintptr_t expected = 0;
uintptr_t actual = wddm->getWddmMinAddress();
EXPECT_EQ(expected, actual);
delete wddm;
}
HWTEST_F(WddmTest, givenWddmCreatedWhenInitedThenMinAddressValid) {
Wddm *wddm = Wddm::createWddm();
bool ret = wddm->init<FamilyType>();
EXPECT_TRUE(ret);
uintptr_t expected = windowsMinAddress;
uintptr_t actual = wddm->getWddmMinAddress();
EXPECT_EQ(expected, actual);
delete wddm;
}
HWTEST_F(WddmInstrumentationTest, configureDeviceAddressSpaceOnInit) { HWTEST_F(WddmInstrumentationTest, configureDeviceAddressSpaceOnInit) {
SYSTEM_INFO sysInfo = {}; SYSTEM_INFO sysInfo = {};
auto mockWddm(new WddmMock()); auto mockWddm(new WddmMock());