feature: Add pidfd option for IPC handle import

Related-To: NEO-10380

Signed-off-by: Aravind Gopalakrishnan <aravind.gopalakrishnan@intel.com>
This commit is contained in:
Aravind Gopalakrishnan
2025-04-18 00:46:50 +00:00
committed by Compute-Runtime-Automation
parent 4e81b84d07
commit b4f95a1a26
4 changed files with 74 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -7,6 +7,7 @@
#include "shared/source/device/device.h"
#include "shared/source/memory_manager/unified_memory_manager.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "level_zero/core/source/context/context_imp.h"
#include "level_zero/core/source/device/device.h"
@@ -23,6 +24,26 @@ bool ContextImp::isShareableMemory(const void *exportDesc, bool exportableMemory
void *ContextImp::getMemHandlePtr(ze_device_handle_t hDevice, uint64_t handle, NEO::AllocationType allocationType, ze_ipc_memory_flags_t flags) {
auto neoDevice = Device::fromHandle(hDevice)->getNEODevice();
bool pidfdOrSocket = false;
if (NEO::debugManager.flags.EnablePidFdOrSocketsForIpc.get() != -1) {
pidfdOrSocket = !!(NEO::debugManager.flags.EnablePidFdOrSocketsForIpc.get());
}
if (pidfdOrSocket) {
// With pidfd approach extract parent pid and target fd before importing handle
pid_t exporterPid = 0;
unsigned int flags = 0u;
int pidfd = NEO::SysCalls::pidfdopen(exporterPid, flags);
if (pidfd == -1) {
PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "pidfd_open Syscall failed, using fallback mechanism for IPC handle exchange\n");
} else {
unsigned int flags = 0u;
int newfd = NEO::SysCalls::pidfdgetfd(pidfd, 0, flags);
if (newfd < 0) {
PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "pidfd_getfd Syscall failed, using fallback mechanism for IPC handle exchange\n");
}
}
}
NEO::SvmAllocationData allocDataInternal(neoDevice->getRootDeviceIndex());
return this->driverHandle->importFdHandle(neoDevice, flags, handle, allocationType, nullptr, nullptr, allocDataInternal);
}

View File

@@ -1,11 +1,12 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/built_ins/sip.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "shared/test/common/mocks/mock_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "shared/test/common/mocks/mock_cpu_page_fault_manager.h"
@@ -13,6 +14,7 @@
#include "shared/test/common/mocks/mock_graphics_allocation.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/mocks/mock_svm_manager.h"
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "shared/test/common/test_macros/test.h"
#include "level_zero/core/source/context/context_imp.h"
@@ -69,5 +71,52 @@ TEST_F(GetMemHandlePtrTest, whenCallingGetMemHandlePtrWithInvalidHandleThenNullp
EXPECT_EQ(nullptr, context->getMemHandlePtr(device, handle, NEO::AllocationType::buffer, 0));
}
TEST_F(GetMemHandlePtrTest, whenCallingGetMemHandlePtrWithPidfdMethodAndSyscallsReturnSuccessThenValidHandleIsReturned) {
DebugManagerStateRestore restorer;
debugManager.flags.EnablePidFdOrSocketsForIpc.set(1);
VariableBackup<decltype(SysCalls::pidfdopenCalled)> pidfdOpenCalledBackup(&NEO::SysCalls::pidfdopenCalled, 0u);
VariableBackup<decltype(SysCalls::pidfdgetfdCalled)> pidfdGetFdCalledBackup(&NEO::SysCalls::pidfdgetfdCalled, 0u);
uint64_t handle = 57;
// Test Successfully returning fd Handle
EXPECT_NE(nullptr, context->getMemHandlePtr(device, handle, NEO::AllocationType::buffer, 0));
EXPECT_EQ(1, NEO::SysCalls::pidfdopenCalled);
EXPECT_EQ(1, NEO::SysCalls::pidfdgetfdCalled);
}
TEST_F(GetMemHandlePtrTest, whenCallingGetMemHandlePtrWithPidfdMethodAndPidfdOpenSyscallReturnFailThenPidfdGetNotCalled) {
DebugManagerStateRestore restorer;
debugManager.flags.EnablePidFdOrSocketsForIpc.set(1);
VariableBackup<decltype(SysCalls::pidfdopenCalled)> pidfdOpenCalledBackup(&NEO::SysCalls::pidfdopenCalled, 0u);
VariableBackup<decltype(SysCalls::pidfdgetfdCalled)> pidfdGetFdCalledBackup(&NEO::SysCalls::pidfdgetfdCalled, 0u);
VariableBackup<decltype(NEO::SysCalls::sysCallsPidfdOpen)> mockPidfdOpen(&NEO::SysCalls::sysCallsPidfdOpen, [](pid_t, unsigned int) -> int {
return -1;
});
uint64_t handle = 57;
EXPECT_NE(nullptr, context->getMemHandlePtr(device, handle, NEO::AllocationType::buffer, 0));
EXPECT_EQ(1, NEO::SysCalls::pidfdopenCalled);
EXPECT_EQ(0, NEO::SysCalls::pidfdgetfdCalled);
}
TEST_F(GetMemHandlePtrTest, whenCallingGetMemHandlePtrWithPidfdMethodAndPidfdGetSyscallReturnFailThenCorrectHandleIsReturned) {
DebugManagerStateRestore restorer;
debugManager.flags.EnablePidFdOrSocketsForIpc.set(1);
VariableBackup<decltype(SysCalls::pidfdopenCalled)> pidfdOpenCalledBackup(&NEO::SysCalls::pidfdopenCalled, 0u);
VariableBackup<decltype(SysCalls::pidfdgetfdCalled)> pidfdGetFdCalledBackup(&NEO::SysCalls::pidfdgetfdCalled, 0u);
VariableBackup<decltype(NEO::SysCalls::sysCallsPidfdGetfd)> mockPidfdGet(&NEO::SysCalls::sysCallsPidfdGetfd, [](int, int, unsigned int) -> int {
return -1;
});
uint64_t handle = 57;
EXPECT_NE(nullptr, context->getMemHandlePtr(device, handle, NEO::AllocationType::buffer, 0));
EXPECT_EQ(1, NEO::SysCalls::pidfdopenCalled);
EXPECT_EQ(1, NEO::SysCalls::pidfdgetfdCalled);
}
} // namespace ult
} // namespace L0

View File

@@ -315,6 +315,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, ForceIndirectDetectionForCMKernels, -1, "-1: def
DECLARE_DEBUG_VARIABLE(int32_t, PipelinedEuThreadArbitration, -1, "-1: default. 1: Use Walker field, 0: Use StateComputeMode command to program pipelinedEuThreadArbitration")
DECLARE_DEBUG_VARIABLE(bool, ForceUseOnlyGlobalTimestamps, 0, "0- default disabled, 1: enable use only global timestamp")
DECLARE_DEBUG_VARIABLE(int32_t, GetSipBinaryFromExternalLib, -1, "-1: default, 0: disabled, 1: enabled. If enabled, then retrieve Sip from external library")
DECLARE_DEBUG_VARIABLE(int32_t, EnablePidFdOrSocketsForIpc, -1, "-1: default, 0: disabled (default), 1: enabled. If enabled, L0 IPC handles are opaque and pidfd or sockets are used for IPC exchange")
/*LOGGING FLAGS*/
DECLARE_DEBUG_VARIABLE(int32_t, PrintDriverDiagnostics, -1, "prints driver diagnostics messages to standard output, value corresponds to hint level")

View File

@@ -670,4 +670,5 @@ GetSipBinaryFromExternalLib = -1
LogUsmReuse = 0
ExperimentalUSMAllocationReuseLimitThreshold = -1
UseIgcAsFcl = 0
EnablePidFdOrSocketsForIpc = -1
# Please don't edit below this line