feature: Add new struct for IPC opacity

Related-To: NEO-15185

Signed-off-by: Aravind Gopalakrishnan <aravind.gopalakrishnan@intel.com>
This commit is contained in:
Aravind Gopalakrishnan
2025-06-24 21:28:23 +00:00
committed by Compute-Runtime-Automation
parent 4a15355471
commit 39b28474ae
7 changed files with 154 additions and 8 deletions

View File

@@ -779,6 +779,14 @@ ze_result_t ContextImp::getIpcMemHandlesImpl(const void *ptr,
ipcType = InternalIpcMemoryType::hostUnifiedMemory;
}
bool pidfdOrSocket = true;
for (auto &device : this->driverHandle->devices) {
auto &productHelper = device->getNEODevice()->getProductHelper();
if (!productHelper.isPidFdOrSocketForIpcSupported()) {
pidfdOrSocket = false;
break;
}
}
uint32_t loopCount = numIpcHandles ? *numIpcHandles : 1u;
for (uint32_t i = 0u; i < loopCount; i++) {
uint64_t handle = 0;
@@ -789,11 +797,14 @@ ze_result_t ContextImp::getIpcMemHandlesImpl(const void *ptr,
memoryManager->registerIpcExportedAllocation(alloc);
using IpcDataT = IpcMemoryData;
IpcDataT &ipcData = *reinterpret_cast<IpcDataT *>(pIpcHandles[i].data);
setIPCHandleData<IpcDataT>(alloc, handle, ipcData, reinterpret_cast<uint64_t>(ptr), static_cast<uint8_t>(ipcType), usmPool);
if (pidfdOrSocket) {
IpcOpaqueMemoryData &ipcData = *reinterpret_cast<IpcOpaqueMemoryData *>(pIpcHandles[i].data);
setIPCHandleData<IpcOpaqueMemoryData>(alloc, handle, ipcData, reinterpret_cast<uint64_t>(ptr), static_cast<uint8_t>(ipcType), usmPool);
} else {
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(pIpcHandles[i].data);
setIPCHandleData<IpcMemoryData>(alloc, handle, ipcData, reinterpret_cast<uint64_t>(ptr), static_cast<uint8_t>(ipcType), usmPool);
}
}
return ZE_RESULT_SUCCESS;
}

View File

@@ -202,8 +202,16 @@ struct ContextImp : Context, NEO::NonCopyableAndNonMovableClass {
std::map<uint64_t, IpcHandleTracking *>::iterator ipcHandleIterator;
ipcData = {};
ipcData.handle = handle;
ipcData.type = type;
if constexpr (std::is_same_v<IpcDataT, IpcMemoryData>) {
ipcData.handle = handle;
ipcData.type = type;
} else if constexpr (std::is_same_v<IpcDataT, IpcOpaqueMemoryData>) {
printf("opaque type used\n");
ipcData.memoryType = type;
ipcData.processId = NEO::SysCalls::getCurrentProcessId();
ipcData.type = IpcHandleType::fdHandle;
ipcData.handle.fd = static_cast<int>(handle);
}
if (usmPool) {
ipcData.poolOffset = usmPool->getOffsetInPool(addrToPtr(ptrAddress));
@@ -220,7 +228,9 @@ struct ContextImp : Context, NEO::NonCopyableAndNonMovableClass {
handleTracking->refcnt = 1;
handleTracking->ptr = ptrAddress;
handleTracking->handle = handle;
handleTracking->ipcData = ipcData;
if constexpr (std::is_same_v<IpcDataT, IpcMemoryData>) {
handleTracking->ipcData = ipcData;
}
this->driverHandle->getIPCHandleMap().insert(std::pair<uint64_t, IpcHandleTracking *>(handle, handleTracking));
}
}

View File

@@ -11,6 +11,7 @@
#include "shared/source/memory_manager/graphics_allocation.h"
#include "shared/source/memory_manager/unified_memory_pooling.h"
#include "shared/source/os_interface/os_library.h"
#include "shared/source/os_interface/sys_calls_common.h"
#include "level_zero/api/extensions/public/ze_exp_ext.h"
#include "level_zero/core/source/driver/driver_handle.h"
@@ -36,6 +37,24 @@ struct IpcMemoryData {
#pragma pack()
static_assert(sizeof(IpcMemoryData) <= ZE_MAX_IPC_HANDLE_SIZE, "IpcMemoryData is bigger than ZE_MAX_IPC_HANDLE_SIZE");
enum class IpcHandleType : uint8_t {
fdHandle = 0,
maxHandle
};
struct IpcOpaqueMemoryData {
union IpcHandle {
int fd;
uint64_t reserved;
};
IpcHandle handle = {};
uint64_t poolOffset = 0;
unsigned int processId = 0;
IpcHandleType type = IpcHandleType::maxHandle;
uint8_t memoryType = 0;
};
static_assert(sizeof(IpcOpaqueMemoryData) <= ZE_MAX_IPC_HANDLE_SIZE, "IpcOpaqueMemoryData is bigger than ZE_MAX_IPC_HANDLE_SIZE");
struct IpcHandleTracking {
uint64_t refcnt = 0;
NEO::GraphicsAllocation *alloc = nullptr;

View File

@@ -553,5 +553,31 @@ void MemoryExportImportImplicitScalingTest::TearDown() {
delete currMemoryManager;
}
void MemoryGetIpcHandlePidfdTest::SetUp() {
neoDevice =
NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
auto mockBuiltIns = new MockBuiltins();
MockRootDeviceEnvironment::resetBuiltins(neoDevice->executionEnvironment->rootDeviceEnvironments[0].get(), mockBuiltIns);
NEO::DeviceVector devices;
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
driverHandle = std::make_unique<DriverHandleImp>();
driverHandle->initialize(std::move(devices));
prevMemoryManager = driverHandle->getMemoryManager();
currMemoryManager = new MemoryManagerOpenIpcMock(*neoDevice->executionEnvironment);
driverHandle->setMemoryManager(currMemoryManager);
device = driverHandle->devices[0];
context = std::make_unique<ContextImp>(driverHandle.get());
EXPECT_NE(context, nullptr);
context->getDevices().insert(std::make_pair(device->getRootDeviceIndex(), device->toHandle()));
auto neoDevice = device->getNEODevice();
context->rootDeviceIndices.pushUnique(neoDevice->getRootDeviceIndex());
context->deviceBitfields.insert({neoDevice->getRootDeviceIndex(), neoDevice->getDeviceBitfield()});
}
void MemoryGetIpcHandlePidfdTest::TearDown() {
driverHandle->setMemoryManager(prevMemoryManager);
delete currMemoryManager;
}
} // namespace ult
} // namespace L0

View File

@@ -402,5 +402,17 @@ struct MemoryExportImportImplicitScalingTest : public ::testing::Test {
std::unique_ptr<ContextIpcMock> context;
};
struct MemoryGetIpcHandlePidfdTest : public ::testing::Test {
void SetUp() override;
void TearDown() override;
NEO::MemoryManager *prevMemoryManager = nullptr;
NEO::MemoryManager *currMemoryManager = nullptr;
std::unique_ptr<DriverHandleImp> driverHandle;
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
std::unique_ptr<ContextImp> context;
};
} // namespace ult
} // namespace L0

View File

@@ -990,5 +990,28 @@ TEST_F(MemoryExportImportImplicitScalingTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryGetIpcHandlePidfdTest,
givenCallToGetIpcHandleWithDeviceAllocationWithPidFdSocketMethodThenIpcHandleIsReturned) {
DebugManagerStateRestore restorer;
debugManager.flags.EnablePidFdOrSocketsForIpc.set(1);
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -9,7 +9,10 @@
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_driver_model.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/os_interface/linux/drm_mock_extended.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
#include "level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h"
@@ -1031,5 +1034,47 @@ TEST_F(MemoryExportImportTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
class DrmIpcPidfdFixture : public DeviceFixture {
public:
void setUp() {
DeviceFixture::setUp();
auto &rootDeviceEnvironment{*neoDevice->executionEnvironment->rootDeviceEnvironments[0]};
drmMock = new DrmMock(rootDeviceEnvironment);
rootDeviceEnvironment.osInterface.reset(new NEO::OSInterface);
rootDeviceEnvironment.osInterface->setDriverModel(std::unique_ptr<NEO::Drm>(drmMock));
}
void tearDown() {
DeviceFixture::tearDown();
}
DrmMock *drmMock = nullptr;
};
using MemoryDrmIpcPidfdTests = Test<DrmIpcPidfdFixture>;
TEST_F(MemoryDrmIpcPidfdTests,
givenCallToGetIpcHandleWithDeviceAllocationWithPidFdSocketMethodAndMockDrmThenIpcHandleIsReturned) {
DebugManagerStateRestore restorer;
debugManager.flags.EnablePidFdOrSocketsForIpc.set(1);
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0