Skip to content

Commit 5b429dd

Browse files
fix: usm reuse, check for in use before returning
Signed-off-by: Dominik Dabek <[email protected]>
1 parent dd3d5c6 commit 5b429dd

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

shared/source/memory_manager/unified_memory_manager.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ bool SVMAllocsManager::SvmAllocationCache::allocUtilizationAllows(size_t request
8686
return true;
8787
}
8888

89+
bool SVMAllocsManager::SvmAllocationCache::isInUse(SvmAllocationData *svmData) {
90+
if (svmData->cpuAllocation && memoryManager->allocInUse(*svmData->cpuAllocation)) {
91+
return true;
92+
}
93+
for (auto &gpuAllocation : svmData->gpuAllocations.getGraphicsAllocations()) {
94+
if (gpuAllocation && memoryManager->allocInUse(*gpuAllocation)) {
95+
return true;
96+
}
97+
}
98+
return false;
99+
}
100+
89101
void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties) {
90102
if (false == sizeAllowed(size)) {
91103
return nullptr;
@@ -102,7 +114,8 @@ void *SVMAllocsManager::SvmAllocationCache::get(size_t size, const UnifiedMemory
102114
UNRECOVERABLE_IF(!svmAllocData);
103115
if (svmAllocData->device == unifiedMemoryProperties.device &&
104116
svmAllocData->allocationFlagsProperty.allFlags == unifiedMemoryProperties.allocationFlags.allFlags &&
105-
svmAllocData->allocationFlagsProperty.allAllocFlags == unifiedMemoryProperties.allocationFlags.allAllocFlags) {
117+
svmAllocData->allocationFlagsProperty.allAllocFlags == unifiedMemoryProperties.allocationFlags.allAllocFlags &&
118+
false == isInUse(svmAllocData)) {
106119
if (svmAllocData->device) {
107120
auto lock = svmAllocData->device->obtainAllocationsReuseLock();
108121
svmAllocData->device->recordAllocationGetFromReuse(allocationIter->allocationSize);
@@ -759,6 +772,7 @@ void SVMAllocsManager::initUsmDeviceAllocationsCache(Device &device) {
759772
this->usmDeviceAllocationsCache.allocations.reserve(128u);
760773
}
761774
this->usmDeviceAllocationsCache.svmAllocsManager = this;
775+
this->usmDeviceAllocationsCache.memoryManager = memoryManager;
762776
}
763777

764778
void SVMAllocsManager::initUsmHostAllocationsCache() {

shared/source/memory_manager/unified_memory_manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class SVMAllocsManager {
167167
static bool sizeAllowed(size_t size) { return size <= SvmAllocationCache::maxServicedSize; }
168168
bool insert(size_t size, void *ptr, SvmAllocationData *svmData);
169169
static bool allocUtilizationAllows(size_t requestedSize, size_t reuseCandidateSize);
170+
bool isInUse(SvmAllocationData *svmData);
170171
void *get(size_t size, const UnifiedMemoryProperties &unifiedMemoryProperties);
171172
void trim();
172173

shared/test/unit_test/memory_manager/unified_memory_manager_cache_tests.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,35 @@ TEST(SvmAllocationCacheSimpleTest, givenDifferentSizesWhenCheckingIfSizeAllowsTh
105105
EXPECT_FALSE(SVMAllocsManager::SvmAllocationCache::sizeAllowed(256 * MemoryConstants::megaByte + 1));
106106
}
107107

108+
TEST(SvmAllocationCacheSimpleTest, givenAllocationsWhenCheckingIsInUseThenReturnCorrectValue) {
109+
SVMAllocsManager::SvmAllocationCache allocationCache;
110+
MockMemoryManager memoryManager;
111+
MockSVMAllocsManager svmAllocsManager(&memoryManager, false);
112+
113+
allocationCache.memoryManager = &memoryManager;
114+
allocationCache.svmAllocsManager = &svmAllocsManager;
115+
116+
{
117+
memoryManager.deferAllocInUse = false;
118+
MockGraphicsAllocation gpuGfxAllocation;
119+
SvmAllocationData svmAllocData(mockRootDeviceIndex);
120+
EXPECT_FALSE(allocationCache.isInUse(&svmAllocData));
121+
svmAllocData.gpuAllocations.addAllocation(&gpuGfxAllocation);
122+
EXPECT_FALSE(allocationCache.isInUse(&svmAllocData));
123+
memoryManager.deferAllocInUse = true;
124+
EXPECT_TRUE(allocationCache.isInUse(&svmAllocData));
125+
}
126+
{
127+
memoryManager.deferAllocInUse = false;
128+
MockGraphicsAllocation cpuGfxAllocation;
129+
SvmAllocationData svmAllocData(mockRootDeviceIndex);
130+
svmAllocData.cpuAllocation = &cpuGfxAllocation;
131+
EXPECT_FALSE(allocationCache.isInUse(&svmAllocData));
132+
memoryManager.deferAllocInUse = true;
133+
EXPECT_TRUE(allocationCache.isInUse(&svmAllocData));
134+
}
135+
}
136+
108137
struct SvmAllocationCacheTestFixture {
109138
SvmAllocationCacheTestFixture() : executionEnvironment(defaultHwInfo.get()) {}
110139
void setUp() {
@@ -717,6 +746,38 @@ TEST_F(SvmDeviceAllocationCacheTest, givenAllocationWithIsInternalAllocationSetW
717746
svmManager->trimUSMDeviceAllocCache();
718747
}
719748

749+
TEST_F(SvmDeviceAllocationCacheTest, givenAllocationInUsageWhenAllocatingAfterFreeThenDoNotReuseAllocation) {
750+
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
751+
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
752+
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
753+
DebugManagerStateRestore restore;
754+
debugManager.flags.ExperimentalEnableDeviceAllocationCache.set(1);
755+
auto device = deviceFactory->rootDevices[0];
756+
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
757+
svmManager->initUsmAllocationsCaches(*device);
758+
EXPECT_TRUE(svmManager->usmDeviceAllocationsCacheEnabled);
759+
svmManager->usmDeviceAllocationsCache.maxSize = 1 * MemoryConstants::gigaByte;
760+
761+
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::deviceUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
762+
unifiedMemoryProperties.device = device;
763+
auto allocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
764+
EXPECT_NE(allocation, nullptr);
765+
svmManager->freeSVMAlloc(allocation);
766+
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 1u);
767+
768+
MockMemoryManager *mockMemoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
769+
mockMemoryManager->deferAllocInUse = true;
770+
auto testedAllocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
771+
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 1u);
772+
auto svmData = svmManager->getSVMAlloc(testedAllocation);
773+
EXPECT_NE(nullptr, svmData);
774+
775+
svmManager->freeSVMAlloc(testedAllocation);
776+
EXPECT_EQ(svmManager->usmDeviceAllocationsCache.allocations.size(), 2u);
777+
778+
svmManager->trimUSMDeviceAllocCache();
779+
}
780+
720781
using SvmHostAllocationCacheTest = Test<SvmAllocationCacheTestFixture>;
721782

722783
TEST_F(SvmHostAllocationCacheTest, givenAllocationCacheDisabledWhenCheckingIfEnabledThenItIsDisabled) {
@@ -1278,4 +1339,35 @@ TEST_F(SvmHostAllocationCacheTest, givenHostOutOfMemoryWhenAllocatingThenCacheIs
12781339
svmManager->trimUSMHostAllocCache();
12791340
ASSERT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 0u);
12801341
}
1342+
1343+
TEST_F(SvmHostAllocationCacheTest, givenAllocationInUsageWhenAllocatingAfterFreeThenDoNotReuseAllocation) {
1344+
std::unique_ptr<UltDeviceFactory> deviceFactory(new UltDeviceFactory(1, 1));
1345+
RootDeviceIndicesContainer rootDeviceIndices = {mockRootDeviceIndex};
1346+
std::map<uint32_t, DeviceBitfield> deviceBitfields{{mockRootDeviceIndex, mockDeviceBitfield}};
1347+
DebugManagerStateRestore restore;
1348+
debugManager.flags.ExperimentalEnableHostAllocationCache.set(1);
1349+
auto device = deviceFactory->rootDevices[0];
1350+
auto svmManager = std::make_unique<MockSVMAllocsManager>(device->getMemoryManager(), false);
1351+
svmManager->initUsmAllocationsCaches(*device);
1352+
EXPECT_TRUE(svmManager->usmHostAllocationsCacheEnabled);
1353+
svmManager->usmHostAllocationsCache.maxSize = 1 * MemoryConstants::gigaByte;
1354+
1355+
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::hostUnifiedMemory, 1, rootDeviceIndices, deviceBitfields);
1356+
auto allocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
1357+
EXPECT_NE(allocation, nullptr);
1358+
svmManager->freeSVMAlloc(allocation);
1359+
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 1u);
1360+
1361+
MockMemoryManager *mockMemoryManager = reinterpret_cast<MockMemoryManager *>(device->getMemoryManager());
1362+
mockMemoryManager->deferAllocInUse = true;
1363+
auto testedAllocation = svmManager->createUnifiedMemoryAllocation(10u, unifiedMemoryProperties);
1364+
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 1u);
1365+
auto svmData = svmManager->getSVMAlloc(testedAllocation);
1366+
EXPECT_NE(nullptr, svmData);
1367+
1368+
svmManager->freeSVMAlloc(testedAllocation);
1369+
EXPECT_EQ(svmManager->usmHostAllocationsCache.allocations.size(), 2u);
1370+
1371+
svmManager->trimUSMHostAllocCache();
1372+
}
12811373
} // namespace NEO

0 commit comments

Comments
 (0)