Share reserved CPU address space region among GfxPartitions

Related-To: NEO-4525

Change-Id: Id7534e317a10849c08ec29a090d782dcc4fabced
Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev
2020-08-12 12:18:34 +02:00
committed by sys_ocldev
parent b09872f595
commit 8a73b072b4
9 changed files with 70 additions and 9 deletions

View File

@ -159,3 +159,52 @@ TEST(GfxPartitionTest, testGfxPartitionFullRange47BitSVMHeap64KBSplit) {
EXPECT_EQ(heapStandard64KBSize, gfxPartition.getHeapSize(HeapIndex::HEAP_STANDARD64KB));
EXPECT_EQ(gfxBase + 4 * sizeHeap32 + heapStandardSize + rootDeviceIndex * heapStandard64KBSize, gfxPartition.getHeapBase(HeapIndex::HEAP_STANDARD64KB));
}
class MockOsMemory : public OSMemory {
public:
MockOsMemory() = default;
~MockOsMemory() { reserveCount = 0; }
uint32_t getReserveCount() { return reserveCount; }
struct MockOSMemoryReservedCpuAddressRange : public OSMemory::ReservedCpuAddressRange {
MockOSMemoryReservedCpuAddressRange(void *ptr, size_t size, size_t align) {
alignedPtr = originalPtr = ptr;
sizeToReserve = actualReservedSize = size;
}
};
OSMemory::ReservedCpuAddressRange reserveCpuAddressRange(size_t sizeToReserve, size_t alignment) override {
return reserveCpuAddressRange(0, sizeToReserve, alignment);
};
OSMemory::ReservedCpuAddressRange reserveCpuAddressRange(void *baseAddress, size_t sizeToReserve, size_t alignment) override {
reserveCount++;
return MockOSMemoryReservedCpuAddressRange(reinterpret_cast<void *>(0x10000), sizeToReserve, alignment);
};
void getMemoryMaps(MemoryMaps &outMemoryMaps) override {}
void releaseCpuAddressRange(const OSMemory::ReservedCpuAddressRange &reservedCpuAddressRange) override{};
void *osReserveCpuAddressRange(void *baseAddress, size_t sizeToReserve) override { return nullptr; }
void osReleaseCpuAddressRange(void *reservedCpuAddressRange, size_t reservedSize) override {}
static uint32_t reserveCount;
};
uint32_t MockOsMemory::reserveCount = 0;
TEST(GfxPartitionTest, given47bitGpuAddressSpaceWhenInitializingMultipleGfxPartitionsThenReserveCpuAddressRangeForDriverAllocationsOnlyOnce) {
if (is32bit) {
GTEST_SKIP();
}
OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
std::vector<std::unique_ptr<MockGfxPartition>> gfxPartitions;
for (int i = 0; i < 10; ++i) {
gfxPartitions.push_back(std::make_unique<MockGfxPartition>(reservedCpuAddressRange));
gfxPartitions[i]->osMemory.reset(new MockOsMemory);
gfxPartitions[i]->init(maxNBitValue(47), reservedCpuAddressRangeSize, i, 10);
}
EXPECT_EQ(1u, static_cast<MockOsMemory *>(gfxPartitions[0]->osMemory.get())->getReserveCount());
}

View File

@ -15,6 +15,9 @@ class MockGfxPartition : public GfxPartition {
public:
using GfxPartition::osMemory;
MockGfxPartition() : GfxPartition(reservedCpuAddressRange) {}
MockGfxPartition(OSMemory::ReservedCpuAddressRange &sharedReservedCpuAddressRange) : GfxPartition(sharedReservedCpuAddressRange) {}
uint64_t getHeapSize(HeapIndex heapIndex) {
return getHeap(heapIndex).getSize();
}
@ -34,4 +37,6 @@ class MockGfxPartition : public GfxPartition {
MOCK_METHOD2(freeGpuAddressRange, void(uint64_t gpuAddress, size_t size));
static std::array<HeapIndex, static_cast<uint32_t>(HeapIndex::TOTAL_HEAPS)> allHeapNames;
OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
};

View File

@ -677,7 +677,7 @@ TEST_F(DrmMemoryManagerFailInjectionTest, givenEnabledLocalMemoryWhenNewFailsThe
mock->ioctl_expected.total = -1; //don't care
class MockGfxPartition : public GfxPartition {
public:
MockGfxPartition() {
MockGfxPartition() : GfxPartition(reservedCpuAddressRange) {
init(defaultHwInfo->capabilityTable.gpuAddressSpace, getSizeToReserve(), 0, 1);
}
~MockGfxPartition() override {
@ -691,6 +691,7 @@ TEST_F(DrmMemoryManagerFailInjectionTest, givenEnabledLocalMemoryWhenNewFailsThe
struct MockHeap : Heap {
using Heap::alloc;
};
OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
};
TestedDrmMemoryManager testedMemoryManager(true, false, true, *executionEnvironment);
testedMemoryManager.overrideGfxPartition(new MockGfxPartition);

View File

@ -24,10 +24,11 @@ const std::array<HeapIndex, 7> GfxPartition::heapNonSvmNames{{HeapIndex::HEAP_IN
HeapIndex::HEAP_STANDARD64KB,
HeapIndex::HEAP_EXTENDED}};
GfxPartition::GfxPartition() : osMemory(OSMemory::create()) {}
GfxPartition::GfxPartition(OSMemory::ReservedCpuAddressRange &sharedReservedCpuAddressRange) : reservedCpuAddressRange(sharedReservedCpuAddressRange), osMemory(OSMemory::create()) {}
GfxPartition::~GfxPartition() {
osMemory->releaseCpuAddressRange(reservedCpuAddressRange);
reservedCpuAddressRange = {0};
}
void GfxPartition::Heap::init(uint64_t base, uint64_t size) {
@ -112,10 +113,12 @@ void GfxPartition::init(uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToRe
gfxBase = maxNBitValue(48 - 1) + 1;
heapInit(HeapIndex::HEAP_SVM, 0ull, gfxBase);
} else if (gpuAddressSpace == maxNBitValue(47)) {
UNRECOVERABLE_IF(cpuAddressRangeSizeToReserve == 0);
reservedCpuAddressRange = osMemory->reserveCpuAddressRange(cpuAddressRangeSizeToReserve, GfxPartition::heapGranularity);
UNRECOVERABLE_IF(reservedCpuAddressRange.originalPtr == nullptr);
UNRECOVERABLE_IF(!isAligned<GfxPartition::heapGranularity>(reservedCpuAddressRange.alignedPtr));
if (reservedCpuAddressRange.alignedPtr == nullptr) {
UNRECOVERABLE_IF(cpuAddressRangeSizeToReserve == 0);
reservedCpuAddressRange = osMemory->reserveCpuAddressRange(cpuAddressRangeSizeToReserve, GfxPartition::heapGranularity);
UNRECOVERABLE_IF(reservedCpuAddressRange.originalPtr == nullptr);
UNRECOVERABLE_IF(!isAligned<GfxPartition::heapGranularity>(reservedCpuAddressRange.alignedPtr));
}
gfxBase = reinterpret_cast<uint64_t>(reservedCpuAddressRange.alignedPtr);
gfxTop = gfxBase + cpuAddressRangeSizeToReserve;
heapInit(HeapIndex::HEAP_SVM, 0ull, gpuAddressSpace + 1);

View File

@ -30,7 +30,7 @@ enum class HeapIndex : uint32_t {
class GfxPartition {
public:
GfxPartition();
GfxPartition(OSMemory::ReservedCpuAddressRange &sharedReservedCpuAddressRange);
MOCKABLE_VIRTUAL ~GfxPartition();
void init(uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToReserve, uint32_t rootDeviceIndex, size_t numRootDevices);
@ -92,7 +92,7 @@ class GfxPartition {
std::array<Heap, static_cast<uint32_t>(HeapIndex::TOTAL_HEAPS)> heaps;
OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
OSMemory::ReservedCpuAddressRange &reservedCpuAddressRange;
std::unique_ptr<OSMemory> osMemory;
};

View File

@ -48,7 +48,7 @@ MemoryManager::MemoryManager(ExecutionEnvironment &executionEnvironment) : execu
this->enable64kbpages[rootDeviceIndex] = DebugManager.flags.Enable64kbpages.get() != 0;
}
gfxPartitions.push_back(std::make_unique<GfxPartition>());
gfxPartitions.push_back(std::make_unique<GfxPartition>(reservedCpuAddressRange));
anyLocalMemorySupported |= this->localMemorySupported[rootDeviceIndex];
}

View File

@ -226,6 +226,7 @@ class MemoryManager {
std::vector<std::unique_ptr<LocalMemoryUsageBankSelector>> localMemoryUsageBankSelector;
void *reservedMemory = nullptr;
std::unique_ptr<PageFaultManager> pageFaultManager;
OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
};
std::unique_ptr<DeferredDeleter> createDeferredDeleter();

View File

@ -20,6 +20,7 @@ OSMemory::ReservedCpuAddressRange OSMemory::reserveCpuAddressRange(void *baseAdd
ReservedCpuAddressRange reservedCpuAddressRange;
reservedCpuAddressRange.sizeToReserve = sizeToReserve;
reservedCpuAddressRange.actualReservedSize = sizeToReserve + alignment;
reservedCpuAddressRange.originalPtr = this->osReserveCpuAddressRange(baseAddress, reservedCpuAddressRange.actualReservedSize);
reservedCpuAddressRange.alignedPtr = alignUp(reservedCpuAddressRange.originalPtr, alignment);

View File

@ -17,6 +17,7 @@ struct OSMemory {
struct ReservedCpuAddressRange {
void *originalPtr = nullptr;
void *alignedPtr = nullptr;
size_t sizeToReserve = 0;
size_t actualReservedSize = 0;
};