1 /*
2 * Copyright (C) 2020-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #include "shared/source/execution_environment/execution_environment.h"
9 #include "shared/source/gmm_helper/gmm_helper.h"
10 #include "shared/source/helpers/heap_assigner.h"
11 #include "shared/source/os_interface/linux/allocator_helper.h"
12 #include "shared/source/os_interface/linux/drm_memory_manager.h"
13 #include "shared/source/os_interface/linux/drm_memory_operations_handler.h"
14 #include "shared/source/os_interface/os_interface.h"
15 #include "shared/test/common/helpers/debug_manager_state_restore.h"
16 #include "shared/test/common/mocks/linux/mock_drm_memory_manager.h"
17 #include "shared/test/common/mocks/mock_execution_environment.h"
18 #include "shared/test/common/mocks/mock_gmm.h"
19 #include "shared/test/common/test_macros/test.h"
20
21 #include "opencl/test/unit_test/mocks/mock_context.h"
22 #include "opencl/test/unit_test/mocks/mock_platform.h"
23 #include "opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests_impl.h"
24 #include "opencl/test/unit_test/os_interface/linux/drm_mock_impl.h"
25 #include "opencl/test/unit_test/os_interface/linux/drm_mock_memory_info.h"
26
27 #include "gtest/gtest.h"
28
29 namespace NEO {
30
31 BufferObject *createBufferObjectInMemoryRegion(Drm *drm, uint64_t gpuAddress, size_t size, uint32_t memoryBanks, size_t maxOsContextCount);
32
33 class DrmMemoryManagerLocalMemoryTest : public ::testing::Test {
34 public:
35 DrmTipMock *mock;
36
SetUp()37 void SetUp() override {
38 const bool localMemoryEnabled = true;
39 executionEnvironment = new ExecutionEnvironment;
40 executionEnvironment->prepareRootDeviceEnvironments(1);
41 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->setHwInfo(defaultHwInfo.get());
42 mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
43 mock->memoryInfo.reset(new MockMemoryInfo());
44 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface = std::make_unique<OSInterface>();
45 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
46 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
47
48 device.reset(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, rootDeviceIndex));
49 memoryManager = std::make_unique<TestedDrmMemoryManager>(localMemoryEnabled, false, false, *executionEnvironment);
50 }
51
isAllocationWithinHeap(const GraphicsAllocation & allocation,HeapIndex heap)52 bool isAllocationWithinHeap(const GraphicsAllocation &allocation, HeapIndex heap) {
53 const auto allocationStart = allocation.getGpuAddress();
54 const auto allocationEnd = allocationStart + allocation.getUnderlyingBufferSize();
55 const auto heapStart = GmmHelper::canonize(memoryManager->getGfxPartition(rootDeviceIndex)->getHeapBase(heap));
56 const auto heapEnd = GmmHelper::canonize(memoryManager->getGfxPartition(rootDeviceIndex)->getHeapLimit(heap));
57 return heapStart <= allocationStart && allocationEnd <= heapEnd;
58 }
59
60 protected:
61 DebugManagerStateRestore restorer{};
62 ExecutionEnvironment *executionEnvironment = nullptr;
63 std::unique_ptr<MockDevice> device;
64 std::unique_ptr<TestedDrmMemoryManager> memoryManager;
65 const uint32_t rootDeviceIndex = 0u;
66 };
67
68 class DrmMemoryManagerLocalMemoryWithCustomMockTest : public ::testing::Test {
69 public:
70 DrmMockCustomImpl *mock;
71
SetUp()72 void SetUp() override {
73 const bool localMemoryEnabled = true;
74 executionEnvironment = new ExecutionEnvironment;
75 executionEnvironment->prepareRootDeviceEnvironments(1);
76 executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get());
77 mock = new DrmMockCustomImpl(*executionEnvironment->rootDeviceEnvironments[0]);
78 executionEnvironment->rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
79 executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
80
81 device.reset(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0));
82 memoryManager = std::make_unique<TestedDrmMemoryManager>(localMemoryEnabled, false, false, *executionEnvironment);
83 }
84
85 protected:
86 ExecutionEnvironment *executionEnvironment = nullptr;
87 std::unique_ptr<MockDevice> device;
88 std::unique_ptr<TestedDrmMemoryManager> memoryManager;
89 };
90
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenDrmMemoryManagerWhenCreateBufferObjectInMemoryRegionIsCalledThenBufferObjectWithAGivenGpuAddressAndSizeIsCreatedAndAllocatedInASpecifiedMemoryRegion,NonDefaultIoctlsSupported)91 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenDrmMemoryManagerWhenCreateBufferObjectInMemoryRegionIsCalledThenBufferObjectWithAGivenGpuAddressAndSizeIsCreatedAndAllocatedInASpecifiedMemoryRegion, NonDefaultIoctlsSupported) {
92 DebugManagerStateRestore restorer;
93 DebugManager.flags.EnableLocalMemory.set(1);
94 MemoryRegion regionInfo[2] = {};
95 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
96 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
97
98 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
99 mock->ioctlCallsCount = 0;
100
101 auto gpuAddress = 0x1234u;
102 auto size = MemoryConstants::pageSize64k;
103
104 auto bo = std::unique_ptr<BufferObject>(memoryManager->createBufferObjectInMemoryRegion(&memoryManager->getDrm(0),
105 gpuAddress,
106 size,
107 (1 << (MemoryBanks::getBankForLocalMemory(0) - 1)),
108 1));
109 ASSERT_NE(nullptr, bo);
110 EXPECT_EQ(1u, mock->ioctlCallsCount);
111 EXPECT_EQ(1u, mock->createExt.handle);
112 EXPECT_EQ(size, mock->createExt.size);
113
114 EXPECT_EQ(1u, mock->numRegions);
115 auto memRegions = mock->memRegions;
116 EXPECT_EQ(I915_MEMORY_CLASS_DEVICE, memRegions.memory_class);
117 EXPECT_EQ(0u, memRegions.memory_instance);
118
119 EXPECT_EQ(gpuAddress, bo->peekAddress());
120 EXPECT_EQ(size, bo->peekSize());
121 }
122
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationThenImportAndExportIoctlAreUsed,NonDefaultIoctlsSupported)123 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationThenImportAndExportIoctlAreUsed, NonDefaultIoctlsSupported) {
124 uint32_t rootDevicesNumber = 3u;
125 MultiGraphicsAllocation multiGraphics(rootDevicesNumber);
126 std::vector<uint32_t> rootDeviceIndices;
127 auto osInterface = executionEnvironment->rootDeviceEnvironments[0]->osInterface.release();
128
129 executionEnvironment->prepareRootDeviceEnvironments(rootDevicesNumber);
130 for (uint32_t i = 0; i < rootDevicesNumber; i++) {
131 executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(defaultHwInfo.get());
132 auto mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[i]);
133
134 MemoryRegion regionInfo[2] = {};
135 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
136 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
137
138 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
139 mock->ioctlCallsCount = 0;
140 executionEnvironment->rootDeviceEnvironments[i]->osInterface = std::make_unique<OSInterface>();
141 executionEnvironment->rootDeviceEnvironments[i]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
142 executionEnvironment->rootDeviceEnvironments[i]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
143
144 rootDeviceIndices.push_back(i);
145 }
146 auto memoryManager = std::make_unique<TestedDrmMemoryManager>(true, false, false, *executionEnvironment);
147
148 size_t size = 4096u;
149 AllocationProperties properties(rootDeviceIndex, true, size, GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, {});
150
151 static_cast<DrmTipMock *>(executionEnvironment->rootDeviceEnvironments[0]->osInterface->getDriverModel()->as<Drm>())->outputFd = 7;
152
153 auto ptr = memoryManager->createMultiGraphicsAllocationInSystemMemoryPool(rootDeviceIndices, properties, multiGraphics);
154
155 EXPECT_NE(ptr, nullptr);
156 EXPECT_NE(static_cast<DrmAllocation *>(multiGraphics.getDefaultGraphicsAllocation())->getMmapPtr(), nullptr);
157 for (uint32_t i = 0; i < rootDevicesNumber; i++) {
158 if (i != 0) {
159 EXPECT_EQ(static_cast<DrmTipMock *>(executionEnvironment->rootDeviceEnvironments[i]->osInterface->getDriverModel()->as<Drm>())->inputFd, 7);
160 }
161 EXPECT_NE(multiGraphics.getGraphicsAllocation(i), nullptr);
162 memoryManager->freeGraphicsMemory(multiGraphics.getGraphicsAllocation(i));
163 }
164
165 executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface);
166 }
167
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationAndImportFailsThenNullptrIsReturned)168 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationAndImportFailsThenNullptrIsReturned) {
169 uint32_t rootDevicesNumber = 3u;
170 MultiGraphicsAllocation multiGraphics(rootDevicesNumber);
171 std::vector<uint32_t> rootDeviceIndices;
172 auto osInterface = executionEnvironment->rootDeviceEnvironments[0]->osInterface.release();
173
174 executionEnvironment->prepareRootDeviceEnvironments(rootDevicesNumber);
175 for (uint32_t i = 0; i < rootDevicesNumber; i++) {
176 executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(defaultHwInfo.get());
177 auto mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[i]);
178
179 MemoryRegion regionInfo[2] = {};
180 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
181 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
182
183 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
184 mock->ioctlCallsCount = 0;
185 mock->fdToHandleRetVal = -1;
186 executionEnvironment->rootDeviceEnvironments[i]->osInterface = std::make_unique<OSInterface>();
187 executionEnvironment->rootDeviceEnvironments[i]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
188 executionEnvironment->rootDeviceEnvironments[i]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
189
190 rootDeviceIndices.push_back(i);
191 }
192 auto memoryManager = std::make_unique<TestedDrmMemoryManager>(true, false, false, *executionEnvironment);
193
194 size_t size = 4096u;
195 AllocationProperties properties(rootDeviceIndex, true, size, GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, {});
196
197 auto ptr = memoryManager->createMultiGraphicsAllocationInSystemMemoryPool(rootDeviceIndices, properties, multiGraphics);
198
199 EXPECT_EQ(ptr, nullptr);
200
201 executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface);
202 }
203
204 using DrmMemoryManagerUsmSharedHandleTest = DrmMemoryManagerLocalMemoryTest;
205
TEST_F(DrmMemoryManagerUsmSharedHandleTest,givenDrmMemoryManagerAndOsHandleWhenCreateIsCalledWithBufferHostMemoryAllocationTypeThenGraphicsAllocationIsReturned)206 TEST_F(DrmMemoryManagerUsmSharedHandleTest, givenDrmMemoryManagerAndOsHandleWhenCreateIsCalledWithBufferHostMemoryAllocationTypeThenGraphicsAllocationIsReturned) {
207 osHandle handle = 1u;
208 this->mock->outputHandle = 2u;
209 size_t size = 4096u;
210 AllocationProperties properties(rootDeviceIndex, false, size, GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, {});
211
212 auto graphicsAllocation = memoryManager->createGraphicsAllocationFromSharedHandle(handle, properties, false, true);
213 ASSERT_NE(nullptr, graphicsAllocation);
214
215 EXPECT_EQ(this->mock->inputFd, (int)handle);
216 EXPECT_EQ(this->mock->setTilingHandle, 0u);
217
218 DrmAllocation *drmAllocation = static_cast<DrmAllocation *>(graphicsAllocation);
219 auto bo = drmAllocation->getBO();
220 EXPECT_EQ(bo->peekHandle(), (int)this->mock->outputHandle);
221 EXPECT_EQ(1u, bo->getRefCount());
222 EXPECT_EQ(size, bo->peekSize());
223
224 memoryManager->freeGraphicsMemory(graphicsAllocation);
225 }
226
TEST_F(DrmMemoryManagerUsmSharedHandleTest,givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationAndImportFailsThenNullptrIsReturned)227 TEST_F(DrmMemoryManagerUsmSharedHandleTest, givenMultiRootDeviceEnvironmentAndMemoryInfoWhenCreateMultiGraphicsAllocationAndImportFailsThenNullptrIsReturned) {
228 uint32_t rootDevicesNumber = 1u;
229 uint32_t rootDeviceIndex = 0u;
230 MultiGraphicsAllocation multiGraphics(rootDevicesNumber);
231 std::vector<uint32_t> rootDeviceIndices;
232 auto osInterface = executionEnvironment->rootDeviceEnvironments[0]->osInterface.release();
233
234 executionEnvironment->prepareRootDeviceEnvironments(rootDevicesNumber);
235 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->setHwInfo(defaultHwInfo.get());
236 auto mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
237
238 MemoryRegion regionInfo[2] = {};
239 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
240 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
241
242 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
243 mock->ioctlCallsCount = 0;
244 mock->fdToHandleRetVal = -1;
245 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface = std::make_unique<OSInterface>();
246 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
247 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
248
249 rootDeviceIndices.push_back(rootDeviceIndex);
250
251 auto memoryManager = std::make_unique<TestedDrmMemoryManager>(true, false, false, *executionEnvironment);
252
253 size_t size = 4096u;
254 AllocationProperties properties(rootDeviceIndex, true, size, GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, {});
255
256 auto ptr = memoryManager->createUSMHostAllocationFromSharedHandle(1, properties, false);
257
258 EXPECT_EQ(ptr, nullptr);
259
260 executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface);
261 }
262
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMultiRootDeviceEnvironmentAndNoMemoryInfoWhenCreateMultiGraphicsAllocationThenOldPathIsUsed)263 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMultiRootDeviceEnvironmentAndNoMemoryInfoWhenCreateMultiGraphicsAllocationThenOldPathIsUsed) {
264 uint32_t rootDevicesNumber = 3u;
265 MultiGraphicsAllocation multiGraphics(rootDevicesNumber);
266 std::vector<uint32_t> rootDeviceIndices;
267 auto osInterface = executionEnvironment->rootDeviceEnvironments[0]->osInterface.release();
268
269 executionEnvironment->prepareRootDeviceEnvironments(rootDevicesNumber);
270 for (uint32_t i = 0; i < rootDevicesNumber; i++) {
271 executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(defaultHwInfo.get());
272 auto mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[i]);
273
274 mock->memoryInfo.reset(nullptr);
275 mock->ioctlCallsCount = 0;
276 mock->fdToHandleRetVal = -1;
277 executionEnvironment->rootDeviceEnvironments[i]->osInterface = std::make_unique<OSInterface>();
278 executionEnvironment->rootDeviceEnvironments[i]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
279 executionEnvironment->rootDeviceEnvironments[i]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
280
281 rootDeviceIndices.push_back(i);
282 }
283 auto memoryManager = std::make_unique<TestedDrmMemoryManager>(true, false, false, *executionEnvironment);
284
285 size_t size = 4096u;
286 AllocationProperties properties(rootDeviceIndex, true, size, GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, {});
287
288 auto ptr = memoryManager->createMultiGraphicsAllocationInSystemMemoryPool(rootDeviceIndices, properties, multiGraphics);
289
290 EXPECT_NE(ptr, nullptr);
291
292 EXPECT_EQ(static_cast<DrmAllocation *>(multiGraphics.getDefaultGraphicsAllocation())->getMmapPtr(), nullptr);
293 for (uint32_t i = 0; i < rootDevicesNumber; i++) {
294 EXPECT_NE(multiGraphics.getGraphicsAllocation(i), nullptr);
295 memoryManager->freeGraphicsMemory(multiGraphics.getGraphicsAllocation(i));
296 }
297
298 executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface);
299 }
300
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenMemoryInfoWhenAllocateWithAlignmentThenGemCreateExtIsUsed,NonDefaultIoctlsSupported)301 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenMemoryInfoWhenAllocateWithAlignmentThenGemCreateExtIsUsed, NonDefaultIoctlsSupported) {
302 DebugManagerStateRestore restorer;
303 DebugManager.flags.EnableBOMmapCreate.set(-1);
304
305 MemoryRegion regionInfo[2] = {};
306 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
307 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
308
309 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
310 mock->ioctlCallsCount = 0;
311
312 AllocationData allocationData;
313 allocationData.size = MemoryConstants::pageSize64k;
314
315 auto allocation = memoryManager->allocateGraphicsMemoryWithAlignment(allocationData);
316
317 EXPECT_NE(allocation, nullptr);
318 EXPECT_NE(allocation->getMmapPtr(), nullptr);
319 EXPECT_NE(allocation->getMmapSize(), 0u);
320 EXPECT_EQ(allocation->getAllocationOffset(), 0u);
321 EXPECT_EQ(1u, mock->createExt.handle);
322
323 memoryManager->freeGraphicsMemory(allocation);
324 }
325
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMemoryInfoAndNotUseObjectMmapPropertyWhenAllocateWithAlignmentThenUserptrIsUsed)326 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMemoryInfoAndNotUseObjectMmapPropertyWhenAllocateWithAlignmentThenUserptrIsUsed) {
327 DebugManagerStateRestore restorer;
328 DebugManager.flags.EnableBOMmapCreate.set(0);
329
330 MemoryRegion regionInfo[2] = {};
331 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
332 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
333
334 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
335 mock->mmapOffsetRetVal = -1;
336
337 AllocationData allocationData;
338 allocationData.size = MemoryConstants::pageSize64k;
339 allocationData.useMmapObject = false;
340
341 auto allocation = memoryManager->allocateGraphicsMemoryWithAlignment(allocationData);
342
343 EXPECT_NE(allocation, nullptr);
344 EXPECT_EQ(static_cast<int>(mock->returnHandle), allocation->getBO()->peekHandle() + 1);
345
346 memoryManager->freeGraphicsMemory(allocation);
347 }
348
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMemoryInfoAndFailedMmapOffsetWhenAllocateWithAlignmentThenNullptr)349 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMemoryInfoAndFailedMmapOffsetWhenAllocateWithAlignmentThenNullptr) {
350 DebugManagerStateRestore restorer;
351 DebugManager.flags.EnableBOMmapCreate.set(-1);
352
353 MemoryRegion regionInfo[2] = {};
354 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
355 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
356
357 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
358 mock->mmapOffsetRetVal = -1;
359
360 AllocationData allocationData;
361 allocationData.size = MemoryConstants::pageSize64k;
362
363 auto allocation = memoryManager->allocateGraphicsMemoryWithAlignment(allocationData);
364
365 EXPECT_EQ(allocation, nullptr);
366 mock->mmapOffsetRetVal = 0;
367 }
368
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMemoryInfoAndDisabledMmapBOCreationtWhenAllocateWithAlignmentThenUserptrIsUsed)369 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMemoryInfoAndDisabledMmapBOCreationtWhenAllocateWithAlignmentThenUserptrIsUsed) {
370 DebugManagerStateRestore restorer;
371 DebugManager.flags.EnableBOMmapCreate.set(0);
372
373 MemoryRegion regionInfo[2] = {};
374 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
375 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
376
377 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
378 mock->mmapOffsetRetVal = -1;
379
380 AllocationData allocationData;
381 allocationData.size = MemoryConstants::pageSize64k;
382
383 auto allocation = memoryManager->allocateGraphicsMemoryWithAlignment(allocationData);
384
385 EXPECT_NE(allocation, nullptr);
386 EXPECT_EQ(static_cast<int>(mock->returnHandle), allocation->getBO()->peekHandle() + 1);
387
388 memoryManager->freeGraphicsMemory(allocation);
389 }
390
TEST_F(DrmMemoryManagerLocalMemoryTest,givenMemoryInfoAndFailedGemCreateExtWhenAllocateWithAlignmentThenNullptr)391 TEST_F(DrmMemoryManagerLocalMemoryTest, givenMemoryInfoAndFailedGemCreateExtWhenAllocateWithAlignmentThenNullptr) {
392 DebugManagerStateRestore restorer;
393 DebugManager.flags.EnableBOMmapCreate.set(-1);
394
395 MemoryRegion regionInfo[2] = {};
396 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
397 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
398
399 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
400 mock->gemCreateExtRetVal = -1;
401
402 AllocationData allocationData;
403 allocationData.size = MemoryConstants::pageSize64k;
404
405 auto allocation = memoryManager->allocateGraphicsMemoryWithAlignment(allocationData);
406
407 EXPECT_EQ(allocation, nullptr);
408 mock->gemCreateExtRetVal = 0;
409 }
410
411 class DrmMemoryManagerLocalMemoryMemoryBankMock : public TestedDrmMemoryManager {
412 public:
DrmMemoryManagerLocalMemoryMemoryBankMock(bool enableLocalMemory,bool allowForcePin,bool validateHostPtrMemory,ExecutionEnvironment & executionEnvironment)413 DrmMemoryManagerLocalMemoryMemoryBankMock(bool enableLocalMemory,
414 bool allowForcePin,
415 bool validateHostPtrMemory,
416 ExecutionEnvironment &executionEnvironment) : TestedDrmMemoryManager(enableLocalMemory, allowForcePin, validateHostPtrMemory, executionEnvironment) {
417 }
418
createBufferObjectInMemoryRegion(Drm * drm,uint64_t gpuAddress,size_t size,uint32_t memoryBanks,size_t maxOsContextCount)419 BufferObject *createBufferObjectInMemoryRegion(Drm *drm,
420 uint64_t gpuAddress,
421 size_t size,
422 uint32_t memoryBanks,
423 size_t maxOsContextCount) override {
424 memoryBankIsOne = (memoryBanks == 1) ? true : false;
425 return nullptr;
426 }
427
428 bool memoryBankIsOne = false;
429 };
430
431 class DrmMemoryManagerLocalMemoryMemoryBankTest : public ::testing::Test {
432 public:
433 DrmTipMock *mock;
434
SetUp()435 void SetUp() override {
436 const bool localMemoryEnabled = true;
437 executionEnvironment = new ExecutionEnvironment;
438 executionEnvironment->prepareRootDeviceEnvironments(1);
439 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->setHwInfo(defaultHwInfo.get());
440 mock = new DrmTipMock(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
441 mock->memoryInfo.reset(new MockMemoryInfo());
442 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface = std::make_unique<OSInterface>();
443 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
444 executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
445
446 device.reset(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(),
447 executionEnvironment,
448 rootDeviceIndex));
449 memoryManager = std::make_unique<DrmMemoryManagerLocalMemoryMemoryBankMock>(localMemoryEnabled,
450 false,
451 false,
452 *executionEnvironment);
453 }
454
455 protected:
456 ExecutionEnvironment *executionEnvironment = nullptr;
457 std::unique_ptr<MockDevice> device;
458 std::unique_ptr<DrmMemoryManagerLocalMemoryMemoryBankMock> memoryManager;
459 const uint32_t rootDeviceIndex = 0u;
460 };
461
TEST_F(DrmMemoryManagerLocalMemoryMemoryBankTest,givenDeviceMemoryWhenGraphicsAllocationInDevicePoolIsAllocatedThenMemoryBankIsSetToOne)462 TEST_F(DrmMemoryManagerLocalMemoryMemoryBankTest, givenDeviceMemoryWhenGraphicsAllocationInDevicePoolIsAllocatedThenMemoryBankIsSetToOne) {
463 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
464 AllocationData allocData;
465 allocData.allFlags = 0;
466 allocData.size = MemoryConstants::pageSize;
467 allocData.flags.useSystemMemory = false;
468 allocData.type = GraphicsAllocation::AllocationType::BUFFER;
469 allocData.rootDeviceIndex = rootDeviceIndex;
470 allocData.storageInfo.memoryBanks = 1u;
471 memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
472 EXPECT_TRUE(memoryManager->memoryBankIsOne);
473 }
474
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenCpuAccessRequiredWhenAllocatingInDevicePoolThenAllocationIsLocked,NonDefaultIoctlsSupported)475 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenCpuAccessRequiredWhenAllocatingInDevicePoolThenAllocationIsLocked, NonDefaultIoctlsSupported) {
476 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
477 AllocationData allocData;
478 allocData.allFlags = 0;
479 allocData.size = MemoryConstants::pageSize;
480 allocData.flags.requiresCpuAccess = true;
481 allocData.flags.allocateMemory = true;
482 allocData.type = GraphicsAllocation::AllocationType::BUFFER;
483 allocData.rootDeviceIndex = rootDeviceIndex;
484
485 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
486 ASSERT_NE(nullptr, allocation);
487 EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
488 EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool());
489 EXPECT_TRUE(allocation->isLocked());
490 EXPECT_NE(nullptr, allocation->getLockedPtr());
491 EXPECT_NE(nullptr, allocation->getUnderlyingBuffer());
492 EXPECT_NE(0u, allocation->getGpuAddress());
493
494 memoryManager->freeGraphicsMemory(allocation);
495 }
496
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenWriteCombinedAllocationWhenAllocatingInDevicePoolThenAllocationIsLockedAndLockedPtrIsUsedAsGpuAddress,NonDefaultIoctlsSupported)497 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenWriteCombinedAllocationWhenAllocatingInDevicePoolThenAllocationIsLockedAndLockedPtrIsUsedAsGpuAddress, NonDefaultIoctlsSupported) {
498 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
499 AllocationData allocData{};
500 allocData.size = MemoryConstants::pageSize;
501 allocData.type = GraphicsAllocation::AllocationType::WRITE_COMBINED;
502 allocData.rootDeviceIndex = rootDeviceIndex;
503 auto sizeAligned = alignUp(allocData.size + MemoryConstants::pageSize64k, 2 * MemoryConstants::megaByte) + 2 * MemoryConstants::megaByte;
504
505 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
506 EXPECT_NE(nullptr, allocation);
507 EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
508 EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool());
509 EXPECT_TRUE(allocation->isLocked());
510 EXPECT_NE(nullptr, allocation->getLockedPtr());
511
512 EXPECT_EQ(allocation->getLockedPtr(), allocation->getUnderlyingBuffer());
513 EXPECT_EQ(allocation->getLockedPtr(), reinterpret_cast<void *>(allocation->getGpuAddress()));
514 EXPECT_EQ(sizeAligned, allocation->getUnderlyingBufferSize());
515
516 EXPECT_EQ(0u, allocation->getReservedAddressSize());
517
518 auto cpuAddress = allocation->getLockedPtr();
519 auto alignedCpuAddress = alignDown(cpuAddress, 2 * MemoryConstants::megaByte);
520 auto offset = ptrDiff(cpuAddress, alignedCpuAddress);
521 EXPECT_EQ(offset, allocation->getAllocationOffset());
522
523 auto drmAllocation = static_cast<DrmAllocation *>(allocation);
524 auto bo = drmAllocation->getBO();
525 EXPECT_NE(nullptr, bo);
526 EXPECT_EQ(reinterpret_cast<uint64_t>(cpuAddress), bo->peekAddress());
527 EXPECT_EQ(sizeAligned, bo->peekSize());
528
529 memoryManager->freeGraphicsMemory(allocation);
530 }
531
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenSupportedTypeWhenAllocatingInDevicePoolThenSuccessStatusAndNonNullPtrIsReturned,NonDefaultIoctlsSupported)532 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenSupportedTypeWhenAllocatingInDevicePoolThenSuccessStatusAndNonNullPtrIsReturned, NonDefaultIoctlsSupported) {
533 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
534 AllocationData allocData;
535 allocData.allFlags = 0;
536 allocData.size = MemoryConstants::pageSize;
537 allocData.flags.allocateMemory = true;
538 allocData.rootDeviceIndex = rootDeviceIndex;
539 ImageDescriptor imgDesc = {};
540 imgDesc.imageType = ImageType::Image2D;
541 imgDesc.imageWidth = MemoryConstants::pageSize;
542 imgDesc.imageHeight = MemoryConstants::pageSize;
543 auto imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
544
545 bool resource48Bit[] = {true, false};
546 GraphicsAllocation::AllocationType supportedTypes[] = {GraphicsAllocation::AllocationType::BUFFER,
547 GraphicsAllocation::AllocationType::IMAGE,
548 GraphicsAllocation::AllocationType::COMMAND_BUFFER,
549 GraphicsAllocation::AllocationType::LINEAR_STREAM,
550 GraphicsAllocation::AllocationType::INDIRECT_OBJECT_HEAP,
551 GraphicsAllocation::AllocationType::TIMESTAMP_PACKET_TAG_BUFFER,
552 GraphicsAllocation::AllocationType::INTERNAL_HEAP,
553 GraphicsAllocation::AllocationType::KERNEL_ISA,
554 GraphicsAllocation::AllocationType::SVM_GPU};
555 for (auto res48bit : resource48Bit) {
556 for (auto supportedType : supportedTypes) {
557 allocData.type = supportedType;
558 allocData.imgInfo = (GraphicsAllocation::AllocationType::IMAGE == supportedType) ? &imgInfo : nullptr;
559 allocData.hostPtr = (GraphicsAllocation::AllocationType::SVM_GPU == supportedType) ? ::alignedMalloc(allocData.size, 4096) : nullptr;
560
561 switch (supportedType) {
562 case GraphicsAllocation::AllocationType::IMAGE:
563 case GraphicsAllocation::AllocationType::INDIRECT_OBJECT_HEAP:
564 case GraphicsAllocation::AllocationType::INTERNAL_HEAP:
565 case GraphicsAllocation::AllocationType::KERNEL_ISA:
566 allocData.flags.resource48Bit = true;
567 break;
568 default:
569 allocData.flags.resource48Bit = res48bit;
570 }
571
572 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
573 ASSERT_NE(nullptr, allocation);
574 EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
575
576 auto gpuAddress = allocation->getGpuAddress();
577 if (allocation->getAllocationType() == GraphicsAllocation::AllocationType::SVM_GPU) {
578 if (!memoryManager->isLimitedRange(0)) {
579 EXPECT_LT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapBase(HeapIndex::HEAP_SVM)), gpuAddress);
580 EXPECT_GT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_SVM)), gpuAddress);
581 }
582 } else if (memoryManager->heapAssigner.useInternal32BitHeap(allocation->getAllocationType())) {
583 EXPECT_LT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapBase(HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY)), gpuAddress);
584 EXPECT_GT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY)), gpuAddress);
585 } else {
586 const bool prefer2MBAlignment = allocation->getUnderlyingBufferSize() >= 2 * MemoryConstants::megaByte;
587
588 auto heap = HeapIndex::HEAP_STANDARD64KB;
589 if (prefer2MBAlignment) {
590 heap = HeapIndex::HEAP_STANDARD2MB;
591 } else if (memoryManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_EXTENDED) > 0 && !allocData.flags.resource48Bit) {
592 heap = HeapIndex::HEAP_EXTENDED;
593 }
594
595 EXPECT_LT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapBase(heap)), gpuAddress);
596 EXPECT_GT(GmmHelper::canonize(memoryManager->getGfxPartition(0)->getHeapLimit(heap)), gpuAddress);
597 }
598
599 memoryManager->freeGraphicsMemory(allocation);
600 if (GraphicsAllocation::AllocationType::SVM_GPU == supportedType) {
601 ::alignedFree(const_cast<void *>(allocData.hostPtr));
602 }
603 }
604 }
605 }
606
TEST_F(DrmMemoryManagerLocalMemoryTest,givenDrmMemoryManagerWithLocalMemoryWhenLockResourceIsCalledOnNullBufferObjectThenReturnNullPtr)607 TEST_F(DrmMemoryManagerLocalMemoryTest, givenDrmMemoryManagerWithLocalMemoryWhenLockResourceIsCalledOnNullBufferObjectThenReturnNullPtr) {
608 auto ptr = memoryManager->lockResourceInLocalMemoryImpl(nullptr);
609 EXPECT_EQ(nullptr, ptr);
610
611 memoryManager->unlockResourceInLocalMemoryImpl(nullptr);
612 }
613
TEST_F(DrmMemoryManagerLocalMemoryWithCustomMockTest,givenDrmMemoryManagerWithLocalMemoryWhenLockResourceIsCalledOnBufferObjectThenReturnPtr)614 TEST_F(DrmMemoryManagerLocalMemoryWithCustomMockTest, givenDrmMemoryManagerWithLocalMemoryWhenLockResourceIsCalledOnBufferObjectThenReturnPtr) {
615 BufferObject bo(mock, 1, 1024, 0);
616
617 DrmAllocation drmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, &bo, nullptr, 0u, 0u, MemoryPool::LocalMemory);
618 EXPECT_EQ(&bo, drmAllocation.getBO());
619
620 auto ptr = memoryManager->lockResourceInLocalMemoryImpl(&bo);
621 EXPECT_NE(nullptr, ptr);
622 EXPECT_EQ(ptr, bo.peekLockedAddress());
623
624 memoryManager->unlockResourceInLocalMemoryImpl(&bo);
625 EXPECT_EQ(nullptr, bo.peekLockedAddress());
626 }
627
628 using DrmMemoryManagerFailInjectionTest = Test<DrmMemoryManagerFixtureImpl>;
629
HWTEST2_F(DrmMemoryManagerFailInjectionTest,givenEnabledLocalMemoryWhenNewFailsThenAllocateInDevicePoolReturnsStatusErrorAndNullallocation,NonDefaultIoctlsSupported)630 HWTEST2_F(DrmMemoryManagerFailInjectionTest, givenEnabledLocalMemoryWhenNewFailsThenAllocateInDevicePoolReturnsStatusErrorAndNullallocation, NonDefaultIoctlsSupported) {
631 mock->ioctl_expected.total = -1; //don't care
632 class MockGfxPartition : public GfxPartition {
633 public:
634 MockGfxPartition() : GfxPartition(reservedCpuAddressRange) {
635 init(defaultHwInfo->capabilityTable.gpuAddressSpace, getSizeToReserve(), 0, 1);
636 }
637 ~MockGfxPartition() override {
638 for (const auto &heap : heaps) {
639 auto mockHeap = static_cast<const MockHeap *>(&heap);
640 if (defaultHwInfo->capabilityTable.gpuAddressSpace != MemoryConstants::max36BitAddress && mockHeap->getSize() > 0) {
641 EXPECT_EQ(0u, mockHeap->alloc->getUsedSize());
642 }
643 }
644 }
645 struct MockHeap : Heap {
646 using Heap::alloc;
647 };
648 OSMemory::ReservedCpuAddressRange reservedCpuAddressRange;
649 };
650 TestedDrmMemoryManager testedMemoryManager(true, false, true, *executionEnvironment);
651 testedMemoryManager.overrideGfxPartition(new MockGfxPartition);
652
653 InjectedFunction method = [&](size_t failureIndex) {
654 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
655 AllocationData allocData;
656 allocData.allFlags = 0;
657 allocData.size = MemoryConstants::pageSize;
658 allocData.flags.allocateMemory = true;
659 allocData.type = GraphicsAllocation::AllocationType::BUFFER;
660 allocData.rootDeviceIndex = rootDeviceIndex;
661
662 auto allocation = testedMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
663
664 if (MemoryManagement::nonfailingAllocation != failureIndex) {
665 EXPECT_EQ(nullptr, allocation);
666 EXPECT_EQ(MemoryManager::AllocationStatus::Error, status);
667 } else {
668 EXPECT_NE(nullptr, allocation);
669 EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
670 testedMemoryManager.freeGraphicsMemory(allocation);
671 }
672 };
673
674 mock->memoryInfo.reset(new MockMemoryInfo());
675 injectFailures(method);
676 }
677
678 using DrmMemoryManagerCopyMemoryToAllocationTest = DrmMemoryManagerLocalMemoryTest;
679
680 struct DrmMemoryManagerToTestCopyMemoryToAllocation : public DrmMemoryManager {
681 using DrmMemoryManager::allocateGraphicsMemoryInDevicePool;
DrmMemoryManagerToTestCopyMemoryToAllocationNEO::DrmMemoryManagerToTestCopyMemoryToAllocation682 DrmMemoryManagerToTestCopyMemoryToAllocation(ExecutionEnvironment &executionEnvironment, bool localMemoryEnabled, size_t lockableLocalMemorySize)
683 : DrmMemoryManager(gemCloseWorkerMode::gemCloseWorkerInactive, false, false, executionEnvironment) {
684 std::fill(this->localMemorySupported.begin(), this->localMemorySupported.end(), localMemoryEnabled);
685 lockedLocalMemorySize = lockableLocalMemorySize;
686 }
lockResourceImplNEO::DrmMemoryManagerToTestCopyMemoryToAllocation687 void *lockResourceImpl(GraphicsAllocation &graphicsAllocation) override {
688 if (lockedLocalMemorySize > 0) {
689 lockedLocalMemory.reset(new uint8_t[lockedLocalMemorySize]);
690 return lockedLocalMemory.get();
691 }
692 return nullptr;
693 }
lockResourceInLocalMemoryImplNEO::DrmMemoryManagerToTestCopyMemoryToAllocation694 void *lockResourceInLocalMemoryImpl(BufferObject *bo) override {
695 if (lockedLocalMemorySize > 0) {
696 lockedLocalMemory.reset(new uint8_t[lockedLocalMemorySize]);
697 return lockedLocalMemory.get();
698 }
699 return nullptr;
700 }
unlockResourceInLocalMemoryImplNEO::DrmMemoryManagerToTestCopyMemoryToAllocation701 void unlockResourceInLocalMemoryImpl(BufferObject *bo) override {
702 }
unlockResourceImplNEO::DrmMemoryManagerToTestCopyMemoryToAllocation703 void unlockResourceImpl(GraphicsAllocation &graphicsAllocation) override {
704 }
705 std::unique_ptr<uint8_t[]> lockedLocalMemory;
706 size_t lockedLocalMemorySize = 0;
707 };
708
HWTEST2_F(DrmMemoryManagerCopyMemoryToAllocationTest,givenDrmMemoryManagerWhenCopyMemoryToAllocationReturnsSuccessThenAllocationIsFilledWithCorrectData,NonDefaultIoctlsSupported)709 HWTEST2_F(DrmMemoryManagerCopyMemoryToAllocationTest, givenDrmMemoryManagerWhenCopyMemoryToAllocationReturnsSuccessThenAllocationIsFilledWithCorrectData, NonDefaultIoctlsSupported) {
710 size_t offset = 3;
711 size_t sourceAllocationSize = MemoryConstants::pageSize;
712 size_t destinationAllocationSize = sourceAllocationSize + offset;
713
714 DrmMemoryManagerToTestCopyMemoryToAllocation drmMemoryManger(*executionEnvironment, true, destinationAllocationSize);
715 std::vector<uint8_t> dataToCopy(sourceAllocationSize, 1u);
716
717 AllocationData allocData;
718 allocData.allFlags = 0;
719 allocData.size = destinationAllocationSize;
720 allocData.flags.allocateMemory = true;
721 allocData.type = GraphicsAllocation::AllocationType::KERNEL_ISA;
722 allocData.rootDeviceIndex = rootDeviceIndex;
723 allocData.storageInfo.memoryBanks.set(0, true);
724 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
725 auto allocation = drmMemoryManger.allocateGraphicsMemoryInDevicePool(allocData, status);
726 ASSERT_NE(nullptr, allocation);
727
728 auto ret = drmMemoryManger.copyMemoryToAllocation(allocation, offset, dataToCopy.data(), dataToCopy.size());
729 EXPECT_TRUE(ret);
730
731 EXPECT_EQ(0, memcmp(ptrOffset(drmMemoryManger.lockedLocalMemory.get(), offset), dataToCopy.data(), dataToCopy.size()));
732
733 drmMemoryManger.freeGraphicsMemory(allocation);
734 }
735
HWTEST2_F(DrmMemoryManagerCopyMemoryToAllocationTest,givenDrmMemoryManagerWhenCopyMemoryToAllocationFailsToLockResourceThenItReturnsFalse,NonDefaultIoctlsSupported)736 HWTEST2_F(DrmMemoryManagerCopyMemoryToAllocationTest, givenDrmMemoryManagerWhenCopyMemoryToAllocationFailsToLockResourceThenItReturnsFalse, NonDefaultIoctlsSupported) {
737 DrmMemoryManagerToTestCopyMemoryToAllocation drmMemoryManger(*executionEnvironment, true, 0);
738 std::vector<uint8_t> dataToCopy(MemoryConstants::pageSize, 1u);
739
740 AllocationData allocData;
741 allocData.allFlags = 0;
742 allocData.size = dataToCopy.size();
743 allocData.flags.allocateMemory = true;
744 allocData.type = GraphicsAllocation::AllocationType::KERNEL_ISA;
745 allocData.rootDeviceIndex = rootDeviceIndex;
746 allocData.storageInfo.memoryBanks.set(0, true);
747 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
748 auto allocation = drmMemoryManger.allocateGraphicsMemoryInDevicePool(allocData, status);
749 ASSERT_NE(nullptr, allocation);
750
751 auto ret = drmMemoryManger.copyMemoryToAllocation(allocation, 0, dataToCopy.data(), dataToCopy.size());
752 EXPECT_FALSE(ret);
753
754 drmMemoryManger.freeGraphicsMemory(allocation);
755 }
756
TEST_F(DrmMemoryManagerCopyMemoryToAllocationTest,givenDrmMemoryManagerWhenCopyMemoryToAllocationWithCpuPtrThenAllocationIsFilledWithCorrectData)757 TEST_F(DrmMemoryManagerCopyMemoryToAllocationTest, givenDrmMemoryManagerWhenCopyMemoryToAllocationWithCpuPtrThenAllocationIsFilledWithCorrectData) {
758 size_t offset = 3;
759 size_t sourceAllocationSize = MemoryConstants::pageSize;
760 size_t destinationAllocationSize = sourceAllocationSize + offset;
761
762 DrmMemoryManagerToTestCopyMemoryToAllocation drmMemoryManger(*executionEnvironment, false, 0);
763 std::vector<uint8_t> dataToCopy(sourceAllocationSize, 1u);
764
765 auto allocation = drmMemoryManger.allocateGraphicsMemoryWithProperties({mockRootDeviceIndex, destinationAllocationSize, GraphicsAllocation::AllocationType::KERNEL_ISA, mockDeviceBitfield});
766 ASSERT_NE(nullptr, allocation);
767
768 auto ret = drmMemoryManger.copyMemoryToAllocation(allocation, offset, dataToCopy.data(), dataToCopy.size());
769 EXPECT_TRUE(ret);
770
771 EXPECT_EQ(0, memcmp(ptrOffset(allocation->getUnderlyingBuffer(), offset), dataToCopy.data(), dataToCopy.size()));
772
773 drmMemoryManger.freeGraphicsMemory(allocation);
774 }
775
776 using DrmMemoryManagerTestImpl = Test<DrmMemoryManagerFixtureImpl>;
777
HWTEST2_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryThenCallIoctlGemMapOffsetAndReturnLockedPtr,NonDefaultIoctlsSupported)778 HWTEST2_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryThenCallIoctlGemMapOffsetAndReturnLockedPtr, NonDefaultIoctlsSupported) {
779 mockExp->ioctlImpl_expected.gemCreateExt = 1;
780 mockExp->ioctl_expected.gemWait = 1;
781 mockExp->ioctl_expected.gemClose = 1;
782 mockExp->ioctl_expected.gemMmapOffset = 1;
783 mockExp->memoryInfo.reset(new MockMemoryInfo());
784
785 AllocationData allocData;
786 allocData.allFlags = 0;
787 allocData.size = MemoryConstants::pageSize;
788 allocData.flags.allocateMemory = true;
789 allocData.type = GraphicsAllocation::AllocationType::INTERNAL_HEAP;
790 allocData.rootDeviceIndex = rootDeviceIndex;
791 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
792 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
793 ASSERT_NE(nullptr, allocation);
794 EXPECT_EQ(nullptr, allocation->getUnderlyingBuffer());
795 EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool());
796
797 auto ptr = memoryManager->lockResource(allocation);
798 EXPECT_NE(nullptr, ptr);
799
800 auto drmAllocation = static_cast<DrmAllocation *>(allocation);
801 EXPECT_NE(nullptr, drmAllocation->getBO()->peekLockedAddress());
802
803 EXPECT_EQ(static_cast<uint32_t>(drmAllocation->getBO()->peekHandle()), mockExp->mmapOffsetHandle);
804 EXPECT_EQ(0u, mockExp->mmapOffsetPad);
805 EXPECT_EQ(0u, mockExp->mmapOffsetExpected);
806 EXPECT_EQ(4u, mockExp->mmapOffsetFlags);
807
808 memoryManager->unlockResource(allocation);
809 EXPECT_EQ(nullptr, drmAllocation->getBO()->peekLockedAddress());
810
811 memoryManager->freeGraphicsMemory(allocation);
812 }
813
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButFailsOnMmapThenReturnNullPtr)814 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButFailsOnMmapThenReturnNullPtr) {
815 mockExp->ioctl_expected.gemMmapOffset = 2;
816 this->ioctlResExt = {mockExp->ioctl_cnt.total, -1};
817 mockExp->ioctl_res_ext = &ioctlResExt;
818
819 BufferObject bo(mockExp, 1, 0, 0);
820 DrmAllocation drmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, &bo, nullptr, 0u, 0u, MemoryPool::LocalMemory);
821 EXPECT_NE(nullptr, drmAllocation.getBO());
822
823 auto ptr = memoryManager->lockResource(&drmAllocation);
824 EXPECT_EQ(nullptr, ptr);
825
826 memoryManager->unlockResource(&drmAllocation);
827 mockExp->ioctl_res_ext = &mockExp->NONE;
828 }
829
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButFailsOnIoctlMmapFunctionOffsetThenReturnNullPtr)830 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButFailsOnIoctlMmapFunctionOffsetThenReturnNullPtr) {
831 mockExp->ioctl_expected.gemMmapOffset = 2;
832 mockExp->returnIoctlExtraErrorValue = true;
833 mockExp->failOnMmapOffset = true;
834
835 BufferObject bo(mockExp, 1, 0, 0);
836 DrmAllocation drmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, &bo, nullptr, 0u, 0u, MemoryPool::LocalMemory);
837 EXPECT_NE(nullptr, drmAllocation.getBO());
838
839 auto ptr = memoryManager->lockResource(&drmAllocation);
840 EXPECT_EQ(nullptr, ptr);
841
842 memoryManager->unlockResource(&drmAllocation);
843 mockExp->ioctl_res_ext = &mockExp->NONE;
844 }
845
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButBufferObjectIsNullThenReturnNullPtr)846 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenLockUnlockIsCalledOnAllocationInLocalMemoryButBufferObjectIsNullThenReturnNullPtr) {
847 DrmAllocation drmAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, nullptr, nullptr, 0u, 0u, MemoryPool::LocalMemory);
848
849 auto ptr = memoryManager->lockResource(&drmAllocation);
850 EXPECT_EQ(nullptr, ptr);
851
852 memoryManager->unlockResource(&drmAllocation);
853 }
854
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledForMemoryInfoThenReturnMemoryRegionSize)855 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledForMemoryInfoThenReturnMemoryRegionSize) {
856 MockExecutionEnvironment executionEnvironment;
857 executionEnvironment.rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
858 auto drm = new DrmMock(*executionEnvironment.rootDeviceEnvironments[0]);
859 drm->memoryInfo.reset(new MockMemoryInfo());
860 executionEnvironment.rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
861 TestedDrmMemoryManager memoryManager(executionEnvironment);
862
863 auto memoryInfo = drm->getMemoryInfo();
864 ASSERT_NE(nullptr, memoryInfo);
865 EXPECT_EQ(memoryInfo->getMemoryRegionSize(MemoryBanks::getBankForLocalMemory(0)), memoryManager.getLocalMemorySize(0u, 0xF));
866 }
867
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledForMemoryInfoAndInvalidDeviceBitfieldThenReturnZero)868 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledForMemoryInfoAndInvalidDeviceBitfieldThenReturnZero) {
869 MockExecutionEnvironment executionEnvironment;
870 executionEnvironment.rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
871 auto drm = new DrmMock(*executionEnvironment.rootDeviceEnvironments[0]);
872 drm->memoryInfo.reset(new MockMemoryInfo());
873 executionEnvironment.rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
874 TestedDrmMemoryManager memoryManager(executionEnvironment);
875
876 auto memoryInfo = drm->getMemoryInfo();
877 ASSERT_NE(nullptr, memoryInfo);
878 EXPECT_EQ(0u, memoryManager.getLocalMemorySize(0u, 0u));
879 }
880
TEST_F(DrmMemoryManagerTestImpl,givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledButMemoryInfoIsNotAvailableThenSizeZeroIsReturned)881 TEST_F(DrmMemoryManagerTestImpl, givenDrmMemoryManagerWhenGetLocalMemorySizeIsCalledButMemoryInfoIsNotAvailableThenSizeZeroIsReturned) {
882 MockExecutionEnvironment executionEnvironment;
883 executionEnvironment.rootDeviceEnvironments[0]->osInterface = std::make_unique<OSInterface>();
884 auto drm = new DrmMock(*executionEnvironment.rootDeviceEnvironments[0]);
885 executionEnvironment.rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
886 TestedDrmMemoryManager memoryManager(executionEnvironment);
887
888 EXPECT_EQ(0u, memoryManager.getLocalMemorySize(0u, 0xF));
889 }
890
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenGraphicsAllocationInDevicePoolIsAllocatedForImage1DWhenTheSizeReturnedFromGmmIsUnalignedThenCreateBufferObjectWithSizeAlignedTo64KB,NonDefaultIoctlsSupported)891 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenGraphicsAllocationInDevicePoolIsAllocatedForImage1DWhenTheSizeReturnedFromGmmIsUnalignedThenCreateBufferObjectWithSizeAlignedTo64KB, NonDefaultIoctlsSupported) {
892 ImageDescriptor imgDesc = {};
893 imgDesc.imageType = ImageType::Image1D;
894 imgDesc.imageWidth = 100;
895 auto imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
896
897 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
898 AllocationData allocData;
899 allocData.allFlags = 0;
900 allocData.size = MemoryConstants::pageSize;
901 allocData.type = GraphicsAllocation::AllocationType::IMAGE;
902 allocData.flags.resource48Bit = true;
903 allocData.imgInfo = &imgInfo;
904 allocData.rootDeviceIndex = rootDeviceIndex;
905
906 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
907 EXPECT_NE(nullptr, allocation);
908 EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
909
910 EXPECT_TRUE(allocData.imgInfo->useLocalMemory);
911 EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool());
912
913 auto gmm = allocation->getDefaultGmm();
914 EXPECT_NE(nullptr, gmm);
915 EXPECT_FALSE(gmm->useSystemMemoryPool);
916
917 auto gpuAddress = allocation->getGpuAddress();
918 auto sizeAlignedTo64KB = alignUp(allocData.imgInfo->size, MemoryConstants::pageSize64k);
919 EXPECT_NE(0u, gpuAddress);
920 EXPECT_EQ(sizeAlignedTo64KB, allocation->getUnderlyingBufferSize());
921 EXPECT_EQ(gpuAddress, reinterpret_cast<uint64_t>(allocation->getReservedAddressPtr()));
922 EXPECT_EQ(sizeAlignedTo64KB, allocation->getReservedAddressSize());
923
924 auto drmAllocation = static_cast<DrmAllocation *>(allocation);
925 auto bo = drmAllocation->getBO();
926 EXPECT_NE(nullptr, bo);
927 EXPECT_EQ(gpuAddress, bo->peekAddress());
928 EXPECT_EQ(sizeAlignedTo64KB, bo->peekSize());
929
930 memoryManager->freeGraphicsMemory(allocation);
931 }
932
933 static uint32_t munmapCalledCount = 0u;
934
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenAlignmentAndSizeWhenMmapReturnsUnalignedPointerThenCreateAllocWithAlignmentUnmapTwoUnalignedPart,NonDefaultIoctlsSupported)935 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsUnalignedPointerThenCreateAllocWithAlignmentUnmapTwoUnalignedPart, NonDefaultIoctlsSupported) {
936 DebugManagerStateRestore restorer;
937 DebugManager.flags.EnableBOMmapCreate.set(-1);
938
939 MemoryRegion regionInfo[2] = {};
940 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
941 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
942
943 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
944 mock->ioctlCallsCount = 0;
945
946 AllocationData allocationData;
947 allocationData.size = MemoryConstants::pageSize64k;
948
949 memoryManager->mmapFunction = [](void *addr, size_t len, int prot,
950 int flags, int fd, off_t offset) throw() {
951 if (addr == 0) {
952 return reinterpret_cast<void *>(0x12345678);
953 } else {
954 return addr;
955 }
956 };
957
958 memoryManager->munmapFunction = [](void *addr, size_t len) throw() {
959 munmapCalledCount++;
960 return 0;
961 };
962
963 munmapCalledCount = 0;
964 auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, MemoryConstants::pageSize64k, MemoryConstants::pageSize64k, 0u);
965
966 EXPECT_EQ(alignUp(reinterpret_cast<void *>(0x12345678), MemoryConstants::pageSize64k), allocation->getMmapPtr());
967 EXPECT_EQ(munmapCalledCount, 2u);
968 munmapCalledCount = 0u;
969 memoryManager->freeGraphicsMemory(allocation);
970 }
971
HWTEST2_F(DrmMemoryManagerLocalMemoryTest,givenAlignmentAndSizeWhenMmapReturnsAlignedThenCreateAllocWithAlignmentUnmapOneUnalignedPart,NonDefaultIoctlsSupported)972 HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsAlignedThenCreateAllocWithAlignmentUnmapOneUnalignedPart, NonDefaultIoctlsSupported) {
973 DebugManagerStateRestore restorer;
974 DebugManager.flags.EnableBOMmapCreate.set(-1);
975
976 MemoryRegion regionInfo[2] = {};
977 regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
978 regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
979
980 mock->memoryInfo.reset(new MemoryInfo(regionInfo, 2));
981 mock->ioctlCallsCount = 0;
982
983 AllocationData allocationData;
984 allocationData.size = MemoryConstants::pageSize64k;
985
986 memoryManager->mmapFunction = [](void *addr, size_t len, int prot,
987 int flags, int fd, off_t offset) throw() {
988 if (addr == 0) {
989 return reinterpret_cast<void *>(0x12345678);
990 } else {
991 return addr;
992 }
993 };
994
995 memoryManager->munmapFunction = [](void *addr, size_t len) throw() {
996 munmapCalledCount++;
997 return 0;
998 };
999
1000 munmapCalledCount = 0u;
1001 auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, 1u, MemoryConstants::pageSize64k, 0u);
1002
1003 EXPECT_EQ(reinterpret_cast<void *>(0x12345678), allocation->getMmapPtr());
1004 EXPECT_EQ(munmapCalledCount, 1u);
1005 munmapCalledCount = 0u;
1006 memoryManager->freeGraphicsMemory(allocation);
1007 }
1008
TEST_F(DrmMemoryManagerLocalMemoryTest,givenAllocationWithInvalidCacheRegionWhenAllocatingInDevicePoolThenReturnNullptr)1009 TEST_F(DrmMemoryManagerLocalMemoryTest, givenAllocationWithInvalidCacheRegionWhenAllocatingInDevicePoolThenReturnNullptr) {
1010 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
1011 AllocationData allocData;
1012 allocData.allFlags = 0;
1013 allocData.size = 18 * MemoryConstants::pageSize64k;
1014 allocData.flags.allocateMemory = true;
1015 allocData.type = GraphicsAllocation::AllocationType::BUFFER;
1016 allocData.storageInfo.memoryBanks = maxNBitValue(MemoryBanks::getBankForLocalMemory(3));
1017 allocData.storageInfo.multiStorage = true;
1018 allocData.rootDeviceIndex = rootDeviceIndex;
1019 allocData.cacheRegion = 0xFFFF;
1020
1021 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
1022 ASSERT_EQ(nullptr, allocation);
1023 EXPECT_EQ(MemoryManager::AllocationStatus::Error, status);
1024 memoryManager->freeGraphicsMemory(allocation);
1025 }
1026
TEST_F(DrmMemoryManagerLocalMemoryTest,givenAllocationWithUnifiedMemoryAllocationThenReturnNullptr)1027 TEST_F(DrmMemoryManagerLocalMemoryTest, givenAllocationWithUnifiedMemoryAllocationThenReturnNullptr) {
1028 MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
1029 AllocationData allocData;
1030 allocData.allFlags = 0;
1031 allocData.size = 18 * MemoryConstants::pageSize64k;
1032 allocData.flags.allocateMemory = true;
1033 allocData.type = GraphicsAllocation::AllocationType::UNIFIED_SHARED_MEMORY;
1034 allocData.rootDeviceIndex = rootDeviceIndex;
1035
1036 auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
1037 ASSERT_EQ(nullptr, allocation);
1038 EXPECT_EQ(MemoryManager::AllocationStatus::Error, status);
1039 memoryManager->freeGraphicsMemory(allocation);
1040 }
1041
TEST(ResidencyTests,whenBuffersIsCreatedWithMakeResidentFlagThenItSuccessfulyCreates)1042 TEST(ResidencyTests, whenBuffersIsCreatedWithMakeResidentFlagThenItSuccessfulyCreates) {
1043 VariableBackup<UltHwConfig> backup(&ultHwConfig);
1044 ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
1045 ultHwConfig.forceOsAgnosticMemoryManager = false;
1046 DebugManagerStateRestore restorer;
1047 DebugManager.flags.MakeAllBuffersResident.set(true);
1048
1049 initPlatform();
1050 auto device = platform()->getClDevice(0u);
1051
1052 MockContext context(device, false);
1053 auto retValue = CL_SUCCESS;
1054 auto clBuffer = clCreateBuffer(&context, 0u, 4096u, nullptr, &retValue);
1055 ASSERT_EQ(retValue, CL_SUCCESS);
1056 clReleaseMemObject(clBuffer);
1057 }
1058
1059 } // namespace NEO
1060