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 <neil.r.spruit@intel.com>
This commit is contained in:
Neil R Spruit 2022-08-03 14:06:59 -07:00 committed by Compute-Runtime-Automation
parent 6b4375efcd
commit ada9b5d4a9
6 changed files with 116 additions and 6 deletions

View File

@ -525,6 +525,9 @@ ze_result_t EventPoolImp::getIpcHandle(ze_ipc_event_pool_handle_t *pIpcHandle) {
// For the event pool, this contains:
// - the number of events the pool has.
// - the id for the device used during pool creation
if (!this->isShareableEventMemory) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
uint64_t handle = this->eventPoolAllocations->getDefaultGraphicsAllocation()->peekInternalHandle(this->context->getDriverHandle()->getMemoryManager());

View File

@ -97,6 +97,9 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin
if (useDeviceAlloc) {
NEO::AllocationProperties allocationProperties{*rootDeviceIndices.begin(), alignedSize, allocationType, devices[0]->getNEODevice()->getDeviceBitfield()};
allocationProperties.alignment = eventAlignment;
if (eventPoolFlags & ZE_EVENT_POOL_FLAG_IPC) {
this->isShareableEventMemory = true;
}
auto graphicsAllocation = driver->getMemoryManager()->allocateGraphicsMemoryWithProperties(allocationProperties);
if (graphicsAllocation) {
@ -112,6 +115,10 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin
allocationProperties,
*eventPoolAllocations);
if (eventPoolFlags & ZE_EVENT_POOL_FLAG_IPC) {
this->isShareableEventMemory = eventPoolAllocations->getDefaultGraphicsAllocation()->isShareableHostMemory;
}
allocatedMemory = (nullptr != eventPoolPtr);
}

View File

@ -277,6 +277,7 @@ struct EventPoolImp : public EventPool {
ContextImp *context = nullptr;
size_t numEvents;
bool isImportedIpcPool = false;
bool isShareableEventMemory = false;
protected:
uint32_t eventAlignment = 0;

View File

@ -275,6 +275,25 @@ TEST_F(EventPoolCreate, GivenDeviceThenEventPoolIsCreated) {
eventPool->destroy();
}
class MemoryManagerEventPoolIPCMock : public NEO::MockMemoryManager {
public:
MemoryManagerEventPoolIPCMock(NEO::ExecutionEnvironment &executionEnvironment) : NEO::MockMemoryManager(executionEnvironment) {}
void *createMultiGraphicsAllocationInSystemMemoryPool(RootDeviceIndicesContainer &rootDeviceIndices, AllocationProperties &properties, NEO::MultiGraphicsAllocation &multiGraphicsAllocation) override {
alloc = new NEO::MockGraphicsAllocation(&buffer, sizeof(buffer));
alloc->isShareableHostMemory = true;
multiGraphicsAllocation.addAllocation(alloc);
return reinterpret_cast<void *>(alloc->getUnderlyingBuffer());
};
void freeGraphicsMemoryImpl(NEO::GraphicsAllocation *gfxAllocation) override {
delete gfxAllocation;
};
void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation, bool isImportedAllocation) override {
delete gfxAllocation;
};
char buffer[64];
NEO::MockGraphicsAllocation *alloc;
};
using EventPoolIPCHandleTests = Test<DeviceFixture>;
TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNumberOfEventsAreReturnedInHandle) {
@ -282,11 +301,14 @@ TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNum
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
numEvents};
auto deviceHandle = device->toHandle();
ze_result_t result = ZE_RESULT_SUCCESS;
auto curMemoryManager = driverHandle->getMemoryManager();
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(mockMemoryManager);
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, eventPool);
@ -303,6 +325,30 @@ TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNum
memcpy_s(&expectedNumEvents, sizeof(expectedNumEvents), ipcHandle.data + sizeof(int), sizeof(expectedNumEvents));
EXPECT_EQ(numEvents, expectedNumEvents);
res = eventPool->destroy();
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
delete mockMemoryManager;
driverHandle->setMemoryManager(curMemoryManager);
}
TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolWhenHostShareableMemoryIsFalseThenUnsuportedIsReturned) {
uint32_t numEvents = 4;
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
numEvents};
auto deviceHandle = device->toHandle();
ze_result_t result = ZE_RESULT_SUCCESS;
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, eventPool);
ze_ipc_event_pool_handle_t ipcHandle = {};
ze_result_t res = eventPool->getIpcHandle(&ipcHandle);
EXPECT_EQ(res, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
res = eventPool->destroy();
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
}
@ -312,11 +358,14 @@ TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolThenEventPoolIsC
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
numEvents};
auto deviceHandle = device->toHandle();
ze_result_t result = ZE_RESULT_SUCCESS;
auto curMemoryManager = driverHandle->getMemoryManager();
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(mockMemoryManager);
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, eventPool);
@ -338,6 +387,45 @@ TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolThenEventPoolIsC
res = eventPool->destroy();
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
delete mockMemoryManager;
driverHandle->setMemoryManager(curMemoryManager);
}
TEST_F(EventPoolIPCHandleTests, GivenEventPoolWithIPCEventFlagAndDeviceMemoryThenShareableEventMemoryIsTrue) {
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_IPC,
1};
ze_result_t result = ZE_RESULT_SUCCESS;
std::unique_ptr<L0::EventPool> eventPool(EventPool::create(driverHandle.get(), context, 0, nullptr, &eventPoolDesc, result));
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ASSERT_NE(nullptr, eventPool);
L0::EventPoolImp *eventPoolImp = reinterpret_cast<L0::EventPoolImp *>(eventPool.get());
EXPECT_TRUE(eventPoolImp->isShareableEventMemory);
}
TEST_F(EventPoolIPCHandleTests, GivenEventPoolWithIPCEventFlagAndHostMemoryThenShareableEventMemoryIsFalse) {
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_IPC | ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
1};
ze_result_t result = ZE_RESULT_SUCCESS;
std::unique_ptr<L0::EventPool> eventPool(EventPool::create(driverHandle.get(), context, 0, nullptr, &eventPoolDesc, result));
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ASSERT_NE(nullptr, eventPool);
auto allocation = &eventPool->getAllocation();
ASSERT_NE(nullptr, allocation);
uint32_t minAllocationSize = eventPool->getEventSize();
EXPECT_GE(allocation->getGraphicsAllocation(device->getNEODevice()->getRootDeviceIndex())->getUnderlyingBufferSize(),
minAllocationSize);
EXPECT_FALSE(allocation->getGraphicsAllocation(device->getNEODevice()->getRootDeviceIndex())->isShareableHostMemory);
}
using EventPoolOpenIPCHandleFailTests = Test<DeviceFixture>;
@ -347,11 +435,14 @@ TEST_F(EventPoolOpenIPCHandleFailTests, givenFailureToAllocateMemoryWhenOpeningI
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
numEvents};
auto deviceHandle = device->toHandle();
ze_result_t result = ZE_RESULT_SUCCESS;
auto originalMemoryManager = driverHandle->getMemoryManager();
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(mockMemoryManager);
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, eventPool);
@ -378,6 +469,8 @@ TEST_F(EventPoolOpenIPCHandleFailTests, givenFailureToAllocateMemoryWhenOpeningI
res = eventPool->destroy();
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
delete mockMemoryManager;
driverHandle->setMemoryManager(originalMemoryManager);
}
class MultiDeviceEventPoolOpenIPCHandleFailTestsMemoryManager : public FailMemoryManager {
@ -412,11 +505,15 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
ze_event_pool_desc_t eventPoolDesc = {
ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
nullptr,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE,
ZE_EVENT_POOL_FLAG_HOST_VISIBLE | ZE_EVENT_POOL_FLAG_IPC,
numEvents};
auto deviceHandle = driverHandle->devices[0]->toHandle();
ze_result_t result = ZE_RESULT_SUCCESS;
NEO::MockDevice *neoDevice = static_cast<NEO::MockDevice *>(driverHandle->devices[0]->getNEODevice());
auto originalMemoryManager = driverHandle->getMemoryManager();
MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(mockMemoryManager);
auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, eventPool);
@ -430,7 +527,6 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
NEO::MemoryManager *currMemoryManager = nullptr;
prevMemoryManager = driverHandle->getMemoryManager();
NEO::MockDevice *neoDevice = static_cast<NEO::MockDevice *>(driverHandle->devices[0]->getNEODevice());
currMemoryManager = new MultiDeviceEventPoolOpenIPCHandleFailTestsMemoryManager(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(currMemoryManager);
@ -444,6 +540,8 @@ TEST_F(MultiDeviceEventPoolOpenIPCHandleFailTests,
res = eventPool->destroy();
EXPECT_EQ(res, ZE_RESULT_SUCCESS);
delete mockMemoryManager;
driverHandle->setMemoryManager(originalMemoryManager);
}
TEST_F(EventPoolCreate, GivenNullptrDeviceAndNumberOfDevicesWhenCreatingEventPoolThenReturnError) {

View File

@ -267,6 +267,7 @@ class GraphicsAllocation : public IDNode<GraphicsAllocation> {
constexpr static uint32_t objectNotUsed = std::numeric_limits<uint32_t>::max();
constexpr static uint32_t objectAlwaysResident = std::numeric_limits<uint32_t>::max() - 1;
std::atomic<uint32_t> hostPtrTaskCountAssignment{0};
bool isShareableHostMemory = false;
protected:
struct UsageInfo {

View File

@ -1705,7 +1705,7 @@ DrmAllocation *DrmMemoryManager::createAllocWithAlignment(const AllocationData &
}
bo.release();
allocation->isShareableHostMemory = true;
return allocation.release();
} else {
return createAllocWithAlignmentFromUserptr(allocationData, size, alignment, alignedSize, gpuAddress);