Skip to content

Commit 3bef9f8

Browse files
fix: Crash on over memory allocation
- Add defer backing flag to gem create ioctl - Make memory resident before lock Related-To: NEO-13403 Signed-off-by: Bellekallu Rajkiran <[email protected]>
1 parent aab1113 commit 3bef9f8

File tree

9 files changed

+78
-4
lines changed

9 files changed

+78
-4
lines changed

shared/source/debug_settings/debug_variables_base.inl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ DECLARE_DEBUG_VARIABLE(bool, ForceSamplerLowFilteringPrecision, false, "Force Lo
485485
DECLARE_DEBUG_VARIABLE(bool, EnablePrivateBO, false, "Enable PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE extension creating VM_PRIVATE BOs")
486486
DECLARE_DEBUG_VARIABLE(bool, EnableAIL, true, "Enables AIL")
487487
DECLARE_DEBUG_VARIABLE(bool, EnableReservingInSvmRange, true, "Enables reserving virtual memory in the SVM range")
488+
DECLARE_DEBUG_VARIABLE(bool, EnableDeferBacking, false, "Enables defer backing on xe kmd")
488489
DECLARE_DEBUG_VARIABLE(bool, DisableProgrammableMetricsSupport, false, "Disable Programmable Metrics support")
489490
DECLARE_DEBUG_VARIABLE(int64_t, VmBindWaitUserFenceTimeout, -1, "-1: default, >0: time in ns for wait function timeout")
490491
DECLARE_DEBUG_VARIABLE(int32_t, ForceRunAloneContext, -1, "Control creation of run-alone HW context, -1:default, 0:disable, 1:enable")

shared/source/os_interface/linux/drm_memory_manager.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1518,8 +1518,17 @@ void *DrmMemoryManager::lockResourceImpl(GraphicsAllocation &graphicsAllocation)
15181518
return cpuPtr;
15191519
}
15201520

1521-
auto bo = static_cast<DrmAllocation &>(graphicsAllocation).getBO();
1521+
auto rootDeviceIndex = graphicsAllocation.getRootDeviceIndex();
1522+
auto ioctlHelper = this->getDrm(rootDeviceIndex).getIoctlHelper();
15221523

1524+
if (ioctlHelper->makeResidentBeforeLockNeeded()) {
1525+
auto memoryOperationsInterface = static_cast<DrmMemoryOperationsHandler *>(executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface.get());
1526+
auto graphicsAllocationPtr = &graphicsAllocation;
1527+
[[maybe_unused]] auto ret = memoryOperationsInterface->makeResidentWithinOsContext(getDefaultOsContext(rootDeviceIndex), ArrayRef<NEO::GraphicsAllocation *>(&graphicsAllocationPtr, 1), false) == MemoryOperationsStatus::success;
1528+
DEBUG_BREAK_IF(!ret);
1529+
}
1530+
1531+
auto bo = static_cast<DrmAllocation &>(graphicsAllocation).getBO();
15231532
if (graphicsAllocation.getAllocationType() == AllocationType::writeCombined) {
15241533
auto addr = lockBufferObject(bo);
15251534
auto alignedAddr = alignUp(addr, MemoryConstants::pageSize64k);

shared/source/os_interface/linux/ioctl_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ class IoctlHelper {
236236

237237
virtual bool isTimestampsRefreshEnabled() { return false; }
238238

239+
virtual bool makeResidentBeforeLockNeeded() const { return false; }
240+
239241
protected:
240242
Drm &drm;
241243
ExternalCtx *externalCtx = nullptr;

shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,10 @@ int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t a
678678
create.placement = static_cast<uint32_t>(memoryInstances.to_ulong());
679679
create.cpu_caching = this->getCpuCachingMode(isCoherent, isSysMemOnly);
680680

681+
if (debugManager.flags.EnableDeferBacking.get()) {
682+
create.flags |= DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING;
683+
}
684+
681685
printDebugString(debugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "Performing DRM_IOCTL_XE_GEM_CREATE with {vmid=0x%x size=0x%lx flags=0x%x placement=0x%x caching=%hu }",
682686
create.vm_id, create.size, create.flags, create.placement, create.cpu_caching);
683687

@@ -720,6 +724,10 @@ uint32_t IoctlHelperXe::createGem(uint64_t size, uint32_t memoryBanks, std::opti
720724
create.placement = static_cast<uint32_t>(memoryInstances.to_ulong());
721725
create.cpu_caching = this->getCpuCachingMode(isCoherent, isSysMemOnly);
722726

727+
if (debugManager.flags.EnableDeferBacking.get()) {
728+
create.flags |= DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING;
729+
}
730+
723731
printDebugString(debugManager.flags.PrintBOCreateDestroyResult.get(), stdout, "Performing DRM_IOCTL_XE_GEM_CREATE with {vmid=0x%x size=0x%lx flags=0x%x placement=0x%x caching=%hu }",
724732
create.vm_id, create.size, create.flags, create.placement, create.cpu_caching);
725733

@@ -1566,6 +1574,14 @@ bool IoctlHelperXe::isImmediateVmBindRequired() const {
15661574
return true;
15671575
}
15681576

1577+
bool IoctlHelperXe::makeResidentBeforeLockNeeded() const {
1578+
auto makeResidentBeforeLockNeeded = false;
1579+
if (debugManager.flags.EnableDeferBacking.get()) {
1580+
makeResidentBeforeLockNeeded = true;
1581+
}
1582+
return makeResidentBeforeLockNeeded;
1583+
}
1584+
15691585
void IoctlHelperXe::insertEngineToContextParams(ContextParamEngines<> &contextParamEngines, uint32_t engineId, const EngineClassInstance *engineClassInstance, uint32_t tileId, bool hasVirtualEngines) {
15701586
auto engines = reinterpret_cast<drm_xe_engine_class_instance *>(contextParamEngines.enginesData);
15711587
if (engineClassInstance) {

shared/source/os_interface/linux/xe/ioctl_helper_xe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class IoctlHelperXe : public IoctlHelper {
133133
int getTileIdFromGtId(int gtId) const override {
134134
return gtIdToTileId[gtId];
135135
}
136+
bool makeResidentBeforeLockNeeded() const override;
136137

137138
protected:
138139
static constexpr uint32_t maxContextSetProperties = 4;

shared/test/common/mocks/linux/mock_ioctl_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MockIoctlHelper : public IoctlHelperPrelim20 {
3131
ADDMETHOD_CONST_NOBASE(isImmediateVmBindRequired, bool, false, ());
3232
ADDMETHOD_CONST_NOBASE(getIoctlRequestValue, unsigned int, 1234u, (DrmIoctl));
3333
ADDMETHOD_CONST_NOBASE(isWaitBeforeBindRequired, bool, false, (bool));
34+
ADDMETHOD_CONST_NOBASE(makeResidentBeforeLockNeeded, bool, false, ());
3435

3536
ADDMETHOD_NOBASE(vmBind, int, 0, (const VmBindParams &));
3637
ADDMETHOD_NOBASE(vmUnbind, int, 0, (const VmBindParams &));

shared/test/common/test_files/igdrcl.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,4 +663,5 @@ DirectSubmissionRelaxedOrderingCounterHeuristicTreshold = -1
663663
ClearStandaloneInOrderTimestampAllocation = -1
664664
PipelinedEuThreadArbitration = -1
665665
ExperimentalUSMAllocationReuseCleaner = -1
666+
EnableDeferBacking = 0
666667
# Please don't edit below this line

shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "shared/source/indirect_heap/indirect_heap.h"
1616
#include "shared/source/memory_manager/memory_banks.h"
1717
#include "shared/source/os_interface/linux/drm_memory_operations_handler.h"
18+
#include "shared/source/os_interface/linux/drm_memory_operations_handler_bind.h"
1819
#include "shared/source/os_interface/linux/i915.h"
1920
#include "shared/source/os_interface/linux/os_context_linux.h"
2021
#include "shared/test/common/helpers/engine_descriptor_helper.h"
@@ -2571,6 +2572,32 @@ TEST_F(DrmMemoryManagerTest, givenDrmMemoryManagerWhenLockUnlockIsCalledThenRetu
25712572
memoryManager->freeGraphicsMemory(allocation);
25722573
}
25732574

2575+
TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmMemoryManagerAndResidentNeededbeforeLockWhenLockIsCalledThenverifyAllocationIsResident) {
2576+
mock->ioctlExpected.gemWait = 1;
2577+
mock->ioctlExpected.gemClose = 1;
2578+
mock->ioctlExpected.gemMmapOffset = 1;
2579+
mock->ioctlExpected.gemCreateExt = 1;
2580+
2581+
auto mockIoctlHelper = new MockIoctlHelper(*mock);
2582+
mockIoctlHelper->makeResidentBeforeLockNeededResult = true;
2583+
2584+
auto &drm = static_cast<DrmMockCustom &>(memoryManager->getDrm(rootDeviceIndex));
2585+
drm.ioctlHelper.reset(mockIoctlHelper);
2586+
2587+
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface.reset(new DrmMemoryOperationsHandlerBind(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex].get(), 0));
2588+
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, true, MemoryConstants::pageSize, AllocationType::buffer});
2589+
ASSERT_NE(nullptr, allocation);
2590+
2591+
auto ptr = memoryManager->lockResource(allocation);
2592+
EXPECT_NE(nullptr, ptr);
2593+
2594+
auto osContext = device->getDefaultEngine().osContext;
2595+
EXPECT_TRUE(allocation->isAlwaysResident(osContext->getContextId()));
2596+
2597+
memoryManager->unlockResource(allocation);
2598+
memoryManager->freeGraphicsMemory(allocation);
2599+
}
2600+
25742601
TEST_F(DrmMemoryManagerTest, givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationWithCpuPtrThenReturnCpuPtrAndSetCpuDomain) {
25752602
mock->ioctlExpected.gemUserptr = 1;
25762603
mock->ioctlExpected.gemSetDomain = 1;

shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,21 @@ TEST_F(IoctlHelperXeGemCreateExtTests, givenIoctlHelperXeWhenCallingGemCreateExt
117117
}
118118

119119
TEST_F(IoctlHelperXeGemCreateExtTests, givenIoctlHelperXeWhenCallingGemCreateExtWithOnlySystemRegionAndCoherencyThenWriteBackCPUCachingIsUsed) {
120+
DebugManagerStateRestore restorer;
121+
debugManager.flags.EnableDeferBacking.set(1);
122+
120123
MemRegionsVec memRegions = {systemMemory};
121124
bool isCoherent = true;
122125

123126
EXPECT_NE(0, xeIoctlHelper->createGemExt(memRegions, allocSize, handle, patIndex, std::nullopt, pairHandle, isChunked, numOfChunks, std::nullopt, std::nullopt, isCoherent));
124127
EXPECT_EQ(DRM_XE_GEM_CPU_CACHING_WB, drm->createParamsCpuCaching);
128+
EXPECT_EQ(static_cast<uint32_t>(DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING), (drm->createParamsFlags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING));
125129
}
126130

127131
TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateAndNoLocalMemoryThenProperValuesSet) {
128132
DebugManagerStateRestore restorer;
129133
debugManager.flags.EnableLocalMemory.set(0);
134+
debugManager.flags.EnableDeferBacking.set(1);
130135
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
131136
auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]);
132137
auto xeIoctlHelper = static_cast<MockIoctlHelperXe *>(drm->getIoctlHelper());
@@ -145,7 +150,7 @@ TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateAndNoLocalMemoryThe
145150
EXPECT_TRUE(xeIoctlHelper->bindInfo.empty());
146151

147152
EXPECT_EQ(size, drm->createParamsSize);
148-
EXPECT_EQ(0u, drm->createParamsFlags);
153+
EXPECT_EQ(static_cast<uint32_t>(DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING), (drm->createParamsFlags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING));
149154
EXPECT_EQ(DRM_XE_GEM_CPU_CACHING_WC, drm->createParamsCpuCaching);
150155
EXPECT_EQ(1u, drm->createParamsPlacement);
151156

@@ -157,6 +162,7 @@ TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateAndNoLocalMemoryThe
157162
TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateWhenMemoryBanksZeroThenProperValuesSet) {
158163
DebugManagerStateRestore restorer;
159164
debugManager.flags.EnableLocalMemory.set(0);
165+
debugManager.flags.EnableDeferBacking.set(1);
160166
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
161167
auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]);
162168
auto xeIoctlHelper = static_cast<MockIoctlHelperXe *>(drm->getIoctlHelper());
@@ -176,7 +182,7 @@ TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateWhenMemoryBanksZero
176182

177183
EXPECT_EQ(size, drm->createParamsSize);
178184
EXPECT_EQ(DRM_XE_GEM_CPU_CACHING_WC, drm->createParamsCpuCaching);
179-
EXPECT_EQ(0u, drm->createParamsFlags);
185+
EXPECT_EQ(static_cast<uint32_t>(DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING), (drm->createParamsFlags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING));
180186
EXPECT_EQ(1u, drm->createParamsPlacement);
181187

182188
// dummy mock handle
@@ -187,6 +193,7 @@ TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateWhenMemoryBanksZero
187193
TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateAndLocalMemoryThenProperValuesSet) {
188194
DebugManagerStateRestore restorer;
189195
debugManager.flags.EnableLocalMemory.set(1);
196+
debugManager.flags.EnableDeferBacking.set(1);
190197
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
191198
auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]);
192199
auto xeIoctlHelper = static_cast<MockIoctlHelperXe *>(drm->getIoctlHelper());
@@ -206,7 +213,7 @@ TEST_F(IoctlHelperXeTest, givenIoctlHelperXeWhenCallGemCreateAndLocalMemoryThenP
206213

207214
EXPECT_EQ(size, drm->createParamsSize);
208215
EXPECT_EQ(DRM_XE_GEM_CPU_CACHING_WC, drm->createParamsCpuCaching);
209-
EXPECT_EQ(0u, drm->createParamsFlags);
216+
EXPECT_EQ(static_cast<uint32_t>(DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING), (drm->createParamsFlags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING));
210217
EXPECT_EQ(6u, drm->createParamsPlacement);
211218

212219
// dummy mock handle
@@ -2677,3 +2684,12 @@ TEST_F(IoctlHelperXeTest, whenQueryDeviceIdAndRevisionAndSharedSystemUsmSupportD
26772684
EXPECT_TRUE(IoctlHelperXe::queryDeviceIdAndRevision(*drm));
26782685
EXPECT_FALSE(drm->isSharedSystemAllocEnabled());
26792686
}
2687+
2688+
TEST_F(IoctlHelperXeTest, givenXeIoctlHelperAndDeferBackingFlagSetToTrueWhenMakeResidentBeforeLockNeededIsCalledThenVerifyTrueIsReturned) {
2689+
DebugManagerStateRestore restorer;
2690+
debugManager.flags.EnableDeferBacking.set(1);
2691+
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
2692+
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
2693+
auto xeIoctlHelper = std::make_unique<IoctlHelperXe>(drm);
2694+
EXPECT_TRUE(xeIoctlHelper->makeResidentBeforeLockNeeded());
2695+
}

0 commit comments

Comments
 (0)