mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
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:
committed by
Compute-Runtime-Automation
parent
4c7bc2ca98
commit
d29ed25f8b
@@ -35,3 +35,11 @@ struct _zes_sched_handle_t {
|
||||
struct _zes_firmware_handle_t {
|
||||
virtual ~_zes_firmware_handle_t() = default;
|
||||
};
|
||||
|
||||
struct _zes_diag_handle_t {
|
||||
virtual ~_zes_diag_handle_t() = default;
|
||||
};
|
||||
|
||||
struct _zes_ras_handle_t {
|
||||
virtual ~_zes_ras_handle_t() = default;
|
||||
};
|
||||
|
||||
@@ -35,13 +35,21 @@ ze_result_t zesDeviceGet(
|
||||
ze_result_t zesDeviceGetProperties(
|
||||
zes_device_handle_t hDevice,
|
||||
zes_device_properties_t *pProperties) {
|
||||
return L0::SysmanDevice::deviceGetProperties(hDevice, pProperties);
|
||||
if (L0::sysmanInitFromCore) {
|
||||
return L0::SysmanDevice::deviceGetProperties(hDevice, pProperties);
|
||||
} else {
|
||||
return L0::Sysman::SysmanDevice::deviceGetProperties(hDevice, pProperties);
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t zesDeviceGetState(
|
||||
zes_device_handle_t hDevice,
|
||||
zes_device_state_t *pState) {
|
||||
return L0::SysmanDevice::deviceGetState(hDevice, pState);
|
||||
if (L0::sysmanInitFromCore) {
|
||||
return L0::SysmanDevice::deviceGetState(hDevice, pState);
|
||||
} else {
|
||||
return L0::Sysman::SysmanDevice::deviceGetState(hDevice, pState);
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t zesDeviceEnumSchedulers(
|
||||
@@ -143,13 +151,21 @@ ze_result_t zesDeviceProcessesGetState(
|
||||
zes_device_handle_t hDevice,
|
||||
uint32_t *pCount,
|
||||
zes_process_state_t *pProcesses) {
|
||||
return L0::SysmanDevice::processesGetState(hDevice, pCount, pProcesses);
|
||||
if (L0::sysmanInitFromCore) {
|
||||
return L0::SysmanDevice::processesGetState(hDevice, pCount, pProcesses);
|
||||
} else {
|
||||
return L0::Sysman::SysmanDevice::processesGetState(hDevice, pCount, pProcesses);
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t zesDeviceReset(
|
||||
zes_device_handle_t hDevice,
|
||||
ze_bool_t force) {
|
||||
return L0::SysmanDevice::deviceReset(hDevice, force);
|
||||
if (L0::sysmanInitFromCore) {
|
||||
return L0::SysmanDevice::deviceReset(hDevice, force);
|
||||
} else {
|
||||
return L0::Sysman::SysmanDevice::deviceReset(hDevice, force);
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t zesDevicePciGetProperties(
|
||||
|
||||
15
level_zero/sysman/source/diagnostics/CMakeLists.txt
Normal file
15
level_zero/sysman/source/diagnostics/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Copyright (C) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/diagnostics.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/diagnostics.cpp
|
||||
)
|
||||
|
||||
add_subdirectories()
|
||||
|
||||
48
level_zero/sysman/source/diagnostics/diagnostics.cpp
Normal file
48
level_zero/sysman/source/diagnostics/diagnostics.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/diagnostics/diagnostics.h"
|
||||
|
||||
#include "shared/source/helpers/basic_math.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
DiagnosticsHandleContext::~DiagnosticsHandleContext() {
|
||||
releaseDiagnosticsHandles();
|
||||
}
|
||||
|
||||
void DiagnosticsHandleContext::releaseDiagnosticsHandles() {
|
||||
for (Diagnostics *pDiagnostics : handleList) {
|
||||
delete pDiagnostics;
|
||||
}
|
||||
handleList.clear();
|
||||
}
|
||||
|
||||
void DiagnosticsHandleContext::init() {
|
||||
}
|
||||
|
||||
ze_result_t DiagnosticsHandleContext::diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phDiagnostics) {
|
||||
std::call_once(initDiagnosticsOnce, [this]() {
|
||||
this->init();
|
||||
this->diagnosticsInitDone = true;
|
||||
});
|
||||
uint32_t handleListSize = static_cast<uint32_t>(handleList.size());
|
||||
uint32_t numToCopy = std::min(*pCount, handleListSize);
|
||||
if (0 == *pCount || *pCount > handleListSize) {
|
||||
*pCount = handleListSize;
|
||||
}
|
||||
if (nullptr != phDiagnostics) {
|
||||
for (uint32_t i = 0; i < numToCopy; i++) {
|
||||
phDiagnostics[i] = handleList[i]->toHandle();
|
||||
}
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
56
level_zero/sysman/source/diagnostics/diagnostics.h
Normal file
56
level_zero/sysman/source/diagnostics/diagnostics.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "level_zero/api/sysman/zes_handles_struct.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
struct OsSysman;
|
||||
|
||||
class Diagnostics : _zes_diag_handle_t {
|
||||
public:
|
||||
~Diagnostics() override {}
|
||||
virtual ze_result_t diagnosticsGetProperties(zes_diag_properties_t *pProperties) = 0;
|
||||
virtual ze_result_t diagnosticsGetTests(uint32_t *pCount, zes_diag_test_t *pTests) = 0;
|
||||
virtual ze_result_t diagnosticsRunTests(uint32_t start, uint32_t end, zes_diag_result_t *pResult) = 0;
|
||||
inline zes_diag_handle_t toHandle() { return this; }
|
||||
|
||||
static Diagnostics *fromHandle(zes_diag_handle_t handle) {
|
||||
return static_cast<Diagnostics *>(handle);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiagnosticsHandleContext {
|
||||
DiagnosticsHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
|
||||
void releaseDiagnosticsHandles();
|
||||
MOCKABLE_VIRTUAL ~DiagnosticsHandleContext();
|
||||
|
||||
MOCKABLE_VIRTUAL void init();
|
||||
|
||||
ze_result_t diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phDiagnostics);
|
||||
std::vector<std::string> supportedDiagTests = {};
|
||||
OsSysman *pOsSysman = nullptr;
|
||||
std::vector<Diagnostics *> handleList = {};
|
||||
bool isDiagnosticsInitDone() {
|
||||
return diagnosticsInitDone;
|
||||
}
|
||||
|
||||
private:
|
||||
void createHandle(const std::string &diagTests);
|
||||
std::once_flag initDiagnosticsOnce;
|
||||
bool diagnosticsInitDone = false;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
16
level_zero/sysman/source/global_operations/CMakeLists.txt
Normal file
16
level_zero/sysman/source/global_operations/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Copyright (C) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/global_operations.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/global_operations_imp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/global_operations_imp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations.h
|
||||
)
|
||||
|
||||
add_subdirectories()
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class GlobalOperations {
|
||||
public:
|
||||
virtual ~GlobalOperations(){};
|
||||
virtual ze_result_t reset(ze_bool_t force) = 0;
|
||||
virtual ze_result_t deviceGetProperties(zes_device_properties_t *pProperties) = 0;
|
||||
virtual ze_result_t processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) = 0;
|
||||
virtual ze_result_t deviceGetState(zes_device_state_t *pState) = 0;
|
||||
|
||||
virtual void init() = 0;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/global_operations_imp.h"
|
||||
|
||||
#include "shared/source/helpers/debug_helpers.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
ze_result_t GlobalOperationsImp::processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) {
|
||||
initGlobalOperations();
|
||||
std::vector<zes_process_state_t> pProcessList;
|
||||
ze_result_t result = pOsGlobalOperations->scanProcessesState(pProcessList);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((*pCount > 0) && (*pCount < pProcessList.size())) {
|
||||
result = ZE_RESULT_ERROR_INVALID_SIZE;
|
||||
}
|
||||
if (pProcesses != nullptr) {
|
||||
uint32_t limit = std::min(*pCount, static_cast<uint32_t>(pProcessList.size()));
|
||||
for (uint32_t i = 0; i < limit; i++) {
|
||||
pProcesses[i].processId = pProcessList[i].processId;
|
||||
pProcesses[i].engines = pProcessList[i].engines;
|
||||
pProcesses[i].memSize = pProcessList[i].memSize;
|
||||
pProcesses[i].sharedSize = pProcessList[i].sharedSize;
|
||||
}
|
||||
}
|
||||
*pCount = static_cast<uint32_t>(pProcessList.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t GlobalOperationsImp::deviceGetProperties(zes_device_properties_t *pProperties) {
|
||||
initGlobalOperations();
|
||||
sysmanProperties.numSubdevices = pOsSysman->getSubDeviceCount();
|
||||
*pProperties = sysmanProperties;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t GlobalOperationsImp::reset(ze_bool_t force) {
|
||||
initGlobalOperations();
|
||||
return pOsGlobalOperations->reset(force);
|
||||
}
|
||||
|
||||
ze_result_t GlobalOperationsImp::deviceGetState(zes_device_state_t *pState) {
|
||||
initGlobalOperations();
|
||||
return pOsGlobalOperations->deviceGetState(pState);
|
||||
}
|
||||
|
||||
void GlobalOperationsImp::init() {
|
||||
if (pOsGlobalOperations == nullptr) {
|
||||
pOsGlobalOperations = OsGlobalOperations::create(pOsSysman);
|
||||
}
|
||||
UNRECOVERABLE_IF(nullptr == pOsGlobalOperations);
|
||||
pOsGlobalOperations->getVendorName(sysmanProperties.vendorName);
|
||||
pOsGlobalOperations->getDriverVersion(sysmanProperties.driverVersion);
|
||||
pOsGlobalOperations->getModelName(sysmanProperties.modelName);
|
||||
pOsGlobalOperations->getBrandName(sysmanProperties.brandName);
|
||||
memset(sysmanProperties.boardNumber, 0, ZES_STRING_PROPERTY_SIZE);
|
||||
if (!pOsGlobalOperations->getBoardNumber(sysmanProperties.boardNumber)) {
|
||||
memcpy_s(sysmanProperties.boardNumber, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), unknown.length() + 1);
|
||||
}
|
||||
memset(sysmanProperties.serialNumber, 0, ZES_STRING_PROPERTY_SIZE);
|
||||
if (!pOsGlobalOperations->getSerialNumber(sysmanProperties.serialNumber)) {
|
||||
memcpy_s(sysmanProperties.serialNumber, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), unknown.length() + 1);
|
||||
}
|
||||
}
|
||||
void GlobalOperationsImp::initGlobalOperations() {
|
||||
std::call_once(initGlobalOpOnce, [this]() {
|
||||
this->init();
|
||||
});
|
||||
}
|
||||
GlobalOperationsImp::~GlobalOperationsImp() {
|
||||
if (nullptr != pOsGlobalOperations) {
|
||||
delete pOsGlobalOperations;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/global_operations.h"
|
||||
#include "level_zero/sysman/source/global_operations/os_global_operations.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class GlobalOperationsImp : public GlobalOperations, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
void init() override;
|
||||
ze_result_t reset(ze_bool_t force) override;
|
||||
ze_result_t deviceGetProperties(zes_device_properties_t *pProperties) override;
|
||||
ze_result_t processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) override;
|
||||
ze_result_t deviceGetState(zes_device_state_t *pState) override;
|
||||
OsGlobalOperations *pOsGlobalOperations = nullptr;
|
||||
|
||||
GlobalOperationsImp() = default;
|
||||
GlobalOperationsImp(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
|
||||
~GlobalOperationsImp() override;
|
||||
|
||||
private:
|
||||
OsSysman *pOsSysman = nullptr;
|
||||
zes_device_properties_t sysmanProperties = {};
|
||||
std::once_flag initGlobalOpOnce;
|
||||
void initGlobalOperations();
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright (C) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
if(UNIX)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_imp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_imp.h
|
||||
)
|
||||
|
||||
if(NEO_ENABLE_i915_PRELIM_DETECTION)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_helper_prelim.cpp
|
||||
)
|
||||
else()
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_helper.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/linux/os_global_operations_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
void LinuxGlobalOperationsImp::getRepairStatus(zes_device_state_t *pState) {}
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/firmware_util/firmware_util.h"
|
||||
#include "level_zero/sysman/source/global_operations/linux/os_global_operations_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
void LinuxGlobalOperationsImp::getRepairStatus(zes_device_state_t *pState) {
|
||||
bool ifrStatus = false;
|
||||
if (IGFX_PVC == pLinuxSysmanImp->getParentSysmanDeviceImp()->getProductFamily()) {
|
||||
auto pFwInterface = pLinuxSysmanImp->getFwUtilInterface();
|
||||
if (pFwInterface != nullptr) {
|
||||
auto result = pFwInterface->fwIfrApplied(ifrStatus);
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
pState->repaired = ZES_REPAIR_STATUS_NOT_PERFORMED;
|
||||
if (ifrStatus) {
|
||||
pState->reset |= ZES_RESET_REASON_FLAG_REPAIR;
|
||||
pState->repaired = ZES_REPAIR_STATUS_PERFORMED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/linux/os_global_operations_imp.h"
|
||||
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/ptr_math.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
#include "shared/source/os_interface/device_factory.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
#include "shared/source/os_interface/linux/pci_path.h"
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/global_operations_imp.h"
|
||||
#include "level_zero/sysman/source/linux/fs_access.h"
|
||||
#include "level_zero/sysman/source/linux/pmt/pmt.h"
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
const std::string LinuxGlobalOperationsImp::deviceDir("device");
|
||||
const std::string LinuxGlobalOperationsImp::vendorFile("device/vendor");
|
||||
const std::string LinuxGlobalOperationsImp::subsystemVendorFile("device/subsystem_vendor");
|
||||
const std::string LinuxGlobalOperationsImp::driverFile("device/driver");
|
||||
const std::string LinuxGlobalOperationsImp::functionLevelReset("device/reset");
|
||||
const std::string LinuxGlobalOperationsImp::clientsDir("clients");
|
||||
const std::string LinuxGlobalOperationsImp::srcVersionFile("/sys/module/i915/srcversion");
|
||||
const std::string LinuxGlobalOperationsImp::agamaVersionFile("/sys/module/i915/agama_version");
|
||||
const std::string LinuxGlobalOperationsImp::ueventWedgedFile("/var/lib/libze_intel_gpu/wedged_file");
|
||||
|
||||
// Map engine entries(numeric values) present in /sys/class/drm/card<n>/clients/<client_n>/busy,
|
||||
// with engine enum defined in leve-zero spec
|
||||
// Note that entries with int 2 and 3(represented by i915 as CLASS_VIDEO and CLASS_VIDEO_ENHANCE)
|
||||
// are both mapped to MEDIA, as CLASS_VIDEO represents any media fixed-function hardware.
|
||||
static const std::map<int, zes_engine_type_flags_t> engineMap = {
|
||||
{0, ZES_ENGINE_TYPE_FLAG_3D},
|
||||
{1, ZES_ENGINE_TYPE_FLAG_DMA},
|
||||
{2, ZES_ENGINE_TYPE_FLAG_MEDIA},
|
||||
{3, ZES_ENGINE_TYPE_FLAG_MEDIA},
|
||||
{4, ZES_ENGINE_TYPE_FLAG_COMPUTE}};
|
||||
|
||||
bool LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(uint64_t &telemOffset, const std::string &key, std::string &telemDir) {
|
||||
std::string &rootPath = pLinuxSysmanImp->getPciRootPath();
|
||||
if (rootPath.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<uint32_t, std::string> telemPciPath;
|
||||
NEO::PmtUtil::getTelemNodesInPciPath(std::string_view(rootPath), telemPciPath);
|
||||
if (telemPciPath.size() < pLinuxSysmanImp->getSubDeviceCount() + 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto iterator = telemPciPath.begin();
|
||||
telemDir = iterator->second;
|
||||
|
||||
std::array<char, NEO::PmtUtil::guidStringSize> guidString = {};
|
||||
if (!NEO::PmtUtil::readGuid(telemDir, guidString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t offset = ULONG_MAX;
|
||||
if (!NEO::PmtUtil::readOffset(telemDir, offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, uint64_t> keyOffsetMap;
|
||||
if (ZE_RESULT_SUCCESS == PlatformMonitoringTech::getKeyOffsetMap(guidString.data(), keyOffsetMap)) {
|
||||
auto keyOffset = keyOffsetMap.find(key.c_str());
|
||||
if (keyOffset != keyOffsetMap.end()) {
|
||||
telemOffset = keyOffset->second + offset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LinuxGlobalOperationsImp::getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
uint64_t offset = 0;
|
||||
std::string telemDir = {};
|
||||
if (!LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(offset, "PPIN", telemDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t value;
|
||||
ssize_t bytesRead = NEO::PmtUtil::readTelem(telemDir.data(), sizeof(uint64_t), offset, &value);
|
||||
if (bytesRead == sizeof(uint64_t)) {
|
||||
std::ostringstream telemDataString;
|
||||
telemDataString << std::hex << std::showbase << value;
|
||||
memcpy_s(serialNumber, ZES_STRING_PROPERTY_SIZE, telemDataString.str().c_str(), telemDataString.str().size());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LinuxGlobalOperationsImp::getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
uint64_t offset = 0;
|
||||
std::string telemDir = {};
|
||||
constexpr uint32_t boardNumberSize = 32;
|
||||
if (!LinuxGlobalOperationsImp::getTelemOffsetAndTelemDir(offset, "BoardNumber", telemDir)) {
|
||||
return false;
|
||||
}
|
||||
std::array<uint8_t, boardNumberSize> value;
|
||||
ssize_t bytesRead = NEO::PmtUtil::readTelem(telemDir.data(), boardNumberSize, offset, value.data());
|
||||
if (bytesRead == boardNumberSize) {
|
||||
memcpy_s(boardNumber, ZES_STRING_PROPERTY_SIZE, value.data(), bytesRead);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LinuxGlobalOperationsImp::getBrandName(char (&brandName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
std::string strVal;
|
||||
ze_result_t result = pSysfsAccess->read(subsystemVendorFile, strVal);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
std::strncpy(brandName, unknown.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
return;
|
||||
}
|
||||
if (strVal.compare(intelPciId) == 0) {
|
||||
std::strncpy(brandName, vendorIntel.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
} else {
|
||||
std::strncpy(brandName, unknown.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxGlobalOperationsImp::getModelName(char (&modelName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
auto &hwInfo = pLinuxSysmanImp->getParentSysmanDeviceImp()->getHardwareInfo();
|
||||
std::string deviceName = hwInfo.capabilityTable.deviceName;
|
||||
if (!deviceName.empty()) {
|
||||
std::strncpy(modelName, deviceName.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream deviceNameDefault;
|
||||
deviceNameDefault << "Intel(R) Graphics";
|
||||
deviceNameDefault << " [0x" << std::hex << std::setw(4) << std::setfill('0') << hwInfo.platform.usDeviceID << "]";
|
||||
std::strncpy(modelName, deviceNameDefault.str().c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
}
|
||||
|
||||
void LinuxGlobalOperationsImp::getVendorName(char (&vendorName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
std::string strVal;
|
||||
ze_result_t result = pSysfsAccess->read(vendorFile, strVal);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
std::strncpy(vendorName, unknown.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
return;
|
||||
}
|
||||
if (strVal.compare(intelPciId) == 0) {
|
||||
std::strncpy(vendorName, vendorIntel.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
} else {
|
||||
std::strncpy(vendorName, unknown.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxGlobalOperationsImp::getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
std::string strVal;
|
||||
std::strncpy(driverVersion, unknown.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
ze_result_t result = pFsAccess->read(agamaVersionFile, strVal);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE != result) {
|
||||
return;
|
||||
}
|
||||
result = pFsAccess->read(srcVersionFile, strVal);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::strncpy(driverVersion, strVal.c_str(), ZES_STRING_PROPERTY_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
ze_result_t LinuxGlobalOperationsImp::reset(ze_bool_t force) {
|
||||
if (!pSysfsAccess->isRootUser()) {
|
||||
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||
}
|
||||
pLinuxSysmanImp->releaseSysmanDeviceResources();
|
||||
std::string resetPath;
|
||||
std::string resetName;
|
||||
ze_result_t result = ZE_RESULT_SUCCESS;
|
||||
|
||||
::pid_t myPid = pProcfsAccess->myProcessId();
|
||||
std::vector<int> myPidFds;
|
||||
std::vector<::pid_t> processes;
|
||||
|
||||
result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &&pid : processes) {
|
||||
std::vector<int> fds;
|
||||
pLinuxSysmanImp->getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (pid == myPid) {
|
||||
// L0 is expected to have this file open.
|
||||
// Keep list of fds. Close before unbind.
|
||||
myPidFds = fds;
|
||||
} else if (!fds.empty()) {
|
||||
if (force) {
|
||||
pProcfsAccess->kill(pid);
|
||||
} else {
|
||||
// Device is in use by another process.
|
||||
// Don't reset while in use.
|
||||
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pSysfsAccess->getRealPath(deviceDir, resetName);
|
||||
resetName = pFsAccess->getBaseName(resetName);
|
||||
|
||||
for (auto &&fd : myPidFds) {
|
||||
// Close open filedescriptors to the device
|
||||
// before unbinding device.
|
||||
// From this point forward, there is no
|
||||
// graceful way to fail the reset call.
|
||||
// All future ze calls by this process for this
|
||||
// device will fail.
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
// Unbind the device from the kernel driver.
|
||||
result = pSysfsAccess->unbindDevice(resetName);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// If someone opened the device
|
||||
// after we check, kill them here.
|
||||
result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
std::vector<::pid_t> deviceUsingPids;
|
||||
deviceUsingPids.clear();
|
||||
for (auto &&pid : processes) {
|
||||
std::vector<int> fds;
|
||||
pLinuxSysmanImp->getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (!fds.empty()) {
|
||||
// Kill all processes that have the device open.
|
||||
pProcfsAccess->kill(pid);
|
||||
deviceUsingPids.push_back(pid);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all the processes to exit
|
||||
// If they don't all exit within resetTimeout
|
||||
// just fail reset.
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
auto end = start;
|
||||
for (auto &&pid : deviceUsingPids) {
|
||||
while (pProcfsAccess->isAlive(pid)) {
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() > resetTimeout) {
|
||||
|
||||
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
|
||||
}
|
||||
struct ::timespec timeout = {.tv_sec = 0, .tv_nsec = 1000};
|
||||
::nanosleep(&timeout, NULL);
|
||||
end = std::chrono::steady_clock::now();
|
||||
}
|
||||
}
|
||||
|
||||
if (!pLinuxSysmanImp->getParentSysmanDeviceImp()->getHardwareInfo().capabilityTable.isIntegratedDevice) {
|
||||
result = pLinuxSysmanImp->osWarmReset();
|
||||
if (ZE_RESULT_SUCCESS == result) {
|
||||
return pLinuxSysmanImp->reInitSysmanDeviceResources();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pSysfsAccess->getRealPath(functionLevelReset, resetPath);
|
||||
|
||||
// Reset the device.
|
||||
result = pFsAccess->write(resetPath, "1");
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rebind the device to the kernel driver.
|
||||
result = pSysfsAccess->bindDevice(resetName);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return pLinuxSysmanImp->reInitSysmanDeviceResources();
|
||||
}
|
||||
|
||||
// Processes in the form of clients are present in sysfs like this:
|
||||
// # /sys/class/drm/card0/clients$ ls
|
||||
// 4 5
|
||||
// # /sys/class/drm/card0/clients/4$ ls
|
||||
// busy name pid
|
||||
// # /sys/class/drm/card0/clients/4/busy$ ls
|
||||
// 0 1 2 3
|
||||
//
|
||||
// Number of processes(If one process opened drm device multiple times, then multiple entries will be
|
||||
// present for same process in clients directory) will be the number of clients
|
||||
// (For example from above example, processes dirs are 4,5)
|
||||
// Thus total number of times drm connection opened with this device will be 2.
|
||||
// process.pid = pid (from above example)
|
||||
// process.engines -> For each client's busy dir, numbers 0,1,2,3 represent engines and they contain
|
||||
// accumulated nanoseconds each client spent on engines.
|
||||
// Thus we traverse each file in busy dir for non-zero time and if we find that file say 0,then we could say that
|
||||
// this engine 0 is used by process.
|
||||
ze_result_t LinuxGlobalOperationsImp::scanProcessesState(std::vector<zes_process_state_t> &pProcessList) {
|
||||
std::vector<std::string> clientIds;
|
||||
struct deviceMemStruct {
|
||||
uint64_t deviceMemorySize;
|
||||
uint64_t deviceSharedMemorySize;
|
||||
};
|
||||
struct engineMemoryPairType {
|
||||
int64_t engineTypeField;
|
||||
deviceMemStruct deviceMemStructField;
|
||||
};
|
||||
|
||||
ze_result_t result = pSysfsAccess->scanDirEntries(clientsDir, clientIds);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
// Create a map with unique pid as key and engineType as value
|
||||
std::map<uint64_t, engineMemoryPairType> pidClientMap;
|
||||
for (const auto &clientId : clientIds) {
|
||||
// realClientPidPath will be something like: clients/<clientId>/pid
|
||||
std::string realClientPidPath = clientsDir + "/" + clientId + "/" + "pid";
|
||||
uint64_t pid;
|
||||
result = pSysfsAccess->read(realClientPidPath, pid);
|
||||
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
std::string bPidString;
|
||||
result = pSysfsAccess->read(realClientPidPath, bPidString);
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
size_t start = bPidString.find("<");
|
||||
size_t end = bPidString.find(">");
|
||||
std::string bPid = bPidString.substr(start + 1, end - start - 1);
|
||||
pid = std::stoull(bPid, nullptr, 10);
|
||||
}
|
||||
}
|
||||
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE == result) {
|
||||
// update the result as Success as ZE_RESULT_ERROR_NOT_AVAILABLE is expected if the "realClientPidPath" folder is empty
|
||||
// this condition(when encountered) must not prevent the information accumulated for other clientIds
|
||||
// this situation occurs when there is no call modifying result,
|
||||
result = ZE_RESULT_SUCCESS;
|
||||
continue;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Traverse the clients/<clientId>/busy directory to get accelerator engines used by process
|
||||
std::vector<std::string> engineNums = {};
|
||||
int64_t engineType = 0;
|
||||
std::string busyDirForEngines = clientsDir + "/" + clientId + "/" + "busy";
|
||||
result = pSysfsAccess->scanDirEntries(busyDirForEngines, engineNums);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE == result) {
|
||||
// update the result as Success as ZE_RESULT_ERROR_NOT_AVAILABLE is expected if the "realClientPidPath" folder is empty
|
||||
// this condition(when encountered) must not prevent the information accumulated for other clientIds
|
||||
// this situation occurs when there is no call modifying result,
|
||||
// Here its seen when the last element of clientIds returns ZE_RESULT_ERROR_NOT_AVAILABLE for some reason.
|
||||
engineType = ZES_ENGINE_TYPE_FLAG_OTHER; // When busy node is absent assign engine type with ZES_ENGINE_TYPE_FLAG_OTHER
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Scan all engine files present in /sys/class/drm/card0/clients/<ClientId>/busy and check
|
||||
// whether that engine is used by process
|
||||
for (const auto &engineNum : engineNums) {
|
||||
uint64_t timeSpent = 0;
|
||||
std::string engine = busyDirForEngines + "/" + engineNum;
|
||||
result = pSysfsAccess->read(engine, timeSpent);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE == result) {
|
||||
continue;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (timeSpent > 0) {
|
||||
int i915EnginNumber = stoi(engineNum);
|
||||
auto i915MapToL0EngineType = engineMap.find(i915EnginNumber);
|
||||
zes_engine_type_flags_t val = ZES_ENGINE_TYPE_FLAG_OTHER;
|
||||
if (i915MapToL0EngineType != engineMap.end()) {
|
||||
// Found a valid map
|
||||
val = i915MapToL0EngineType->second;
|
||||
}
|
||||
// In this for loop we want to retrieve the overall engines used by process
|
||||
engineType = engineType | val;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t memSize = 0;
|
||||
std::string realClientTotalMemoryPath = clientsDir + "/" + clientId + "/" + "total_device_memory_buffer_objects" + "/" + "created_bytes";
|
||||
result = pSysfsAccess->read(realClientTotalMemoryPath, memSize);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE != result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t sharedMemSize = 0;
|
||||
std::string realClientTotalSharedMemoryPath = clientsDir + "/" + clientId + "/" + "total_device_memory_buffer_objects" + "/" + "imported_bytes";
|
||||
result = pSysfsAccess->read(realClientTotalSharedMemoryPath, sharedMemSize);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (ZE_RESULT_ERROR_NOT_AVAILABLE != result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
deviceMemStruct totalDeviceMem = {memSize, sharedMemSize};
|
||||
engineMemoryPairType engineMemoryPair = {engineType, totalDeviceMem};
|
||||
auto ret = pidClientMap.insert(std::make_pair(pid, engineMemoryPair));
|
||||
if (ret.second == false) {
|
||||
// insertion failed as entry with same pid already exists in map
|
||||
// Now update the engineMemoryPairType field for the existing pid entry
|
||||
engineMemoryPairType updateEngineMemoryPair;
|
||||
auto pidEntryFromMap = pidClientMap.find(pid);
|
||||
auto existingEngineType = pidEntryFromMap->second.engineTypeField;
|
||||
auto existingdeviceMemorySize = pidEntryFromMap->second.deviceMemStructField.deviceMemorySize;
|
||||
auto existingdeviceSharedMemorySize = pidEntryFromMap->second.deviceMemStructField.deviceSharedMemorySize;
|
||||
updateEngineMemoryPair.engineTypeField = existingEngineType | engineMemoryPair.engineTypeField;
|
||||
updateEngineMemoryPair.deviceMemStructField.deviceMemorySize = existingdeviceMemorySize + engineMemoryPair.deviceMemStructField.deviceMemorySize;
|
||||
updateEngineMemoryPair.deviceMemStructField.deviceSharedMemorySize = existingdeviceSharedMemorySize + engineMemoryPair.deviceMemStructField.deviceSharedMemorySize;
|
||||
pidClientMap[pid] = updateEngineMemoryPair;
|
||||
}
|
||||
result = ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// iterate through all elements of pidClientMap
|
||||
for (auto itr = pidClientMap.begin(); itr != pidClientMap.end(); ++itr) {
|
||||
zes_process_state_t process;
|
||||
process.processId = static_cast<uint32_t>(itr->first);
|
||||
process.memSize = itr->second.deviceMemStructField.deviceMemorySize;
|
||||
process.sharedSize = itr->second.deviceMemStructField.deviceSharedMemorySize;
|
||||
process.engines = static_cast<uint32_t>(itr->second.engineTypeField);
|
||||
pProcessList.push_back(process);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LinuxGlobalOperationsImp::getWedgedStatus(zes_device_state_t *pState) {
|
||||
NEO::GemContextCreateExt gcc{};
|
||||
auto hwDeviceId = pLinuxSysmanImp->getSysmanHwDeviceId();
|
||||
hwDeviceId->openFileDescriptor();
|
||||
auto pDrm = pLinuxSysmanImp->getDrm();
|
||||
// Device is said to be in wedged if context creation returns EIO.
|
||||
auto ret = pDrm->getIoctlHelper()->ioctl(NEO::DrmIoctl::GemContextCreateExt, &gcc);
|
||||
if (ret == 0) {
|
||||
pDrm->destroyDrmContext(gcc.contextId);
|
||||
return;
|
||||
}
|
||||
hwDeviceId->closeFileDescriptor();
|
||||
|
||||
if (pDrm->getErrno() == EIO) {
|
||||
pState->reset |= ZES_RESET_REASON_FLAG_WEDGED;
|
||||
}
|
||||
}
|
||||
ze_result_t LinuxGlobalOperationsImp::deviceGetState(zes_device_state_t *pState) {
|
||||
memset(pState, 0, sizeof(zes_device_state_t));
|
||||
pState->repaired = ZES_REPAIR_STATUS_UNSUPPORTED;
|
||||
getWedgedStatus(pState);
|
||||
getRepairStatus(pState);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
LinuxGlobalOperationsImp::LinuxGlobalOperationsImp(OsSysman *pOsSysman) {
|
||||
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
|
||||
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
pProcfsAccess = &pLinuxSysmanImp->getProcfsAccess();
|
||||
pFsAccess = &pLinuxSysmanImp->getFsAccess();
|
||||
devicePciBdf = pLinuxSysmanImp->getParentSysmanDeviceImp()->getRootDeviceEnvironment().osInterface->getDriverModel()->as<NEO::Drm>()->getPciPath();
|
||||
rootDeviceIndex = pLinuxSysmanImp->getParentSysmanDeviceImp()->getRootDeviceIndex();
|
||||
}
|
||||
|
||||
OsGlobalOperations *OsGlobalOperations::create(OsSysman *pOsSysman) {
|
||||
LinuxGlobalOperationsImp *pLinuxGlobalOperationsImp = new LinuxGlobalOperationsImp(pOsSysman);
|
||||
return static_cast<OsGlobalOperations *>(pLinuxGlobalOperationsImp);
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/os_interface/linux/pmt_util.h"
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/os_global_operations.h"
|
||||
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
class SysfsAccess;
|
||||
|
||||
class LinuxGlobalOperationsImp : public OsGlobalOperations, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
bool getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
bool getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getBrandName(char (&brandName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getModelName(char (&modelName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getVendorName(char (&vendorName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getWedgedStatus(zes_device_state_t *pState) override;
|
||||
void getRepairStatus(zes_device_state_t *pState) override;
|
||||
ze_result_t reset(ze_bool_t force) override;
|
||||
ze_result_t scanProcessesState(std::vector<zes_process_state_t> &pProcessList) override;
|
||||
ze_result_t deviceGetState(zes_device_state_t *pState) override;
|
||||
LinuxGlobalOperationsImp() = default;
|
||||
LinuxGlobalOperationsImp(OsSysman *pOsSysman);
|
||||
~LinuxGlobalOperationsImp() override = default;
|
||||
|
||||
protected:
|
||||
FsAccess *pFsAccess = nullptr;
|
||||
ProcfsAccess *pProcfsAccess = nullptr;
|
||||
SysfsAccess *pSysfsAccess = nullptr;
|
||||
LinuxSysmanImp *pLinuxSysmanImp = nullptr;
|
||||
int resetTimeout = 10000; // in milliseconds
|
||||
void releaseSysmanDeviceResources();
|
||||
void releaseDeviceResources();
|
||||
ze_result_t initDevice();
|
||||
void reInitSysmanDeviceResources();
|
||||
|
||||
private:
|
||||
static const std::string deviceDir;
|
||||
static const std::string vendorFile;
|
||||
static const std::string subsystemVendorFile;
|
||||
static const std::string driverFile;
|
||||
static const std::string functionLevelReset;
|
||||
static const std::string clientsDir;
|
||||
static const std::string srcVersionFile;
|
||||
static const std::string agamaVersionFile;
|
||||
static const std::string ueventWedgedFile;
|
||||
bool getTelemOffsetAndTelemDir(uint64_t &telemOffset, const std::string &key, std::string &telemDir);
|
||||
std::string devicePciBdf = "";
|
||||
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
uint32_t rootDeviceIndex = 0u;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "level_zero/sysman/source/os_sysman.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class OsGlobalOperations {
|
||||
public:
|
||||
virtual bool getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual bool getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual void getBrandName(char (&brandName)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual void getModelName(char (&modelName)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual void getVendorName(char (&vendorName)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) = 0;
|
||||
virtual void getWedgedStatus(zes_device_state_t *pState) = 0;
|
||||
virtual void getRepairStatus(zes_device_state_t *pState) = 0;
|
||||
virtual ze_result_t reset(ze_bool_t force) = 0;
|
||||
virtual ze_result_t scanProcessesState(std::vector<zes_process_state_t> &pProcessList) = 0;
|
||||
virtual ze_result_t deviceGetState(zes_device_state_t *pState) = 0;
|
||||
static OsGlobalOperations *create(OsSysman *pOsSysman);
|
||||
virtual ~OsGlobalOperations() {}
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Copyright (C) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
if(WIN32)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_imp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_global_operations_imp.cpp
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/windows/os_global_operations_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
bool WddmGlobalOperationsImp::getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WddmGlobalOperationsImp::getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WddmGlobalOperationsImp::getBrandName(char (&brandName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
}
|
||||
|
||||
void WddmGlobalOperationsImp::getModelName(char (&modelName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
}
|
||||
|
||||
void WddmGlobalOperationsImp::getVendorName(char (&vendorName)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
}
|
||||
|
||||
void WddmGlobalOperationsImp::getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) {
|
||||
}
|
||||
|
||||
void WddmGlobalOperationsImp::getWedgedStatus(zes_device_state_t *pState) {
|
||||
}
|
||||
void WddmGlobalOperationsImp::getRepairStatus(zes_device_state_t *pState) {
|
||||
}
|
||||
ze_result_t WddmGlobalOperationsImp::reset(ze_bool_t force) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmGlobalOperationsImp::scanProcessesState(std::vector<zes_process_state_t> &pProcessList) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmGlobalOperationsImp::deviceGetState(zes_device_state_t *pState) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
WddmGlobalOperationsImp::WddmGlobalOperationsImp(OsSysman *pOsSysman) {
|
||||
}
|
||||
|
||||
OsGlobalOperations *OsGlobalOperations::create(OsSysman *pOsSysman) {
|
||||
WddmGlobalOperationsImp *pWddmGlobalOperationsImp = new WddmGlobalOperationsImp(pOsSysman);
|
||||
return static_cast<OsGlobalOperations *>(pWddmGlobalOperationsImp);
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/os_global_operations.h"
|
||||
#include "level_zero/sysman/source/windows/os_sysman_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class WddmGlobalOperationsImp : public OsGlobalOperations, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
bool getSerialNumber(char (&serialNumber)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
bool getBoardNumber(char (&boardNumber)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getBrandName(char (&brandName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getModelName(char (&modelName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getVendorName(char (&vendorName)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getDriverVersion(char (&driverVersion)[ZES_STRING_PROPERTY_SIZE]) override;
|
||||
void getWedgedStatus(zes_device_state_t *pState) override;
|
||||
void getRepairStatus(zes_device_state_t *pState) override;
|
||||
ze_result_t reset(ze_bool_t force) override;
|
||||
ze_result_t scanProcessesState(std::vector<zes_process_state_t> &pProcessList) override;
|
||||
ze_result_t deviceGetState(zes_device_state_t *pState) override;
|
||||
|
||||
WddmGlobalOperationsImp(OsSysman *pOsSysman);
|
||||
WddmGlobalOperationsImp() = default;
|
||||
~WddmGlobalOperationsImp() override = default;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -7,9 +7,12 @@
|
||||
|
||||
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/helpers/gfx_core_helper.h"
|
||||
#include "shared/source/helpers/sleep.h"
|
||||
#include "shared/source/os_interface/driver_info.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/pci_path.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
|
||||
#include "level_zero/sysman/source/firmware_util/firmware_util.h"
|
||||
@@ -17,6 +20,8 @@
|
||||
#include "level_zero/sysman/source/linux/pmt/pmt.h"
|
||||
#include "level_zero/sysman/source/linux/pmu/pmu.h"
|
||||
|
||||
#include <linux/pci_regs.h>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
@@ -55,6 +60,9 @@ ze_result_t LinuxSysmanImp::init() {
|
||||
subDeviceCount = 0;
|
||||
}
|
||||
|
||||
rootPath = NEO::getPciRootPath(myDeviceFd).value_or("");
|
||||
pSysfsAccess->getRealPath(deviceDir, gtDevicePath);
|
||||
|
||||
osInterface.getDriverModel()->as<NEO::Drm>()->cleanup();
|
||||
// Close Drm handles
|
||||
sysmanHwDeviceId->closeFileDescriptor();
|
||||
@@ -62,6 +70,10 @@ ze_result_t LinuxSysmanImp::init() {
|
||||
return createPmtHandles();
|
||||
}
|
||||
|
||||
std::string &LinuxSysmanImp::getPciRootPath() {
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
SysmanHwDeviceIdDrm *LinuxSysmanImp::getSysmanHwDeviceId() {
|
||||
return static_cast<SysmanHwDeviceIdDrm *>(getDrm()->getHwDeviceId().get());
|
||||
}
|
||||
@@ -95,6 +107,21 @@ static std::string modifyPathOnLevel(std::string realPciPath, uint8_t nLevel) {
|
||||
}
|
||||
return realPciPath;
|
||||
}
|
||||
std::string LinuxSysmanImp::getPciRootPortDirectoryPath(std::string realPciPath) {
|
||||
// the rootport is always the first pci folder after the pcie slot.
|
||||
// +-[0000:89]-+-00.0
|
||||
// | +-00.1
|
||||
// | +-00.2
|
||||
// | +-00.4
|
||||
// | \-02.0-[8a-8e]----00.0-[8b-8e]--+-01.0-[8c-8d]----00.0
|
||||
// | \-02.0-[8e]--+-00.0
|
||||
// | +-00.1
|
||||
// | \-00.2
|
||||
// /sys/devices/pci0000:89/0000:89:02.0/0000:8a:00.0/0000:8b:01.0/0000:8c:00.0
|
||||
// '/sys/devices/pci0000:89/0000:89:02.0/' will always be the same distance.
|
||||
// from 0000:8c:00.0 i.e the 3rd PCI address from the gt tile
|
||||
return modifyPathOnLevel(realPciPath, 3);
|
||||
}
|
||||
|
||||
std::string LinuxSysmanImp::getPciCardBusDirectoryPath(std::string realPciPath) {
|
||||
// the cardbus is always the second pci folder after the pcie slot.
|
||||
@@ -204,6 +231,214 @@ LinuxSysmanImp::~LinuxSysmanImp() {
|
||||
releasePmtObject();
|
||||
}
|
||||
|
||||
void LinuxSysmanImp::getPidFdsForOpenDevice(ProcfsAccess *pProcfsAccess, SysfsAccess *pSysfsAccess, const ::pid_t pid, std::vector<int> &deviceFds) {
|
||||
// Return a list of all the file descriptors of this process that point to this device
|
||||
std::vector<int> fds;
|
||||
deviceFds.clear();
|
||||
if (ZE_RESULT_SUCCESS != pProcfsAccess->getFileDescriptors(pid, fds)) {
|
||||
// Process exited. Not an error. Just ignore.
|
||||
return;
|
||||
}
|
||||
for (auto &&fd : fds) {
|
||||
std::string file;
|
||||
if (pProcfsAccess->getFileName(pid, fd, file) != ZE_RESULT_SUCCESS) {
|
||||
// Process closed this file. Not an error. Just ignore.
|
||||
continue;
|
||||
}
|
||||
if (pSysfsAccess->isMyDeviceFile(file)) {
|
||||
deviceFds.push_back(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxSysmanImp::gpuProcessCleanup() {
|
||||
::pid_t myPid = pProcfsAccess->myProcessId();
|
||||
std::vector<::pid_t> processes;
|
||||
std::vector<int> myPidFds;
|
||||
ze_result_t result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"gpuProcessCleanup: listProcesses() failed with error code: %ld\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto &&pid : processes) {
|
||||
std::vector<int> fds;
|
||||
getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (pid == myPid) {
|
||||
// L0 is expected to have this file open.
|
||||
// Keep list of fds. Close before unbind.
|
||||
myPidFds = fds;
|
||||
continue;
|
||||
}
|
||||
if (!fds.empty()) {
|
||||
pProcfsAccess->kill(pid);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&fd : myPidFds) {
|
||||
// Close open filedescriptors to the device
|
||||
// before unbinding device.
|
||||
// From this point forward, there is no
|
||||
// graceful way to fail the reset call.
|
||||
// All future ze calls by this process for this
|
||||
// device will fail.
|
||||
NEO::SysCalls::close(fd);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void LinuxSysmanImp::releaseSysmanDeviceResources() {
|
||||
getSysmanDeviceImp()->pEngineHandleContext->releaseEngines();
|
||||
getSysmanDeviceImp()->pRasHandleContext->releaseRasHandles();
|
||||
if (!diagnosticsReset) {
|
||||
getSysmanDeviceImp()->pDiagnosticsHandleContext->releaseDiagnosticsHandles();
|
||||
}
|
||||
getSysmanDeviceImp()->pFirmwareHandleContext->releaseFwHandles();
|
||||
releasePmtObject();
|
||||
if (!diagnosticsReset) {
|
||||
releaseFwUtilInterface();
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxSysmanImp::reInitSysmanDeviceResources() {
|
||||
createPmtHandles();
|
||||
if (!diagnosticsReset) {
|
||||
createFwUtilInterface();
|
||||
}
|
||||
if (getSysmanDeviceImp()->pRasHandleContext->isRasInitDone()) {
|
||||
getSysmanDeviceImp()->pRasHandleContext->init(getSubDeviceCount());
|
||||
}
|
||||
if (getSysmanDeviceImp()->pEngineHandleContext->isEngineInitDone()) {
|
||||
getSysmanDeviceImp()->pEngineHandleContext->init(getSubDeviceCount());
|
||||
}
|
||||
if (!diagnosticsReset) {
|
||||
if (getSysmanDeviceImp()->pDiagnosticsHandleContext->isDiagnosticsInitDone()) {
|
||||
getSysmanDeviceImp()->pDiagnosticsHandleContext->init();
|
||||
}
|
||||
}
|
||||
this->diagnosticsReset = false;
|
||||
if (getSysmanDeviceImp()->pFirmwareHandleContext->isFirmwareInitDone()) {
|
||||
getSysmanDeviceImp()->pFirmwareHandleContext->init();
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// function to clear Hot-Plug interrupt enable bit in the slot control register
|
||||
// this is required to prevent interrupts from being raised in the warm reset path.
|
||||
void LinuxSysmanImp::clearHPIE(int fd) {
|
||||
uint8_t value = 0x00;
|
||||
uint8_t resetValue = 0x00;
|
||||
uint8_t offset = 0x0;
|
||||
this->preadFunction(fd, &offset, 0x01, PCI_CAPABILITY_LIST);
|
||||
// Bottom two bits of capability pointer register are reserved and
|
||||
// software should mask these bits to get pointer to capability list.
|
||||
// PCI_EXP_SLTCTL - offset for slot control register.
|
||||
offset = (offset & 0xfc) + PCI_EXP_SLTCTL;
|
||||
this->preadFunction(fd, &value, 0x01, offset);
|
||||
resetValue = value & (~PCI_EXP_SLTCTL_HPIE);
|
||||
this->pwriteFunction(fd, &resetValue, 0x01, offset);
|
||||
NEO::sleep(std::chrono::seconds(10)); // Sleep for 10seconds just to make sure the change is propagated.
|
||||
}
|
||||
|
||||
// A 'warm reset' is a conventional reset that is triggered across a PCI express link.
|
||||
// A warm reset is triggered either when a link is forced into electrical idle or
|
||||
// by sending TS1 and TS2 ordered sets with the hot reset bit set.
|
||||
// Software can initiate a warm reset by setting and then clearing the secondary bus reset bit
|
||||
// in the bridge control register in the PCI configuration space of the bridge port upstream of the device.
|
||||
ze_result_t LinuxSysmanImp::osWarmReset() {
|
||||
std::string rootPortPath;
|
||||
rootPortPath = getPciRootPortDirectoryPath(gtDevicePath);
|
||||
|
||||
int fd = 0;
|
||||
std::string configFilePath = rootPortPath + '/' + "config";
|
||||
fd = this->openFunction(configFilePath.c_str(), O_RDWR);
|
||||
if (fd < 0) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
std::string cardBusPath = getPciCardBusDirectoryPath(gtDevicePath);
|
||||
ze_result_t result = pFsAccess->write(cardBusPath + '/' + "remove", "1");
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
if (diagnosticsReset) {
|
||||
NEO::sleep(std::chrono::seconds(30)); // Sleep for 30seconds to make sure that the config spaces of all devices are saved correctly after IFR
|
||||
} else {
|
||||
NEO::sleep(std::chrono::seconds(10)); // Sleep for 10seconds to make sure that the config spaces of all devices are saved correctly
|
||||
}
|
||||
|
||||
clearHPIE(fd);
|
||||
|
||||
uint8_t offset = PCI_BRIDGE_CONTROL; // Bridge control offset in Header of PCI config space
|
||||
uint8_t value = 0x00;
|
||||
uint8_t resetValue = 0x00;
|
||||
|
||||
this->preadFunction(fd, &value, 0x01, offset);
|
||||
resetValue = value | PCI_BRIDGE_CTL_BUS_RESET;
|
||||
this->pwriteFunction(fd, &resetValue, 0x01, offset);
|
||||
NEO::sleep(std::chrono::seconds(10)); // Sleep for 10seconds just to make sure the change is propagated.
|
||||
this->pwriteFunction(fd, &value, 0x01, offset);
|
||||
NEO::sleep(std::chrono::seconds(10)); // Sleep for 10seconds to make sure the change is propagated. before rescan is done.
|
||||
|
||||
result = pFsAccess->write(rootPortPath + '/' + "rescan", "1");
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
if (diagnosticsReset) {
|
||||
NEO::sleep(std::chrono::seconds(30)); // Sleep for 30seconds to make sure that the config spaces of all devices are saved correctly after IFR
|
||||
} else {
|
||||
NEO::sleep(std::chrono::seconds(10)); // Sleep for 10seconds, allows the rescan to complete on all devices attached to the root port.
|
||||
}
|
||||
|
||||
int ret = this->closeFunction(fd);
|
||||
if (ret < 0) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string LinuxSysmanImp::getAddressFromPath(std::string &rootPortPath) {
|
||||
size_t loc;
|
||||
loc = rootPortPath.find_last_of('/'); // we get the pci address of the root port from rootPortPath
|
||||
return rootPortPath.substr(loc + 1, std::string::npos);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSysmanImp::osColdReset() {
|
||||
const std::string slotPath("/sys/bus/pci/slots/"); // holds the directories matching to the number of slots in the PC
|
||||
std::string cardBusPath; // will hold the PCIe Root port directory path (the address of the PCIe slot).
|
||||
// will hold the absolute real path (not symlink) to the selected Device
|
||||
cardBusPath = getPciCardBusDirectoryPath(gtDevicePath); // e.g cardBusPath=/sys/devices/pci0000:89/0000:89:02.0/
|
||||
std::string rootAddress = getAddressFromPath(cardBusPath); // e.g rootAddress = 0000:8a:00.0
|
||||
|
||||
std::vector<std::string> dir;
|
||||
ze_result_t result = pFsAccess->listDirectory(slotPath, dir); // get list of slot directories from /sys/bus/pci/slots/
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &slot : dir) {
|
||||
std::string slotAddress;
|
||||
result = pFsAccess->read((slotPath + slot + "/address"), slotAddress); // extract slot address from the slot directory /sys/bus/pci/slots/<slot num>/address
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
if (slotAddress.compare(rootAddress) == 0) { // compare slot address to root port address
|
||||
result = pFsAccess->write((slotPath + slot + "/power"), "0"); // turn off power
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
NEO::sleep(std::chrono::milliseconds(100)); // Sleep for 100 milliseconds just to make sure, 1 ms is defined as part of spec
|
||||
result = pFsAccess->write((slotPath + slot + "/power"), "1"); // turn on power
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ZE_RESULT_ERROR_DEVICE_LOST; // incase the reset fails inform upper layers.
|
||||
}
|
||||
|
||||
OsSysman *OsSysman::create(SysmanDeviceImp *pParentSysmanDeviceImp) {
|
||||
LinuxSysmanImp *pLinuxSysmanImp = new LinuxSysmanImp(pParentSysmanDeviceImp);
|
||||
return static_cast<OsSysman *>(pLinuxSysmanImp);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
#include "shared/source/os_interface/linux/sys_calls.h"
|
||||
|
||||
#include "level_zero/sysman/source/linux/hw_device_id_linux.h"
|
||||
#include "level_zero/sysman/source/os_sysman.h"
|
||||
@@ -43,16 +44,31 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
|
||||
SysmanDeviceImp *getSysmanDeviceImp();
|
||||
uint32_t getSubDeviceCount() override;
|
||||
std::string getPciCardBusDirectoryPath(std::string realPciPath);
|
||||
static std::string getPciRootPortDirectoryPath(std::string realPciPath);
|
||||
PlatformMonitoringTech *getPlatformMonitoringTechAccess(uint32_t subDeviceId);
|
||||
PRODUCT_FAMILY getProductFamily() const { return pParentSysmanDeviceImp->getProductFamily(); }
|
||||
SysmanHwDeviceIdDrm *getSysmanHwDeviceId();
|
||||
NEO::Drm *getDrm();
|
||||
void releasePmtObject();
|
||||
void releaseSysmanDeviceResources();
|
||||
ze_result_t reInitSysmanDeviceResources();
|
||||
MOCKABLE_VIRTUAL void getPidFdsForOpenDevice(ProcfsAccess *, SysfsAccess *, const ::pid_t, std::vector<int> &);
|
||||
MOCKABLE_VIRTUAL ze_result_t osWarmReset();
|
||||
MOCKABLE_VIRTUAL ze_result_t osColdReset();
|
||||
ze_result_t gpuProcessCleanup();
|
||||
std::string getAddressFromPath(std::string &rootPortPath);
|
||||
decltype(&NEO::SysCalls::open) openFunction = NEO::SysCalls::open;
|
||||
decltype(&NEO::SysCalls::close) closeFunction = NEO::SysCalls::close;
|
||||
decltype(&NEO::SysCalls::pread) preadFunction = NEO::SysCalls::pread;
|
||||
decltype(&NEO::SysCalls::pwrite) pwriteFunction = NEO::SysCalls::pwrite;
|
||||
ze_result_t createPmtHandles();
|
||||
|
||||
SysmanDeviceImp *getParentSysmanDeviceImp() { return pParentSysmanDeviceImp; }
|
||||
std::string &getPciRootPath();
|
||||
std::string devicePciBdf = "";
|
||||
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
uint32_t rootDeviceIndex;
|
||||
bool diagnosticsReset = false;
|
||||
std::string gtDevicePath;
|
||||
|
||||
protected:
|
||||
FsAccess *pFsAccess = nullptr;
|
||||
@@ -62,6 +78,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
|
||||
uint32_t subDeviceCount = 0;
|
||||
FirmwareUtil *pFwUtilInterface = nullptr;
|
||||
PmuInterface *pPmuInterface = nullptr;
|
||||
std::string rootPath;
|
||||
void releaseFwUtilInterface();
|
||||
|
||||
private:
|
||||
@@ -69,6 +86,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
|
||||
SysmanDeviceImp *pParentSysmanDeviceImp = nullptr;
|
||||
static const std::string deviceDir;
|
||||
void createFwUtilInterface();
|
||||
void clearHPIE(int fd);
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
|
||||
14
level_zero/sysman/source/ras/CMakeLists.txt
Normal file
14
level_zero/sysman/source/ras/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Copyright (C) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ras.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ras.cpp
|
||||
)
|
||||
|
||||
add_subdirectories()
|
||||
51
level_zero/sysman/source/ras/ras.cpp
Normal file
51
level_zero/sysman/source/ras/ras.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/ras/ras.h"
|
||||
|
||||
#include "shared/source/helpers/basic_math.h"
|
||||
|
||||
#include "level_zero/sysman/source/os_sysman.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
void RasHandleContext::releaseRasHandles() {
|
||||
for (Ras *pRas : handleList) {
|
||||
delete pRas;
|
||||
}
|
||||
handleList.clear();
|
||||
}
|
||||
|
||||
RasHandleContext::~RasHandleContext() {
|
||||
releaseRasHandles();
|
||||
}
|
||||
|
||||
void RasHandleContext::init(uint32_t subDeviceCount) {
|
||||
}
|
||||
|
||||
ze_result_t RasHandleContext::rasGet(uint32_t *pCount,
|
||||
zes_ras_handle_t *phRas) {
|
||||
std::call_once(initRasOnce, [this]() {
|
||||
this->init(pOsSysman->getSubDeviceCount());
|
||||
this->rasInitDone = true;
|
||||
});
|
||||
uint32_t handleListSize = static_cast<uint32_t>(handleList.size());
|
||||
uint32_t numToCopy = std::min(*pCount, handleListSize);
|
||||
if (0 == *pCount || *pCount > handleListSize) {
|
||||
*pCount = handleListSize;
|
||||
}
|
||||
if (nullptr != phRas) {
|
||||
for (uint32_t i = 0; i < numToCopy; i++) {
|
||||
phRas[i] = handleList[i]->toHandle();
|
||||
}
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
58
level_zero/sysman/source/ras/ras.h
Normal file
58
level_zero/sysman/source/ras/ras.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "level_zero/api/sysman/zes_handles_struct.h"
|
||||
#include "level_zero/sysman/source/sysman_device.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
struct OsSysman;
|
||||
|
||||
class Ras : _zes_ras_handle_t {
|
||||
public:
|
||||
virtual ze_result_t rasGetProperties(zes_ras_properties_t *pProperties) = 0;
|
||||
virtual ze_result_t rasGetConfig(zes_ras_config_t *pConfig) = 0;
|
||||
virtual ze_result_t rasSetConfig(const zes_ras_config_t *pConfig) = 0;
|
||||
virtual ze_result_t rasGetState(zes_ras_state_t *pState, ze_bool_t clear) = 0;
|
||||
|
||||
static Ras *fromHandle(zes_ras_handle_t handle) {
|
||||
return static_cast<Ras *>(handle);
|
||||
}
|
||||
inline zes_ras_handle_t toHandle() { return this; }
|
||||
bool isRasErrorSupported = false;
|
||||
zes_ras_error_type_t rasErrorType{};
|
||||
};
|
||||
|
||||
struct RasHandleContext {
|
||||
RasHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
|
||||
MOCKABLE_VIRTUAL ~RasHandleContext();
|
||||
|
||||
MOCKABLE_VIRTUAL void init(uint32_t subDeviceCount);
|
||||
void releaseRasHandles();
|
||||
|
||||
ze_result_t rasGet(uint32_t *pCount, zes_ras_handle_t *phRas);
|
||||
|
||||
OsSysman *pOsSysman = nullptr;
|
||||
std::vector<Ras *> handleList = {};
|
||||
bool isRasInitDone() {
|
||||
return rasInitDone;
|
||||
}
|
||||
|
||||
private:
|
||||
void createHandle(zes_ras_error_type_t type, ze_device_handle_t deviceHandle);
|
||||
std::once_flag initRasOnce;
|
||||
bool rasInitDone = false;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -60,10 +60,39 @@ ze_result_t SysmanDevice::schedulerGet(zes_device_handle_t hDevice, uint32_t *pC
|
||||
return pSysmanDevice->schedulerGet(pCount, phScheduler);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::rasGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_ras_handle_t *phRas) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->rasGet(pCount, phRas);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::diagnosticsGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_diag_handle_t *phDiagnostics) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->diagnosticsGet(pCount, phDiagnostics);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::firmwareGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_firmware_handle_t *phFirmware) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->firmwareGet(pCount, phFirmware);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::deviceGetProperties(zes_device_handle_t hDevice, zes_device_properties_t *pProperties) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->deviceGetProperties(pProperties);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::processesGetState(zes_device_handle_t hDevice, uint32_t *pCount, zes_process_state_t *pProcesses) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->processesGetState(pCount, pProcesses);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDevice::deviceReset(zes_device_handle_t hDevice, ze_bool_t force) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->deviceReset(force);
|
||||
}
|
||||
ze_result_t SysmanDevice::deviceGetState(zes_device_handle_t hDevice, zes_device_state_t *pState) {
|
||||
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
|
||||
return pSysmanDevice->deviceGetState(pState);
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
|
||||
#include "level_zero/core/source/device/device.h"
|
||||
#include "level_zero/sysman/source/diagnostics/diagnostics.h"
|
||||
#include "level_zero/sysman/source/engine/engine.h"
|
||||
#include "level_zero/sysman/source/fabric_port/fabric_port.h"
|
||||
#include "level_zero/sysman/source/firmware/firmware.h"
|
||||
#include "level_zero/sysman/source/frequency/frequency.h"
|
||||
#include "level_zero/sysman/source/global_operations/global_operations.h"
|
||||
#include "level_zero/sysman/source/memory/memory.h"
|
||||
#include "level_zero/sysman/source/power/power.h"
|
||||
#include "level_zero/sysman/source/ras/ras.h"
|
||||
#include "level_zero/sysman/source/scheduler/scheduler.h"
|
||||
#include <level_zero/ze_api.h>
|
||||
#include <level_zero/zes_api.h>
|
||||
@@ -35,6 +38,7 @@ struct SysmanDevice : _ze_device_handle_t {
|
||||
virtual ze_result_t powerGetCardDomain(zes_pwr_handle_t *phPower) = 0;
|
||||
static ze_result_t fabricPortGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort);
|
||||
virtual ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) = 0;
|
||||
|
||||
static ze_result_t memoryGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_mem_handle_t *phMemory);
|
||||
virtual ze_result_t memoryGet(uint32_t *pCount, zes_mem_handle_t *phMemory) = 0;
|
||||
|
||||
@@ -49,6 +53,24 @@ struct SysmanDevice : _ze_device_handle_t {
|
||||
|
||||
static ze_result_t firmwareGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_firmware_handle_t *phFirmware);
|
||||
virtual ze_result_t firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) = 0;
|
||||
|
||||
static ze_result_t diagnosticsGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_diag_handle_t *phDiagnostics);
|
||||
virtual ze_result_t diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phDiagnostics) = 0;
|
||||
|
||||
static ze_result_t rasGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_ras_handle_t *phRas);
|
||||
virtual ze_result_t rasGet(uint32_t *pCount, zes_ras_handle_t *phRas) = 0;
|
||||
|
||||
static ze_result_t deviceReset(zes_device_handle_t hDevice, ze_bool_t force);
|
||||
virtual ze_result_t deviceReset(ze_bool_t force) = 0;
|
||||
|
||||
static ze_result_t deviceGetProperties(zes_device_handle_t hDevice, zes_device_properties_t *pProperties);
|
||||
virtual ze_result_t deviceGetProperties(zes_device_properties_t *pProperties) = 0;
|
||||
|
||||
static ze_result_t deviceGetState(zes_device_handle_t hDevice, zes_device_state_t *pState);
|
||||
virtual ze_result_t deviceGetState(zes_device_state_t *pState) = 0;
|
||||
|
||||
static ze_result_t processesGetState(zes_device_handle_t hDevice, uint32_t *pCount, zes_process_state_t *pProcesses);
|
||||
virtual ze_result_t processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) = 0;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "shared/source/helpers/debug_helpers.h"
|
||||
|
||||
#include "level_zero/sysman/source/global_operations/global_operations_imp.h"
|
||||
#include "level_zero/sysman/source/os_sysman.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -28,18 +29,24 @@ SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment
|
||||
pFrequencyHandleContext = new FrequencyHandleContext(pOsSysman);
|
||||
pSchedulerHandleContext = new SchedulerHandleContext(pOsSysman);
|
||||
pFirmwareHandleContext = new FirmwareHandleContext(pOsSysman);
|
||||
pRasHandleContext = new RasHandleContext(pOsSysman);
|
||||
pDiagnosticsHandleContext = new DiagnosticsHandleContext(pOsSysman);
|
||||
pGlobalOperations = new GlobalOperationsImp(pOsSysman);
|
||||
}
|
||||
|
||||
SysmanDeviceImp::~SysmanDeviceImp() {
|
||||
executionEnvironment->decRefInternal();
|
||||
freeResource(pSchedulerHandleContext);
|
||||
freeResource(pPowerHandleContext);
|
||||
freeResource(pEngineHandleContext);
|
||||
freeResource(pFabricPortHandleContext);
|
||||
freeResource(pMemoryHandleContext);
|
||||
freeResource(pFrequencyHandleContext);
|
||||
freeResource(pGlobalOperations);
|
||||
freeResource(pDiagnosticsHandleContext);
|
||||
freeResource(pRasHandleContext);
|
||||
freeResource(pFirmwareHandleContext);
|
||||
freeResource(pSchedulerHandleContext);
|
||||
freeResource(pFrequencyHandleContext);
|
||||
freeResource(pEngineHandleContext);
|
||||
freeResource(pPowerHandleContext);
|
||||
freeResource(pMemoryHandleContext);
|
||||
freeResource(pFabricPortHandleContext);
|
||||
freeResource(pOsSysman);
|
||||
executionEnvironment->decRefInternal();
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::init() {
|
||||
@@ -50,6 +57,22 @@ ze_result_t SysmanDeviceImp::init() {
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::deviceGetProperties(zes_device_properties_t *pProperties) {
|
||||
return pGlobalOperations->deviceGetProperties(pProperties);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) {
|
||||
return pGlobalOperations->processesGetState(pCount, pProcesses);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::deviceReset(ze_bool_t force) {
|
||||
return pGlobalOperations->reset(force);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::deviceGetState(zes_device_state_t *pState) {
|
||||
return pGlobalOperations->deviceGetState(pState);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) {
|
||||
return pFabricPortHandleContext->fabricPortGet(pCount, phPort);
|
||||
}
|
||||
@@ -78,9 +101,17 @@ ze_result_t SysmanDeviceImp::schedulerGet(uint32_t *pCount, zes_sched_handle_t *
|
||||
return pSchedulerHandleContext->schedulerGet(pCount, phScheduler);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::rasGet(uint32_t *pCount, zes_ras_handle_t *phRas) {
|
||||
return pRasHandleContext->rasGet(pCount, phRas);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) {
|
||||
return pFirmwareHandleContext->firmwareGet(pCount, phFirmware);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phDiagnostics) {
|
||||
return pDiagnosticsHandleContext->diagnosticsGet(pCount, phDiagnostics);
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
|
||||
@@ -41,20 +41,28 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
|
||||
NEO::ExecutionEnvironment *getExecutionEnvironment() const { return executionEnvironment; }
|
||||
uint32_t getRootDeviceIndex() const { return rootDeviceIndex; }
|
||||
|
||||
GlobalOperations *pGlobalOperations = nullptr;
|
||||
FabricPortHandleContext *pFabricPortHandleContext = nullptr;
|
||||
MemoryHandleContext *pMemoryHandleContext = nullptr;
|
||||
EngineHandleContext *pEngineHandleContext = nullptr;
|
||||
SchedulerHandleContext *pSchedulerHandleContext = nullptr;
|
||||
FirmwareHandleContext *pFirmwareHandleContext = nullptr;
|
||||
RasHandleContext *pRasHandleContext = nullptr;
|
||||
DiagnosticsHandleContext *pDiagnosticsHandleContext = nullptr;
|
||||
FrequencyHandleContext *pFrequencyHandleContext = nullptr;
|
||||
|
||||
ze_result_t memoryGet(uint32_t *pCount, zes_mem_handle_t *phMemory) override;
|
||||
ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) override;
|
||||
ze_result_t engineGet(uint32_t *pCount, zes_engine_handle_t *phEngine) override;
|
||||
ze_result_t schedulerGet(uint32_t *pCount, zes_sched_handle_t *phScheduler) override;
|
||||
|
||||
FrequencyHandleContext *pFrequencyHandleContext = nullptr;
|
||||
ze_result_t frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency) override;
|
||||
ze_result_t firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) override;
|
||||
ze_result_t rasGet(uint32_t *pCount, zes_ras_handle_t *phRas) override;
|
||||
ze_result_t diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phFirmware) override;
|
||||
ze_result_t deviceGetProperties(zes_device_properties_t *pProperties) override;
|
||||
ze_result_t processesGetState(uint32_t *pCount, zes_process_state_t *pProcesses) override;
|
||||
ze_result_t deviceReset(ze_bool_t force) override;
|
||||
ze_result_t deviceGetState(zes_device_state_t *pState) override;
|
||||
|
||||
private:
|
||||
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
@@ -6,16 +6,13 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "level_zero/api/sysman/zes_handles_struct.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct _zes_diag_handle_t {
|
||||
virtual ~_zes_diag_handle_t() = default;
|
||||
};
|
||||
|
||||
namespace L0 {
|
||||
|
||||
struct OsSysman;
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "level_zero/api/sysman/zes_handles_struct.h"
|
||||
#include "level_zero/core/source/device/device.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
struct _zes_ras_handle_t {
|
||||
virtual ~_zes_ras_handle_t() = default;
|
||||
};
|
||||
|
||||
namespace L0 {
|
||||
|
||||
struct OsSysman;
|
||||
|
||||
Reference in New Issue
Block a user