feature: set error description in os_interface/linux

Added setErrorDescription for drm_buffer_object, drm_memory_manager,
and ioctl_helper_prelim

Related-To: NEO-12456

Signed-off-by: Chandio, Bibrak Qamar <bibrak.qamar.chandio@intel.com>
This commit is contained in:
Chandio, Bibrak Qamar
2024-08-29 22:35:24 +00:00
committed by Compute-Runtime-Automation
parent 05250e7460
commit 27c7fbc611
7 changed files with 188 additions and 11 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 <algorithm>
#include <cerrno>
@@ -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;
}

View File

@@ -102,6 +102,40 @@ TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithoutDataThenRegiste
EXPECT_EQ(ioctlHelper->classHandles[static_cast<uint32_t>(DrmResourceClass::isa)], receivedUuid->uuidClass);
}
TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithoutDataThenRegisterUUIDIoctlReturnsWithError) {
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
auto ioctlHelper = std::make_unique<MockIoctlHelperPrelimResourceRegistration>(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<uint32_t>(DrmResourceClass::isa)], receivedUuid->uuidClass);
}
TEST_F(DrmDebugPrelimTest, GivenDrmWhenRegisteringResourceWithDataThenRegisterUUIDIoctlIsCalledWithCorrectData) {
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
auto ioctlHelper = std::make_unique<MockIoctlHelperPrelimResourceRegistration>(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]);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);