Implement zesDriverEventListenEx

Signed-off-by: Mayank Raghuwanshi <mayank.raghuwanshi@intel.com>
This commit is contained in:
Mayank Raghuwanshi
2021-04-05 09:38:22 +05:30
committed by Compute-Runtime-Automation
parent ebb1474210
commit 61c08c052f
18 changed files with 146 additions and 19 deletions

View File

@@ -669,6 +669,17 @@ zesDriverEventListen(
return L0::DriverHandle::fromHandle(hDriver)->sysmanEventsListen(timeout, count, phDevices, pNumDeviceEvents, pEvents);
}
ZE_APIEXPORT ze_result_t ZE_APICALL
zesDriverEventListenEx(
ze_driver_handle_t hDriver,
uint64_t timeout,
uint32_t count,
zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents,
zes_event_type_flags_t *pEvents) {
return L0::DriverHandle::fromHandle(hDriver)->sysmanEventsListenEx(timeout, count, phDevices, pNumDeviceEvents, pEvents);
}
ZE_APIEXPORT ze_result_t ZE_APICALL
zesDeviceEnumDiagnosticTestSuites(
zes_device_handle_t hDevice,

View File

@@ -58,6 +58,8 @@ struct DriverHandle : _ze_driver_handle_t {
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;
virtual ze_result_t sysmanEventsListenEx(uint64_t timeout, uint32_t count, zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) = 0;
virtual ze_result_t importExternalPointer(void *ptr, size_t size) = 0;
virtual ze_result_t releaseImportedPointer(void *ptr) = 0;
virtual ze_result_t getHostPointerBaseAddress(void *ptr, void **baseAddress) = 0;

View File

@@ -58,6 +58,9 @@ struct DriverHandleImp : public DriverHandle {
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;
ze_result_t sysmanEventsListenEx(uint64_t timeout, uint32_t count, zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) override;
ze_result_t importExternalPointer(void *ptr, size_t size) override;
ze_result_t releaseImportedPointer(void *ptr) override;
ze_result_t getHostPointerBaseAddress(void *ptr, void **baseAddress) override;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -13,7 +13,7 @@ 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, uint32_t timeout) = 0;
virtual bool eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) = 0;
virtual void init() = 0;
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -15,7 +15,7 @@ ze_result_t EventsImp::eventRegister(zes_event_type_flags_t events) {
return pOsEvents->eventRegister(events);
}
bool EventsImp::eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) {
bool EventsImp::eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) {
return pOsEvents->eventListen(pEvent, timeout);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -17,7 +17,7 @@ class EventsImp : public Events, NEO::NonCopyableOrMovableClass {
public:
void init() override;
ze_result_t eventRegister(zes_event_type_flags_t events) override;
bool eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) override;
bool eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) override;
OsEvents *pOsEvents = nullptr;
EventsImp() = default;

View File

@@ -72,7 +72,7 @@ bool LinuxEventsImp::checkIfMemHealthChanged(zes_event_type_flags_t &pEvent) {
return false;
}
bool LinuxEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) {
bool LinuxEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) {
if (registeredEvents & ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED) {
if (isResetRequired(pEvent)) {
registeredEvents &= ~(ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED); //After receiving event unregister it

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -13,7 +13,7 @@ namespace L0 {
class LinuxEventsImp : public OsEvents, NEO::NonCopyableOrMovableClass {
public:
bool eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) override;
bool eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) override;
ze_result_t eventRegister(zes_event_type_flags_t events) override;
LinuxEventsImp() = default;
LinuxEventsImp(OsSysman *pOsSysman);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -15,7 +15,7 @@ namespace L0 {
class OsEvents {
public:
static OsEvents *create(OsSysman *pOsSysman);
virtual bool eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) = 0;
virtual bool eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) = 0;
virtual ze_result_t eventRegister(zes_event_type_flags_t events) = 0;
virtual ~OsEvents() {}
};

View File

@@ -89,7 +89,7 @@ ze_result_t WddmEventsImp::eventRegister(zes_event_type_flags_t events) {
return (eventList.size() == 0) ? ZE_RESULT_ERROR_UNSUPPORTED_FEATURE : ZE_RESULT_SUCCESS;
}
bool WddmEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) {
bool WddmEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) {
HANDLE events[MAXIMUM_WAIT_OBJECTS];
pEvent = 0;
@@ -104,7 +104,7 @@ bool WddmEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout
events[eventList.size()] = exitHandle;
// Setting the last handle for the exit handle, then the exit handle is signaled, it breaks from the wait.
uint32_t signaledEvent = WaitForMultipleObjects(static_cast<uint32_t>(eventList.size() + 1), events, FALSE, timeout);
uint32_t signaledEvent = WaitForMultipleObjects(static_cast<uint32_t>(eventList.size() + 1), events, FALSE, static_cast<uint32_t>(timeout));
// Was a timeout
if (signaledEvent == WAIT_TIMEOUT) {

View File

@@ -24,7 +24,7 @@ struct EventHandler {
class WddmEventsImp : public OsEvents, NEO::NonCopyableOrMovableClass {
public:
bool eventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) override;
bool eventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) override;
ze_result_t eventRegister(zes_event_type_flags_t events) override;
WddmEventsImp(OsSysman *pOsSysman);
~WddmEventsImp() {

View File

@@ -43,7 +43,7 @@ ze_result_t DriverHandleImp::sysmanEventsListen(
zes_event_type_flags_t *pEvents) {
bool gotSysmanEvent = false;
memset(pEvents, 0, count * sizeof(zes_event_type_flags_t));
auto timeToExitLoop = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout);
auto timeToExitLoop = L0::steadyClock::now() + std::chrono::milliseconds(timeout);
do {
for (uint32_t devIndex = 0; devIndex < count; devIndex++) {
gotSysmanEvent = L0::SysmanDevice::fromHandle(phDevices[devIndex])->deviceEventListen(pEvents[devIndex], timeout);
@@ -56,7 +56,33 @@ ze_result_t DriverHandleImp::sysmanEventsListen(
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));
} while ((L0::steadyClock::now() <= timeToExitLoop));
return ZE_RESULT_SUCCESS;
}
ze_result_t DriverHandleImp::sysmanEventsListenEx(
uint64_t timeout,
uint32_t count,
zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents,
zes_event_type_flags_t *pEvents) {
bool gotSysmanEvent = false;
memset(pEvents, 0, count * sizeof(zes_event_type_flags_t));
auto timeToExitLoop = L0::steadyClock::now() + std::chrono::duration<uint64_t, std::milli>(timeout);
do {
for (uint32_t devIndex = 0; devIndex < count; devIndex++) {
gotSysmanEvent = L0::SysmanDevice::fromHandle(phDevices[devIndex])->deviceEventListen(pEvents[devIndex], timeout);
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 ((L0::steadyClock::now() <= timeToExitLoop));
return ZE_RESULT_SUCCESS;
}

View File

@@ -54,7 +54,7 @@ struct SysmanDevice : _ze_device_handle_t {
virtual ze_result_t diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phDiagnostics) = 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, uint32_t timeout) = 0;
virtual bool deviceEventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) = 0;
virtual ~SysmanDevice() = default;
};

View File

@@ -6,6 +6,7 @@
*/
#pragma once
#include <chrono>
#include <string>
const std::string vendorIntel("Intel(R) Corporation");
const std::string unknown("unknown");
@@ -13,6 +14,20 @@ const std::string intelPciId("0x8086");
constexpr uint32_t MbpsToBytesPerSecond = 125000;
constexpr double milliVoltsFactor = 1000.0;
namespace L0 {
struct steadyClock {
typedef std::chrono::duration<uint64_t, std::milli> duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<steadyClock> time_point;
static constexpr bool is_steady = true;
static time_point now() noexcept {
static auto epoch = std::chrono::steady_clock::now();
return time_point(std::chrono::duration_cast<duration>(std::chrono::steady_clock::now() - epoch));
}
};
} // namespace L0
namespace PciLinkSpeeds {
constexpr double Pci2_5GigatransfersPerSecond = 2.5;
constexpr double Pci5_0GigatransfersPerSecond = 5.0;

View File

@@ -142,7 +142,7 @@ ze_result_t SysmanDeviceImp::deviceEventRegister(zes_event_type_flags_t events)
return pEvents->eventRegister(events);
}
bool SysmanDeviceImp::deviceEventListen(zes_event_type_flags_t &pEvent, uint32_t timeout) {
bool SysmanDeviceImp::deviceEventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) {
return pEvents->eventListen(pEvent, timeout);
}

View File

@@ -66,7 +66,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
ze_result_t diagnosticsGet(uint32_t *pCount, zes_diag_handle_t *phFirmware) 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, uint32_t timeout) override;
bool deviceEventListen(zes_event_type_flags_t &pEvent, uint64_t timeout) override;
private:
template <typename T>

View File

@@ -763,6 +763,35 @@ void testSysmanListenEvents(ze_driver_handle_t driver, std::vector<ze_device_han
}
}
void testSysmanListenEventsEx(ze_driver_handle_t driver, std::vector<ze_device_handle_t> &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()];
uint64_t timeout = 10000u;
uint32_t numDevices = static_cast<uint32_t>(devices.size());
VALIDATECALL(zesDriverEventListenEx(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;
}
if (pEvents[index] & ZES_EVENT_TYPE_FLAG_DEVICE_DETACH) {
std::cout << "Device " << index << "got DEVICE_DETACH event" << std::endl;
}
if (pEvents[index] & ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH) {
std::cout << "Device " << index << "got DEVICE_ATTACH event" << std::endl;
}
if (pEvents[index] & ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS) {
std::cout << "Device " << index << "got RAS UNCORRECTABLE event" << std::endl;
}
if (pEvents[index] & ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS) {
std::cout << "Device " << index << "got RAS CORRECTABLE event" << std::endl;
}
}
}
}
}
std::string getFabricPortStatus(zes_fabric_port_status_t status) {
static const std::map<zes_fabric_port_status_t, std::string> fabricPortStatus{
{ZES_FABRIC_PORT_STATUS_UNKNOWN, "ZES_FABRIC_PORT_STATUS_UNKNOWN"},
@@ -1021,6 +1050,12 @@ int main(int argc, char *argv[]) {
});
testSysmanListenEvents(driver, devices,
ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED | ZES_EVENT_TYPE_FLAG_DEVICE_DETACH | ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH | ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS | ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS);
std::for_each(devices.begin(), devices.end(), [&](auto device) {
zesDeviceEventRegister(device,
ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED | ZES_EVENT_TYPE_FLAG_DEVICE_DETACH | ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH | ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS | ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS);
});
testSysmanListenEventsEx(driver, devices,
ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED | ZES_EVENT_TYPE_FLAG_DEVICE_DETACH | ZES_EVENT_TYPE_FLAG_DEVICE_ATTACH | ZES_EVENT_TYPE_FLAG_RAS_CORRECTABLE_ERRORS | ZES_EVENT_TYPE_FLAG_RAS_UNCORRECTABLE_ERRORS);
break;
case 'F':
std::for_each(devices.begin(), devices.end(), [&](auto device) {

View File

@@ -240,5 +240,40 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForAListOfEventsT
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ENUMERATION, zesDeviceEventRegister(device->toHandle(), events2));
}
TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIReturnsAfterReceivingEventWithinTimeout) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsOne));
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, zesDriverEventListenEx(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, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenExAPIWaitForTimeoutIfEventNotReceived) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED));
ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValReturnValAsZero));
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, zesDriverEventListenEx(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
EXPECT_EQ(0u, numDeviceEvents);
ON_CALL(*pFsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EventsFsAccess>::getValFileNotFound));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListenEx(driverHandle->toHandle(), 100u, 1u, phDevices, &numDeviceEvents, pDeviceEvents));
EXPECT_EQ(0u, numDeviceEvents);
delete[] phDevices;
delete[] pDeviceEvents;
}
} // namespace ult
} // namespace L0