diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 937dda3738..2532d9c3e1 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -8,6 +8,7 @@ #include "shared/source/os_interface/linux/drm_buffer_object.h" #include "shared/source/command_stream/task_count_helper.h" +#include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/root_device_environment.h" #include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/helpers/aligned_memory.h" @@ -129,8 +130,12 @@ bool BufferObject::close() { int ret = ioctlHelper->ioctl(DrmIoctl::gemClose, &close); if (ret != 0) { int err = errno; - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(GEM_CLOSE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + + CREATE_DEBUG_STRING(str, "ioctl(GEM_CLOSE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm->getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); DEBUG_BREAK_IF(true); + return false; } diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index f13760e486..f50ded3cd6 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -2243,8 +2243,12 @@ bool DrmMemoryManager::retrieveMmapOffsetForBufferObject(uint32_t rootDeviceInde } if (ret != 0) { int err = drm.getErrno(); - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(DRM_IOCTL_I915_GEM_MMAP_OFFSET) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); - DEBUG_BREAK_IF(ret != 0); + + CREATE_DEBUG_STRING(str, "ioctl(DRM_IOCTL_I915_GEM_MMAP_OFFSET) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); + DEBUG_BREAK_IF(true); + return false; } @@ -2615,8 +2619,12 @@ DrmAllocation *DrmMemoryManager::createUSMHostAllocationFromSharedHandle(osHandl auto ret = ioctlHelper->ioctl(DrmIoctl::primeFdToHandle, &openFd); if (ret != 0) { int err = drm.getErrno(); - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRIME_FD_TO_HANDLE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); - DEBUG_BREAK_IF(ret != 0); + + CREATE_DEBUG_STRING(str, "ioctl(PRIME_FD_TO_HANDLE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); + DEBUG_BREAK_IF(true); + return nullptr; } diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 55367769f5..6583d055c9 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -6,6 +6,7 @@ */ #include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/root_device_environment.h" #include "shared/source/helpers/basic_math.h" #include "shared/source/helpers/bit_helpers.h" @@ -27,6 +28,7 @@ #include "shared/source/os_interface/linux/os_context_linux.h" #include "shared/source/os_interface/linux/sys_calls.h" #include "shared/source/os_interface/product_helper.h" +#include "shared/source/utilities/logger.h" #include #include @@ -403,8 +405,12 @@ bool IoctlHelperPrelim20::setVmBoAdviseForChunking(int32_t handle, uint64_t star int ret = IoctlHelper::ioctl(DrmIoctl::gemVmAdvise, &vmAdvise); if (ret != 0) { int err = errno; - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); DEBUG_BREAK_IF(true); + return false; } return true; @@ -422,8 +428,12 @@ bool IoctlHelperPrelim20::setVmBoAdvise(int32_t handle, uint32_t attribute, void int ret = IoctlHelper::ioctl(DrmIoctl::gemVmAdvise, &vmAdvise); if (ret != 0) { int err = errno; - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); DEBUG_BREAK_IF(true); + return false; } return true; @@ -440,8 +450,12 @@ bool IoctlHelperPrelim20::setVmPrefetch(uint64_t start, uint64_t length, uint32_ int ret = IoctlHelper::ioctl(DrmIoctl::gemVmPrefetch, &vmPrefetch); if (ret != 0) { int err = errno; - PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(PRELIM_DRM_I915_GEM_VM_PREFETCH) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_I915_GEM_VM_PREFETCH) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, str.get()); DEBUG_BREAK_IF(true); + return false; } return true; @@ -1090,7 +1104,13 @@ uint32_t IoctlHelperPrelim20::registerIsaCookie(uint32_t isaHandle) { const auto result = registerUuid(uuid, isaHandle, 0, 0); PRINT_DEBUGGER_INFO_LOG("PRELIM_DRM_IOCTL_I915_UUID_REGISTER: isa handle = %lu, uuid = %s, data = %p, handle = %lu, ret = %d\n", isaHandle, std::string(uuid, 36).c_str(), 0, result.handle, result.retVal); - DEBUG_BREAK_IF(result.retVal != 0); + if (result.retVal != 0) { + int err = errno; + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s)\n", result.retVal, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + DEBUG_BREAK_IF(true); + } return result.handle; } @@ -1098,7 +1118,13 @@ uint32_t IoctlHelperPrelim20::registerIsaCookie(uint32_t isaHandle) { void IoctlHelperPrelim20::unregisterResource(uint32_t handle) { PRINT_DEBUGGER_INFO_LOG("PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER: handle = %lu\n", handle); [[maybe_unused]] const auto ret = unregisterUuid(handle); - DEBUG_BREAK_IF(ret != 0); + if (ret != 0) { + int err = errno; + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + DEBUG_BREAK_IF(true); + } } std::string IoctlHelperPrelim20::generateUUID() { @@ -1149,7 +1175,14 @@ uint32_t IoctlHelperPrelim20::registerResource(DrmResourceClass classType, const const auto result = registerUuid(uuid, uuidClass, ptr, size); PRINT_DEBUGGER_INFO_LOG("PRELIM_DRM_IOCTL_I915_UUID_REGISTER: classType = %d, uuid = %s, data = %p, handle = %lu, ret = %d\n", (int)classType, std::string(uuid, 36).c_str(), ptr, result.handle, result.retVal); - DEBUG_BREAK_IF(result.retVal != 0); + + if (result.retVal != 0) { + int err = errno; + + CREATE_DEBUG_STRING(str, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s)\n", result.retVal, err, strerror(err)); + drm.getRootDeviceEnvironment().executionEnvironment.setErrorDescription(std::string(str.get())); + DEBUG_BREAK_IF(true); + } return result.handle; } diff --git a/shared/test/unit_test/os_interface/linux/drm_debug_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_debug_prelim_tests.cpp index a9d18c8869..df0474c8eb 100644 --- a/shared/test/unit_test/os_interface/linux/drm_debug_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_debug_prelim_tests.cpp @@ -102,6 +102,40 @@ TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithoutDataThenRegiste EXPECT_EQ(ioctlHelper->classHandles[static_cast(DrmResourceClass::isa)], receivedUuid->uuidClass); } +TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithoutDataThenRegisterUUIDIoctlReturnsWithError) { + DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); + auto ioctlHelper = std::make_unique(drm); + + const auto result = ioctlHelper->registerResourceClasses(); + EXPECT_TRUE(result); + + const auto handle = drm.context.uuidHandle; + + // To induce the error at IoctlHelperPrelim20::registerUuid() + drm.context.uuidControlReturn = -2; + + auto registeredHandle = ioctlHelper->registerResource(DrmResourceClass::isa, nullptr, 0); + + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s)\n", drm.context.uuidControlReturn, drm.getErrno(), strerror(drm.getErrno())); + + EXPECT_STREQ(expectedErrorDescription, systemErrorDescription); + + EXPECT_EQ(handle + 1, drm.context.uuidHandle); + EXPECT_EQ(handle, registeredHandle); + + const auto &receivedUuid = drm.context.receivedRegisterUuid; + ASSERT_TRUE(receivedUuid); + + EXPECT_EQ(nullptr, receivedUuid->ptr); + EXPECT_EQ(0u, receivedUuid->size); + EXPECT_TRUE(hasSubstr(std::string(receivedUuid->uuid), std::string("00000000-0000-0000"))); + EXPECT_EQ(ioctlHelper->classHandles[static_cast(DrmResourceClass::isa)], receivedUuid->uuidClass); +} + TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithDataThenRegisterUUIDIoctlIsCalledWithCorrectData) { DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); auto ioctlHelper = std::make_unique(drm); @@ -150,6 +184,39 @@ TEST_F(DrmDebugPrelimTest, GivenDrmWhenUnregisteringResourceThenUnregisterUUIDIo EXPECT_EQ(0u, receivedUuid->extensions); } +TEST_F(DrmDebugPrelimTest, GivenDrmWhenUnregisteringResourceThenUnregisterUUIDIoctlReturnsWithError) { + DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); + + auto result = drm.registerResourceClasses(); + EXPECT_TRUE(result); + + uint64_t data = 0x12345678; + auto registeredHandle = drm.registerResource(DrmResourceClass::isa, &data, sizeof(uint64_t)); + + // To induce the error at IoctlHelperPrelim20::registerUuid() + drm.context.uuidControlReturn = -2; + + drm.unregisterResource(registeredHandle); + + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER) failed with %d. errno=%d(%s)\n", drm.context.uuidControlReturn, drm.getErrno(), strerror(drm.getErrno())); + + EXPECT_STREQ(expectedErrorDescription, systemErrorDescription); + + const auto &receivedUuid = drm.context.receivedUnregisterUuid; + ASSERT_TRUE(receivedUuid); + + EXPECT_EQ(registeredHandle, receivedUuid->handle); + EXPECT_EQ(nullptr, receivedUuid->ptr); + EXPECT_EQ(0u, receivedUuid->size); + EXPECT_EQ(0u, receivedUuid->uuidClass); + EXPECT_EQ(0u, receivedUuid->flags); + EXPECT_EQ(0u, receivedUuid->extensions); +} + TEST_F(DrmDebugPrelimTest, GivenDrmWhenNotifyFirstCommandQueueCreatedCalledThenCorrectUuidIsRegisteredWithCorrectData) { DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); @@ -187,6 +254,31 @@ TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringIsaCookieThenRegisterUUIDIoctl EXPECT_EQ(3u, drm.context.receivedRegisterUuid->uuidClass); } +TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringIsaCookieThenRegisterUUIDIoctlReturnsError) { + DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); + + auto result = drm.registerResourceClasses(); + EXPECT_TRUE(result); + + // To induce the error at IoctlHelperPrelim20::registerUuid() + drm.context.uuidControlReturn = -2; + + auto prevIoctls = drm.ioctlCallsCount; + auto registeredHandle = drm.registerIsaCookie(3); + + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s)\n", drm.context.uuidControlReturn, drm.getErrno(), strerror(drm.getErrno())); + + EXPECT_STREQ(expectedErrorDescription, systemErrorDescription); + + EXPECT_EQ(prevIoctls + 1u, drm.ioctlCallsCount); + EXPECT_EQ(drm.context.uuidHandle - 1, registeredHandle); + EXPECT_EQ(3u, drm.context.receivedRegisterUuid->uuidClass); +} + TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringElfResourceWithoutDataThenRegisterUUIDIoctlIsCalled) { DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp index a2646e2a4a..1f3f5256f8 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp @@ -250,6 +250,15 @@ TEST_F(DrmMemoryManagerUsmSharedHandlePrelimTest, givenMultiRootDeviceEnvironmen AllocationProperties properties(rootDeviceIndex, true, size, AllocationType::bufferHostMemory, false, {}); auto ptr = memoryManager->createUSMHostAllocationFromSharedHandle(1, properties, nullptr, true); + + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(PRIME_FD_TO_HANDLE) failed with %d. errno=%d(%s)\n", mock->fdToHandleRetVal, mock->getErrno(), strerror(mock->getErrno())); + + EXPECT_FALSE(strncmp(expectedErrorDescription, systemErrorDescription, 256)); + EXPECT_EQ(ptr, nullptr); executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp index 611dd9180a..53d7bdb292 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_localmem_upstream_tests.cpp @@ -280,6 +280,14 @@ TEST_F(DrmMemoryManagerUsmSharedHandleTest, givenMultiRootDeviceEnvironmentAndMe auto ptr = memoryManager->createUSMHostAllocationFromSharedHandle(1, properties, nullptr, true); + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(PRIME_FD_TO_HANDLE) failed with %d. errno=%d(%s)\n", mock->fdToHandleRetVal, mock->getErrno(), strerror(mock->getErrno())); + + EXPECT_FALSE(strncmp(expectedErrorDescription, systemErrorDescription, 256)); + EXPECT_EQ(ptr, nullptr); executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface); diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index 2b919f23b3..61d0b10bf0 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -7385,6 +7385,28 @@ TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmWhenRetrieveMmapOffsetForBuf EXPECT_FALSE(ret); } +TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmWhenRetrieveMmapOffsetForBufferObjectFailsThenReturnFalseTestErrorDescription) { + mock->ioctlExpected.gemMmapOffset = 2; + BufferObject bo(rootDeviceIndex, mock, 3, 1, 1024, 0); + mock->failOnMmapOffset = true; + + // To set the error value used to create the debug string in retrieveMmapOffsetForBufferObject() + mock->errnoValue = -2; + + uint64_t offset = 0; + auto ret = memoryManager->retrieveMmapOffsetForBufferObject(rootDeviceIndex, bo, 0, offset); + + const char *systemErrorDescription = nullptr; + executionEnvironment->getErrorDescription(&systemErrorDescription); + + char expectedErrorDescription[256]; + snprintf(expectedErrorDescription, 256, "ioctl(DRM_IOCTL_I915_GEM_MMAP_OFFSET) failed with %d. errno=%d(%s)\n", -1, mock->getErrno(), strerror(mock->getErrno())); + + EXPECT_STREQ(expectedErrorDescription, systemErrorDescription); + + EXPECT_FALSE(ret); +} + TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmWhenRetrieveMmapOffsetForBufferObjectIsCalledForLocalMemoryThenApplyCorrectFlags) { mock->ioctlExpected.gemMmapOffset = 5; BufferObject bo(rootDeviceIndex, mock, 3, 1, 1024, 0);