Return error when there is no memory to evict

We want to return error code to the application instead of aborting when
we are not able to make more memory resident.

Related-To: NEO-7289
Signed-off-by: Fabian Zwolinski <fabian.zwolinski@intel.com>
This commit is contained in:
Fabian Zwolinski
2022-09-13 14:26:03 +00:00
committed by Compute-Runtime-Automation
parent 501873d0e0
commit 645600d141
20 changed files with 159 additions and 55 deletions

View File

@@ -73,6 +73,20 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily
return this->submissionAggregator.get();
}
bool processResidency(const ResidencyContainer &allocationsForResidency, uint32_t handleId) override {
if (callBaseProcessResidency) {
return DrmCommandStreamReceiver<GfxFamily>::processResidency(allocationsForResidency, handleId);
}
return processResidencyResult;
}
int exec(const BatchBuffer &batchBuffer, uint32_t vmHandleId, uint32_t drmContextId, uint32_t index) override {
if (callBaseExec) {
return DrmCommandStreamReceiver<GfxFamily>::exec(batchBuffer, vmHandleId, drmContextId, index);
}
return execResult;
}
void overrideSubmissionAggregator(SubmissionAggregator *newSubmissionsAggregator) {
this->submissionAggregator.reset(newSubmissionsAggregator);
}
@@ -105,11 +119,11 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily
}
}
int flushInternal(const BatchBuffer &batchBuffer, const ResidencyContainer &allocationsForResidency) override {
SubmissionStatus flushInternal(const BatchBuffer &batchBuffer, const ResidencyContainer &allocationsForResidency) override {
if (callHwFlush) {
return DrmCommandStreamReceiver<GfxFamily>::flushInternal(batchBuffer, allocationsForResidency);
}
return 0;
return SubmissionStatus::SUCCESS;
}
void readBackAllocation(void *source) override {
@@ -119,6 +133,10 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily
void *latestReadBackAddress = nullptr;
bool callHwFlush = true;
bool callBaseProcessResidency = true;
bool processResidencyResult = true;
bool callBaseExec = true;
int execResult = 0;
};
template <typename GfxFamily>

View File

@@ -599,6 +599,44 @@ HWTEST_TEMPLATED_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhen
mm->freeGraphicsMemory(commandBuffer);
}
HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenFailingProcessResidencyWhenFlushingThenFlushReturnsOutOfMemory) {
auto commandBuffer = mm->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
LinearStream cs(commandBuffer);
CommandStreamReceiverHw<FamilyType>::addBatchBufferEnd(cs, nullptr);
EncodeNoop<FamilyType>::alignToCacheLine(cs);
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false};
auto allocation = mm->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
executionEnvironment->rootDeviceEnvironments[csr->getRootDeviceIndex()]->memoryOperationsInterface->makeResident(device.get(), ArrayRef<GraphicsAllocation *>(&allocation, 1));
static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->callBaseProcessResidency = false;
static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->processResidencyResult = false;
SubmissionStatus ret = csr->flush(batchBuffer, csr->getResidencyAllocations());
EXPECT_EQ(SubmissionStatus::OUT_OF_MEMORY, ret);
mm->freeGraphicsMemory(allocation);
mm->freeGraphicsMemory(commandBuffer);
}
HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenFailingExecWhenFlushingThenFlushReturnsFailed) {
auto commandBuffer = mm->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
LinearStream cs(commandBuffer);
CommandStreamReceiverHw<FamilyType>::addBatchBufferEnd(cs, nullptr);
EncodeNoop<FamilyType>::alignToCacheLine(cs);
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false};
auto allocation = mm->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
executionEnvironment->rootDeviceEnvironments[csr->getRootDeviceIndex()]->memoryOperationsInterface->makeResident(device.get(), ArrayRef<GraphicsAllocation *>(&allocation, 1));
static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->callBaseExec = false;
static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execResult = -1;
SubmissionStatus ret = csr->flush(batchBuffer, csr->getResidencyAllocations());
EXPECT_EQ(SubmissionStatus::FAILED, ret);
mm->freeGraphicsMemory(allocation);
mm->freeGraphicsMemory(commandBuffer);
}
struct DrmCommandStreamDirectSubmissionTest : public DrmCommandStreamEnhancedTest {
template <typename GfxFamily>
void setUpT() {

View File

@@ -275,7 +275,7 @@ class DrmCommandStreamForceTileTest : public ::testing::Test {
: DrmCommandStreamReceiver<GfxFamily>(executionEnvironment, rootDeviceIndex, deviceBitfield, mode), expectedHandleId(inputHandleId) {
}
void processResidency(const ResidencyContainer &allocationsForResidency, uint32_t handleId) override {
bool processResidency(const ResidencyContainer &allocationsForResidency, uint32_t handleId) override {
EXPECT_EQ(handleId, expectedHandleId);
return DrmCommandStreamReceiver<GfxFamily>::processResidency(allocationsForResidency, handleId);
}
@@ -587,10 +587,11 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DrmImplicitScalingCommandStreamTest, givenUseSingle
execCalled++;
return 0;
}
void processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
bool processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
EXPECT_EQ(0u, processResidencyCalled);
EXPECT_EQ(0u, handleId);
processResidencyCalled++;
return true;
}
uint32_t execCalled = 0;
@@ -627,10 +628,11 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DrmImplicitScalingCommandStreamTest, givenDisabledI
execCalled++;
return 0;
}
void processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
bool processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
EXPECT_EQ(0u, processResidencyCalled);
EXPECT_EQ(0u, handleId);
processResidencyCalled++;
return true;
}
uint32_t execCalled = 0;
@@ -663,8 +665,9 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DrmImplicitScalingCommandStreamTest, givenMultiTile
execCalled++;
return 0;
}
void processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
bool processResidency(const ResidencyContainer &inputAllocationsForResidency, uint32_t handleId) override {
EXPECT_EQ(execCalled, handleId);
return true;
}
uint32_t execCalled = 0;

View File

@@ -101,8 +101,8 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DrmCommandStreamMultiTileMemExecTest, GivenDrmSuppo
uint64_t expectedCompletionGpuAddress = testCsr->getTagAllocation()->getGpuAddress() + Drm::completionFenceOffset + testCsr->postSyncWriteOffset;
int ret = testCsr->flushInternal(batchBuffer, testCsr->getResidencyAllocations());
EXPECT_EQ(0, ret);
SubmissionStatus ret = testCsr->flushInternal(batchBuffer, testCsr->getResidencyAllocations());
EXPECT_EQ(SubmissionStatus::SUCCESS, ret);
EXPECT_EQ(expectedCompletionGpuAddress, bo.receivedCompletionGpuAddress);
EXPECT_EQ(testCsr->latestSentTaskCount, bo.receivedCompletionValue);

View File

@@ -306,6 +306,22 @@ TEST_F(WddmCommandStreamTest, givenWdmmWhenSubmitIsCalledThenCoherencyRequiredFl
memoryManager->freeGraphicsMemory(commandBuffer);
}
TEST_F(WddmCommandStreamTest, givenFailureFromMakeResidentWhenFlushingThenOutOfMemoryIsReturned) {
GraphicsAllocation *commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
ASSERT_NE(nullptr, commandBuffer);
LinearStream cs(commandBuffer);
wddm->makeResidentNumberOfBytesToTrim = 4 * 4096;
wddm->makeResidentStatus = false;
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false};
SubmissionStatus retVal = csr->flush(batchBuffer, csr->getResidencyAllocations());
EXPECT_EQ(SubmissionStatus::OUT_OF_MEMORY, retVal);
memoryManager->freeGraphicsMemory(commandBuffer);
}
struct WddmPreemptionHeaderFixture {
void setUp() {
executionEnvironment = getExecutionEnvironmentImpl(hwInfo, 1);