Skip to content

Commit ada9b5d

Browse files
Handle if L0 Event Memory is Shareable
- Properly check for IPC event handle flag to determine if the event pool memory is sharable between processes. - Given Host Visible Event Pool, a check is done to determine if the Host memory can be shared between the processes. - Enabled handling if Event Host Memory is shareable for DRM - If Event Pool Memory is Not shareable, then retrieving the IPC Event Pool Handle returns unsupported. Signed-off-by: Neil R Spruit <[email protected]>
1 parent 6b4375e commit ada9b5d

File tree

6 files changed

+116
-6
lines changed

6 files changed

+116
-6
lines changed

level_zero/core/source/context/context_imp.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ ze_result_t EventPoolImp::getIpcHandle(ze_ipc_event_pool_handle_t *pIpcHandle) {
525525
// For the event pool, this contains:
526526
// - the number of events the pool has.
527527
// - the id for the device used during pool creation
528+
if (!this->isShareableEventMemory) {
529+
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
530+
}
528531

529532
uint64_t handle = this->eventPoolAllocations->getDefaultGraphicsAllocation()->peekInternalHandle(this->context->getDriverHandle()->getMemoryManager());
530533

level_zero/core/source/event/event.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin
9797
if (useDeviceAlloc) {
9898
NEO::AllocationProperties allocationProperties{*rootDeviceIndices.begin(), alignedSize, allocationType, devices[0]->getNEODevice()->getDeviceBitfield()};
9999
allocationProperties.alignment = eventAlignment;
100+
if (eventPoolFlags & ZE_EVENT_POOL_FLAG_IPC) {
101+
this->isShareableEventMemory = true;
102+
}
100103

101104
auto graphicsAllocation = driver->getMemoryManager()->allocateGraphicsMemoryWithProperties(allocationProperties);
102105
if (graphicsAllocation) {
@@ -112,6 +115,10 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin
112115
allocationProperties,
113116
*eventPoolAllocations);
114117

118+
if (eventPoolFlags & ZE_EVENT_POOL_FLAG_IPC) {
119+
this->isShareableEventMemory = eventPoolAllocations->getDefaultGraphicsAllocation()->isShareableHostMemory;
120+
}
121+
115122
allocatedMemory = (nullptr != eventPoolPtr);
116123
}
117124

level_zero/core/source/event/event.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ struct EventPoolImp : public EventPool {
277277
ContextImp *context = nullptr;
278278
size_t numEvents;
279279
bool isImportedIpcPool = false;
280+
bool isShareableEventMemory = false;
280281

281282
protected:
282283
uint32_t eventAlignment = 0;

level_zero/core/test/unit_tests/sources/event/test_event.cpp

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,40 @@ TEST_F(EventPoolCreate, GivenDeviceThenEventPoolIsCreated) {
275275
eventPool->destroy();
276276
}
277277

278+
class MemoryManagerEventPoolIPCMock : public NEO::MockMemoryManager {
279+
public:
280+
MemoryManagerEventPoolIPCMock(NEO::ExecutionEnvironment &executionEnvironment) : NEO::MockMemoryManager(executionEnvironment) {}
281+
void *createMultiGraphicsAllocationInSystemMemoryPool(RootDeviceIndicesContainer &rootDeviceIndices, AllocationProperties &properties, NEO::MultiGraphicsAllocation &multiGraphicsAllocation) override {
282+
alloc = new NEO::MockGraphicsAllocation(&buffer, sizeof(buffer));
283+
alloc->isShareableHostMemory = true;
284+
multiGraphicsAllocation.addAllocation(alloc);
285+
return reinterpret_cast<void *>(alloc->getUnderlyingBuffer());
286+
};
287+
void freeGraphicsMemoryImpl(NEO::GraphicsAllocation *gfxAllocation) override {
288+
delete gfxAllocation;
289+
};
290+
void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation, bool isImportedAllocation) override {
291+
delete gfxAllocation;
292+
};
293+
char buffer[64];
294+
NEO::MockGraphicsAllocation *alloc;
295+
};
296+
278297
using EventPoolIPCHandleTests = Test<DeviceFixture>;
279298

280299
TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNumberOfEventsAreReturnedInHandle) {
281300
uint32_t numEvents = 4;
282301
ze_event_pool_desc_t eventPoolDesc = {
283302
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
284303
nullptr,
285-
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
304+
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
286305
numEvents};
287306

288307
auto deviceHandle = device->toHandle();
289308
ze_result_t result = ZE_RESULT_SUCCESS;
309+
auto curMemoryManager = driverHandle->getMemoryManager();
310+
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
311+
driverHandle->setMemoryManager(mockMemoryManager);
290312
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
291313
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
292314
EXPECT_NE(nullptr, eventPool);
@@ -303,6 +325,30 @@ TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNum
303325
memcpy_s(&expectedNumEvents, sizeof(expectedNumEvents), ipcHandle.data + sizeof(int), sizeof(expectedNumEvents));
304326
EXPECT_EQ(numEvents, expectedNumEvents);
305327

328+
res = eventPool->destroy();
329+
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
330+
delete mockMemoryManager;
331+
driverHandle->setMemoryManager(curMemoryManager);
332+
}
333+
334+
TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolWhenHostShareableMemoryIsFalseThenUnsuportedIsReturned) {
335+
uint32_t numEvents = 4;
336+
ze_event_pool_desc_t eventPoolDesc = {
337+
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
338+
nullptr,
339+
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
340+
numEvents};
341+
342+
auto deviceHandle = device->toHandle();
343+
ze_result_t result = ZE_RESULT_SUCCESS;
344+
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
345+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
346+
EXPECT_NE(nullptr, eventPool);
347+
348+
ze_ipc_event_pool_handle_t ipcHandle = {};
349+
ze_result_t res = eventPool->getIpcHandle(&ipcHandle);
350+
EXPECT_EQ(res, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
351+
306352
res = eventPool->destroy();
307353
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
308354
}
@@ -312,11 +358,14 @@ TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolThenEventPoolIsC
312358
ze_event_pool_desc_t eventPoolDesc = {
313359
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
314360
nullptr,
315-
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
361+
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
316362
numEvents};
317363

318364
auto deviceHandle = device->toHandle();
319365
ze_result_t result = ZE_RESULT_SUCCESS;
366+
auto curMemoryManager = driverHandle->getMemoryManager();
367+
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
368+
driverHandle->setMemoryManager(mockMemoryManager);
320369
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
321370
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
322371
EXPECT_NE(nullptr, eventPool);
@@ -338,6 +387,45 @@ TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolThenEventPoolIsC
338387

339388
res = eventPool->destroy();
340389
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
390+
delete mockMemoryManager;
391+
driverHandle->setMemoryManager(curMemoryManager);
392+
}
393+
394+
TEST_F(EventPoolIPCHandleTests, GivenEventPoolWithIPCEventFlagAndDeviceMemoryThenShareableEventMemoryIsTrue) {
395+
ze_event_pool_desc_t eventPoolDesc = {
396+
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
397+
nullptr,
398+
ZE_EVENT_POOL_FLAG_IPC,
399+
1};
400+
401+
ze_result_t result = ZE_RESULT_SUCCESS;
402+
std::unique_ptr<L0::EventPool> eventPool(EventPool::create(driverHandle.get(), context, 0, nullptr, &eventPoolDesc, result));
403+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
404+
ASSERT_NE(nullptr, eventPool);
405+
L0::EventPoolImp *eventPoolImp = reinterpret_cast<L0::EventPoolImp *>(eventPool.get());
406+
407+
EXPECT_TRUE(eventPoolImp->isShareableEventMemory);
408+
}
409+
410+
TEST_F(EventPoolIPCHandleTests, GivenEventPoolWithIPCEventFlagAndHostMemoryThenShareableEventMemoryIsFalse) {
411+
ze_event_pool_desc_t eventPoolDesc = {
412+
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
413+
nullptr,
414+
ZE_EVENT_POOL_FLAG_IPC | ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
415+
1};
416+
417+
ze_result_t result = ZE_RESULT_SUCCESS;
418+
std::unique_ptr<L0::EventPool> eventPool(EventPool::create(driverHandle.get(), context, 0, nullptr, &eventPoolDesc, result));
419+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
420+
ASSERT_NE(nullptr, eventPool);
421+
422+
auto allocation = &eventPool->getAllocation();
423+
ASSERT_NE(nullptr, allocation);
424+
425+
uint32_t minAllocationSize = eventPool->getEventSize();
426+
EXPECT_GE(allocation->getGraphicsAllocation(device->getNEODevice()->getRootDeviceIndex())->getUnderlyingBufferSize(),
427+
minAllocationSize);
428+
EXPECT_FALSE(allocation->getGraphicsAllocation(device->getNEODevice()->getRootDeviceIndex())->isShareableHostMemory);
341429
}
342430

343431
using EventPoolOpenIPCHandleFailTests = Test<DeviceFixture>;
@@ -347,11 +435,14 @@ TEST_F(EventPoolOpenIPCHandleFailTests, givenFailureToAllocateMemoryWhenOpeningI
347435
ze_event_pool_desc_t eventPoolDesc = {
348436
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
349437
nullptr,
350-
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
438+
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
351439
numEvents};
352440

353441
auto deviceHandle = device->toHandle();
354442
ze_result_t result = ZE_RESULT_SUCCESS;
443+
auto originalMemoryManager = driverHandle->getMemoryManager();
444+
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
445+
driverHandle->setMemoryManager(mockMemoryManager);
355446
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
356447
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
357448
EXPECT_NE(nullptr, eventPool);
@@ -378,6 +469,8 @@ TEST_F(EventPoolOpenIPCHandleFailTests, givenFailureToAllocateMemoryWhenOpeningI
378469

379470
res = eventPool->destroy();
380471
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
472+
delete mockMemoryManager;
473+
driverHandle->setMemoryManager(originalMemoryManager);
381474
}
382475

383476
class MultiDeviceEventPoolOpenIPCHandleFailTestsMemoryManager : public FailMemoryManager {
@@ -412,11 +505,15 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
412505
ze_event_pool_desc_t eventPoolDesc = {
413506
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
414507
nullptr,
415-
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
508+
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
416509
numEvents};
417510

418511
auto deviceHandle = driverHandle->devices[0]->toHandle();
419512
ze_result_t result = ZE_RESULT_SUCCESS;
513+
NEO::MockDevice *neoDevice = static_cast<NEO::MockDevice *>(driverHandle->devices[0]->getNEODevice());
514+
auto originalMemoryManager = driverHandle->getMemoryManager();
515+
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
516+
driverHandle->setMemoryManager(mockMemoryManager);
420517
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
421518
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
422519
EXPECT_NE(nullptr, eventPool);
@@ -430,7 +527,6 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
430527
NEO::MemoryManager *currMemoryManager = nullptr;
431528

432529
prevMemoryManager = driverHandle->getMemoryManager();
433-
NEO::MockDevice *neoDevice = static_cast<NEO::MockDevice *>(driverHandle->devices[0]->getNEODevice());
434530
currMemoryManager = new MultiDeviceEventPoolOpenIPCHandleFailTestsMemoryManager(*neoDevice->executionEnvironment);
435531
driverHandle->setMemoryManager(currMemoryManager);
436532

@@ -444,6 +540,8 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
444540

445541
res = eventPool->destroy();
446542
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
543+
delete mockMemoryManager;
544+
driverHandle->setMemoryManager(originalMemoryManager);
447545
}
448546

449547
TEST_F(EventPoolCreate, GivenNullptrDeviceAndNumberOfDevicesWhenCreatingEventPoolThenReturnError) {

shared/source/memory_manager/graphics_allocation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class GraphicsAllocation : public IDNode<GraphicsAllocation> {
267267
constexpr static uint32_t objectNotUsed = std::numeric_limits<uint32_t>::max();
268268
constexpr static uint32_t objectAlwaysResident = std::numeric_limits<uint32_t>::max() - 1;
269269
std::atomic<uint32_t> hostPtrTaskCountAssignment{0};
270+
bool isShareableHostMemory = false;
270271

271272
protected:
272273
struct UsageInfo {

shared/source/os_interface/linux/drm_memory_manager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1705,7 +1705,7 @@ DrmAllocation *DrmMemoryManager::createAllocWithAlignment(const AllocationData &
17051705
}
17061706

17071707
bo.release();
1708-
1708+
allocation->isShareableHostMemory = true;
17091709
return allocation.release();
17101710
} else {
17111711
return createAllocWithAlignmentFromUserptr(allocationData, size, alignment, alignedSize, gpuAddress);

0 commit comments

Comments
 (0)