Add support for global_operations in new sysman design

Related-To: LOCI-4135
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2023-03-24 07:32:22 +00:00
committed by Compute-Runtime-Automation
parent 4c7bc2ca98
commit d29ed25f8b
35 changed files with 3241 additions and 23 deletions

View File

@@ -0,0 +1,10 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
target_sources(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
)
add_subdirectories()

View File

@@ -0,0 +1,24 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_TESTS_SYSMAN_GLOBAL_OPERATIONS_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_global_operations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_global_operations.h
)
if(NEO_ENABLE_i915_PRELIM_DETECTION)
list(APPEND L0_TESTS_SYSMAN_GLOBAL_OPERATIONS_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_global_operations_prelim.cpp
)
endif()
if(UNIX)
target_sources(${TARGET_NAME}
PRIVATE
${L0_TESTS_SYSMAN_GLOBAL_OPERATIONS_LINUX}
)
endif()

View File

@@ -0,0 +1,579 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/test_macros/mock_method_macros.h"
#include "level_zero/sysman/source/firmware_util/firmware_util.h"
#include "level_zero/sysman/source/global_operations/global_operations_imp.h"
#include "level_zero/sysman/source/global_operations/linux/os_global_operations_imp.h"
#include "level_zero/sysman/source/linux/fs_access.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_hw_device_id.h"
namespace L0 {
namespace ult {
const std::string vendorIntel("Intel(R) Corporation");
const std::string unknown("unknown");
const std::string intelPciId("0x8086");
const std::string deviceDir("device");
const std::string vendorFile("device/vendor");
const std::string deviceFile("device/device");
const std::string subsystemVendorFile("device/subsystem_vendor");
const std::string driverFile("device/driver");
const std::string agamaVersionFile("/sys/module/i915/agama_version");
const std::string srcVersionFile("/sys/module/i915/srcversion");
const std::string functionLevelReset("device/reset");
const std::string clientsDir("clients");
constexpr uint64_t pid1 = 1711u;
constexpr uint64_t pid2 = 1722u;
constexpr uint64_t pid3 = 1723u;
constexpr uint64_t pid4 = 1733u;
constexpr uint64_t pid6 = 1744u;
constexpr uint64_t pid7 = 1755u;
const std::string bPid4 = "<1733>";
constexpr uint64_t engineTimeSpent = 123456u;
const std::string clientId1("4");
const std::string clientId2("5");
const std::string clientId3("6");
const std::string clientId4("7");
const std::string clientId5("8");
const std::string clientId6("10");
const std::string clientId7("11");
const std::string clientId8("12");
const std::string clientId9("13");
const std::string engine0("0");
const std::string engine1("1");
const std::string engine2("2");
const std::string engine3("3");
const std::string engine6("6");
const std::string driverVersion("5.0.0-37-generic SMP mod_unload");
const std::string srcVersion("5.0.0-37");
const std::string ueventWedgedFile("/var/lib/libze_intel_gpu/wedged_file");
const std::string mockFunctionResetPath("/MOCK_FUNCTION_LEVEL_RESET_PATH");
const std::string mockDeviceDir("devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0");
const std::string mockDeviceName("/MOCK_DEVICE_NAME");
enum mockEnumListProcessCall {
DEVICE_IN_USE = 0,
DEVICE_UNUSED = 1,
RETURN_ERROR = 2
};
struct MockGlobalOperationsEngineHandleContext : public L0::Sysman::EngineHandleContext {
MockGlobalOperationsEngineHandleContext(L0::Sysman::OsSysman *pOsSysman) : EngineHandleContext(pOsSysman) {}
ADDMETHOD_NOBASE_VOIDRETURN(init, (uint32_t subDeviceCount));
};
struct MockGlobalOperationsRasHandleContext : public L0::Sysman::RasHandleContext {
MockGlobalOperationsRasHandleContext(L0::Sysman::OsSysman *pOsSysman) : RasHandleContext(pOsSysman) {}
ADDMETHOD_NOBASE_VOIDRETURN(init, (uint32_t subDeviceCount));
};
struct MockGlobalOperationsDiagnosticsHandleContext : public L0::Sysman::DiagnosticsHandleContext {
MockGlobalOperationsDiagnosticsHandleContext(L0::Sysman::OsSysman *pOsSysman) : DiagnosticsHandleContext(pOsSysman) {}
ADDMETHOD_NOBASE_VOIDRETURN(init, ());
};
struct MockGlobalOperationsFirmwareHandleContext : public L0::Sysman::FirmwareHandleContext {
MockGlobalOperationsFirmwareHandleContext(L0::Sysman::OsSysman *pOsSysman) : FirmwareHandleContext(pOsSysman) {}
ADDMETHOD_NOBASE_VOIDRETURN(init, ());
};
struct MockGlobalOperationsSysfsAccess : public L0::Sysman::SysfsAccess {
ze_result_t mockScanDirEntriesError = ZE_RESULT_SUCCESS;
ze_result_t mockReadError = ZE_RESULT_SUCCESS;
ze_result_t mockBindDeviceError = ZE_RESULT_SUCCESS;
ze_result_t mockUnbindDeviceError = ZE_RESULT_SUCCESS;
uint32_t mockCount = 0;
bool isRootSet = true;
bool mockGetScannedDir4EntriesStatus = false;
bool mockGetScannedDirPidEntriesStatus = false;
bool mockGetScannedDirPidEntriesForClientsStatus = false;
bool mockReadStatus = false;
bool mockGetValUnsignedLongStatus = false;
ze_result_t getRealPath(const std::string file, std::string &val) override {
if (file.compare(functionLevelReset) == 0) {
val = mockFunctionResetPath;
} else if (file.compare(deviceDir) == 0) {
val = mockDeviceDir;
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
enum class Index {
MockSubsystemVendor,
MockDevice,
MockVendor,
MockCount
};
ze_result_t readResult = ZE_RESULT_SUCCESS;
std::string mockReadVal[static_cast<int>(Index::MockCount)] = {"0x8086", "0x3ea5", "0x8086"};
ze_result_t read(const std::string file, std::string &val) override {
if (mockReadError != ZE_RESULT_SUCCESS) {
return mockReadError;
}
if (file.compare(subsystemVendorFile) == 0) {
val = mockReadVal[static_cast<int>(Index::MockSubsystemVendor)];
} else if (file.compare(deviceFile) == 0) {
val = mockReadVal[static_cast<int>(Index::MockDevice)];
} else if (file.compare(vendorFile) == 0) {
val = mockReadVal[static_cast<int>(Index::MockVendor)];
} else if (file.compare("clients/8/pid") == 0) {
val = bPid4;
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return readResult;
}
ze_result_t read(const std::string file, uint64_t &val) override {
if (mockReadStatus == true) {
if (mockCount == 0) {
mockCount++;
return getValUnsignedLongCreatedBytesSuccess(file, val);
}
else {
return ZE_RESULT_ERROR_UNKNOWN;
}
}
if (mockReadError != ZE_RESULT_SUCCESS) {
return mockReadError;
}
if (mockGetValUnsignedLongStatus == true) {
return getValUnsignedLongCreatedBytesSuccess(file, val);
}
if ((file.compare("clients/4/pid") == 0) || (file.compare("clients/5/pid") == 0)) {
val = pid1;
} else if (file.compare("clients/6/pid") == 0) {
val = pid2;
} else if (file.compare("clients/7/pid") == 0) {
val = pid3;
} else if (file.compare("clients/10/pid") == 0) {
val = pid6;
} else if (file.compare("clients/11/pid") == 0) {
val = pid7;
} else if (file.compare("clients/12/pid") == 0) {
val = pid7;
} else if (file.compare("clients/13/pid") == 0) {
val = pid7;
} else if ((file.compare("clients/4/busy/0") == 0) || (file.compare("clients/4/busy/3") == 0) ||
(file.compare("clients/5/busy/1") == 0) || (file.compare("clients/6/busy/0") == 0) ||
(file.compare("clients/8/busy/1") == 0) || (file.compare("clients/8/busy/0") == 0) ||
(file.compare("clients/13/busy/6") == 0)) {
val = engineTimeSpent;
} else if ((file.compare("clients/4/busy/1") == 0) || (file.compare("clients/4/busy/2") == 0) ||
(file.compare("clients/5/busy/0") == 0) || (file.compare("clients/5/busy/2") == 0) ||
(file.compare("clients/7/busy/0") == 0) || (file.compare("clients/7/busy/2") == 0) ||
(file.compare("clients/5/busy/3") == 0) || (file.compare("clients/6/busy/1") == 0) ||
(file.compare("clients/6/busy/2") == 0) || (file.compare("clients/6/busy/3") == 0) ||
(file.compare("clients/8/busy/2") == 0) || (file.compare("clients/8/busy/3") == 0)) {
val = 0;
} else if ((file.compare("clients/4/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/5/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/6/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/8/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/10/total_device_memory_buffer_objects/created_bytes") == 0)) {
val = 1024;
} else if ((file.compare("clients/4/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/5/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/6/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/8/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/10/total_device_memory_buffer_objects/imported_bytes") == 0)) {
val = 512;
} else if (file.compare("clients/7/total_device_memory_buffer_objects/created_bytes") == 0) {
return ZE_RESULT_ERROR_UNKNOWN;
} else if (file.compare("clients/7/total_device_memory_buffer_objects/imported_bytes") == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
} else if (file.compare("clients/13/total_device_memory_buffer_objects/imported_bytes") == 0) {
return ZE_RESULT_ERROR_UNKNOWN;
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getValUnsignedLongCreatedBytesSuccess(const std::string file, uint64_t &val) {
if ((file.compare("clients/4/pid") == 0) || (file.compare("clients/5/pid") == 0)) {
val = pid1;
} else if (file.compare("clients/6/pid") == 0) {
val = pid2;
} else if ((file.compare("clients/4/busy/0") == 0) || (file.compare("clients/4/busy/3") == 0) ||
(file.compare("clients/5/busy/1") == 0) || (file.compare("clients/6/busy/0") == 0) ||
(file.compare("clients/8/busy/1") == 0) || (file.compare("clients/8/busy/0") == 0)) {
val = engineTimeSpent;
} else if ((file.compare("clients/4/busy/1") == 0) || (file.compare("clients/4/busy/2") == 0) ||
(file.compare("clients/5/busy/0") == 0) || (file.compare("clients/5/busy/2") == 0) ||
(file.compare("clients/7/busy/0") == 0) || (file.compare("clients/7/busy/2") == 0) ||
(file.compare("clients/5/busy/3") == 0) || (file.compare("clients/6/busy/1") == 0) ||
(file.compare("clients/6/busy/2") == 0) || (file.compare("clients/6/busy/3") == 0) ||
(file.compare("clients/8/busy/2") == 0) || (file.compare("clients/8/busy/3") == 0)) {
val = 0;
} else if ((file.compare("clients/4/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/5/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/6/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/8/total_device_memory_buffer_objects/created_bytes") == 0) ||
(file.compare("clients/7/total_device_memory_buffer_objects/created_bytes") == 0)) {
val = 1024;
} else if ((file.compare("clients/4/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/5/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/6/total_device_memory_buffer_objects/imported_bytes") == 0) ||
(file.compare("clients/8/total_device_memory_buffer_objects/imported_bytes") == 0)) {
val = 512;
} else if (file.compare("clients/7/total_device_memory_buffer_objects/imported_bytes") == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getScannedDir4Entries(const std::string path, std::vector<std::string> &list) {
if (path.compare(clientsDir) == 0) {
list.push_back(clientId1);
list.push_back(clientId2);
list.push_back(clientId3);
list.push_back(clientId4);
list.push_back(clientId5);
list.push_back(clientId6);
} else if ((path.compare("clients/4/busy") == 0) || (path.compare("clients/5/busy") == 0) ||
(path.compare("clients/6/busy") == 0) || (path.compare("clients/7/busy") == 0) ||
(path.compare("clients/8/busy") == 0)) {
list.push_back(engine0);
list.push_back(engine1);
list.push_back(engine2);
list.push_back(engine3);
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t scanDirEntries(const std::string path, std::vector<std::string> &list) override {
if (mockScanDirEntriesError != ZE_RESULT_SUCCESS) {
return mockScanDirEntriesError;
}
if (mockGetScannedDir4EntriesStatus == true) {
return getScannedDir4Entries(path, list);
}
if (mockGetScannedDirPidEntriesStatus == true) {
return getScannedDirPidEntries(path, list);
}
if (mockGetScannedDirPidEntriesForClientsStatus == true) {
return getScannedDirPidEntiresForClients(path, list);
}
if (path.compare(clientsDir) == 0) {
list.push_back(clientId1);
list.push_back(clientId2);
list.push_back(clientId3);
list.push_back(clientId5);
list.push_back(clientId6);
list.push_back(clientId7);
} else if ((path.compare("clients/4/busy") == 0) || (path.compare("clients/5/busy") == 0) ||
(path.compare("clients/6/busy") == 0) || (path.compare("clients/8/busy") == 0)) {
list.push_back(engine0);
list.push_back(engine1);
list.push_back(engine2);
list.push_back(engine3);
} else {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getScannedDirPidEntries(const std::string path, std::vector<std::string> &list) {
if (path.compare(clientsDir) == 0) {
list.push_back(clientId8);
} else if (path.compare("clients/12/busy") == 0) {
return ZE_RESULT_ERROR_UNKNOWN;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getScannedDirPidEntiresForClients(const std::string path, std::vector<std::string> &list) {
if (path.compare(clientsDir) == 0) {
list.push_back(clientId9);
} else if (path.compare("clients/13/busy") == 0) {
list.push_back(engine6);
}
return ZE_RESULT_SUCCESS;
}
bool isMyDeviceFile(const std::string dev) override {
if (dev.compare(mockDeviceName) == 0) {
return true;
}
return false;
}
bool isRootUser() override {
if (isRootSet == true) {
return true;
} else {
return false;
}
}
ze_result_t unbindDevice(const std::string device) override {
if (mockUnbindDeviceError != ZE_RESULT_SUCCESS) {
return mockUnbindDeviceError;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t bindDevice(const std::string device) override {
if (mockBindDeviceError != ZE_RESULT_SUCCESS) {
return mockBindDeviceError;
}
return ZE_RESULT_SUCCESS;
}
MockGlobalOperationsSysfsAccess() = default;
ADDMETHOD_NOBASE(fileExists, bool, true, (const std::string file));
};
struct MockGlobalOperationsProcfsAccess : public L0::Sysman::ProcfsAccess {
const ::pid_t extraPid = 4;
const int extraFd = 5;
std::vector<::pid_t> pidList = {1, 2, 3};
std::vector<int> fdList = {0, 1, 2};
::pid_t ourDevicePid = 0;
int ourDeviceFd = 0;
std::vector<mockEnumListProcessCall> mockListProcessCall{};
std::vector<bool> isRepeated{};
ze_result_t listProcessesResult = ZE_RESULT_SUCCESS;
uint32_t listProcessCalled = 0u;
ze_result_t listProcesses(std::vector<::pid_t> &list) override {
listProcessCalled++;
list = pidList;
if (!mockListProcessCall.empty()) {
mockEnumListProcessCall mockListProcessCallValue = mockListProcessCall.front();
if (mockListProcessCallValue == mockEnumListProcessCall::DEVICE_IN_USE) {
if (ourDevicePid) {
list.push_back(ourDevicePid);
}
}
else if (mockListProcessCallValue == mockEnumListProcessCall::DEVICE_UNUSED) {
}
else if (mockListProcessCallValue == mockEnumListProcessCall::RETURN_ERROR) {
listProcessesResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
}
if (!isRepeated.empty()) {
if (isRepeated.front() == false) {
mockListProcessCall.erase(mockListProcessCall.begin());
isRepeated.erase(isRepeated.begin());
}
}
}
return listProcessesResult;
}
::pid_t myProcessId() override {
return ::getpid();
}
ze_result_t mockGetFileDescriptorsError = ZE_RESULT_SUCCESS;
ze_result_t getFileDescriptorsResult = ZE_RESULT_SUCCESS;
ze_result_t getFileDescriptors(const ::pid_t pid, std::vector<int> &list) override {
list.clear();
if (mockGetFileDescriptorsError != ZE_RESULT_SUCCESS) {
getFileDescriptorsResult = mockGetFileDescriptorsError;
mockGetFileDescriptorsError = ZE_RESULT_SUCCESS;
return getFileDescriptorsResult;
}
list = fdList;
if (ourDevicePid == pid) {
list.push_back(ourDeviceFd);
}
return getFileDescriptorsResult;
}
ze_result_t mockGetFileNameError = ZE_RESULT_SUCCESS;
ze_result_t getFileNameResult = ZE_RESULT_SUCCESS;
ze_result_t getFileName(const ::pid_t pid, const int fd, std::string &val) override {
if (mockGetFileNameError != ZE_RESULT_SUCCESS) {
return mockGetFileNameError;
}
if (pid == ourDevicePid && fd == ourDeviceFd) {
val = mockDeviceName;
} else {
// return fake filenames for other file descriptors
val = std::string("/FILENAME") + std::to_string(fd);
}
return getFileNameResult;
}
bool isAlive(const ::pid_t pid) override {
if (pid == ourDevicePid) {
return true;
}
return false;
}
bool mockNoKill = false;
void kill(const ::pid_t pid) override {
if (mockNoKill == true) {
return;
}
ourDevicePid = 0;
}
MockGlobalOperationsProcfsAccess() = default;
};
struct MockGlobalOperationsFsAccess : public L0::Sysman::FsAccess {
ze_result_t mockReadError = ZE_RESULT_SUCCESS;
ze_result_t readResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
std::string mockReadVal = "";
ze_result_t read(const std::string file, std::string &val) override {
if (mockReadError != ZE_RESULT_SUCCESS) {
return mockReadError;
}
if (mockReadVal == srcVersion) {
if (file.compare(srcVersionFile) == 0) {
val = mockReadVal;
readResult = ZE_RESULT_SUCCESS;
return readResult;
}
} else if (mockReadVal == driverVersion) {
if (file.compare(agamaVersionFile) == 0) {
val = mockReadVal;
readResult = ZE_RESULT_SUCCESS;
return readResult;
}
} else {
readResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return readResult;
}
ze_result_t mockWriteError = ZE_RESULT_SUCCESS;
ze_result_t writeResult = ZE_RESULT_SUCCESS;
ze_result_t write(const std::string file, const std::string val) override {
if (mockWriteError != ZE_RESULT_SUCCESS) {
return mockWriteError;
}
return writeResult;
}
ADDMETHOD_NOBASE(canWrite, ze_result_t, ZE_RESULT_SUCCESS, (const std::string file));
MockGlobalOperationsFsAccess() = default;
};
struct MockGlobalOpsFwInterface : public L0::Sysman::FirmwareUtil {
ze_result_t mockIfrError = ZE_RESULT_SUCCESS;
ze_result_t mockIfrResult = ZE_RESULT_SUCCESS;
bool mockIfrStatus = true;
ze_result_t fwIfrApplied(bool &ifrStatus) override {
if (mockIfrError != ZE_RESULT_SUCCESS) {
return mockIfrError;
}
ifrStatus = mockIfrStatus;
return mockIfrResult;
}
MockGlobalOpsFwInterface() = default;
ADDMETHOD_NOBASE(fwDeviceInit, ze_result_t, ZE_RESULT_SUCCESS, (void));
ADDMETHOD_NOBASE(getFirstDevice, ze_result_t, ZE_RESULT_SUCCESS, (igsc_device_info * info));
ADDMETHOD_NOBASE(getFwVersion, ze_result_t, ZE_RESULT_SUCCESS, (std::string fwType, std::string &firmwareVersion));
ADDMETHOD_NOBASE(flashFirmware, ze_result_t, ZE_RESULT_SUCCESS, (std::string fwType, void *pImage, uint32_t size));
ADDMETHOD_NOBASE(fwSupportedDiagTests, ze_result_t, ZE_RESULT_SUCCESS, (std::vector<std::string> & supportedDiagTests));
ADDMETHOD_NOBASE(fwRunDiagTests, ze_result_t, ZE_RESULT_SUCCESS, (std::string & osDiagType, zes_diag_result_t *pResult));
ADDMETHOD_NOBASE(fwGetMemoryErrorCount, ze_result_t, ZE_RESULT_SUCCESS, (zes_ras_error_type_t category, uint32_t subDeviceCount, uint32_t subDeviceId, uint64_t &count));
ADDMETHOD_NOBASE(fwGetEccConfig, ze_result_t, ZE_RESULT_SUCCESS, (uint8_t * currentState, uint8_t *pendingState));
ADDMETHOD_NOBASE(fwSetEccConfig, ze_result_t, ZE_RESULT_SUCCESS, (uint8_t newState, uint8_t *currentState, uint8_t *pendingState));
ADDMETHOD_NOBASE_VOIDRETURN(getDeviceSupportedFwTypes, (std::vector<std::string> & fwTypes));
ADDMETHOD_NOBASE_VOIDRETURN(fwGetMemoryHealthIndicator, (zes_mem_health_t * health));
};
struct MockGlobalOpsLinuxSysmanImp : public L0::Sysman::LinuxSysmanImp {
using LinuxSysmanImp::pFsAccess;
using LinuxSysmanImp::pProcfsAccess;
using LinuxSysmanImp::pSysfsAccess;
MockGlobalOpsLinuxSysmanImp(L0::Sysman::SysmanDeviceImp *pParentSysmanDeviceImp) : LinuxSysmanImp(pParentSysmanDeviceImp) {}
std::vector<int> fdList = {0, 1, 2};
::pid_t ourDevicePid = 0;
int ourDeviceFd = 0;
ze_result_t mockError = ZE_RESULT_SUCCESS;
ze_result_t mockInitDeviceError = ZE_RESULT_SUCCESS;
void getPidFdsForOpenDevice(L0::Sysman::ProcfsAccess *pProcfsAccess, L0::Sysman::SysfsAccess *pSysfsAccess, const ::pid_t pid, std::vector<int> &deviceFds) override {
if (ourDevicePid) {
deviceFds.push_back(ourDeviceFd);
}
}
ze_result_t osWarmReset() override {
if (mockError != ZE_RESULT_SUCCESS) {
return mockError;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t osColdReset() override {
if (mockError != ZE_RESULT_SUCCESS) {
return mockError;
}
return ZE_RESULT_SUCCESS;
}
void setMockError(ze_result_t result) {
mockError = result;
}
void setMockInitDeviceError(ze_result_t result) {
mockInitDeviceError = result;
}
};
constexpr int mockFdGlobalOperations = 33;
class DrmGlobalOpsMock : public Drm {
public:
DrmGlobalOpsMock(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<MockSysmanHwDeviceIdDrm>(mockFdGlobalOperations, ""), rootDeviceEnvironment) {}
using Drm::setupIoctlHelper;
int ioctlRetVal = 0;
int ioctlErrno = 0;
int ioctl(DrmIoctl request, void *arg) override {
return ioctlRetVal;
}
int getErrno() override { return ioctlErrno; }
};
class PublicLinuxGlobalOperationsImp : public L0::Sysman::LinuxGlobalOperationsImp {
public:
using LinuxGlobalOperationsImp::pLinuxSysmanImp;
using LinuxGlobalOperationsImp::resetTimeout;
};
} // namespace ult
} // namespace L0

View File

@@ -0,0 +1,942 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/linux/pci_path.h"
#include "shared/test/common/helpers/ult_hw_config.h"
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "level_zero/sysman/test/unit_tests/sources/global_operations/linux/mock_global_operations.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include <fcntl.h>
#include <sys/stat.h>
namespace L0 {
namespace ult {
constexpr uint64_t memSize1 = 2048;
constexpr uint64_t memSize2 = 1024;
constexpr uint64_t memSize4 = 1024;
constexpr uint64_t memSize6 = 1024;
constexpr uint64_t memSize7 = 0;
constexpr uint64_t sharedMemSize1 = 1024;
constexpr uint64_t sharedMemSize2 = 512;
constexpr uint64_t sharedMemSize4 = 512;
constexpr uint64_t sharedMemSize6 = 512;
constexpr uint64_t sharedMemSize7 = 0;
// In mock function getValUnsignedLong, we have set the engines used as 0, 3 and 1.
// Hence, expecting 28 as engine field because 28 in binary would be 00011100
// This indicates bit number 2, 3 and 4 are set, thus this indicates, this process
// used ZES_ENGINE_TYPE_FLAG_3D, ZES_ENGINE_TYPE_FLAG_MEDIA and ZES_ENGINE_TYPE_FLAG_DMA
// Their corresponding mapping with i915 engine numbers are 0, 3 and 1 respectively.
constexpr int64_t engines1 = 28u;
// 4 in binary 0100, as 2nd bit is set, hence it indicates, process used ZES_ENGINE_TYPE_FLAG_3D
// Corresponding i915 mapped value in mocked getValUnsignedLong() is 0.
constexpr int64_t engines2 = 4u;
constexpr int64_t engines4 = 20u;
constexpr int64_t engines6 = 1u;
constexpr int64_t engines7 = 1u;
constexpr uint32_t totalProcessStates = 5u; // Three process States for three pids
constexpr uint32_t totalProcessStatesForFaultyClients = 3u;
class SysmanGlobalOperationsFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<MockGlobalOperationsEngineHandleContext> pEngineHandleContext;
std::unique_ptr<MockGlobalOperationsDiagnosticsHandleContext> pDiagnosticsHandleContext;
std::unique_ptr<MockGlobalOperationsFirmwareHandleContext> pFirmwareHandleContext;
std::unique_ptr<MockGlobalOperationsRasHandleContext> pRasHandleContext;
std::unique_ptr<MockGlobalOperationsSysfsAccess> pSysfsAccess;
std::unique_ptr<MockGlobalOperationsProcfsAccess> pProcfsAccess;
std::unique_ptr<MockGlobalOperationsFsAccess> pFsAccess;
L0::Sysman::EngineHandleContext *pEngineHandleContextOld = nullptr;
L0::Sysman::DiagnosticsHandleContext *pDiagnosticsHandleContextOld = nullptr;
L0::Sysman::FirmwareHandleContext *pFirmwareHandleContextOld = nullptr;
L0::Sysman::RasHandleContext *pRasHandleContextOld = nullptr;
L0::Sysman::SysfsAccess *pSysfsAccessOld = nullptr;
L0::Sysman::ProcfsAccess *pProcfsAccessOld = nullptr;
L0::Sysman::FsAccess *pFsAccessOld = nullptr;
L0::Sysman::LinuxSysmanImp *pLinuxSysmanImpOld = nullptr;
L0::Sysman::OsGlobalOperations *pOsGlobalOperationsPrev = nullptr;
L0::Sysman::GlobalOperations *pGlobalOperationsPrev = nullptr;
L0::Sysman::GlobalOperationsImp *pGlobalOperationsImp;
L0::Sysman::SysmanDeviceImp *device = nullptr;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pEngineHandleContextOld = pSysmanDeviceImp->pEngineHandleContext;
pDiagnosticsHandleContextOld = pSysmanDeviceImp->pDiagnosticsHandleContext;
pFirmwareHandleContextOld = pSysmanDeviceImp->pFirmwareHandleContext;
pRasHandleContextOld = pSysmanDeviceImp->pRasHandleContext;
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pProcfsAccessOld = pLinuxSysmanImp->pProcfsAccess;
pFsAccessOld = pLinuxSysmanImp->pFsAccess;
pLinuxSysmanImpOld = pLinuxSysmanImp;
pEngineHandleContext = std::make_unique<MockGlobalOperationsEngineHandleContext>(pOsSysman);
pSysfsAccess = std::make_unique<MockGlobalOperationsSysfsAccess>();
pProcfsAccess = std::make_unique<MockGlobalOperationsProcfsAccess>();
pFsAccess = std::make_unique<MockGlobalOperationsFsAccess>();
pDiagnosticsHandleContext = std::make_unique<MockGlobalOperationsDiagnosticsHandleContext>(pOsSysman);
pFirmwareHandleContext = std::make_unique<MockGlobalOperationsFirmwareHandleContext>(pOsSysman);
pRasHandleContext = std::make_unique<MockGlobalOperationsRasHandleContext>(pOsSysman);
auto pDrmLocal = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrmLocal->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterfaceLocal = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterfaceLocal->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrmLocal));
pSysmanDeviceImp->pEngineHandleContext = pEngineHandleContext.get();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
pLinuxSysmanImp->pProcfsAccess = pProcfsAccess.get();
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
pSysmanDeviceImp->pDiagnosticsHandleContext = pDiagnosticsHandleContext.get();
pSysmanDeviceImp->pFirmwareHandleContext = pFirmwareHandleContext.get();
pSysmanDeviceImp->pRasHandleContext = pRasHandleContext.get();
pFsAccess->mockReadVal = driverVersion;
pGlobalOperationsImp = static_cast<L0::Sysman::GlobalOperationsImp *>(pSysmanDeviceImp->pGlobalOperations);
pOsGlobalOperationsPrev = pGlobalOperationsImp->pOsGlobalOperations;
pGlobalOperationsImp->pOsGlobalOperations = nullptr;
device = pSysmanDeviceImp;
}
void TearDown() override {
if (nullptr != pGlobalOperationsImp->pOsGlobalOperations) {
delete pGlobalOperationsImp->pOsGlobalOperations;
}
pGlobalOperationsImp->pOsGlobalOperations = pOsGlobalOperationsPrev;
pGlobalOperationsImp = nullptr;
pSysmanDeviceImp->pEngineHandleContext = pEngineHandleContextOld;
pSysmanDeviceImp->pDiagnosticsHandleContext = pDiagnosticsHandleContextOld;
pSysmanDeviceImp->pFirmwareHandleContext = pFirmwareHandleContextOld;
pSysmanDeviceImp->pRasHandleContext = pRasHandleContextOld;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
pLinuxSysmanImp->pProcfsAccess = pProcfsAccessOld;
pLinuxSysmanImp->pFsAccess = pFsAccessOld;
SysmanDeviceFixture::TearDown();
}
void initGlobalOps() {
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
}
};
class SysmanGlobalOperationsIntegratedFixture : public SysmanGlobalOperationsFixture {
void SetUp() override {
SysmanGlobalOperationsFixture::SetUp();
auto mockHardwareInfo = device->getHardwareInfo();
// auto mockHardwareInfo = neoDevice->getHardwareInfo();
mockHardwareInfo.capabilityTable.isIntegratedDevice = true;
device->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->setHwInfoAndInitHelpers(&mockHardwareInfo);
}
void TearDown() override {
SysmanGlobalOperationsFixture::TearDown();
}
};
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhenCallingzesGlobalOperationsGetPropertiesThenVerifyValidPropertiesAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/guid",
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
// skipping "0"
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "0x41fe79a5\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
if (supportedFiles[fd].second == "dummy") {
if (count == sizeof(uint64_t)) {
uint64_t data = 0x3e8c9dfe1c2e4d5c;
memcpy(buf, &data, sizeof(data));
return count;
} else {
// Board number will be in ASCII format, Expected board number should be decoded value
// i.e 0821VPTW910091000821VPTW91009100 for data provided below.
uint64_t data[] = {0x5754505631323830, 0x3030313930303139, 0x5754505631323830, 0x3030313930303139};
memcpy(buf, &data, sizeof(data));
return count;
}
}
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
pLinuxSysmanImp->rootPath = NEO::getPciRootPath(pLinuxSysmanImp->getDrm()->getFileDescriptor()).value_or("");
zes_device_properties_t properties;
const std::string expectedSerialNumber("0x3e8c9dfe1c2e4d5c");
const std::string expectedBoardNumber("0821VPTW910091000821VPTW91009100");
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(properties.numSubdevices, 0u);
EXPECT_TRUE(0 == expectedBoardNumber.compare(properties.boardNumber));
EXPECT_TRUE(0 == vendorIntel.compare(properties.brandName));
EXPECT_TRUE(0 == driverVersion.compare(properties.driverVersion));
std::stringstream expectedModelName;
expectedModelName << "Intel(R) Graphics";
expectedModelName << " [0x" << std::hex << std::setw(4) << std::setfill('0') << device->getHardwareInfo().platform.usDeviceID << "]";
EXPECT_TRUE(0 == expectedModelName.str().compare(properties.modelName));
EXPECT_TRUE(0 == expectedSerialNumber.compare(properties.serialNumber));
EXPECT_TRUE(0 == vendorIntel.compare(properties.vendorName));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndReadTelemOffsetFailsWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/guid",
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
if (std::string(pathname) == "/sys/class/intel_pmt/telem1/offset") {
return 0;
}
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "0x41fe79a5\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
if (supportedFiles[fd].second == "dummy") {
uint64_t data = 0x3e8c9dfe1c2e4d5c;
memcpy(buf, &data, sizeof(data));
return count;
}
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndInvalidGuidWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/guid",
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "Invalidguid\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
if (supportedFiles[fd].second == "dummy") {
uint64_t data = 0x3e8c9dfe1c2e4d5c;
memcpy(buf, &data, sizeof(data));
return count;
}
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndPpinandBoardNumberOffsetAreAbsentWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/guid",
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "0xb15a0edd\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
if (supportedFiles[fd].second == "dummy") {
uint64_t data = 0x3e8c9dfe1c2e4d5c;
memcpy(buf, &data, sizeof(data));
return count;
}
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndReadTelemDataFailsWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
std::vector<std::string> supportedFiles = {
"/sys/class/intel_pmt/telem1/guid",
"/sys/class/intel_pmt/telem1/offset",
"/sys/class/intel_pmt/telem1/telem",
};
auto itr = std::find(supportedFiles.begin(), supportedFiles.end(), std::string(pathname));
if (itr != supportedFiles.end()) {
return static_cast<int>(std::distance(supportedFiles.begin(), itr)) + 1;
}
return 0;
});
VariableBackup<decltype(SysCalls::sysCallsPread)> mockPread(&SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t {
std::vector<std::pair<std::string, std::string>> supportedFiles = {
{"/sys/class/intel_pmt/telem1/guid", "0x41fe79a5\n"},
{"/sys/class/intel_pmt/telem1/offset", "0\n"},
{"/sys/class/intel_pmt/telem1/telem", "dummy"},
};
if ((--fd >= 0) && (fd < static_cast<int>(supportedFiles.size()))) {
if (supportedFiles[fd].first == "/sys/class/intel_pmt/telem1/telem") {
return 0;
}
memcpy(buf, supportedFiles[fd].second.c_str(), supportedFiles[fd].second.size());
return count;
}
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndOpenSysCallFailsWhenCallingzesGlobalOperationsGetPropertiesThenInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
{"/sys/class/intel_pmt/telem1", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem1/"},
{"/sys/class/intel_pmt/telem2", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0/intel-dvsec-2.1.auto/intel_pmt/telem2/"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
return 0;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndTelemNodeReadLinkFailsWhenCallingzesGlobalOperationsGetPropertiesThenVerifyInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
std::map<std::string, std::string> fileNameLinkMap = {
{"/sys/dev/char/226:128", "../../devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:02.0/0000:8a:00.0/drm/renderD128"},
};
auto it = fileNameLinkMap.find(std::string(path));
if (it != fileNameLinkMap.end()) {
std::memcpy(buf, it->second.c_str(), it->second.size());
return static_cast<int>(it->second.size());
}
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleAndReadLinkFailsWhenCallingzesGlobalOperationsGetPropertiesThenVerifyInvalidSerialNumberAndBoardNumberAreReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsReadlink)> mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int {
return -1;
});
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.serialNumber));
EXPECT_TRUE(0 == unknown.compare(properties.boardNumber));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDriverVersionWhenAgmaFileIsAbsentThenVerifyzesDeviceGetPropertiesCallSucceeds) {
zes_device_properties_t properties;
std::string test;
test = srcVersion;
pFsAccess->mockReadVal = srcVersion;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == test.compare(properties.driverVersion));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDriverVersionWhenAgmaFileAndSrcFileIsAbsentThenVerifyzesDeviceGetPropertiesCallSucceeds) {
zes_device_properties_t properties;
pFsAccess->mockReadError = ZE_RESULT_ERROR_NOT_AVAILABLE;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.driverVersion));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDriverVersionWhenDriverVersionFileIsNotAvaliableThenVerifyzesDeviceGetPropertiesCallSucceeds) {
zes_device_properties_t properties;
pFsAccess->mockReadError = ZE_RESULT_ERROR_NOT_AVAILABLE;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.driverVersion));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDriverVersionWhenDriverVersionFileReadFailsThenVerifyzesDeviceGetPropertiesCallSucceeds) {
zes_device_properties_t properties;
pFsAccess->mockReadError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.driverVersion));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDevicePropertiesWhenVendorIsUnKnownThenVerifyzesDeviceGetPropertiesCallSucceeds) {
pSysfsAccess->mockReadVal[static_cast<int>(MockGlobalOperationsSysfsAccess::Index::MockSubsystemVendor)] = "0xa086";
pSysfsAccess->mockReadVal[static_cast<int>(MockGlobalOperationsSysfsAccess::Index::MockVendor)] = "0x1806"; // Unknown Vendor id
zes_device_properties_t properties;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.vendorName));
EXPECT_TRUE(0 == unknown.compare(properties.brandName));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhenCallingzesDeviceGetPropertiesForCheckingDriverVersionWhenAccessingAgamaFileOrSrcFileGotPermissionDeniedThenVerifyzesDeviceGetPropertiesCallSucceeds) {
zes_device_properties_t properties;
pFsAccess->mockReadError = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
ze_result_t result = zesDeviceGetProperties(device, &properties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_TRUE(0 == unknown.compare(properties.driverVersion));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingDeviceThenSuccessIsReturned) {
uint32_t count = 0;
ASSERT_EQ(ZE_RESULT_SUCCESS, zesDeviceProcessesGetState(device, &count, nullptr));
EXPECT_EQ(count, totalProcessStates);
std::vector<zes_process_state_t> processes(count);
ASSERT_EQ(ZE_RESULT_SUCCESS, zesDeviceProcessesGetState(device, &count, processes.data()));
EXPECT_EQ(processes[0].processId, pid1);
EXPECT_EQ(processes[0].engines, engines1);
EXPECT_EQ(processes[0].memSize, memSize1);
EXPECT_EQ(processes[0].sharedSize, sharedMemSize1);
EXPECT_EQ(processes[1].processId, pid2);
EXPECT_EQ(processes[1].engines, engines2);
EXPECT_EQ(processes[1].memSize, memSize2);
EXPECT_EQ(processes[1].sharedSize, sharedMemSize2);
EXPECT_EQ(processes[2].processId, pid4);
EXPECT_EQ(processes[2].engines, engines4);
EXPECT_EQ(processes[2].memSize, memSize4);
EXPECT_EQ(processes[2].sharedSize, sharedMemSize4);
EXPECT_EQ(processes[3].processId, pid6);
EXPECT_EQ(processes[3].engines, engines6);
EXPECT_EQ(processes[3].memSize, memSize6);
EXPECT_EQ(processes[3].sharedSize, sharedMemSize6);
EXPECT_EQ(processes[4].processId, pid7);
EXPECT_EQ(processes[4].engines, engines7);
EXPECT_EQ(processes[4].memSize, memSize7);
EXPECT_EQ(processes[4].sharedSize, sharedMemSize7);
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingDeviceThenSuccessIsReturnedEvenwithFaultyClient) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDir4EntriesStatus = true;
pSysfsAccess->mockGetValUnsignedLongStatus = true;
ASSERT_EQ(ZE_RESULT_SUCCESS, zesDeviceProcessesGetState(device, &count, nullptr));
EXPECT_EQ(count, totalProcessStatesForFaultyClients);
std::vector<zes_process_state_t> processes(count);
ASSERT_EQ(ZE_RESULT_SUCCESS, zesDeviceProcessesGetState(device, &count, processes.data()));
EXPECT_EQ(processes[0].processId, pid1);
EXPECT_EQ(processes[0].engines, engines1);
EXPECT_EQ(processes[0].memSize, memSize1);
EXPECT_EQ(processes[0].sharedSize, sharedMemSize1);
EXPECT_EQ(processes[1].processId, pid2);
EXPECT_EQ(processes[1].engines, engines2);
EXPECT_EQ(processes[1].memSize, memSize2);
EXPECT_EQ(processes[1].sharedSize, sharedMemSize2);
EXPECT_EQ(processes[2].processId, pid4);
EXPECT_EQ(processes[2].engines, engines4);
EXPECT_EQ(processes[2].memSize, memSize4);
EXPECT_EQ(processes[2].sharedSize, sharedMemSize4);
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileCountValueIsProvidedThenFailureIsReturned) {
uint32_t count = 2;
ASSERT_EQ(ZE_RESULT_ERROR_INVALID_SIZE, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingFaultyClientFileThenFailureIsReturned) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDir4EntriesStatus = true;
ASSERT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingNullDirThenFailureIsReturned) {
uint32_t count = 0;
pSysfsAccess->mockScanDirEntriesError = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingDeviceThenFailureIsReturnedEvenwithFaultyClient) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDirPidEntriesStatus = true;
pSysfsAccess->mockReadError = ZE_RESULT_ERROR_UNKNOWN;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingBusyDirForEnginesReadThenFailureIsReturnedEvenwithFaultyClient) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDirPidEntriesStatus = true;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture,
GivenValidDeviceHandleWhileRetrievingInformationAboutHostProcessesUsingBusyDirForEnginesThenFailureIsReturnedEvenwithFaultyClient) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDir4EntriesStatus = true;
pSysfsAccess->mockReadStatus = true;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileReadingInvalidBufferObjectsThenErrorIsReturned) {
uint32_t count = 0;
pSysfsAccess->mockGetScannedDirPidEntriesForClientsStatus = true;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesDeviceProcessesGetState(device, &count, nullptr));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileReadingExistingMemoryFileThenCorrectValueIsReturned) {
uint64_t memSize = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, pSysfsAccess->read("clients/6/total_device_memory_buffer_objects/created_bytes", memSize));
EXPECT_EQ(memSize2, memSize);
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileReadingInvalidMemoryFileThenErrorIsReturned) {
uint64_t memSize = 0;
pSysfsAccess->mockGetScannedDir4EntriesStatus = true;
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pSysfsAccess->read("clients/7/total_device_memory_buffer_objects/imported_bytes", memSize));
}
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileReadingNonExistingFileThenErrorIsReturned) {
std::vector<std::string> engineEntries;
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pSysfsAccess->scanDirEntries("clients/7/busy", engineEntries));
}
TEST_F(SysmanGlobalOperationsFixture, GivenDeviceIsWedgedWhenCallingGetDeviceStateThenZesResetReasonFlagWedgedIsReturned) {
auto pDrm = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrm->ioctlRetVal = -1;
pDrm->ioctlErrno = EIO;
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterface->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrm));
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(ZES_RESET_REASON_FLAG_WEDGED, deviceState.reset);
}
TEST_F(SysmanGlobalOperationsFixture, GivenDeviceIsNotWedgedWhenCallingGetDeviceStateThenZeroIsReturned) {
auto pDrm = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterface->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrm));
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(0u, deviceState.reset);
}
TEST_F(SysmanGlobalOperationsFixture, GivenGemCreateIoctlFailsWithEINVALWhenCallingGetDeviceStateThenVerifyResetIsNotNeeded) {
auto pDrm = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrm->ioctlRetVal = -1;
pDrm->ioctlErrno = EINVAL;
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterface->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrm));
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(0u, deviceState.reset);
}
TEST_F(SysmanGlobalOperationsFixture, GivenForceTrueWhenCallingResetThenSuccessIsReturned) {
ze_result_t result = zesDeviceReset(device, true);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenPermissionDeniedWhenCallingGetDeviceStateThenZeResultErrorInsufficientPermissionsIsReturned) {
pSysfsAccess->isRootSet = false;
ze_result_t result = zesDeviceReset(device, true);
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenDeviceInUseWhenCallingResetThenZeResultErrorHandleObjectInUseIsReturned) {
pProcfsAccess->ourDevicePid = pProcfsAccess->extraPid;
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenDeviceNotInUseWhenCallingResetThenSuccessIsReturned) {
// Pretend we have the device open
pProcfsAccess->ourDevicePid = getpid();
pProcfsAccess->ourDeviceFd = ::open("/dev/null", 0);
// The first time we get the process list, include our own process, that has the file open
// Reset should close the file (we verify after reset). On subsequent calls, return
// the process list without our process
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(true);
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
// Check that reset closed the device
// If the device is already closed, then close will fail with errno of EBADF
EXPECT_NE(0, ::close(pProcfsAccess->ourDevicePid));
EXPECT_EQ(errno, EBADF);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenForceTrueAndDeviceInUseWhenCallingResetThenSuccessIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
ze_result_t result = zesDeviceReset(device, true);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenProcessStartsMidResetWhenCallingResetThenSuccessIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenProcessStartsMidResetWhenCallingResetAndBindFailsThenFailureIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
pSysfsAccess->mockBindDeviceError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenDeviceInUseWhenCallingResetAndListProcessesFailsThenZeResultErrorIsReturned) {
pProcfsAccess->ourDevicePid = pProcfsAccess->extraPid;
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
pProcfsAccess->mockListProcessCall.push_back(RETURN_ERROR);
pProcfsAccess->isRepeated.push_back(false);
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenProcessStartsMidResetWhenListProcessesFailsAfterUnbindThenFailureIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(RETURN_ERROR);
pProcfsAccess->isRepeated.push_back(false);
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenProcessStartsMidResetWhenCallingResetAndWriteFailsAfterUnbindThenFailureIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
pFsAccess->mockWriteError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenProcessStartsMidResetWhenCallingResetAndUnbindFailsThenFailureIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(true);
pSysfsAccess->mockUnbindDeviceError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenProcessStartsMidResetWhenCallingResetAndGetFileNameFailsThenSuccessIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
pProcfsAccess->mockGetFileNameError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture,
GivenProcessWontDieWhenCallingResetThenZeResultErrorHandleObjectInUseErrorIsReturned) {
initGlobalOps();
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
static_cast<PublicLinuxGlobalOperationsImp *>(pGlobalOperationsImp->pOsGlobalOperations)->resetTimeout = 0; // timeout immediate
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_UNUSED);
pProcfsAccess->isRepeated.push_back(false);
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
pProcfsAccess->mockNoKill = true;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE, result);
}
TEST_F(SysmanGlobalOperationsIntegratedFixture, GivenProcessStartsMidResetWhenCallingResetAndGetFileDescriptorsFailsThenSuccessIsReturned) {
// Pretend another process has the device open
pProcfsAccess->ourDevicePid = getpid() + 1; // make sure it isn't our process id
pProcfsAccess->ourDeviceFd = pProcfsAccess->extraFd;
// Return process list without open fd on first call, but with open fd on subsequent calls
pProcfsAccess->mockListProcessCall.push_back(DEVICE_IN_USE);
pProcfsAccess->isRepeated.push_back(true);
pProcfsAccess->mockGetFileDescriptorsError = ZE_RESULT_ERROR_UNKNOWN;
pProcfsAccess->mockGetFileNameError = ZE_RESULT_ERROR_UNKNOWN;
ze_result_t result = zesDeviceReset(device, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleWhenCallingDeviceGetStateThenSuccessResultIsReturned) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
auto pDrm = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterface->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrm));
zes_device_state_t deviceState;
ze_result_t result = zesDeviceGetState(pSysmanDevice, &deviceState);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/test/unit_tests/sources/global_operations/linux/mock_global_operations.h"
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
namespace L0 {
namespace ult {
class SysmanGlobalOperationsHelperFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<MockGlobalOperationsSysfsAccess> pSysfsAccess;
std::unique_ptr<MockGlobalOperationsProcfsAccess> pProcfsAccess;
std::unique_ptr<MockGlobalOperationsFsAccess> pFsAccess;
std::unique_ptr<MockGlobalOpsFwInterface> pMockFwInterface;
L0::Sysman::FirmwareUtil *pFwUtilInterfaceOld = nullptr;
L0::Sysman::SysfsAccess *pSysfsAccessOld = nullptr;
L0::Sysman::ProcfsAccess *pProcfsAccessOld = nullptr;
L0::Sysman::FsAccess *pFsAccessOld = nullptr;
L0::Sysman::OsGlobalOperations *pOsGlobalOperationsPrev = nullptr;
L0::Sysman::GlobalOperations *pGlobalOperationsPrev = nullptr;
L0::Sysman::GlobalOperationsImp *pGlobalOperationsImp;
L0::Sysman::SysmanDeviceImp *device = nullptr;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pProcfsAccessOld = pLinuxSysmanImp->pProcfsAccess;
pFsAccessOld = pLinuxSysmanImp->pFsAccess;
pFwUtilInterfaceOld = pLinuxSysmanImp->pFwUtilInterface;
pSysfsAccess = std::make_unique<MockGlobalOperationsSysfsAccess>();
pProcfsAccess = std::make_unique<MockGlobalOperationsProcfsAccess>();
pFsAccess = std::make_unique<MockGlobalOperationsFsAccess>();
pMockFwInterface = std::make_unique<MockGlobalOpsFwInterface>();
pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface.get();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
pLinuxSysmanImp->pProcfsAccess = pProcfsAccess.get();
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
auto pDrmLocal = new DrmGlobalOpsMock(const_cast<NEO::RootDeviceEnvironment &>(pSysmanDeviceImp->getRootDeviceEnvironment()));
pDrmLocal->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
auto &osInterfaceLocal = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface;
osInterfaceLocal->setDriverModel(std::unique_ptr<DrmGlobalOpsMock>(pDrmLocal));
pFsAccess->mockReadVal = driverVersion;
pGlobalOperationsImp = static_cast<L0::Sysman::GlobalOperationsImp *>(pSysmanDeviceImp->pGlobalOperations);
pOsGlobalOperationsPrev = pGlobalOperationsImp->pOsGlobalOperations;
pGlobalOperationsImp->pOsGlobalOperations = nullptr;
device = pSysmanDeviceImp;
}
void TearDown() override {
if (nullptr != pGlobalOperationsImp->pOsGlobalOperations) {
delete pGlobalOperationsImp->pOsGlobalOperations;
}
pGlobalOperationsImp->pOsGlobalOperations = pOsGlobalOperationsPrev;
pGlobalOperationsImp = nullptr;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
pLinuxSysmanImp->pProcfsAccess = pProcfsAccessOld;
pLinuxSysmanImp->pFsAccess = pFsAccessOld;
pLinuxSysmanImp->pFwUtilInterface = pFwUtilInterfaceOld;
SysmanDeviceFixture::TearDown();
}
};
HWTEST2_F(SysmanGlobalOperationsHelperFixture, GivenDeviceIsRepairedWhenCallingGetDeviceStateThenZesResetReasonFlagRepairedIsReturned, IsPVC) {
pMockFwInterface->mockIfrStatus = true;
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(ZES_RESET_REASON_FLAG_REPAIR, deviceState.reset);
EXPECT_EQ(ZES_REPAIR_STATUS_PERFORMED, deviceState.repaired);
}
HWTEST2_F(SysmanGlobalOperationsHelperFixture, GivenDeviceIsRepairedWhenCallingGetDeviceStateThenZesResetReasonFlagRepairedIsReturned, IsNotPVC) {
pMockFwInterface->mockIfrStatus = true;
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(ZES_REPAIR_STATUS_UNSUPPORTED, deviceState.repaired);
}
HWTEST2_F(SysmanGlobalOperationsHelperFixture, GivenDeviceIsRepairedWhenCallingGetDeviceStateAndFirmwareRepairStatusIsFalseThenZesResetReasonFlagRepairedIsNotReturned, IsPVC) {
pMockFwInterface->mockIfrStatus = false;
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(0u, deviceState.reset);
EXPECT_EQ(ZES_REPAIR_STATUS_NOT_PERFORMED, deviceState.repaired);
}
HWTEST2_F(SysmanGlobalOperationsHelperFixture, GivenDeviceIsRepairedWhenCallingGetDeviceStateAndFirmwareRepairStatusIsFalseThenZesResetReasonFlagRepairedIsNotReturned, IsNotPVC) {
pMockFwInterface->mockIfrStatus = false;
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(0u, deviceState.reset);
EXPECT_EQ(ZES_REPAIR_STATUS_UNSUPPORTED, deviceState.repaired);
}
TEST_F(SysmanGlobalOperationsHelperFixture, GivenDeviceIsRepairedWhenCallingGetDeviceStateAndFirmwareRepairStatusFailsThenZesResetReasonFlagRepairedIsNotReturned) {
pMockFwInterface->mockIfrError = ZE_RESULT_ERROR_UNKNOWN;
zes_device_state_t deviceState;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceGetState(device, &deviceState));
EXPECT_EQ(0u, deviceState.reset);
EXPECT_EQ(ZES_REPAIR_STATUS_UNSUPPORTED, deviceState.repaired);
}
} // namespace ult
} // namespace L0

View File

@@ -36,6 +36,7 @@ class PublicLinuxSysmanImp : public L0::Sysman::LinuxSysmanImp {
using LinuxSysmanImp::pPmuInterface;
using LinuxSysmanImp::pProcfsAccess;
using LinuxSysmanImp::pSysfsAccess;
using LinuxSysmanImp::rootPath;
};
class SysmanDeviceFixture : public ::testing::Test {