Added support for Standby APIs

- Added support for the Standby APIs in the new sysman design.
- Added ULTs for the Standby APIs in the new sysman design.

Related-To: LOCI-4097

Signed-off-by: Bari, Pratik <pratik.bari@intel.com>
This commit is contained in:
Bari, Pratik
2023-04-01 18:00:23 +00:00
committed by Compute-Runtime-Automation
parent e056082710
commit f8623fadaf
22 changed files with 966 additions and 12 deletions

View File

@ -43,3 +43,7 @@ struct _zes_diag_handle_t {
struct _zes_ras_handle_t {
virtual ~_zes_ras_handle_t() = default;
};
struct _zes_standby_handle_t {
virtual ~_zes_standby_handle_t() = default;
};

View File

@ -519,25 +519,41 @@ ze_result_t zesDeviceEnumStandbyDomains(
zes_device_handle_t hDevice,
uint32_t *pCount,
zes_standby_handle_t *phStandby) {
return L0::SysmanDevice::standbyGet(hDevice, pCount, phStandby);
if (L0::sysmanInitFromCore) {
return L0::SysmanDevice::standbyGet(hDevice, pCount, phStandby);
} else {
return L0::Sysman::SysmanDevice::standbyGet(hDevice, pCount, phStandby);
}
}
ze_result_t zesStandbyGetProperties(
zes_standby_handle_t hStandby,
zes_standby_properties_t *pProperties) {
return L0::Standby::fromHandle(hStandby)->standbyGetProperties(pProperties);
if (L0::sysmanInitFromCore) {
return L0::Standby::fromHandle(hStandby)->standbyGetProperties(pProperties);
} else {
return L0::Sysman::Standby::fromHandle(hStandby)->standbyGetProperties(pProperties);
}
}
ze_result_t zesStandbyGetMode(
zes_standby_handle_t hStandby,
zes_standby_promo_mode_t *pMode) {
return L0::Standby::fromHandle(hStandby)->standbyGetMode(pMode);
if (L0::sysmanInitFromCore) {
return L0::Standby::fromHandle(hStandby)->standbyGetMode(pMode);
} else {
return L0::Sysman::Standby::fromHandle(hStandby)->standbyGetMode(pMode);
}
}
ze_result_t zesStandbySetMode(
zes_standby_handle_t hStandby,
zes_standby_promo_mode_t mode) {
return L0::Standby::fromHandle(hStandby)->standbySetMode(mode);
if (L0::sysmanInitFromCore) {
return L0::Standby::fromHandle(hStandby)->standbySetMode(mode);
} else {
return L0::Sysman::Standby::fromHandle(hStandby)->standbySetMode(mode);
}
}
ze_result_t zesDeviceEnumFirmwares(

View File

@ -0,0 +1,17 @@
#
# 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}/os_standby.h
${CMAKE_CURRENT_SOURCE_DIR}/standby.cpp
${CMAKE_CURRENT_SOURCE_DIR}/standby.h
${CMAKE_CURRENT_SOURCE_DIR}/standby_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/standby_imp.h
)
add_subdirectories()

View File

@ -0,0 +1,14 @@
#
# 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_standby_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_standby_imp.h
)
endif()

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/standby/linux/os_standby_imp.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
namespace L0 {
namespace Sysman {
ze_result_t LinuxStandbyImp::osStandbyGetProperties(zes_standby_properties_t &properties) {
properties.pNext = nullptr;
properties.type = ZES_STANDBY_TYPE_GLOBAL;
properties.onSubdevice = isSubdevice;
properties.subdeviceId = subdeviceId;
return ZE_RESULT_SUCCESS;
}
bool LinuxStandbyImp::isStandbySupported(void) {
auto rel = pSysfsAccess->canRead(standbyModeFile);
if (ZE_RESULT_SUCCESS == rel) {
return true;
} else {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <can't read file %s> <error: 0x%x>\n", __func__, standbyModeFile.c_str(), rel);
return false;
}
return true;
}
ze_result_t LinuxStandbyImp::getMode(zes_standby_promo_mode_t &mode) {
int currentMode = -1;
ze_result_t result = pSysfsAccess->read(standbyModeFile, currentMode);
if (ZE_RESULT_SUCCESS != result) {
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to read file %s> <result: 0x%x>\n", __func__, standbyModeFile.c_str(), result);
return result;
}
if (standbyModeDefault == currentMode) {
mode = ZES_STANDBY_PROMO_MODE_DEFAULT;
} else if (standbyModeNever == currentMode) {
mode = ZES_STANDBY_PROMO_MODE_NEVER;
} else {
result = ZE_RESULT_ERROR_UNKNOWN;
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <unknown or internal error occured> <currentMode: %d & result: 0x%x>\n", __func__, currentMode, result);
}
return result;
}
ze_result_t LinuxStandbyImp::setMode(zes_standby_promo_mode_t mode) {
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
if (ZES_STANDBY_PROMO_MODE_DEFAULT == mode) {
result = pSysfsAccess->write(standbyModeFile, standbyModeDefault);
} else {
result = pSysfsAccess->write(standbyModeFile, standbyModeNever);
}
if (ZE_RESULT_ERROR_NOT_AVAILABLE == result) {
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <Unsupported feature> <result: 0x%x>\n", __func__, result);
}
return result;
}
void LinuxStandbyImp::init() {
const std::string baseDir = "gt/gt" + std::to_string(subdeviceId) + "/";
if (pSysfsAccess->directoryExists(baseDir)) {
standbyModeFile = baseDir + "rc6_enable";
} else {
standbyModeFile = "power/rc6_enable";
}
}
LinuxStandbyImp::LinuxStandbyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : isSubdevice(onSubdevice), subdeviceId(subdeviceId) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
init();
}
std::unique_ptr<OsStandby> OsStandby::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
std::unique_ptr<LinuxStandbyImp> pLinuxStandbyImp = std::make_unique<LinuxStandbyImp>(pOsSysman, onSubdevice, subdeviceId);
return pLinuxStandbyImp;
}
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,44 @@
/*
* 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/linux/fs_access.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
#include "level_zero/sysman/source/standby/os_standby.h"
#include "level_zero/sysman/source/standby/standby_imp.h"
namespace L0 {
namespace Sysman {
class LinuxStandbyImp : public OsStandby, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getMode(zes_standby_promo_mode_t &mode) override;
ze_result_t setMode(zes_standby_promo_mode_t mode) override;
ze_result_t osStandbyGetProperties(zes_standby_properties_t &properties) override;
bool isStandbySupported(void) override;
LinuxStandbyImp() = default;
LinuxStandbyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
~LinuxStandbyImp() override = default;
protected:
SysfsAccess *pSysfsAccess = nullptr;
private:
std::string standbyModeFile;
static const int standbyModeDefault = 1;
static const int standbyModeNever = 0;
bool isSubdevice = false;
uint32_t subdeviceId = 0;
void init();
};
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,31 @@
/*
* 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 <memory>
namespace L0 {
namespace Sysman {
class OsStandby {
public:
virtual ze_result_t getMode(zes_standby_promo_mode_t &mode) = 0;
virtual ze_result_t setMode(zes_standby_promo_mode_t mode) = 0;
virtual ze_result_t osStandbyGetProperties(zes_standby_properties_t &properties) = 0;
virtual bool isStandbySupported(void) = 0;
static std::unique_ptr<OsStandby> create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
virtual ~OsStandby() {}
};
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/standby/standby.h"
#include "shared/source/helpers/basic_math.h"
#include "level_zero/sysman/source/standby/standby_imp.h"
namespace L0 {
namespace Sysman {
StandbyHandleContext::~StandbyHandleContext() = default;
void StandbyHandleContext::createHandle(bool onSubdevice, uint32_t subDeviceId) {
std::unique_ptr<Standby> pStandby = std::make_unique<StandbyImp>(pOsSysman, onSubdevice, subDeviceId);
if (pStandby->isStandbyEnabled == true) {
handleList.push_back(std::move(pStandby));
}
}
ze_result_t StandbyHandleContext::init(uint32_t subDeviceCount) {
if (subDeviceCount > 0) {
for (uint32_t subDeviceId = 0; subDeviceId < subDeviceCount; subDeviceId++) {
createHandle(true, subDeviceId);
}
} else {
createHandle(false, 0);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t StandbyHandleContext::standbyGet(uint32_t *pCount, zes_standby_handle_t *phStandby) {
std::call_once(initStandbyOnce, [this]() {
this->init(pOsSysman->getSubDeviceCount());
});
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 != phStandby) {
for (uint32_t i = 0; i < numToCopy; i++) {
phStandby[i] = handleList[i]->toStandbyHandle();
}
}
return ZE_RESULT_SUCCESS;
}
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,53 @@
/*
* 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 <memory>
#include <mutex>
#include <vector>
namespace L0 {
namespace Sysman {
struct OsSysman;
class Standby : _zes_standby_handle_t {
public:
~Standby() override {}
virtual ze_result_t standbyGetProperties(zes_standby_properties_t *pProperties) = 0;
virtual ze_result_t standbyGetMode(zes_standby_promo_mode_t *pMode) = 0;
virtual ze_result_t standbySetMode(const zes_standby_promo_mode_t mode) = 0;
inline zes_standby_handle_t toStandbyHandle() { return this; }
static Standby *fromHandle(zes_standby_handle_t handle) {
return static_cast<Standby *>(handle);
}
bool isStandbyEnabled = false;
};
struct StandbyHandleContext {
StandbyHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
~StandbyHandleContext();
ze_result_t init(uint32_t subDeviceCount);
ze_result_t standbyGet(uint32_t *pCount, zes_standby_handle_t *phStandby);
OsSysman *pOsSysman;
std::vector<std::unique_ptr<Standby>> handleList = {};
private:
void createHandle(bool onSubdevice, uint32_t subDeviceId);
std::once_flag initStandbyOnce;
};
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "standby_imp.h"
#include "shared/source/helpers/debug_helpers.h"
#include "level_zero/sysman/source/sysman_device_imp.h"
namespace L0 {
namespace Sysman {
ze_result_t StandbyImp::standbyGetProperties(zes_standby_properties_t *pProperties) {
*pProperties = standbyProperties;
return ZE_RESULT_SUCCESS;
}
ze_result_t StandbyImp::standbyGetMode(zes_standby_promo_mode_t *pMode) {
return pOsStandby->getMode(*pMode);
}
ze_result_t StandbyImp::standbySetMode(const zes_standby_promo_mode_t mode) {
return pOsStandby->setMode(mode);
}
void StandbyImp::init() {
pOsStandby->osStandbyGetProperties(standbyProperties);
this->isStandbyEnabled = pOsStandby->isStandbySupported();
}
StandbyImp::StandbyImp(OsSysman *pOsSysman, bool onSubdevice, uint32_t subDeviceId) {
pOsStandby = OsStandby::create(pOsSysman, onSubdevice, subDeviceId);
init();
}
StandbyImp::~StandbyImp() {}
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,36 @@
/*
* 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/standby/os_standby.h"
#include "level_zero/sysman/source/standby/standby.h"
#include <level_zero/zes_api.h>
namespace L0 {
namespace Sysman {
class StandbyImp : public Standby, NEO::NonCopyableOrMovableClass {
public:
ze_result_t standbyGetProperties(zes_standby_properties_t *pProperties) override;
ze_result_t standbyGetMode(zes_standby_promo_mode_t *pMode) override;
ze_result_t standbySetMode(const zes_standby_promo_mode_t mode) override;
StandbyImp() = default;
StandbyImp(OsSysman *pOsSysman, bool onSubdevice, uint32_t subDeviceId);
~StandbyImp() override;
std::unique_ptr<OsStandby> pOsStandby = nullptr;
void init();
private:
zes_standby_properties_t standbyProperties = {};
};
} // namespace Sysman
} // namespace L0

View File

@ -0,0 +1,13 @@
#
# 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_standby_imp.cpp
)
endif()

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/standby/os_standby.h"
namespace L0 {
namespace Sysman {
class WddmStandbyImp : public OsStandby {
public:
ze_result_t getMode(zes_standby_promo_mode_t &mode) override;
ze_result_t setMode(zes_standby_promo_mode_t mode) override;
ze_result_t osStandbyGetProperties(zes_standby_properties_t &properties) override;
bool isStandbySupported(void) override;
};
ze_result_t WddmStandbyImp::setMode(zes_standby_promo_mode_t mode) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmStandbyImp::getMode(zes_standby_promo_mode_t &mode) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmStandbyImp::osStandbyGetProperties(zes_standby_properties_t &properties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
bool WddmStandbyImp::isStandbySupported(void) {
return false;
}
std::unique_ptr<OsStandby> OsStandby::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
std::unique_ptr<WddmStandbyImp> pWddmStandbyImp = std::make_unique<WddmStandbyImp>();
return pWddmStandbyImp;
}
} // namespace Sysman
} // namespace L0

View File

@ -94,5 +94,10 @@ ze_result_t SysmanDevice::deviceGetState(zes_device_handle_t hDevice, zes_device
return pSysmanDevice->deviceGetState(pState);
}
ze_result_t SysmanDevice::standbyGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_standby_handle_t *phStandby) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->standbyGet(pCount, phStandby);
}
} // namespace Sysman
} // namespace L0

View File

@ -19,6 +19,7 @@
#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/sysman/source/standby/standby.h"
#include <level_zero/ze_api.h>
#include <level_zero/zes_api.h>
@ -71,6 +72,9 @@ struct SysmanDevice : _ze_device_handle_t {
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;
static ze_result_t standbyGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_standby_handle_t *phStandby);
virtual ze_result_t standbyGet(uint32_t *pCount, zes_standby_handle_t *phStandby) = 0;
};
} // namespace Sysman

View File

@ -32,6 +32,7 @@ SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment
pRasHandleContext = new RasHandleContext(pOsSysman);
pDiagnosticsHandleContext = new DiagnosticsHandleContext(pOsSysman);
pGlobalOperations = new GlobalOperationsImp(pOsSysman);
pStandbyHandleContext = new StandbyHandleContext(pOsSysman);
}
SysmanDeviceImp::~SysmanDeviceImp() {
@ -45,6 +46,7 @@ SysmanDeviceImp::~SysmanDeviceImp() {
freeResource(pPowerHandleContext);
freeResource(pMemoryHandleContext);
freeResource(pFabricPortHandleContext);
freeResource(pStandbyHandleContext);
freeResource(pOsSysman);
executionEnvironment->decRefInternal();
}
@ -113,5 +115,9 @@ ze_result_t SysmanDeviceImp::diagnosticsGet(uint32_t *pCount, zes_diag_handle_t
return pDiagnosticsHandleContext->diagnosticsGet(pCount, phDiagnostics);
}
ze_result_t SysmanDeviceImp::standbyGet(uint32_t *pCount, zes_standby_handle_t *phStandby) {
return pStandbyHandleContext->standbyGet(pCount, phStandby);
}
} // namespace Sysman
} // namespace L0

View File

@ -28,10 +28,6 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
ze_result_t init();
OsSysman *pOsSysman = nullptr;
PowerHandleContext *pPowerHandleContext = nullptr;
ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) override;
ze_result_t powerGetCardDomain(zes_pwr_handle_t *phPower) override;
const NEO::RootDeviceEnvironment &getRootDeviceEnvironment() const {
return *executionEnvironment->rootDeviceEnvironments[rootDeviceIndex];
@ -42,6 +38,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
uint32_t getRootDeviceIndex() const { return rootDeviceIndex; }
GlobalOperations *pGlobalOperations = nullptr;
PowerHandleContext *pPowerHandleContext = nullptr;
FabricPortHandleContext *pFabricPortHandleContext = nullptr;
MemoryHandleContext *pMemoryHandleContext = nullptr;
EngineHandleContext *pEngineHandleContext = nullptr;
@ -50,7 +47,10 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
RasHandleContext *pRasHandleContext = nullptr;
DiagnosticsHandleContext *pDiagnosticsHandleContext = nullptr;
FrequencyHandleContext *pFrequencyHandleContext = nullptr;
StandbyHandleContext *pStandbyHandleContext = nullptr;
ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) override;
ze_result_t powerGetCardDomain(zes_pwr_handle_t *phPower) override;
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;
@ -63,6 +63,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
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;
ze_result_t standbyGet(uint32_t *pCount, zes_standby_handle_t *phStandby) override;
private:
NEO::ExecutionEnvironment *executionEnvironment = nullptr;

View File

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

View File

@ -0,0 +1,21 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_TESTS_SYSMAN_STANDBY_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
)
list(APPEND L0_TESTS_SYSMAN_STANDBY_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_sysman_standby.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_sysfs_standby.h
)
if(UNIX)
target_sources(${TARGET_NAME}
PRIVATE
${L0_TESTS_SYSMAN_STANDBY_LINUX}
)
endif()

View File

@ -0,0 +1,108 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/test/common/test_macros/mock_method_macros.h"
#include "level_zero/sysman/source/standby/linux/os_standby_imp.h"
namespace L0 {
namespace ult {
const std::string standbyModeFile("gt/gt0/rc6_enable");
const std::string standbyModeFile1("gt/gt1/rc6_enable");
const std::string standbyModeFileLegacy("power/rc6_enable");
struct MockStandbySysfsAccess : public L0::Sysman::SysfsAccess {
ze_result_t mockError = ZE_RESULT_SUCCESS;
int mockStandbyMode = -1;
bool isStandbyModeFileAvailable = true;
::mode_t mockStandbyFileMode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR;
ADDMETHOD_NOBASE(directoryExists, bool, true, (const std::string path));
ze_result_t read(const std::string file, int &val) override {
return getVal(file, val);
}
ze_result_t write(const std::string file, int val) override {
return setVal(file, val);
}
ze_result_t canRead(const std::string file) override {
return getCanReadStatus(file);
}
ze_result_t getCanReadStatus(const std::string file) {
if (isFileAccessible(file) == true) {
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t getVal(const std::string file, int &val) {
if (mockError != ZE_RESULT_SUCCESS) {
return mockError;
}
if ((isFileAccessible(file) == true) &&
(mockStandbyFileMode & S_IRUSR) != 0) {
val = mockStandbyMode;
return ZE_RESULT_SUCCESS;
}
if (isStandbyModeFileAvailable == false) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
if ((mockStandbyFileMode & S_IRUSR) == 0) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
return ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t setVal(const std::string file, const int val) {
if ((isFileAccessible(file) == true) &&
(mockStandbyFileMode & S_IWUSR) != 0) {
mockStandbyMode = val;
return ZE_RESULT_SUCCESS;
}
if (isFileAccessible(file) == false) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
if ((mockStandbyFileMode & S_IWUSR) == 0) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
return ZE_RESULT_ERROR_UNKNOWN;
}
void setValReturnError(ze_result_t error) {
mockError = error;
}
MockStandbySysfsAccess() = default;
~MockStandbySysfsAccess() override = default;
private:
bool isFileAccessible(const std::string file) {
if (((file.compare(standbyModeFile) == 0) || (file.compare(standbyModeFile1) == 0) || (file.compare(standbyModeFileLegacy) == 0)) && (isStandbyModeFileAvailable == true)) {
return true;
}
return false;
}
};
class PublicLinuxStandbyImp : public L0::Sysman::LinuxStandbyImp {
public:
PublicLinuxStandbyImp(L0::Sysman::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : L0::Sysman::LinuxStandbyImp(pOsSysman, onSubdevice, subdeviceId) {}
using L0::Sysman::LinuxStandbyImp::pSysfsAccess;
};
} // namespace ult
} // namespace L0

View File

@ -0,0 +1,337 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h"
#include "level_zero/sysman/test/unit_tests/sources/standby/linux/mock_sysfs_standby.h"
namespace L0 {
namespace ult {
constexpr int standbyModeDefault = 1;
constexpr int standbyModeNever = 0;
constexpr int standbyModeInvalid = 0xff;
constexpr uint32_t mockHandleCount = 1u;
uint32_t mockSubDeviceHandleCount = 0u;
class ZesStandbyFixture : public SysmanDeviceFixture {
protected:
L0::Sysman::SysmanDevice *device = nullptr;
std::unique_ptr<MockStandbySysfsAccess> ptestSysfsAccess;
zes_standby_handle_t hSysmanStandby = {};
L0::Sysman::SysfsAccess *pOriginalSysfsAccess = nullptr;
void SetUp() override {
SysmanDeviceFixture::SetUp();
device = pSysmanDevice;
ptestSysfsAccess = std::make_unique<MockStandbySysfsAccess>();
pOriginalSysfsAccess = pLinuxSysmanImp->pSysfsAccess;
pLinuxSysmanImp->pSysfsAccess = ptestSysfsAccess.get();
ptestSysfsAccess->setVal(standbyModeFile, standbyModeDefault);
pSysmanDeviceImp->pStandbyHandleContext->handleList.clear();
}
void TearDown() override {
pLinuxSysmanImp->pSysfsAccess = pOriginalSysfsAccess;
SysmanDeviceFixture::TearDown();
}
std::vector<zes_standby_handle_t> getStandbyHandles(uint32_t count) {
std::vector<zes_standby_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumStandbyDomains(device, &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
TEST_F(ZesStandbyFixture, GivenStandbyModeFilesNotAvailableWhenCallingEnumerateThenSuccessResultAndZeroCountIsReturned) {
uint32_t count = 0;
ptestSysfsAccess->isStandbyModeFileAvailable = false;
ze_result_t result = zesDeviceEnumStandbyDomains(device, &count, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, 0u);
}
TEST_F(ZesStandbyFixture, GivenComponentCountZeroWhenCallingzesStandbyGetThenNonZeroCountIsReturnedAndVerifyzesStandbyGetCallSucceeds) {
std::vector<zes_standby_handle_t> standbyHandle = {};
uint32_t count = 0;
ze_result_t result = zesDeviceEnumStandbyDomains(device, &count, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, mockHandleCount);
uint32_t testCount = count + 1;
result = zesDeviceEnumStandbyDomains(device, &testCount, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(testCount, count);
standbyHandle.resize(count);
result = zesDeviceEnumStandbyDomains(device, &count, standbyHandle.data());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, standbyHandle.data());
EXPECT_EQ(count, mockHandleCount);
auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount();
ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true;
uint32_t subdeviceId = 0;
std::unique_ptr<L0::Sysman::StandbyImp> ptestStandbyImp = std::make_unique<L0::Sysman::StandbyImp>(pSysmanDeviceImp->pStandbyHandleContext->pOsSysman, onSubdevice, subdeviceId);
count = 0;
pSysmanDeviceImp->pStandbyHandleContext->handleList.push_back(std::move(ptestStandbyImp));
result = zesDeviceEnumStandbyDomains(device, &count, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, mockHandleCount + 1);
testCount = count + 1;
standbyHandle.resize(testCount);
result = zesDeviceEnumStandbyDomains(device, &testCount, standbyHandle.data());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, standbyHandle.data());
EXPECT_EQ(testCount, mockHandleCount + 1);
pSysmanDeviceImp->pStandbyHandleContext->handleList.pop_back();
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetPropertiesThenVerifyzesStandbyGetPropertiesCallSucceeds) {
zes_standby_properties_t properties = {};
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetProperties(hSysmanStandby, &properties));
EXPECT_EQ(nullptr, properties.pNext);
EXPECT_EQ(ZES_STANDBY_TYPE_GLOBAL, properties.type);
EXPECT_FALSE(properties.onSubdevice);
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetModeThenVerifyzesStandbyGetModeCallSucceedsForDefaultMode) {
zes_standby_promo_mode_t mode = {};
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_DEFAULT, mode);
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetModeThenVerifyzesStandbyGetModeCallSucceedsForNeverMode) {
zes_standby_promo_mode_t mode = {};
ptestSysfsAccess->setVal(standbyModeFile, standbyModeNever);
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_NEVER, mode);
}
}
TEST_F(ZesStandbyFixture, GivenInvalidStandbyFileWhenReadisCalledThenExpectFailure) {
zes_standby_promo_mode_t mode = {};
ptestSysfsAccess->setValReturnError(ZE_RESULT_ERROR_NOT_AVAILABLE);
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
EXPECT_NE(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetModeThenVerifyzesStandbyGetModeCallFailsForInvalidMode) {
zes_standby_promo_mode_t mode = {};
ptestSysfsAccess->setVal(standbyModeFile, standbyModeInvalid);
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesStandbyGetMode(hSysmanStandby, &mode));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetModeOnUnavailableFileThenVerifyzesStandbyGetModeCallFailsForUnsupportedFeature) {
zes_standby_promo_mode_t mode = {};
ptestSysfsAccess->setVal(standbyModeFile, standbyModeInvalid);
auto handles = getStandbyHandles(mockHandleCount);
ptestSysfsAccess->isStandbyModeFileAvailable = false;
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesStandbyGetMode(hSysmanStandby, &mode));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbyGetModeWithInsufficientPermissionsThenVerifyzesStandbyGetModeCallFailsForInsufficientPermissions) {
zes_standby_promo_mode_t mode = {};
ptestSysfsAccess->setVal(standbyModeFile, standbyModeInvalid);
auto handles = getStandbyHandles(mockHandleCount);
ptestSysfsAccess->mockStandbyFileMode &= ~S_IRUSR;
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesStandbyGetMode(hSysmanStandby, &mode));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeThenwithUnwritableFileVerifySysmanzesySetModeCallFailedWithInsufficientPermissions) {
auto handles = getStandbyHandles(mockHandleCount);
ptestSysfsAccess->mockStandbyFileMode &= ~S_IWUSR;
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_NEVER));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeOnUnavailableFileThenVerifyzesStandbySetModeCallFailsForUnsupportedFeature) {
auto handles = getStandbyHandles(mockHandleCount);
ptestSysfsAccess->isStandbyModeFileAvailable = false;
for (auto hSysmanStandby : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_NEVER));
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeNeverThenVerifySysmanzesySetModeCallSucceeds) {
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
zes_standby_promo_mode_t mode;
ptestSysfsAccess->setVal(standbyModeFile, standbyModeDefault);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_DEFAULT, mode);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_NEVER));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_NEVER, mode);
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeDefaultThenVerifySysmanzesySetModeCallSucceeds) {
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
zes_standby_promo_mode_t mode;
ptestSysfsAccess->setVal(standbyModeFile, standbyModeNever);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_NEVER, mode);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_DEFAULT));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_DEFAULT, mode);
}
}
TEST_F(ZesStandbyFixture, GivenOnSubdeviceNotSetWhenValidatingosStandbyGetPropertiesThenSuccessIsReturned) {
auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount();
zes_standby_properties_t properties = {};
ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true;
uint32_t subdeviceId = 0;
std::unique_ptr<PublicLinuxStandbyImp> pLinuxStandbyImp = std::make_unique<PublicLinuxStandbyImp>(pOsSysman, onSubdevice, subdeviceId);
EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxStandbyImp->osStandbyGetProperties(properties));
EXPECT_EQ(properties.subdeviceId, subdeviceId);
EXPECT_EQ(properties.onSubdevice, onSubdevice);
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeDefaultWithLegacyPathThenVerifySysmanzesySetModeCallSucceeds) {
pSysmanDeviceImp->pStandbyHandleContext->handleList.clear();
ptestSysfsAccess->directoryExistsResult = false;
pSysmanDeviceImp->pStandbyHandleContext->init(pLinuxSysmanImp->getSubDeviceCount());
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
zes_standby_promo_mode_t mode;
ptestSysfsAccess->setVal(standbyModeFile, standbyModeNever);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_NEVER, mode);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_DEFAULT));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_DEFAULT, mode);
}
}
TEST_F(ZesStandbyFixture, GivenValidStandbyHandleWhenCallingzesStandbySetModeNeverWithLegacyPathThenVerifySysmanzesySetModeCallSucceeds) {
pSysmanDeviceImp->pStandbyHandleContext->handleList.clear();
ptestSysfsAccess->directoryExistsResult = false;
pSysmanDeviceImp->pStandbyHandleContext->init(pLinuxSysmanImp->getSubDeviceCount());
auto handles = getStandbyHandles(mockHandleCount);
for (auto hSysmanStandby : handles) {
zes_standby_promo_mode_t mode;
ptestSysfsAccess->setVal(standbyModeFile, standbyModeDefault);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_DEFAULT, mode);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbySetMode(hSysmanStandby, ZES_STANDBY_PROMO_MODE_NEVER));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesStandbyGetMode(hSysmanStandby, &mode));
EXPECT_EQ(ZES_STANDBY_PROMO_MODE_NEVER, mode);
}
}
class ZesStandbyMultiDeviceFixture : public SysmanMultiDeviceFixture {
std::unique_ptr<MockStandbySysfsAccess> ptestSysfsAccess;
L0::Sysman::SysfsAccess *pOriginalSysfsAccess = nullptr;
protected:
L0::Sysman::SysmanDevice *device = nullptr;
void SetUp() override {
SysmanMultiDeviceFixture::SetUp();
device = pSysmanDevice;
mockSubDeviceHandleCount = pLinuxSysmanImp->getSubDeviceCount();
ptestSysfsAccess = std::make_unique<MockStandbySysfsAccess>();
pOriginalSysfsAccess = pLinuxSysmanImp->pSysfsAccess;
pLinuxSysmanImp->pSysfsAccess = ptestSysfsAccess.get();
ptestSysfsAccess->setVal(standbyModeFile, standbyModeDefault);
pSysmanDeviceImp->pStandbyHandleContext->handleList.clear();
}
void TearDown() override {
pLinuxSysmanImp->pSysfsAccess = pOriginalSysfsAccess;
SysmanMultiDeviceFixture::TearDown();
}
std::vector<zes_standby_handle_t> getStandbyHandles(uint32_t count) {
std::vector<zes_standby_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumStandbyDomains(device, &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
TEST_F(ZesStandbyMultiDeviceFixture, GivenComponentCountZeroWhenCallingzesStandbyGetThenNonZeroCountIsReturnedAndVerifyzesStandbyGetCallSucceeds) {
std::vector<zes_standby_handle_t> standbyHandle = {};
uint32_t count = 0;
ze_result_t result = zesDeviceEnumStandbyDomains(device, &count, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, mockSubDeviceHandleCount);
uint32_t testCount = count + 1;
result = zesDeviceEnumStandbyDomains(device, &testCount, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(testCount, count);
standbyHandle.resize(count);
result = zesDeviceEnumStandbyDomains(device, &count, standbyHandle.data());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, standbyHandle.data());
EXPECT_EQ(count, mockSubDeviceHandleCount);
}
TEST_F(ZesStandbyMultiDeviceFixture, GivenOnSubdeviceNotSetWhenValidatingosStandbyGetPropertiesThenSuccessIsReturned) {
auto subDeviceCount = pLinuxSysmanImp->getSubDeviceCount();
zes_standby_properties_t properties = {};
ze_bool_t onSubdevice = (subDeviceCount == 0) ? false : true;
uint32_t subdeviceId = 0;
std::unique_ptr<PublicLinuxStandbyImp> pLinuxStandbyImp = std::make_unique<PublicLinuxStandbyImp>(pOsSysman, onSubdevice, subdeviceId);
EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxStandbyImp->osStandbyGetProperties(properties));
EXPECT_EQ(properties.subdeviceId, subdeviceId);
EXPECT_EQ(properties.onSubdevice, onSubdevice);
}
} // namespace ult
} // namespace L0

View File

@ -6,16 +6,13 @@
*/
#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_standby_handle_t {
virtual ~_zes_standby_handle_t() = default;
};
namespace L0 {
struct OsSysman;