feature: Add prefetch for chunking with shared and device mem

Perform prefetching of chunks on shared and device allocations
after bind.

Related-To: NEO-8066

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:
John Falkowski
2023-07-26 00:59:11 +00:00
committed by Compute-Runtime-Automation
parent cb2b4214b4
commit f652c7311d
11 changed files with 167 additions and 15 deletions

View File

@@ -23,6 +23,7 @@
#include "shared/test/common/helpers/engine_descriptor_helper.h"
#include "shared/test/common/libult/linux/drm_query_mock.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/linux/mock_drm_memory_manager.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_command_stream_receiver.h"
@@ -555,6 +556,36 @@ TEST_F(DrmMemoryOperationsHandlerBindTest, givenMakeBOsResidentFailsThenMakeResi
delete allocation;
}
TEST_F(DrmMemoryOperationsHandlerBindTest,
givenDrmAllocationWithChunkingAndmakeResidentWithinOsContextCalledThenprefetchBOWithChunkingCalled) {
struct MockDrmAllocationBOsResident : public DrmAllocation {
MockDrmAllocationBOsResident(uint32_t rootDeviceIndex, AllocationType allocationType, BufferObjects &bos, void *ptrIn, uint64_t gpuAddress, size_t sizeIn, MemoryPool pool)
: DrmAllocation(rootDeviceIndex, allocationType, bos, ptrIn, gpuAddress, sizeIn, pool) {
}
};
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(3);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
DebugManager.flags.PrintBOPrefetchingResult.set(1);
auto size = 4096u;
BufferObjects bos;
MockBufferObject mockBo(device->getRootDeviceIndex(), mock, 3, 0, 0, 1);
mockBo.isChunked = 1;
mockBo.setSize(1024);
bos.push_back(&mockBo);
auto allocation = new MockDrmAllocationBOsResident(0, AllocationType::UNKNOWN, bos, nullptr, 0u, size, MemoryPool::LocalMemory);
allocation->setNumHandles(1);
allocation->storageInfo.isChunked = 1;
allocation->storageInfo.numOfChunks = 4;
allocation->storageInfo.subDeviceBitfield = 0b0011;
auto graphicsAllocation = static_cast<GraphicsAllocation *>(allocation);
EXPECT_EQ(operationHandler->makeResidentWithinOsContext(device->getDefaultEngine().osContext, ArrayRef<GraphicsAllocation *>(&graphicsAllocation, 1), false), MemoryOperationsStatus::SUCCESS);
delete allocation;
}
TEST_F(DrmMemoryOperationsHandlerBindTest, givenDrmMemoryOperationBindWhenMakeResidentWithinOsContextEvictableAllocationThenAllocationIsNotMarkedAsAlwaysResident) {
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), MemoryConstants::pageSize});

View File

@@ -62,7 +62,7 @@ TEST(DrmVmBindTest, givenBoRequiringExplicitResidencyWhenBindingThenMakeResident
}
TEST(DrmVmBindTest,
givenBoWithChunkingRequiringExplicitResidencyWhenBindingThenMakeResidentFlagIsNotPassedAndUserFenceIsSetup) {
givenBoWithChunkingRequiringExplicitResidencyWhenBindingThenMakeResidentFlagIsPassedAndUserFenceIsSetup) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
executionEnvironment->initializeMemoryManager();
@@ -80,7 +80,7 @@ TEST(DrmVmBindTest,
bo.bind(&osContext, vmHandleId);
if (requireResidency) {
EXPECT_EQ(DrmPrelimHelper::getImmediateVmBindFlag(), drm.context.receivedVmBind->flags);
EXPECT_EQ(DrmPrelimHelper::getImmediateVmBindFlag() | DrmPrelimHelper::getMakeResidentVmBindFlag(), 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);

View File

@@ -35,7 +35,6 @@ class DrmPrelimMock : public DrmMock {
void getPrelimVersion(std::string &prelimVersion) override {
prelimVersion = "2.0";
}
int handleRemainingRequests(DrmIoctl request, void *arg) override {
if (request == DrmIoctl::Query && arg != nullptr) {
auto queryArg = static_cast<Query *>(arg);
@@ -157,7 +156,7 @@ TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtWithChunkingThenGet
MemRegionsVec memClassInstance = {{drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE, 0}};
ioctlHelper->createGemExt(memClassInstance, allocSize, handle, 0, {}, -1, true, getNumOfChunks);
std::string output = testing::internal::GetCapturedStdout();
std::string expectedOutput("GEM_CREATE_EXT with BOChunkingSize 65536, chunkingParamRegion.param.data 65536, numOfChunks 2\n");
std::string expectedOutput("GEM_CREATE_EXT BO-1 with BOChunkingSize 65536, chunkingParamRegion.param.data 65536, numOfChunks 2\n");
EXPECT_EQ(expectedOutput, output);
EXPECT_EQ(2u, getNumOfChunks);
}
@@ -460,6 +459,65 @@ TEST_F(IoctlHelperPrelimFixture, givenDrmAllocationWhenSetMemPrefetchFailsThenRe
EXPECT_FALSE(allocation.setMemPrefetch(drm.get(), subDeviceIds));
}
TEST_F(IoctlHelperPrelimFixture,
givenDrmAllocationWithChunkingAndsetMemPrefetchCalledSuccessIsReturned) {
SubDeviceIdsVec subDeviceIds{0, 1};
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
DebugManager.flags.PrintBOPrefetchingResult.set(1);
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);
bo.isChunked = 1;
bo.setSize(1024);
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;
allocation.storageInfo.subDeviceBitfield = 0b0001;
EXPECT_TRUE(allocation.setMemPrefetch(drm.get(), subDeviceIds));
}
TEST_F(IoctlHelperPrelimFixture,
givenDrmAllocationWithChunkingAndsetMemPrefetchWithIoctlFailureThenFailureReturned) {
SubDeviceIdsVec subDeviceIds{0, 1};
DebugManagerStateRestore restore;
DebugManager.flags.EnableBOChunking.set(1);
DebugManager.flags.EnableBOChunkingPreferredLocationHint.set(true);
DebugManager.flags.PrintBOPrefetchingResult.set(1);
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);
bo.isChunked = 1;
bo.setSize(1024);
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;
allocation.storageInfo.subDeviceBitfield = 0b0001;
drm->ioctlRetVal = EINVAL;
EXPECT_FALSE(allocation.setMemPrefetch(drm.get(), subDeviceIds));
}
TEST_F(IoctlHelperPrelimFixture, givenVariousDirectSubmissionFlagSettingWhenCreateDrmContextIsCalledThenCorrectFlagsArePassedToIoctl) {
DebugManagerStateRestore stateRestore;
uint32_t vmId = 0u;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2022 Intel Corporation
* Copyright (C) 2021-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -90,6 +90,7 @@ int handlePrelimRequests(DrmIoctl request, void *arg, int ioctlRetVal, int query
}
} else if (request == DrmIoctl::GemVmPrefetch) {
auto vmPrefetchParams = static_cast<prelim_drm_i915_gem_vm_prefetch *>(arg);
// Valid vm_id must be nonzero
EXPECT_NE(0u, vmPrefetchParams->vm_id);
}
return ioctlRetVal;