Fix resource destruction scheme on device closure.

- Call waitForTaskCountAndCleanAllocationList with latest flushed task count
to reflect what was actually sent to HW.

- refactor cleanAllocationList to waitForTaskCountAndCleanAllocationList

Change-Id: I5301185c5fce212e39eb017b952b43c279559cf4
This commit is contained in:
Mrozek, Michal
2018-01-12 16:41:45 +01:00
committed by sys_ocldev
parent 42798fcae0
commit af77720f9c
12 changed files with 68 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -409,7 +409,7 @@ void CommandQueueHw<GfxFamily>::enqueueHandler(Surface **surfacesForResidency,
if (printfHandler) { if (printfHandler) {
printfHandler->printEnqueueOutput(); printfHandler->printEnqueueOutput();
} }
commandStreamReceiver.cleanAllocationList(taskCount, TEMPORARY_ALLOCATION); commandStreamReceiver.waitForTaskCountAndCleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -43,7 +43,7 @@ cl_int CommandQueueHw<GfxFamily>::finish(bool dcFlush) {
// Stall until HW reaches CQ taskCount // Stall until HW reaches CQ taskCount
waitUntilComplete(taskCountToWaitFor, flushStampToWaitFor); waitUntilComplete(taskCountToWaitFor, flushStampToWaitFor);
commandStreamReceiver.cleanAllocationList(taskCountToWaitFor, TEMPORARY_ALLOCATION); commandStreamReceiver.waitForTaskCountAndCleanAllocationList(taskCountToWaitFor, TEMPORARY_ALLOCATION);
return CL_SUCCESS; return CL_SUCCESS;
} }

View File

@@ -98,7 +98,7 @@ GraphicsAllocation *CommandStreamReceiver::createAllocationAndHandleResidency(co
return graphicsAllocation; return graphicsAllocation;
} }
void CommandStreamReceiver::cleanAllocationList(uint32_t requiredTaskCount, uint32_t allocationType) { void CommandStreamReceiver::waitForTaskCountAndCleanAllocationList(uint32_t requiredTaskCount, uint32_t allocationType) {
auto address = getTagAddress(); auto address = getTagAddress();
if (address && requiredTaskCount != (unsigned int)-1) { if (address && requiredTaskCount != (unsigned int)-1) {
@@ -153,6 +153,9 @@ void CommandStreamReceiver::cleanupResources() {
if (!memoryManager) if (!memoryManager)
return; return;
waitForTaskCountAndCleanAllocationList(this->latestFlushedTaskCount, TEMPORARY_ALLOCATION);
waitForTaskCountAndCleanAllocationList(this->latestFlushedTaskCount, REUSABLE_ALLOCATION);
if (scratchAllocation) { if (scratchAllocation) {
memoryManager->freeGraphicsMemory(scratchAllocation); memoryManager->freeGraphicsMemory(scratchAllocation);
scratchAllocation = nullptr; scratchAllocation = nullptr;
@@ -162,9 +165,6 @@ void CommandStreamReceiver::cleanupResources() {
memoryManager->freeGraphicsMemory(preemptionCsrAllocation); memoryManager->freeGraphicsMemory(preemptionCsrAllocation);
} }
cleanAllocationList(-1, TEMPORARY_ALLOCATION);
cleanAllocationList(-1, REUSABLE_ALLOCATION);
if (commandStream.getBase()) { if (commandStream.getBase()) {
memoryManager->freeGraphicsMemory(commandStream.getGraphicsAllocation()); memoryManager->freeGraphicsMemory(commandStream.getGraphicsAllocation());
commandStream.replaceGraphicsAllocation(nullptr); commandStream.replaceGraphicsAllocation(nullptr);
@@ -196,7 +196,7 @@ bool CommandStreamReceiver::waitForCompletionWithTimeout(bool enableTimeout, int
void CommandStreamReceiver::setTagAllocation(GraphicsAllocation *allocation) { void CommandStreamReceiver::setTagAllocation(GraphicsAllocation *allocation) {
this->tagAllocation = allocation; this->tagAllocation = allocation;
this->tagAddress = reinterpret_cast<uint32_t *>(allocation->getUnderlyingBuffer()); this->tagAddress = allocation ? reinterpret_cast<uint32_t *>(allocation->getUnderlyingBuffer()) : nullptr;
} }
void CommandStreamReceiver::setRequiredScratchSize(uint32_t newRequiredScratchSize) { void CommandStreamReceiver::setRequiredScratchSize(uint32_t newRequiredScratchSize) {

View File

@@ -75,7 +75,7 @@ class CommandStreamReceiver {
void setMemoryManager(MemoryManager *mm); void setMemoryManager(MemoryManager *mm);
GraphicsAllocation *createAllocationAndHandleResidency(const void *address, size_t size, bool addToDefferFreeList = true); GraphicsAllocation *createAllocationAndHandleResidency(const void *address, size_t size, bool addToDefferFreeList = true);
void cleanAllocationList(uint32_t requiredTaskCount, uint32_t allocationType); void waitForTaskCountAndCleanAllocationList(uint32_t requiredTaskCount, uint32_t allocationType);
LinearStream &getCS(size_t minRequiredSize = 1024u); LinearStream &getCS(size_t minRequiredSize = 1024u);
OSInterface *getOSInterface() { return osInterface.get(); }; OSInterface *getOSInterface() { return osInterface.get(); };

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -83,14 +83,14 @@ Device::Device(const HardwareInfo &hwInfo,
Device::~Device() { Device::~Device() {
DEBUG_BREAK_IF(nullptr == memoryManager); DEBUG_BREAK_IF(nullptr == memoryManager);
if (memoryManager) {
memoryManager->freeGraphicsMemory(tagAllocation);
}
tagAllocation = nullptr;
if (performanceCounters) { if (performanceCounters) {
performanceCounters->shutdown(); performanceCounters->shutdown();
} }
delete commandStreamReceiver; delete commandStreamReceiver;
if (memoryManager) {
memoryManager->freeGraphicsMemory(tagAllocation);
}
tagAllocation = nullptr;
commandStreamReceiver = nullptr; commandStreamReceiver = nullptr;
if (memoryManager) { if (memoryManager) {
memoryManager->waitForDeletions(); memoryManager->waitForDeletions();

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -509,6 +509,7 @@ HWTEST_F(EnqueueThreading, flushWaitList_ReleaseOwnershipWhenQueueIsBlocked) {
pMyDevice->setMemoryManager(memoryManager); pMyDevice->setMemoryManager(memoryManager);
auto pTagAllocation = memoryManager->allocateGraphicsMemory(sizeof(uint32_t), sizeof(uint32_t)); auto pTagAllocation = memoryManager->allocateGraphicsMemory(sizeof(uint32_t), sizeof(uint32_t));
*(uint32_t *)(pTagAllocation->getUnderlyingBuffer()) = initialHardwareTag;
ASSERT_NE(nullptr, pTagAllocation); ASSERT_NE(nullptr, pTagAllocation);
pMyDevice->setTagAllocation(pTagAllocation); pMyDevice->setTagAllocation(pTagAllocation);

View File

@@ -2823,3 +2823,40 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenThreeTas
auto ppcAfterChange = genCmdCast<typename FamilyType::PIPE_CONTROL *>(ppc3); auto ppcAfterChange = genCmdCast<typename FamilyType::PIPE_CONTROL *>(ppc3);
EXPECT_NE(nullptr, ppcAfterChange); EXPECT_NE(nullptr, ppcAfterChange);
} }
typedef UltCommandStreamReceiverTest CommandStreamReceiverCleanupTests;
HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrWhenTemporaryAndReusableAllocationsArePresentThenCleanupResourcesOnlyCleansThoseAboveLatestFlushTaskLevel) {
auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver<FamilyType>();
auto memoryManager = pDevice->getMemoryManager();
auto temporaryToClean = memoryManager->allocateGraphicsMemory(4096u);
auto temporaryToHold = memoryManager->allocateGraphicsMemory(4096u);
auto reusableToClean = memoryManager->allocateGraphicsMemory(4096u);
auto reusableToHold = memoryManager->allocateGraphicsMemory(4096u);
memoryManager->storeAllocation(std::unique_ptr<GraphicsAllocation>(temporaryToClean), TEMPORARY_ALLOCATION);
memoryManager->storeAllocation(std::unique_ptr<GraphicsAllocation>(temporaryToHold), TEMPORARY_ALLOCATION);
memoryManager->storeAllocation(std::unique_ptr<GraphicsAllocation>(reusableToClean), REUSABLE_ALLOCATION);
memoryManager->storeAllocation(std::unique_ptr<GraphicsAllocation>(reusableToHold), REUSABLE_ALLOCATION);
temporaryToClean->taskCount = 1;
reusableToClean->taskCount = 1;
temporaryToHold->taskCount = 10;
reusableToHold->taskCount = 10;
commandStreamReceiver.latestFlushedTaskCount = 9;
commandStreamReceiver.cleanupResources();
EXPECT_EQ(reusableToHold, memoryManager->allocationsForReuse.peekHead());
EXPECT_EQ(reusableToHold, memoryManager->allocationsForReuse.peekTail());
EXPECT_EQ(temporaryToHold, memoryManager->graphicsAllocations.peekHead());
EXPECT_EQ(temporaryToHold, memoryManager->graphicsAllocations.peekTail());
commandStreamReceiver.latestFlushedTaskCount = 11;
commandStreamReceiver.cleanupResources();
EXPECT_TRUE(memoryManager->allocationsForReuse.peekIsEmpty());
EXPECT_TRUE(memoryManager->graphicsAllocations.peekIsEmpty());
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -909,7 +909,7 @@ TEST_F(EventTests, waitForEventsDestroysTemporaryAllocations) {
MemoryManager *memoryManager = csr.getMemoryManager(); MemoryManager *memoryManager = csr.getMemoryManager();
//kill some temporary objects that fixture creates. //kill some temporary objects that fixture creates.
csr.cleanAllocationList(-1, TEMPORARY_ALLOCATION); csr.waitForTaskCountAndCleanAllocationList(-1, TEMPORARY_ALLOCATION);
EXPECT_TRUE(memoryManager->graphicsAllocations.peekIsEmpty()); EXPECT_TRUE(memoryManager->graphicsAllocations.peekIsEmpty());

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -46,6 +46,7 @@ class UltCommandStreamReceiver : public CommandStreamReceiverHw<GfxFamily> {
using BaseClass::CommandStreamReceiver::lastSentCoherencyRequest; using BaseClass::CommandStreamReceiver::lastSentCoherencyRequest;
using BaseClass::CommandStreamReceiver::lastSentL3Config; using BaseClass::CommandStreamReceiver::lastSentL3Config;
using BaseClass::CommandStreamReceiver::lastSentThreadAribtrationPolicy; using BaseClass::CommandStreamReceiver::lastSentThreadAribtrationPolicy;
using BaseClass::CommandStreamReceiver::latestFlushedTaskCount;
using BaseClass::CommandStreamReceiver::latestSentStatelessMocsConfig; using BaseClass::CommandStreamReceiver::latestSentStatelessMocsConfig;
using BaseClass::CommandStreamReceiver::taskCount; using BaseClass::CommandStreamReceiver::taskCount;
using BaseClass::CommandStreamReceiver::taskLevel; using BaseClass::CommandStreamReceiver::taskLevel;
@@ -77,16 +78,17 @@ class UltCommandStreamReceiver : public CommandStreamReceiverHw<GfxFamily> {
} }
protected: protected:
using BaseClass::CommandStreamReceiver::cleanAllocationList;
using BaseClass::CommandStreamReceiver::memoryManager; using BaseClass::CommandStreamReceiver::memoryManager;
using BaseClass::CommandStreamReceiver::tagAddress; using BaseClass::CommandStreamReceiver::tagAddress;
using BaseClass::CommandStreamReceiver::tagAllocation; using BaseClass::CommandStreamReceiver::tagAllocation;
using BaseClass::CommandStreamReceiver::waitForTaskCountAndCleanAllocationList;
GraphicsAllocation *tempTagLocation; GraphicsAllocation *tempTagLocation;
}; };
template <typename GfxFamily> template <typename GfxFamily>
UltCommandStreamReceiver<GfxFamily>::~UltCommandStreamReceiver() { UltCommandStreamReceiver<GfxFamily>::~UltCommandStreamReceiver() {
this->setTagAllocation(nullptr);
delete tempTagLocation; delete tempTagLocation;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Intel Corporation * Copyright (c) 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"),
@@ -981,6 +981,7 @@ TEST_F(DrmCommandStreamBatchingTests, givenCsrWhenDispatchPolicyIsSetToBatchingT
mm->freeGraphicsMemory(dummyAllocation); mm->freeGraphicsMemory(dummyAllocation);
mm->freeGraphicsMemory(commandBuffer); mm->freeGraphicsMemory(commandBuffer);
mm->freeGraphicsMemory(tagAllocation); mm->freeGraphicsMemory(tagAllocation);
tCsr->setTagAllocation(nullptr);
} }
TEST_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhenItIsSubmittedThenFlushTaskIsProperlyCalled) { TEST_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhenItIsSubmittedThenFlushTaskIsProperlyCalled) {
@@ -1043,6 +1044,7 @@ TEST_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhenItIsSubmitte
mm->freeGraphicsMemory(dummyAllocation); mm->freeGraphicsMemory(dummyAllocation);
mm->freeGraphicsMemory(commandBuffer); mm->freeGraphicsMemory(commandBuffer);
mm->freeGraphicsMemory(tagAllocation); mm->freeGraphicsMemory(tagAllocation);
tCsr->setTagAllocation(nullptr);
} }
typedef Test<DrmCommandStreamEnhancedFixture> DrmCommandStreamLeaksTest; typedef Test<DrmCommandStreamEnhancedFixture> DrmCommandStreamLeaksTest;

View File

@@ -114,6 +114,8 @@ class WddmCommandStreamWithMockGdiFixture : public WddmFixture {
mm->device = device; mm->device = device;
tagAllocation = mm->allocateGraphicsMemory(1024, 4096); tagAllocation = mm->allocateGraphicsMemory(1024, 4096);
auto tagBuffer = (uint32_t *)tagAllocation->getUnderlyingBuffer();
tagBuffer[0] = initialHardwareTag;
} }
void TearDown() { void TearDown() {
@@ -339,7 +341,7 @@ TEST_F(WddmCommandStreamTest, killAllTemporaryAllocation) {
ASSERT_NE(nullptr, graphicsAllocation); ASSERT_NE(nullptr, graphicsAllocation);
graphicsAllocation->taskCount = 1; graphicsAllocation->taskCount = 1;
csr->cleanAllocationList(-1, TEMPORARY_ALLOCATION); csr->waitForTaskCountAndCleanAllocationList(-1, TEMPORARY_ALLOCATION);
//no memory leaks reported makes this test pass. //no memory leaks reported makes this test pass.
} }
@@ -356,7 +358,7 @@ TEST_F(WddmCommandStreamTest, killCompletedAllocations) {
graphicsAllocation->taskCount = 1; graphicsAllocation->taskCount = 1;
graphicsAllocation2->taskCount = 100; graphicsAllocation2->taskCount = 100;
csr->cleanAllocationList(1, TEMPORARY_ALLOCATION); csr->waitForTaskCountAndCleanAllocationList(1, TEMPORARY_ALLOCATION);
//graphicsAllocation2 still lives //graphicsAllocation2 still lives
EXPECT_EQ(host_ptr2, graphicsAllocation2->getUnderlyingBuffer()); EXPECT_EQ(host_ptr2, graphicsAllocation2->getUnderlyingBuffer());