feature: Track IPC Handles in DriverHandle vs Context

Related-To: NEO-9116

- To allow for IPC handles to be shared between contexts, the ipc handle
tracking is now moved to the driver handle to be tracked globally.

Signed-off-by: Spruit, Neil R <neil.r.spruit@intel.com>
This commit is contained in:
Spruit, Neil R 2023-10-09 18:51:35 +00:00 committed by Compute-Runtime-Automation
parent 53ec99f27c
commit c8674c16c6
5 changed files with 57 additions and 56 deletions

View File

@ -407,14 +407,14 @@ ze_result_t ContextImp::freeMem(const void *ptr, bool blocking) {
}
std::map<uint64_t, IpcHandleTracking *>::iterator ipcHandleIterator;
auto lockIPC = this->lockIPCHandleMap();
ipcHandleIterator = this->getIPCHandleMap().begin();
while (ipcHandleIterator != this->getIPCHandleMap().end()) {
auto lockIPC = this->driverHandle->lockIPCHandleMap();
ipcHandleIterator = this->driverHandle->getIPCHandleMap().begin();
while (ipcHandleIterator != this->driverHandle->getIPCHandleMap().end()) {
if (ipcHandleIterator->second->ptr == reinterpret_cast<uint64_t>(ptr)) {
auto *memoryManager = driverHandle->getMemoryManager();
memoryManager->closeInternalHandle(ipcHandleIterator->second->ipcData.handle, ipcHandleIterator->second->handleId, nullptr);
delete ipcHandleIterator->second;
this->getIPCHandleMap().erase(ipcHandleIterator->first);
this->driverHandle->getIPCHandleMap().erase(ipcHandleIterator->first);
break;
}
ipcHandleIterator++;
@ -555,15 +555,15 @@ ze_result_t ContextImp::closeIpcMemHandle(const void *ptr) {
ze_result_t ContextImp::putIpcMemHandle(ze_ipc_mem_handle_t ipcHandle) {
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(ipcHandle.data);
std::map<uint64_t, IpcHandleTracking *>::iterator ipcHandleIterator;
auto lock = this->lockIPCHandleMap();
ipcHandleIterator = this->getIPCHandleMap().find(ipcData.handle);
if (ipcHandleIterator != this->getIPCHandleMap().end()) {
auto lock = this->driverHandle->lockIPCHandleMap();
ipcHandleIterator = this->driverHandle->getIPCHandleMap().find(ipcData.handle);
if (ipcHandleIterator != this->driverHandle->getIPCHandleMap().end()) {
ipcHandleIterator->second->refcnt -= 1;
if (ipcHandleIterator->second->refcnt == 0) {
auto *memoryManager = driverHandle->getMemoryManager();
memoryManager->closeInternalHandle(ipcData.handle, ipcHandleIterator->second->handleId, ipcHandleIterator->second->alloc);
delete ipcHandleIterator->second;
this->getIPCHandleMap().erase(ipcData.handle);
this->driverHandle->getIPCHandleMap().erase(ipcData.handle);
}
}
return ZE_RESULT_SUCCESS;
@ -576,9 +576,9 @@ void ContextImp::setIPCHandleData(NEO::GraphicsAllocation *graphicsAllocation, u
ipcData.handle = handle;
ipcData.type = type;
auto lock = this->lockIPCHandleMap();
ipcHandleIterator = this->getIPCHandleMap().find(handle);
if (ipcHandleIterator != this->getIPCHandleMap().end()) {
auto lock = this->driverHandle->lockIPCHandleMap();
ipcHandleIterator = this->driverHandle->getIPCHandleMap().find(handle);
if (ipcHandleIterator != this->driverHandle->getIPCHandleMap().end()) {
ipcHandleIterator->second->refcnt += 1;
} else {
IpcHandleTracking *handleTracking = new IpcHandleTracking;
@ -586,7 +586,7 @@ void ContextImp::setIPCHandleData(NEO::GraphicsAllocation *graphicsAllocation, u
handleTracking->refcnt = 1;
handleTracking->ptr = ptrAddress;
handleTracking->ipcData = ipcData;
this->getIPCHandleMap().insert(std::pair<uint64_t, IpcHandleTracking *>(handle, handleTracking));
this->driverHandle->getIPCHandleMap().insert(std::pair<uint64_t, IpcHandleTracking *>(handle, handleTracking));
}
}
@ -620,9 +620,9 @@ ze_result_t ContextImp::getIpcMemHandle(const void *ptr,
ze_result_t ContextImp::getIpcHandleFromFd(uint64_t handle, ze_ipc_mem_handle_t *pIpcHandle) {
std::map<uint64_t, IpcHandleTracking *>::iterator ipcHandleIterator;
auto lock = this->lockIPCHandleMap();
ipcHandleIterator = this->getIPCHandleMap().find(handle);
if (ipcHandleIterator != this->getIPCHandleMap().end()) {
auto lock = this->driverHandle->lockIPCHandleMap();
ipcHandleIterator = this->driverHandle->getIPCHandleMap().find(handle);
if (ipcHandleIterator != this->driverHandle->getIPCHandleMap().end()) {
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(pIpcHandle->data);
ipcData = ipcHandleIterator->second->ipcData;
} else {
@ -634,9 +634,9 @@ ze_result_t ContextImp::getIpcHandleFromFd(uint64_t handle, ze_ipc_mem_handle_t
ze_result_t ContextImp::getFdFromIpcHandle(ze_ipc_mem_handle_t ipcHandle, uint64_t *pHandle) {
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(ipcHandle.data);
std::map<uint64_t, IpcHandleTracking *>::iterator ipcHandleIterator;
auto lock = this->lockIPCHandleMap();
ipcHandleIterator = this->getIPCHandleMap().find(ipcData.handle);
if (ipcHandleIterator != this->getIPCHandleMap().end()) {
auto lock = this->driverHandle->lockIPCHandleMap();
ipcHandleIterator = this->driverHandle->getIPCHandleMap().find(ipcData.handle);
if (ipcHandleIterator != this->driverHandle->getIPCHandleMap().end()) {
*pHandle = ipcHandleIterator->first;
} else {
return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY;

View File

@ -11,6 +11,7 @@
#include "shared/source/utilities/stackvec.h"
#include "level_zero/core/source/context/context.h"
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include <map>
@ -19,23 +20,6 @@ struct StructuresLookupTable;
struct DriverHandleImp;
struct Device;
#pragma pack(1)
struct IpcMemoryData {
uint64_t handle = 0;
uint8_t type = 0;
};
#pragma pack()
static_assert(sizeof(IpcMemoryData) <= ZE_MAX_IPC_HANDLE_SIZE, "IpcMemoryData is bigger than ZE_MAX_IPC_HANDLE_SIZE");
struct IpcHandleTracking {
uint64_t refcnt = 0;
NEO::GraphicsAllocation *alloc = nullptr;
uint32_t handleId = 0;
uint64_t handle = 0;
uint64_t ptr = 0;
struct IpcMemoryData ipcData = {};
};
struct ContextImp : Context {
ContextImp(DriverHandle *driverHandle);
~ContextImp() override = default;
@ -185,8 +169,6 @@ struct ContextImp : Context {
this->numDevices = static_cast<uint32_t>(this->deviceHandles.size());
}
NEO::VirtualMemoryReservation *findSupportedVirtualReservation(const void *ptr, size_t size);
std::map<uint64_t, IpcHandleTracking *> &getIPCHandleMap() { return this->ipcHandles; };
[[nodiscard]] std::unique_lock<std::mutex> lockIPCHandleMap() { return std::unique_lock<std::mutex>(this->ipcHandleMapMutex); };
ze_result_t checkMemSizeLimit(Device *inDevice, size_t size, bool relaxedSizeAllowed, void **ptr);
protected:
@ -195,8 +177,6 @@ struct ContextImp : Context {
size_t getPageSizeRequired(size_t size);
std::map<uint32_t, ze_device_handle_t> devices;
std::map<uint64_t, IpcHandleTracking *> ipcHandles;
std::mutex ipcHandleMapMutex;
std::vector<ze_device_handle_t> deviceHandles;
DriverHandleImp *driverHandle = nullptr;
uint32_t numDevices = 0;

View File

@ -29,6 +29,22 @@ enum L0DeviceHierarchyMode {
L0_DEVICE_HIERARCHY_FLAT,
L0_DEVICE_HIERARCHY_COMBINED
};
#pragma pack(1)
struct IpcMemoryData {
uint64_t handle = 0;
uint8_t type = 0;
};
#pragma pack()
static_assert(sizeof(IpcMemoryData) <= ZE_MAX_IPC_HANDLE_SIZE, "IpcMemoryData is bigger than ZE_MAX_IPC_HANDLE_SIZE");
struct IpcHandleTracking {
uint64_t refcnt = 0;
NEO::GraphicsAllocation *alloc = nullptr;
uint32_t handleId = 0;
uint64_t handle = 0;
uint64_t ptr = 0;
struct IpcMemoryData ipcData = {};
};
struct DriverHandleImp : public DriverHandle {
~DriverHandleImp() override;
@ -105,6 +121,8 @@ struct DriverHandleImp : public DriverHandle {
ze_result_t formatRTASCompatibilityCheck(ze_rtas_format_exp_t rtasFormatA, ze_rtas_format_exp_t rtasFormatB) override;
ze_result_t parseAffinityMaskCombined(uint32_t *pCount, ze_device_handle_t *phDevices);
std::map<uint64_t, IpcHandleTracking *> &getIPCHandleMap() { return this->ipcHandles; };
[[nodiscard]] std::unique_lock<std::mutex> lockIPCHandleMap() { return std::unique_lock<std::mutex>(this->ipcHandleMapMutex); };
std::unique_ptr<HostPointerManager> hostPointerManager;
// Experimental functions
@ -150,6 +168,9 @@ struct DriverHandleImp : public DriverHandle {
uint32_t numDevices = 0;
std::map<uint64_t, IpcHandleTracking *> ipcHandles;
std::mutex ipcHandleMapMutex;
RootDeviceIndicesContainer rootDeviceIndices;
std::map<uint32_t, NEO::DeviceBitfield> deviceBitfields;
void updateRootDeviceBitFields(std::unique_ptr<NEO::Device> &neoDevice);

View File

@ -66,7 +66,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -92,7 +92,7 @@ TEST_F(MemoryIPCTests,
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
}
TEST_F(MemoryIPCTests,
@ -140,7 +140,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -185,7 +185,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -241,7 +241,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -340,7 +340,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -369,12 +369,12 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(0u, context->getIPCHandleMap().size());
EXPECT_NE(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
}
TEST_F(MemoryIPCTests,
@ -404,12 +404,12 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = contextInvalid->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);

View File

@ -66,7 +66,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -92,7 +92,7 @@ TEST_F(MemoryIPCTests,
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
}
TEST_F(MemoryIPCTests,
@ -121,7 +121,7 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -150,12 +150,12 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(0u, context->getIPCHandleMap().size());
EXPECT_NE(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
}
TEST_F(MemoryIPCTests,
@ -185,12 +185,12 @@ TEST_F(MemoryIPCTests,
result = context->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = contextInvalid->putIpcMemHandle(ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, context->getIPCHandleMap().size());
EXPECT_EQ(0u, driverHandle->getIPCHandleMap().size());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);