diff --git a/level_zero/api/sysman/zes_sysman.cpp b/level_zero/api/sysman/zes_sysman.cpp index f70a91df3a..619d1844ed 100644 --- a/level_zero/api/sysman/zes_sysman.cpp +++ b/level_zero/api/sysman/zes_sysman.cpp @@ -5,8 +5,6 @@ * */ -#include - #include "sysman/sysman.h" ZE_APIEXPORT ze_result_t ZE_APICALL @@ -657,7 +655,7 @@ ZE_APIEXPORT ze_result_t ZE_APICALL zesDeviceEventRegister( zes_device_handle_t hDevice, zes_event_type_flags_t events) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::SysmanDevice::fromHandle(hDevice)->deviceEventRegister(events); } ZE_APIEXPORT ze_result_t ZE_APICALL @@ -668,7 +666,7 @@ zesDriverEventListen( zes_device_handle_t *phDevices, uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::DriverHandle::fromHandle(hDriver)->sysmanEventsListen(timeout, count, phDevices, pNumDeviceEvents, pEvents); } ZE_APIEXPORT ze_result_t ZE_APICALL diff --git a/level_zero/core/source/driver/driver_handle.h b/level_zero/core/source/driver/driver_handle.h index f5da3070b2..f251dbdf43 100644 --- a/level_zero/core/source/driver/driver_handle.h +++ b/level_zero/core/source/driver/driver_handle.h @@ -12,6 +12,7 @@ #include "level_zero/core/source/context/context.h" #include "level_zero/core/source/device/device.h" #include +#include struct _ze_driver_handle_t { virtual ~_ze_driver_handle_t() = default; @@ -65,6 +66,8 @@ struct DriverHandle : _ze_driver_handle_t { bool *allocationRangeCovered) = 0; virtual NEO::SVMAllocsManager *getSvmAllocsManager() = 0; + virtual ze_result_t sysmanEventsListen(uint32_t timeout, uint32_t count, zes_device_handle_t *phDevices, + uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) = 0; static DriverHandle *fromHandle(ze_driver_handle_t handle) { return static_cast(handle); } inline ze_driver_handle_t toHandle() { return this; } diff --git a/level_zero/core/source/driver/driver_handle_imp.h b/level_zero/core/source/driver/driver_handle_imp.h index dfff703175..ffc21864c8 100644 --- a/level_zero/core/source/driver/driver_handle_imp.h +++ b/level_zero/core/source/driver/driver_handle_imp.h @@ -60,6 +60,9 @@ struct DriverHandleImp : public DriverHandle { size_t size, bool *allocationRangeCovered) override; + ze_result_t sysmanEventsListen(uint32_t timeout, uint32_t count, zes_device_handle_t *phDevices, + uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) override; + uint32_t parseAffinityMask(std::vector> &neoDevices); uint32_t numDevices = 0; diff --git a/level_zero/tools/source/sysman/events/CMakeLists.txt b/level_zero/tools/source/sysman/events/CMakeLists.txt new file mode 100644 index 0000000000..d0511d890b --- /dev/null +++ b/level_zero/tools/source/sysman/events/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_TOOLS_SYSMAN_EVENTS + ${CMAKE_CURRENT_SOURCE_DIR}/events.h + ${CMAKE_CURRENT_SOURCE_DIR}/events_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/events_imp.h + ${CMAKE_CURRENT_SOURCE_DIR}/os_events.h +) + +target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_TOOLS_SYSMAN_EVENTS} + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) + +if(UNIX) + add_subdirectory(linux) +else() + add_subdirectory(windows) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_TOOLS_SYSMAN_EVENTS ${L0_SRCS_TOOLS_SYSMAN_EVENTS}) diff --git a/level_zero/tools/source/sysman/events/events.h b/level_zero/tools/source/sysman/events/events.h new file mode 100644 index 0000000000..6efef8fb04 --- /dev/null +++ b/level_zero/tools/source/sysman/events/events.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include +namespace L0 { + +class Events { + public: + virtual ~Events(){}; + virtual ze_result_t eventRegister(zes_event_type_flags_t events) = 0; + virtual bool eventListen(zes_event_type_flags_t &pEvent) = 0; + virtual void init() = 0; +}; + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/events_imp.cpp b/level_zero/tools/source/sysman/events/events_imp.cpp new file mode 100644 index 0000000000..518c4fc6c8 --- /dev/null +++ b/level_zero/tools/source/sysman/events/events_imp.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "events_imp.h" + +#include "shared/source/helpers/debug_helpers.h" + +namespace L0 { + +bool EventsImp::eventListen(zes_event_type_flags_t &pEvent) { + if (registeredEvents & ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED) { + return pOsEvents->isResetRequired(pEvent); + } + return false; +} + +void EventsImp::init() { + pOsEvents = OsEvents::create(pOsSysman); + UNRECOVERABLE_IF(nullptr == pOsEvents); +} + +EventsImp::~EventsImp() { + if (nullptr != pOsEvents) { + delete pOsEvents; + } +} + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/events_imp.h b/level_zero/tools/source/sysman/events/events_imp.h new file mode 100644 index 0000000000..8829e0cbe3 --- /dev/null +++ b/level_zero/tools/source/sysman/events/events_imp.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "events.h" +#include "os_events.h" + +namespace L0 { + +class EventsImp : public Events, NEO::NonCopyableOrMovableClass { + public: + void init() override; + ze_result_t eventRegister(zes_event_type_flags_t events) override { + registeredEvents = events; + return ZE_RESULT_SUCCESS; + } + bool eventListen(zes_event_type_flags_t &pEvent) override; + OsEvents *pOsEvents = nullptr; + + EventsImp() = default; + EventsImp(OsSysman *pOsSysman) : pOsSysman(pOsSysman){}; + ~EventsImp() override; + + private: + OsSysman *pOsSysman = nullptr; + zes_event_type_flags_t registeredEvents = 0; +}; + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/linux/CMakeLists.txt b/level_zero/tools/source/sysman/events/linux/CMakeLists.txt new file mode 100644 index 0000000000..4fa265eabc --- /dev/null +++ b/level_zero/tools/source/sysman/events/linux/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_TOOLS_SYSMAN_EVENTS_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/os_events_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_events_imp.h +) + +if(UNIX) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_TOOLS_SYSMAN_EVENTS_LINUX} + ) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_TOOLS_SYSMAN_EVENTS_LINUX ${L0_SRCS_TOOLS_SYSMAN_EVENTS_LINUX}) diff --git a/level_zero/tools/source/sysman/events/linux/os_events_imp.cpp b/level_zero/tools/source/sysman/events/linux/os_events_imp.cpp new file mode 100644 index 0000000000..abbc37d834 --- /dev/null +++ b/level_zero/tools/source/sysman/events/linux/os_events_imp.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/tools/source/sysman/events/linux/os_events_imp.h" + +#include "sysman/events/events_imp.h" +#include "sysman/linux/os_sysman_imp.h" + +namespace L0 { + +bool LinuxEventsImp::isResetRequired(zes_event_type_flags_t &pEvent) { + zes_device_state_t pState = {}; + if (pLinuxSysmanImp->getSysmanDeviceImp()->deviceGetState(&pState) != ZE_RESULT_SUCCESS) { + return false; + } + if (pState.reset) { + pEvent = ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED; + return true; + } + return false; +} + +LinuxEventsImp::LinuxEventsImp(OsSysman *pOsSysman) { + pLinuxSysmanImp = static_cast(pOsSysman); +} + +OsEvents *OsEvents::create(OsSysman *pOsSysman) { + LinuxEventsImp *pLinuxEventsImp = new LinuxEventsImp(pOsSysman); + return static_cast(pLinuxEventsImp); +} + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/linux/os_events_imp.h b/level_zero/tools/source/sysman/events/linux/os_events_imp.h new file mode 100644 index 0000000000..66ce527227 --- /dev/null +++ b/level_zero/tools/source/sysman/events/linux/os_events_imp.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/tools/source/sysman/events/os_events.h" +#include "level_zero/tools/source/sysman/linux/os_sysman_imp.h" + +namespace L0 { + +class LinuxEventsImp : public OsEvents, NEO::NonCopyableOrMovableClass { + public: + bool isResetRequired(zes_event_type_flags_t &pEvent) override; + LinuxEventsImp() = default; + LinuxEventsImp(OsSysman *pOsSysman); + ~LinuxEventsImp() override = default; + + protected: + LinuxSysmanImp *pLinuxSysmanImp = nullptr; +}; + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/os_events.h b/level_zero/tools/source/sysman/events/os_events.h new file mode 100644 index 0000000000..e5e22644de --- /dev/null +++ b/level_zero/tools/source/sysman/events/os_events.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "level_zero/tools/source/sysman/os_sysman.h" +#include + +namespace L0 { + +class OsEvents { + public: + static OsEvents *create(OsSysman *pOsSysman); + virtual bool isResetRequired(zes_event_type_flags_t &pEvent) = 0; + virtual ~OsEvents() {} +}; + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/events/windows/CMakeLists.txt b/level_zero/tools/source/sysman/events/windows/CMakeLists.txt new file mode 100644 index 0000000000..e5d865fa7a --- /dev/null +++ b/level_zero/tools/source/sysman/events/windows/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(L0_SRCS_TOOLS_SYSMAN_EVENTS_WINDOWS + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/os_events_imp.cpp +) + +if(WIN32) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_TOOLS_SYSMAN_EVENTS_WINDOWS} + ) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_TOOLS_SYSMAN_EVENTS_WINDOWS ${L0_SRCS_TOOLS_SYSMAN_EVENTS_WINDOWS}) diff --git a/level_zero/tools/source/sysman/events/windows/os_events_imp.cpp b/level_zero/tools/source/sysman/events/windows/os_events_imp.cpp new file mode 100644 index 0000000000..f2f75c5607 --- /dev/null +++ b/level_zero/tools/source/sysman/events/windows/os_events_imp.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/tools/source/sysman/events/os_events.h" +#include "level_zero/tools/source/sysman/windows/os_sysman_imp.h" + +namespace L0 { + +class WddmEventsImp : public OsEvents { + public: + bool isResetRequired(zes_event_type_flags_t &pEvent) override; + WddmEventsImp(OsSysman *pOsSysman); + ~WddmEventsImp() = default; + + // Don't allow copies of the WddmEventsImp object + WddmEventsImp(const WddmEventsImp &obj) = delete; + WddmEventsImp &operator=(const WddmEventsImp &obj) = delete; +}; + +bool WddmEventsImp::isResetRequired(zes_event_type_flags_t &pEvent) { + return false; +} + +WddmEventsImp::WddmEventsImp(OsSysman *pOsSysman) { +} + +OsEvents *OsEvents::create(OsSysman *pOsSysman) { + WddmEventsImp *pWddmEventsImp = new WddmEventsImp(pOsSysman); + return static_cast(pWddmEventsImp); +} + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/sysman.cpp b/level_zero/tools/source/sysman/sysman.cpp index 2b3bcbcf6a..79820aec54 100644 --- a/level_zero/tools/source/sysman/sysman.cpp +++ b/level_zero/tools/source/sysman/sysman.cpp @@ -31,4 +31,29 @@ SysmanDevice *DeviceImp::getSysmanHandle() { return pSysmanDevice; } +ze_result_t DriverHandleImp::sysmanEventsListen( + uint32_t timeout, + uint32_t count, + zes_device_handle_t *phDevices, + uint32_t *pNumDeviceEvents, + zes_event_type_flags_t *pEvents) { + bool gotSysmanEvent = false; + auto timeToExitLoop = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout); + do { + for (uint32_t devIndex = 0; devIndex < count; devIndex++) { + gotSysmanEvent = L0::SysmanDevice::fromHandle(phDevices[devIndex])->deviceEventListen(pEvents[devIndex]); + if (gotSysmanEvent) { + *pNumDeviceEvents = 1; + break; + } + } + if (gotSysmanEvent) { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // Sleep for 10 milliseconds before next check of events + } while ((std::chrono::steady_clock::now() <= timeToExitLoop)); + + return ZE_RESULT_SUCCESS; +} + } // namespace L0 diff --git a/level_zero/tools/source/sysman/sysman.h b/level_zero/tools/source/sysman/sysman.h index ba61059739..1ff4dad83c 100644 --- a/level_zero/tools/source/sysman/sysman.h +++ b/level_zero/tools/source/sysman/sysman.h @@ -6,8 +6,8 @@ */ #pragma once -#include "level_zero/core/source/device/device.h" #include "level_zero/tools/source/sysman/engine/engine.h" +#include "level_zero/tools/source/sysman/events/events.h" #include "level_zero/tools/source/sysman/fabric_port/fabric_port.h" #include "level_zero/tools/source/sysman/fan/fan.h" #include "level_zero/tools/source/sysman/firmware/firmware.h" @@ -21,14 +21,11 @@ #include "level_zero/tools/source/sysman/standby/standby.h" #include "level_zero/tools/source/sysman/temperature/temperature.h" #include -#include - -#include struct _zet_sysman_handle_t {}; namespace L0 { - +struct Device; struct SysmanDevice : _ze_device_handle_t { static SysmanDevice *fromHandle(zes_device_handle_t handle) { return Device::fromHandle(handle)->getSysmanHandle(); } @@ -52,6 +49,8 @@ struct SysmanDevice : _ze_device_handle_t { virtual ze_result_t memoryGet(uint32_t *pCount, zes_mem_handle_t *phMemory) = 0; virtual ze_result_t fanGet(uint32_t *pCount, zes_fan_handle_t *phFan) = 0; virtual ze_result_t firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) = 0; + virtual ze_result_t deviceEventRegister(zes_event_type_flags_t events) = 0; + virtual bool deviceEventListen(zes_event_type_flags_t &pEvent) = 0; virtual ~SysmanDevice() = default; }; diff --git a/level_zero/tools/source/sysman/sysman_imp.cpp b/level_zero/tools/source/sysman/sysman_imp.cpp index 195858c32d..d6e51e5ed1 100644 --- a/level_zero/tools/source/sysman/sysman_imp.cpp +++ b/level_zero/tools/source/sysman/sysman_imp.cpp @@ -9,6 +9,7 @@ #include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/driver/driver_handle_imp.h" +#include "level_zero/tools/source/sysman/events/events_imp.h" #include "level_zero/tools/source/sysman/global_operations/global_operations_imp.h" #include "level_zero/tools/source/sysman/pci/pci_imp.h" #include "level_zero/tools/source/sysman/sysman.h" @@ -32,13 +33,15 @@ SysmanDeviceImp::SysmanDeviceImp(ze_device_handle_t hDevice) { pRasHandleContext = new RasHandleContext(pOsSysman); pMemoryHandleContext = new MemoryHandleContext(pOsSysman); pGlobalOperations = new GlobalOperationsImp(pOsSysman); + pEvents = new EventsImp(pOsSysman); pFanHandleContext = new FanHandleContext(pOsSysman); pFirmwareHandleContext = new FirmwareHandleContext(pOsSysman); } SysmanDeviceImp::~SysmanDeviceImp() { - freeResource(pFanHandleContext); freeResource(pFirmwareHandleContext); + freeResource(pFanHandleContext); + freeResource(pEvents); freeResource(pGlobalOperations); freeResource(pMemoryHandleContext); freeResource(pRasHandleContext); @@ -99,6 +102,9 @@ void SysmanDeviceImp::init() { if (pGlobalOperations) { pGlobalOperations->init(); } + if (pEvents) { + pEvents->init(); + } if (pFanHandleContext) { pFanHandleContext->init(); } @@ -123,6 +129,14 @@ ze_result_t SysmanDeviceImp::deviceReset(ze_bool_t force) { return pGlobalOperations->reset(force); } +ze_result_t SysmanDeviceImp::deviceEventRegister(zes_event_type_flags_t events) { + return pEvents->eventRegister(events); +} + +bool SysmanDeviceImp::deviceEventListen(zes_event_type_flags_t &pEvent) { + return pEvents->eventListen(pEvent); +} + ze_result_t SysmanDeviceImp::deviceGetState(zes_device_state_t *pState) { return pGlobalOperations->deviceGetState(pState); } diff --git a/level_zero/tools/source/sysman/sysman_imp.h b/level_zero/tools/source/sysman/sysman_imp.h index 2129c3b183..6edf5f5a44 100644 --- a/level_zero/tools/source/sysman/sysman_imp.h +++ b/level_zero/tools/source/sysman/sysman_imp.h @@ -28,6 +28,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass { OsSysman *pOsSysman = nullptr; Pci *pPci = nullptr; GlobalOperations *pGlobalOperations = nullptr; + Events *pEvents = nullptr; PowerHandleContext *pPowerHandleContext = nullptr; FrequencyHandleContext *pFrequencyHandleContext = nullptr; FabricPortHandleContext *pFabricPortHandleContext = nullptr; @@ -59,6 +60,8 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass { ze_result_t memoryGet(uint32_t *pCount, zes_mem_handle_t *phMemory) override; ze_result_t fanGet(uint32_t *pCount, zes_fan_handle_t *phFan) override; ze_result_t firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) override; + ze_result_t deviceEventRegister(zes_event_type_flags_t events) override; + bool deviceEventListen(zes_event_type_flags_t &pEvent) override; private: template diff --git a/level_zero/tools/test/black_box_tests/zello_sysman.cpp b/level_zero/tools/test/black_box_tests/zello_sysman.cpp index c6c8b49876..368f36b860 100644 --- a/level_zero/tools/test/black_box_tests/zello_sysman.cpp +++ b/level_zero/tools/test/black_box_tests/zello_sysman.cpp @@ -80,24 +80,25 @@ void usage() { "\n zello_sysman [OPTIONS]" "\n" "\n OPTIONS:" - "\n -p, --pci selectively run pci black box test" - "\n -f, --frequency selectively run frequency black box test" - "\n -s, --standby selectively run standby black box test" - "\n -e, --engine selectively run engine black box test" - "\n -c, --scheduler selectively run scheduler black box test" - "\n -t, --temperature selectively run temperature black box test" - "\n -o, --power selectively run power black box test" - "\n -m, --memory selectively run memory black box test" - "\n -g, --global selectively run device/global operations black box test" - "\n -r, --reset force|noforce selectively run device reset test" - "\n -h, --help display help message" + "\n -p, --pci selectively run pci black box test" + "\n -f, --frequency selectively run frequency black box test" + "\n -s, --standby selectively run standby black box test" + "\n -e, --engine selectively run engine black box test" + "\n -c, --scheduler selectively run scheduler black box test" + "\n -t, --temperature selectively run temperature black box test" + "\n -o, --power selectively run power black box test" + "\n -m, --memory selectively run memory black box test" + "\n -g, --global selectively run device/global operations black box test" + "\n -E, --event set and listen to events black box test" + "\n -r, --reset force|noforce selectively run device reset test" + "\n -h, --help display help message" "\n" "\n All L0 Syman APIs that set values require root privileged execution" "\n" "\n"; } -void getDeviceHandles(std::vector &devices, int argc, char *argv[]) { +void getDeviceHandles(ze_driver_handle_t &driverHandle, std::vector &devices, int argc, char *argv[]) { VALIDATECALL(zeInit(ZE_INIT_FLAG_GPU_ONLY)); @@ -107,7 +108,6 @@ void getDeviceHandles(std::vector &devices, int argc, char * std::cout << "Error could not retrieve driver" << std::endl; std::terminate(); } - ze_driver_handle_t driverHandle; VALIDATECALL(zeDriverGet(&driverCount, &driverHandle)); uint32_t deviceCount = 0; @@ -572,11 +572,30 @@ void testSysmanMemory(ze_device_handle_t &device) { } } } + void testSysmanReset(ze_device_handle_t &device, bool force) { std::cout << std::endl << " ---- Reset test (force = " << (force ? "true" : "false") << ") ---- " << std::endl; VALIDATECALL(zesDeviceReset(device, force)); } + +void testSysmanListenEvents(ze_driver_handle_t driver, std::vector &devices, zes_event_type_flags_t events) { + uint32_t numDeviceEvents = 0; + zes_event_type_flags_t *pEvents = new zes_event_type_flags_t[devices.size()]; + uint32_t timeout = 10000u; + uint32_t numDevices = static_cast(devices.size()); + VALIDATECALL(zesDriverEventListen(driver, timeout, numDevices, devices.data(), &numDeviceEvents, pEvents)); + if (verbose) { + if (numDeviceEvents) { + for (auto index = 0u; index < devices.size(); index++) { + if (pEvents[index] & ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED) { + std::cout << "Device " << index << "got reset required event" << std::endl; + } + } + } + } +} + void testSysmanGlobalOperations(ze_device_handle_t &device) { std::cout << std::endl << " ---- Global Operations tests ---- " << std::endl; @@ -613,12 +632,13 @@ bool validateGetenv(const char *name) { } int main(int argc, char *argv[]) { std::vector devices; + ze_driver_handle_t driver; if (!validateGetenv("ZES_ENABLE_SYSMAN")) { std::cout << "Must set environment variable ZES_ENABLE_SYSMAN=1" << std::endl; exit(0); } - getDeviceHandles(devices, argc, argv); + getDeviceHandles(driver, devices, argc, argv); int opt; static struct option long_opts[] = { {"help", no_argument, nullptr, 'h'}, @@ -631,11 +651,12 @@ int main(int argc, char *argv[]) { {"power", no_argument, nullptr, 'o'}, {"global", no_argument, nullptr, 'g'}, {"memory", no_argument, nullptr, 'm'}, + {"event", no_argument, nullptr, 'E'}, {"reset", required_argument, nullptr, 'r'}, {0, 0, 0, 0}, }; bool force = false; - while ((opt = getopt_long(argc, argv, "hpfsectogmr:", long_opts, nullptr)) != -1) { + while ((opt = getopt_long(argc, argv, "hpfsectogmrE:", long_opts, nullptr)) != -1) { switch (opt) { case 'h': usage(); @@ -699,6 +720,12 @@ int main(int argc, char *argv[]) { testSysmanReset(device, force); }); break; + case 'E': + std::for_each(devices.begin(), devices.end(), [&](auto device) { + zesDeviceEventRegister(device, ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED); + }); + testSysmanListenEvents(driver, devices, ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED); + break; default: usage(); diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/events/CMakeLists.txt new file mode 100644 index 0000000000..6dc7b33a72 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt +) +add_subdirectories() diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/CMakeLists.txt new file mode 100644 index 0000000000..0cb8cdcd82 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + target_sources(${TARGET_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_events.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_events.h + ) +endif() diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events.h b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events.h new file mode 100644 index 0000000000..6e8b7e3183 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/tools/source/sysman/events/events_imp.h" +#include "level_zero/tools/source/sysman/events/linux/os_events_imp.h" + +namespace L0 { +namespace ult { + +const std::string ueventWedgedFile("/var/lib/libze_intel_gpu/wedged_file"); + +class EventsFsAccess : public FsAccess {}; + +template <> +struct Mock : public EventsFsAccess { + + ze_result_t getValWedgedFileTrue(const std::string file, uint32_t &val) { + if (file.compare(ueventWedgedFile) == 0) { + val = 1; + } else { + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + return ZE_RESULT_SUCCESS; + } + + ze_result_t getValWedgedFileFalse(const std::string file, uint32_t &val) { + if (file.compare(ueventWedgedFile) == 0) { + val = 0; + } else { + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + return ZE_RESULT_SUCCESS; + } + + ze_result_t getValWedgedFileNotFound(const std::string file, uint32_t &val) { + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } + + ze_result_t getValWedgedFileInsufficientPermissions(const std::string file, uint32_t &val) { + return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS; + } + + Mock() = default; + + MOCK_METHOD(ze_result_t, read, (const std::string file, std::string &val), (override)); + MOCK_METHOD(ze_result_t, read, (const std::string file, uint32_t &val), (override)); + MOCK_METHOD(ze_result_t, canWrite, (const std::string file), (override)); +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events.cpp b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events.cpp new file mode 100644 index 0000000000..216abeb5bc --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/tools/source/sysman/global_operations/global_operations_imp.h" +#include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h" + +#include "mock_events.h" + +using ::testing::Matcher; + +namespace L0 { +namespace ult { + +class SysmanEventsFixture : public SysmanDeviceFixture { + protected: + std::unique_ptr> pFsAccess; + FsAccess *pFsAccessOld = nullptr; + OsEvents *pOsEventsPrev = nullptr; + L0::EventsImp *pEventsImp; + GlobalOperations *pGlobalOperationsOld = nullptr; + std::unique_ptr pGlobalOperations; + + void SetUp() override { + SysmanDeviceFixture::SetUp(); + pFsAccessOld = pLinuxSysmanImp->pFsAccess; + pFsAccess = std::make_unique>>(); + pLinuxSysmanImp->pFsAccess = pFsAccess.get(); + + pEventsImp = static_cast(pSysmanDeviceImp->pEvents); + pOsEventsPrev = pEventsImp->pOsEvents; + pEventsImp->pOsEvents = nullptr; + pGlobalOperations = std::make_unique(pLinuxSysmanImp); + pGlobalOperationsOld = pSysmanDeviceImp->pGlobalOperations; + pSysmanDeviceImp->pGlobalOperations = pGlobalOperations.get(); + pSysmanDeviceImp->pGlobalOperations->init(); + pEventsImp->init(); + } + + void TearDown() override { + if (nullptr != pEventsImp->pOsEvents) { + delete pEventsImp->pOsEvents; + } + pEventsImp->pOsEvents = pOsEventsPrev; + pEventsImp = nullptr; + pLinuxSysmanImp->pFsAccess = pFsAccessOld; + pSysmanDeviceImp->pGlobalOperations = pGlobalOperationsOld; + SysmanDeviceFixture::TearDown(); + } +}; + +TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED)); + ON_CALL(*pFsAccess.get(), read(_, Matcher(_))) + .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock::getValWedgedFileTrue)); + zes_device_handle_t *phDevices = new zes_device_handle_t[1]; + phDevices[0] = device->toHandle(); + uint32_t numDeviceEvents = 0; + zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1]; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents)); + EXPECT_EQ(1u, numDeviceEvents); + EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED, pDeviceEvents[0]); + delete[] phDevices; + delete[] pDeviceEvents; +} + +TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED)); + ON_CALL(*pFsAccess.get(), read(_, Matcher(_))) + .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock::getValWedgedFileFalse)); + zes_device_handle_t *phDevices = new zes_device_handle_t[1]; + phDevices[0] = device->toHandle(); + uint32_t numDeviceEvents = 0; + zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1]; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents)); + EXPECT_EQ(0u, numDeviceEvents); + + ON_CALL(*pFsAccess.get(), read(_, Matcher(_))) + .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock::getValWedgedFileNotFound)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents)); + EXPECT_EQ(0u, numDeviceEvents); + + delete[] phDevices; + delete[] pDeviceEvents; +} + +TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForCurrentlyUnsupportedEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_TEMP_THRESHOLD2)); + ON_CALL(*pFsAccess.get(), read(_, Matcher(_))) + .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock::getValWedgedFileTrue)); + zes_device_handle_t *phDevices = new zes_device_handle_t[1]; + phDevices[0] = device->toHandle(); + uint32_t numDeviceEvents = 0; + zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1]; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents)); + EXPECT_EQ(0u, numDeviceEvents); + delete[] phDevices; + delete[] pDeviceEvents; +} + +} // namespace ult +} // namespace L0