diff --git a/runtime/mem_obj/mem_obj.cpp b/runtime/mem_obj/mem_obj.cpp index 23719fee58..be3e583c80 100644 --- a/runtime/mem_obj/mem_obj.cpp +++ b/runtime/mem_obj/mem_obj.cpp @@ -175,7 +175,7 @@ cl_int MemObj::getMemObjectInfo(cl_mem_info paramName, srcParam = &refCnt; break; case CL_MEM_ALLOCATION_HANDLE_INTEL: - internalHandle = this->getGraphicsAllocation()->peekInternalHandle(); + internalHandle = this->getGraphicsAllocation()->peekInternalHandle(this->memoryManager); srcParamSize = sizeof(internalHandle); srcParam = &internalHandle; break; diff --git a/runtime/memory_manager/graphics_allocation.h b/runtime/memory_manager/graphics_allocation.h index 9aaa52d1bc..5b6d4326f3 100644 --- a/runtime/memory_manager/graphics_allocation.h +++ b/runtime/memory_manager/graphics_allocation.h @@ -34,6 +34,7 @@ constexpr auto nonSharedResource = 0u; } class Gmm; +class MemoryManager; struct AllocationProperties; class GraphicsAllocation : public IDNode { @@ -166,7 +167,7 @@ class GraphicsAllocation : public IDNode { bool isResidencyTaskCountBelow(uint32_t taskCount, uint32_t contextId) const { return !isResident(contextId) || getResidencyTaskCount(contextId) < taskCount; } virtual std::string getAllocationInfoString() const; - virtual uint64_t peekInternalHandle() { return 0llu; } + virtual uint64_t peekInternalHandle(MemoryManager *memoryManager) { return 0llu; } static bool isCpuAccessRequired(AllocationType allocationType) { return allocationType == AllocationType::LINEAR_STREAM || diff --git a/runtime/os_interface/debug_variables_base.inl b/runtime/os_interface/debug_variables_base.inl index 9ee1026caf..ebe82b121a 100644 --- a/runtime/os_interface/debug_variables_base.inl +++ b/runtime/os_interface/debug_variables_base.inl @@ -100,6 +100,7 @@ DECLARE_DEBUG_VARIABLE(bool, EnableExtendedVaFormats, false, "Enable more format DECLARE_DEBUG_VARIABLE(bool, AddClGlSharing, false, "Add cl-gl extension") DECLARE_DEBUG_VARIABLE(bool, EnablePassInlineData, false, "Enable passing of inline data") DECLARE_DEBUG_VARIABLE(bool, EnableFormatQuery, false, "Enable sharing format querying") +DECLARE_DEBUG_VARIABLE(bool, AllowOpenFdOperations, false, "When enabled driver is allowed to call DRM_IOCTL_PRIME_HANDLE_TO_FD.") DECLARE_DEBUG_VARIABLE(bool, EnableBlitterOperationsForReadWriteBuffers, false, "Use Blitter engine for Read/Write Buffers operations") DECLARE_DEBUG_VARIABLE(int32_t, EnableCacheFlushAfterWalker, 0, "-1: platform behavior, 0: disabled, 1: enabled. Adds dedicated cache flush command after WALKER command when surfaces used by kernel require to flush the cache") DECLARE_DEBUG_VARIABLE(int32_t, EnableLocalMemory, -1, "-1: default behavior, 0: disabled, 1: enabled, Allows allocating graphics memory in Local Memory") diff --git a/runtime/os_interface/linux/drm_allocation.cpp b/runtime/os_interface/linux/drm_allocation.cpp index f25693d058..3d5df4570b 100644 --- a/runtime/os_interface/linux/drm_allocation.cpp +++ b/runtime/os_interface/linux/drm_allocation.cpp @@ -8,6 +8,7 @@ #include "runtime/os_interface/linux/drm_allocation.h" #include "runtime/os_interface/linux/drm_buffer_object.h" +#include "runtime/os_interface/linux/drm_memory_manager.h" #include @@ -20,5 +21,12 @@ std::string DrmAllocation::getAllocationInfoString() const { return ss.str(); } -uint64_t DrmAllocation::peekInternalHandle() { return static_cast(getBO()->peekHandle()); } +uint64_t DrmAllocation::peekInternalHandle(MemoryManager *memoryManager) { + auto drmMemoryManager = static_cast(memoryManager); + if (DebugManager.flags.AllowOpenFdOperations.get()) { + return static_cast(drmMemoryManager->obtainFdFromHandle(getBO()->peekHandle())); + } else { + return 0llu; + } +} } // namespace NEO diff --git a/runtime/os_interface/linux/drm_allocation.h b/runtime/os_interface/linux/drm_allocation.h index 85ec8ee125..71f0716c3d 100644 --- a/runtime/os_interface/linux/drm_allocation.h +++ b/runtime/os_interface/linux/drm_allocation.h @@ -35,7 +35,7 @@ class DrmAllocation : public GraphicsAllocation { } return this->bo; } - uint64_t peekInternalHandle() override; + uint64_t peekInternalHandle(MemoryManager *memoryManager) override; protected: BufferObject *bo; diff --git a/runtime/os_interface/linux/drm_memory_manager.cpp b/runtime/os_interface/linux/drm_memory_manager.cpp index 5e9187d7f5..b5c67299ce 100644 --- a/runtime/os_interface/linux/drm_memory_manager.cpp +++ b/runtime/os_interface/linux/drm_memory_manager.cpp @@ -768,4 +768,14 @@ void *DrmMemoryManager::reserveCpuAddressRange(size_t size) { void DrmMemoryManager::releaseReservedCpuAddressRange(void *reserved, size_t size) { munmapFunction(reserved, size); } +int DrmMemoryManager::obtainFdFromHandle(int boHandle) { + drm_prime_handle openFd = {0, 0, 0}; + + openFd.flags = DRM_CLOEXEC | DRM_RDWR; + openFd.handle = boHandle; + + drm->ioctl(DRM_IOCTL_PRIME_HANDLE_TO_FD, &openFd); + + return openFd.fd; +} } // namespace NEO diff --git a/runtime/os_interface/linux/drm_memory_manager.h b/runtime/os_interface/linux/drm_memory_manager.h index 30de475e81..112e7f2d15 100644 --- a/runtime/os_interface/linux/drm_memory_manager.h +++ b/runtime/os_interface/linux/drm_memory_manager.h @@ -57,6 +57,8 @@ class DrmMemoryManager : public MemoryManager { void *reserveCpuAddressRange(size_t size) override; void releaseReservedCpuAddressRange(void *reserved, size_t size) override; + int obtainFdFromHandle(int boHandle); + protected: BufferObject *findAndReferenceSharedBufferObject(int boHandle); BufferObject *createSharedBufferObject(int boHandle, size_t size, bool requireSpecificBitness); diff --git a/unit_tests/memory_manager/graphics_allocation_tests.cpp b/unit_tests/memory_manager/graphics_allocation_tests.cpp index f77fe28cf4..b2ed9ef99b 100644 --- a/unit_tests/memory_manager/graphics_allocation_tests.cpp +++ b/unit_tests/memory_manager/graphics_allocation_tests.cpp @@ -141,5 +141,5 @@ TEST(GraphicsAllocationTest, givenDefaultAllocationWhenGettingNumHandlesThenOneI TEST(GraphicsAllocationTest, givenDefaultGraphicsAllocationWhenInternalHandleIsBeingObtainedThenZeroIsReturned) { MockGraphicsAllocation graphicsAllocation; - EXPECT_EQ(0llu, graphicsAllocation.peekInternalHandle()); + EXPECT_EQ(0llu, graphicsAllocation.peekInternalHandle(nullptr)); } diff --git a/unit_tests/os_interface/linux/device_command_stream_fixture.h b/unit_tests/os_interface/linux/device_command_stream_fixture.h index 1fe83d54d9..4c99743768 100644 --- a/unit_tests/os_interface/linux/device_command_stream_fixture.h +++ b/unit_tests/os_interface/linux/device_command_stream_fixture.h @@ -80,6 +80,7 @@ class DrmMockCustom : public Drm { gemSetTiling = 0; gemGetTiling = 0; primeFdToHandle = 0; + handleToPrimeFd = 0; gemMmap = 0; gemSetDomain = 0; gemWait = 0; @@ -97,6 +98,7 @@ class DrmMockCustom : public Drm { std::atomic gemSetTiling; std::atomic gemGetTiling; std::atomic primeFdToHandle; + std::atomic handleToPrimeFd; std::atomic gemMmap; std::atomic gemSetDomain; std::atomic gemWait; @@ -126,6 +128,7 @@ class DrmMockCustom : public Drm { NEO_IOCTL_EXPECT_EQ(gemSetTiling); NEO_IOCTL_EXPECT_EQ(gemGetTiling); NEO_IOCTL_EXPECT_EQ(primeFdToHandle); + NEO_IOCTL_EXPECT_EQ(handleToPrimeFd); NEO_IOCTL_EXPECT_EQ(gemMmap); NEO_IOCTL_EXPECT_EQ(gemSetDomain); NEO_IOCTL_EXPECT_EQ(gemWait); @@ -153,6 +156,10 @@ class DrmMockCustom : public Drm { //DRM_IOCTL_PRIME_FD_TO_HANDLE __u32 outputHandle = 0; __s32 inputFd = 0; + //DRM_IOCTL_PRIME_HANDLE_TO_FD + __u32 inputHandle = 0; + __s32 outputFd = 0; + __s32 inputFlags = 0; //DRM_IOCTL_I915_GEM_USERPTR __u32 returnHandle = 0; //DRM_IOCTL_I915_GEM_MMAP @@ -216,6 +223,14 @@ class DrmMockCustom : public Drm { inputFd = primeToHandleParams->fd; ioctl_cnt.primeFdToHandle++; } break; + case DRM_IOCTL_PRIME_HANDLE_TO_FD: { + auto *handleToPrimeParams = (drm_prime_handle *)arg; + //return FD + inputHandle = handleToPrimeParams->handle; + inputFlags = handleToPrimeParams->flags; + handleToPrimeParams->fd = outputFd; + ioctl_cnt.handleToPrimeFd++; + } break; case DRM_IOCTL_I915_GEM_MMAP: { auto mmapParams = (drm_i915_gem_mmap *)arg; mmapHandle = mmapParams->handle; diff --git a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp index 600b3eb2c9..9b80f5ed75 100644 --- a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp @@ -145,12 +145,19 @@ TEST_F(DrmMemoryManagerTest, pinAfterAllocateWhenAskedAndAllowedAndBigAllocation } TEST_F(DrmMemoryManagerTest, whenPeekInternalHandleIsCalledThenBoIsReturend) { + DebugManagerStateRestore restore; + DebugManager.flags.AllowOpenFdOperations.set(1); mock->ioctl_expected.gemUserptr = 1; mock->ioctl_expected.gemWait = 1; mock->ioctl_expected.gemClose = 1; + mock->ioctl_expected.handleToPrimeFd = 1; + mock->outputFd = 1337; auto allocation = static_cast(this->memoryManager->allocateGraphicsMemoryWithProperties(createAllocationProperties(10 * MemoryConstants::pageSize, true))); ASSERT_NE(allocation->getBO(), nullptr); - ASSERT_EQ(allocation->peekInternalHandle(), static_cast(allocation->getBO()->peekHandle())); + ASSERT_EQ(allocation->peekInternalHandle(this->memoryManager), static_cast(1337)); + + DebugManager.flags.AllowOpenFdOperations.set(0); + ASSERT_EQ(allocation->peekInternalHandle(this->memoryManager), 0llu); memoryManager->freeGraphicsMemory(allocation); } @@ -1130,7 +1137,10 @@ TEST_F(DrmMemoryManagerTest, GivenSizeAbove2GBWhenAllocHostPtrAndUseHostPtrAreCr } TEST_F(DrmMemoryManagerTest, givenDrmBufferWhenItIsQueriedForInternalAllocationThenBoIsReturned) { + DebugManagerStateRestore restore; + DebugManager.flags.AllowOpenFdOperations.set(1); mock->ioctl_expected.total = -1; + mock->outputFd = 1337; MockContext context; context.setMemoryManager(memoryManager); @@ -1149,8 +1159,7 @@ TEST_F(DrmMemoryManagerTest, givenDrmBufferWhenItIsQueriedForInternalAllocationT retVal = clGetMemObjectInfo(buffer, CL_MEM_ALLOCATION_HANDLE_INTEL, sizeof(handle), &handle, nullptr); EXPECT_EQ(retVal, CL_SUCCESS); - auto drmAllocation = static_cast(buffer->getGraphicsAllocation()); - EXPECT_EQ(static_cast(drmAllocation->getBO()->peekHandle()), handle); + EXPECT_EQ(static_cast(1337), handle); clReleaseMemObject(buffer); } @@ -3188,3 +3197,13 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, whenReservingAddressRangeTh EXPECT_EQ(size, allocation->getReservedAddressSize()); memoryManager->freeGraphicsMemory(allocation); } + +TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, whenObtainFdFromHandleIsCalledThenProperFdHandleIsReturned) { + int boHandle = 3; + this->mock->outputFd = 1337; + this->mock->ioctl_expected.handleToPrimeFd = 1; + auto fdHandle = memoryManager->obtainFdFromHandle(boHandle); + EXPECT_EQ(this->mock->inputHandle, static_cast(boHandle)); + EXPECT_EQ(this->mock->inputFlags, DRM_CLOEXEC | DRM_RDWR); + EXPECT_EQ(1337, fdHandle); +} diff --git a/unit_tests/test_files/igdrcl.config b/unit_tests/test_files/igdrcl.config index 30d465fb51..9c45f04470 100644 --- a/unit_tests/test_files/igdrcl.config +++ b/unit_tests/test_files/igdrcl.config @@ -110,4 +110,5 @@ EnableHostPtrTracking = 1 DisableDcFlushInEpilogue = 0 OverrideInvalidEngineWithDefault = 0 EnableFormatQuery = 0 +AllowOpenFdOperations = 0 EnableBlitterOperationsForReadWriteBuffers = 0