Skip to content

Commit 477a06a

Browse files
Move creation of os storage for host ptr allocation to host ptr manager
Change-Id: If7b6c17e21c72c807031232a502265559dfa48b1 Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
1 parent f374696 commit 477a06a

File tree

5 files changed

+88
-103
lines changed

5 files changed

+88
-103
lines changed

runtime/memory_manager/host_ptr_manager.cpp

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
*
66
*/
77

8-
#include "host_ptr_manager.h"
8+
#include "runtime/command_stream/command_stream_receiver.h"
99
#include "runtime/helpers/ptr_math.h"
1010
#include "runtime/helpers/abort.h"
11+
#include "runtime/memory_manager/memory_manager.h"
1112

1213
using namespace OCLRT;
1314

14-
std::map<const void *, FragmentStorage>::iterator OCLRT::HostPtrManager::findElement(const void *ptr) {
15+
std::map<const void *, FragmentStorage>::iterator HostPtrManager::findElement(const void *ptr) {
1516
auto nextElement = partialAllocations.lower_bound(ptr);
1617
auto element = nextElement;
1718
if (element != partialAllocations.end()) {
@@ -43,7 +44,7 @@ std::map<const void *, FragmentStorage>::iterator OCLRT::HostPtrManager::findEle
4344
return partialAllocations.end();
4445
}
4546

46-
AllocationRequirements OCLRT::HostPtrManager::getAllocationRequirements(const void *inputPtr, size_t size) {
47+
AllocationRequirements HostPtrManager::getAllocationRequirements(const void *inputPtr, size_t size) {
4748
AllocationRequirements requiredAllocations;
4849

4950
auto allocationCount = 0;
@@ -89,7 +90,7 @@ AllocationRequirements OCLRT::HostPtrManager::getAllocationRequirements(const vo
8990
return requiredAllocations;
9091
}
9192

92-
OsHandleStorage OCLRT::HostPtrManager::populateAlreadyAllocatedFragments(AllocationRequirements &requirements, CheckedFragments *checkedFragments) {
93+
OsHandleStorage HostPtrManager::populateAlreadyAllocatedFragments(AllocationRequirements &requirements, CheckedFragments *checkedFragments) {
9394
OsHandleStorage handleStorage;
9495
for (unsigned int i = 0; i < requirements.requiredFragmentsCount; i++) {
9596
OverlapStatus overlapStatus = OverlapStatus::FRAGMENT_NOT_CHECKED;
@@ -133,8 +134,8 @@ OsHandleStorage OCLRT::HostPtrManager::populateAlreadyAllocatedFragments(Allocat
133134
return handleStorage;
134135
}
135136

136-
void OCLRT::HostPtrManager::storeFragment(FragmentStorage &fragment) {
137-
std::lock_guard<std::mutex> lock(allocationsMutex);
137+
void HostPtrManager::storeFragment(FragmentStorage &fragment) {
138+
std::lock_guard<decltype(allocationsMutex)> lock(allocationsMutex);
138139
auto element = findElement(fragment.fragmentCpuPointer);
139140
if (element != partialAllocations.end()) {
140141
element->second.refCount++;
@@ -144,7 +145,7 @@ void OCLRT::HostPtrManager::storeFragment(FragmentStorage &fragment) {
144145
}
145146
}
146147

147-
void OCLRT::HostPtrManager::storeFragment(AllocationStorageData &storageData) {
148+
void HostPtrManager::storeFragment(AllocationStorageData &storageData) {
148149
FragmentStorage fragment;
149150
fragment.fragmentCpuPointer = const_cast<void *>(storageData.cpuPtr);
150151
fragment.fragmentSize = storageData.fragmentSize;
@@ -153,16 +154,16 @@ void OCLRT::HostPtrManager::storeFragment(AllocationStorageData &storageData) {
153154
storeFragment(fragment);
154155
}
155156

156-
void OCLRT::HostPtrManager::releaseHandleStorage(OsHandleStorage &fragments) {
157+
void HostPtrManager::releaseHandleStorage(OsHandleStorage &fragments) {
157158
for (int i = 0; i < maxFragmentsCount; i++) {
158159
if (fragments.fragmentStorageData[i].fragmentSize || fragments.fragmentStorageData[i].cpuPtr) {
159160
fragments.fragmentStorageData[i].freeTheFragment = releaseHostPtr(fragments.fragmentStorageData[i].cpuPtr);
160161
}
161162
}
162163
}
163164

164-
bool OCLRT::HostPtrManager::releaseHostPtr(const void *ptr) {
165-
std::lock_guard<std::mutex> lock(allocationsMutex);
165+
bool HostPtrManager::releaseHostPtr(const void *ptr) {
166+
std::lock_guard<decltype(allocationsMutex)> lock(allocationsMutex);
166167
bool fragmentReadyToBeReleased = false;
167168

168169
auto element = findElement(ptr);
@@ -178,8 +179,8 @@ bool OCLRT::HostPtrManager::releaseHostPtr(const void *ptr) {
178179
return fragmentReadyToBeReleased;
179180
}
180181

181-
FragmentStorage *OCLRT::HostPtrManager::getFragment(const void *inputPtr) {
182-
std::lock_guard<std::mutex> lock(allocationsMutex);
182+
FragmentStorage *HostPtrManager::getFragment(const void *inputPtr) {
183+
std::lock_guard<decltype(allocationsMutex)> lock(allocationsMutex);
183184
auto element = findElement(inputPtr);
184185
if (element != partialAllocations.end()) {
185186
return &element->second;
@@ -188,8 +189,8 @@ FragmentStorage *OCLRT::HostPtrManager::getFragment(const void *inputPtr) {
188189
}
189190

190191
//for given inputs see if any allocation overlaps
191-
FragmentStorage *OCLRT::HostPtrManager::getFragmentAndCheckForOverlaps(const void *inPtr, size_t size, OverlapStatus &overlappingStatus) {
192-
std::lock_guard<std::mutex> lock(allocationsMutex);
192+
FragmentStorage *HostPtrManager::getFragmentAndCheckForOverlaps(const void *inPtr, size_t size, OverlapStatus &overlappingStatus) {
193+
std::lock_guard<decltype(allocationsMutex)> lock(allocationsMutex);
193194
void *inputPtr = const_cast<void *>(inPtr);
194195
auto nextElement = partialAllocations.lower_bound(inputPtr);
195196
auto element = nextElement;
@@ -246,3 +247,64 @@ FragmentStorage *OCLRT::HostPtrManager::getFragmentAndCheckForOverlaps(const voi
246247
}
247248
return nullptr;
248249
}
250+
251+
OsHandleStorage HostPtrManager::prepareOsStorageForAllocation(MemoryManager &memoryManager, size_t size, const void *ptr) {
252+
std::lock_guard<decltype(allocationsMutex)> lock(allocationsMutex);
253+
auto requirements = HostPtrManager::getAllocationRequirements(ptr, size);
254+
255+
CheckedFragments checkedFragments;
256+
UNRECOVERABLE_IF(checkAllocationsForOverlapping(memoryManager, &requirements, &checkedFragments) == RequirementsStatus::FATAL);
257+
258+
auto osStorage = populateAlreadyAllocatedFragments(requirements, &checkedFragments);
259+
if (osStorage.fragmentCount > 0) {
260+
if (memoryManager.populateOsHandles(osStorage) != MemoryManager::AllocationStatus::Success) {
261+
memoryManager.cleanOsHandles(osStorage);
262+
osStorage.fragmentCount = 0;
263+
}
264+
}
265+
return osStorage;
266+
}
267+
268+
RequirementsStatus HostPtrManager::checkAllocationsForOverlapping(MemoryManager &memoryManager, AllocationRequirements *requirements, CheckedFragments *checkedFragments) {
269+
DEBUG_BREAK_IF(requirements == nullptr);
270+
DEBUG_BREAK_IF(checkedFragments == nullptr);
271+
272+
RequirementsStatus status = RequirementsStatus::SUCCESS;
273+
checkedFragments->count = 0;
274+
275+
for (unsigned int i = 0; i < maxFragmentsCount; i++) {
276+
checkedFragments->status[i] = OverlapStatus::FRAGMENT_NOT_CHECKED;
277+
checkedFragments->fragments[i] = nullptr;
278+
}
279+
for (unsigned int i = 0; i < requirements->requiredFragmentsCount; i++) {
280+
checkedFragments->count++;
281+
checkedFragments->fragments[i] = getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
282+
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
283+
// clean temporary allocations
284+
285+
auto commandStreamReceiver = memoryManager.getCommandStreamReceiver(0);
286+
uint32_t taskCount = *commandStreamReceiver->getTagAddress();
287+
memoryManager.cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
288+
289+
// check overlapping again
290+
checkedFragments->fragments[i] = getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
291+
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
292+
293+
// Wait for completion
294+
while (*commandStreamReceiver->getTagAddress() < commandStreamReceiver->peekLatestSentTaskCount())
295+
;
296+
297+
taskCount = *commandStreamReceiver->getTagAddress();
298+
memoryManager.cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
299+
300+
// check overlapping last time
301+
checkedFragments->fragments[i] = getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
302+
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
303+
status = RequirementsStatus::FATAL;
304+
break;
305+
}
306+
}
307+
}
308+
}
309+
return status;
310+
}

runtime/memory_manager/host_ptr_manager.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace OCLRT {
1515

1616
typedef std::map<const void *, FragmentStorage> HostPtrFragmentsContainer;
17-
17+
class MemoryManager;
1818
class HostPtrManager {
1919
public:
2020
static AllocationRequirements getAllocationRequirements(const void *inputPtr, size_t size);
@@ -28,11 +28,13 @@ class HostPtrManager {
2828
FragmentStorage *getFragment(const void *inputPtr);
2929
size_t getFragmentCount() { return partialAllocations.size(); }
3030
FragmentStorage *getFragmentAndCheckForOverlaps(const void *inputPtr, size_t size, OverlapStatus &overlappingStatus);
31+
OsHandleStorage prepareOsStorageForAllocation(MemoryManager &memoryManager, size_t size, const void *ptr);
32+
RequirementsStatus checkAllocationsForOverlapping(MemoryManager &memoryManager, AllocationRequirements *requirements, CheckedFragments *checkedFragments);
3133

3234
private:
3335
std::map<const void *, FragmentStorage>::iterator findElement(const void *ptr);
3436

3537
HostPtrFragmentsContainer partialAllocations;
36-
std::mutex allocationsMutex;
38+
std::recursive_mutex allocationsMutex;
3739
};
3840
} // namespace OCLRT

runtime/memory_manager/memory_manager.cpp

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -116,31 +116,14 @@ GraphicsAllocation *MemoryManager::allocateGraphicsMemoryForSVM(size_t size, boo
116116

117117
GraphicsAllocation *MemoryManager::allocateGraphicsMemory(size_t size, const void *ptr, bool forcePin) {
118118
std::lock_guard<decltype(mtx)> lock(mtx);
119-
auto requirements = HostPtrManager::getAllocationRequirements(ptr, size);
120-
GraphicsAllocation *graphicsAllocation = nullptr;
121-
122119
if (deferredDeleter) {
123120
deferredDeleter->drain(true);
124121
}
125-
126-
//check for overlaping
127-
CheckedFragments checkedFragments;
128-
if (checkAllocationsForOverlapping(&requirements, &checkedFragments) == RequirementsStatus::FATAL) {
129-
//abort whole application instead of silently passing.
130-
abortExecution();
131-
}
132-
133-
auto osStorage = hostPtrManager.populateAlreadyAllocatedFragments(requirements, &checkedFragments);
134-
if (osStorage.fragmentCount == 0) {
135-
return nullptr;
136-
}
137-
auto result = populateOsHandles(osStorage);
138-
if (result != AllocationStatus::Success) {
139-
cleanOsHandles(osStorage);
140-
return nullptr;
122+
GraphicsAllocation *graphicsAllocation = nullptr;
123+
auto osStorage = hostPtrManager.prepareOsStorageForAllocation(*this, size, ptr);
124+
if (osStorage.fragmentCount > 0) {
125+
graphicsAllocation = createGraphicsAllocation(osStorage, size, ptr);
141126
}
142-
143-
graphicsAllocation = createGraphicsAllocation(osStorage, size, ptr);
144127
return graphicsAllocation;
145128
}
146129

@@ -261,50 +244,6 @@ bool MemoryManager::isMemoryBudgetExhausted() const {
261244
return false;
262245
}
263246

264-
RequirementsStatus MemoryManager::checkAllocationsForOverlapping(AllocationRequirements *requirements, CheckedFragments *checkedFragments) {
265-
DEBUG_BREAK_IF(requirements == nullptr);
266-
DEBUG_BREAK_IF(checkedFragments == nullptr);
267-
268-
RequirementsStatus status = RequirementsStatus::SUCCESS;
269-
checkedFragments->count = 0;
270-
271-
for (unsigned int i = 0; i < maxFragmentsCount; i++) {
272-
checkedFragments->status[i] = OverlapStatus::FRAGMENT_NOT_CHECKED;
273-
checkedFragments->fragments[i] = nullptr;
274-
}
275-
276-
for (unsigned int i = 0; i < requirements->requiredFragmentsCount; i++) {
277-
checkedFragments->count++;
278-
checkedFragments->fragments[i] = hostPtrManager.getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
279-
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
280-
// clean temporary allocations
281-
282-
uint32_t taskCount = *getCommandStreamReceiver(0)->getTagAddress();
283-
cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
284-
285-
// check overlapping again
286-
checkedFragments->fragments[i] = hostPtrManager.getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
287-
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
288-
289-
// Wait for completion
290-
while (*getCommandStreamReceiver(0)->getTagAddress() < getCommandStreamReceiver(0)->peekLatestSentTaskCount()) {
291-
}
292-
293-
taskCount = *getCommandStreamReceiver(0)->getTagAddress();
294-
cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
295-
296-
// check overlapping last time
297-
checkedFragments->fragments[i] = hostPtrManager.getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
298-
if (checkedFragments->status[i] == OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT) {
299-
status = RequirementsStatus::FATAL;
300-
break;
301-
}
302-
}
303-
}
304-
}
305-
return status;
306-
}
307-
308247
void MemoryManager::registerOsContext(OsContext *contextToRegister) {
309248
auto contextId = contextToRegister->getContextId();
310249
if (contextId + 1 > registeredOsContexts.size()) {

runtime/memory_manager/memory_manager.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,6 @@ class MemoryManager {
207207
void storeAllocation(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage);
208208
void storeAllocation(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage, uint32_t taskCount);
209209

210-
RequirementsStatus checkAllocationsForOverlapping(AllocationRequirements *requirements, CheckedFragments *checkedFragments);
211-
212210
TagAllocator<HwTimeStamps> *getEventTsAllocator();
213211
TagAllocator<HwPerfCounter> *getEventPerfCountAllocator();
214212
TagAllocator<TimestampPacket> *getTimestampPacketAllocator();

unit_tests/memory_manager/memory_manager_tests.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,22 +1237,6 @@ TEST(OsAgnosticMemoryManager, GivenEnabled64kbPagesWhenHostMemoryAllocationIsCre
12371237
memoryManager.freeGraphicsMemory(galloc);
12381238
}
12391239

1240-
TEST(OsAgnosticMemoryManager, checkAllocationsForOverlappingWithNullCsrInMemoryManager) {
1241-
ExecutionEnvironment executionEnvironment;
1242-
OsAgnosticMemoryManager memoryManager(false, false, executionEnvironment);
1243-
1244-
AllocationRequirements requirements;
1245-
CheckedFragments checkedFragments;
1246-
1247-
requirements.requiredFragmentsCount = 1;
1248-
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
1249-
1250-
RequirementsStatus status = memoryManager.checkAllocationsForOverlapping(&requirements, &checkedFragments);
1251-
1252-
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
1253-
EXPECT_EQ(1u, checkedFragments.count);
1254-
}
1255-
12561240
TEST(OsAgnosticMemoryManager, givenPointerAndSizeWhenCreateInternalAllocationIsCalledThenGraphicsAllocationIsReturned) {
12571241
ExecutionEnvironment executionEnvironment;
12581242
OsAgnosticMemoryManager memoryManager(false, false, executionEnvironment);
@@ -1478,7 +1462,7 @@ TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithoutBiggerOver
14781462
requirements.AllocationFragments[1].allocationSize = MemoryConstants::pageSize;
14791463
requirements.AllocationFragments[1].fragmentPosition = FragmentPosition::TRAILING;
14801464

1481-
RequirementsStatus status = memoryManager->checkAllocationsForOverlapping(&requirements, &checkedFragments);
1465+
RequirementsStatus status = memoryManager->hostPtrManager.checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
14821466

14831467
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
14841468
EXPECT_EQ(2u, checkedFragments.count);
@@ -1528,7 +1512,7 @@ TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlap
15281512
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
15291513
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
15301514

1531-
RequirementsStatus status = memoryManager->checkAllocationsForOverlapping(&requirements, &checkedFragments);
1515+
RequirementsStatus status = memoryManager->hostPtrManager.checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
15321516

15331517
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
15341518
EXPECT_EQ(1u, checkedFragments.count);
@@ -1584,7 +1568,7 @@ TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlap
15841568

15851569
EXPECT_CALL(*gmockMemoryManager, cleanAllocationList(::testing::_, ::testing::_)).Times(2).WillOnce(::testing::Invoke(cleanAllocations)).WillOnce(::testing::Invoke(cleanAllocationsWithTaskCount));
15861570

1587-
RequirementsStatus status = memoryManager->checkAllocationsForOverlapping(&requirements, &checkedFragments);
1571+
RequirementsStatus status = memoryManager->hostPtrManager.checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
15881572

15891573
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
15901574
EXPECT_EQ(1u, checkedFragments.count);
@@ -1636,7 +1620,7 @@ TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlap
16361620

16371621
EXPECT_CALL(*gmockMemoryManager, cleanAllocationList(::testing::_, ::testing::_)).Times(2).WillRepeatedly(::testing::Invoke(cleanAllocations));
16381622

1639-
RequirementsStatus status = memoryManager->checkAllocationsForOverlapping(&requirements, &checkedFragments);
1623+
RequirementsStatus status = memoryManager->hostPtrManager.checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
16401624

16411625
EXPECT_EQ(RequirementsStatus::FATAL, status);
16421626
EXPECT_EQ(1u, checkedFragments.count);

0 commit comments

Comments
 (0)