diff --git a/level_zero/tools/source/sysman/events/linux/os_events_imp_prelim.cpp b/level_zero/tools/source/sysman/events/linux/os_events_imp_prelim.cpp index 14b3bbcdf0..ecd6b6171b 100644 --- a/level_zero/tools/source/sysman/events/linux/os_events_imp_prelim.cpp +++ b/level_zero/tools/source/sysman/events/linux/os_events_imp_prelim.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -75,8 +75,6 @@ bool LinuxEventsImp::isResetRequired(void *dev, zes_event_type_flags_t &pEvent) return true; } - // ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED event could also be received when, reset Reason is - // ZES_RESET_REASON_FLAG_REPAIR. return false; } @@ -286,6 +284,16 @@ bool LinuxEventsImp::eventListen(zes_event_type_flags_t &pEvent, uint64_t timeou } } + // check if any reset required for reason field repair + if (registeredEvents & ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED) { + zes_device_state_t deviceState = {}; + pLinuxSysmanImp->getSysmanDeviceImp()->pGlobalOperations->deviceGetState(&deviceState); + if (deviceState.reset & ZES_RESET_REASON_FLAG_REPAIR) { + pEvent |= ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED; + return true; + } + } + return listenSystemEvents(pEvent, timeout); } diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events_prelim.h b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events_prelim.h index 6ed6289b3d..933fd35e98 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events_prelim.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events_prelim.h @@ -10,6 +10,7 @@ #include "level_zero/tools/source/sysman/events/events_imp.h" #include "level_zero/tools/source/sysman/events/linux/os_events_imp_prelim.h" +#include "level_zero/tools/source/sysman/firmware_util/firmware_util.h" namespace L0 { namespace ult { @@ -211,6 +212,27 @@ class UdevLibMock : public UdevLib { ADDMETHOD_NOBASE_VOIDRETURN(dropDeviceReference, (void *dev)); }; +struct MockEventsFwInterface : public FirmwareUtil { + bool mockIfrStatus = false; + ze_result_t fwIfrApplied(bool &ifrStatus) override { + ifrStatus = mockIfrStatus; + return ZE_RESULT_SUCCESS; + } + MockEventsFwInterface() = 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 & 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 & fwTypes)); + ADDMETHOD_NOBASE_VOIDRETURN(fwGetMemoryHealthIndicator, (zes_mem_health_t * health)); +}; + class PublicLinuxEventsImp : public L0::LinuxEventsImp { public: PublicLinuxEventsImp(OsSysman *pOsSysman) : LinuxEventsImp(pOsSysman) {} diff --git a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events_prelim.cpp b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events_prelim.cpp index dea54392a6..4110b65157 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events_prelim.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/events/linux/test_zes_events_prelim.cpp @@ -7,7 +7,6 @@ #include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h" -#include "level_zero/tools/source/sysman/global_operations/global_operations_imp.h" #include "level_zero/tools/test/unit_tests/sources/sysman/events/linux/mock_events_prelim.h" #include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h" @@ -28,8 +27,6 @@ class SysmanEventsFixture : public SysmanDeviceFixture { FsAccess *pFsAccessOriginal = nullptr; OsEvents *pOsEventsPrev = nullptr; L0::EventsImp *pEventsImp; - GlobalOperations *pGlobalOperationsOriginal = nullptr; - std::unique_ptr pGlobalOperations; std::unique_ptr pSysfsAccess; SysfsAccess *pSysfsAccessOriginal = nullptr; std::unique_ptr pPmuInterface; @@ -56,12 +53,6 @@ class SysmanEventsFixture : public SysmanDeviceFixture { pLinuxSysmanImp->pUdevLib = new UdevLibMock(); pLinuxEventsImp = new PublicLinuxEventsImp(pOsSysman); pEventsImp->pOsEvents = pLinuxEventsImp; - - pGlobalOperations = std::make_unique(pLinuxSysmanImp); - pGlobalOperationsOriginal = pSysmanDeviceImp->pGlobalOperations; - pSysmanDeviceImp->pGlobalOperations = pGlobalOperations.get(); - pSysmanDeviceImp->pGlobalOperations->init(); - pPmuInterface = std::make_unique(pLinuxSysmanImp); pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); @@ -94,7 +85,6 @@ class SysmanEventsFixture : public SysmanDeviceFixture { pEventsImp = nullptr; pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal; pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; - pSysmanDeviceImp->pGlobalOperations = pGlobalOperationsOriginal; pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; SysmanDeviceFixture::TearDown(); } @@ -130,6 +120,10 @@ TEST_F(SysmanEventsFixture, GivenLibUdevLibraryNotFoundWhenListeningForEventsThe TEST_F(SysmanEventsFixture, GivenValidDeviceHandleAndListeningForEventsWhenEventGenerationSourceDeviceIsNotDrmAndPlatformThenEventListenReturnFalse) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -180,6 +174,7 @@ TEST_F(SysmanEventsFixture, pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanEventsFixture, @@ -287,6 +282,10 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleAndListeningEventsWhenNullEven TEST_F(SysmanEventsFixture, GivenValidDeviceHandleAndListeningForEventsWhenUdevCallToAllocateDeviceFailsThenEventListenReturnFalse) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -335,9 +334,14 @@ TEST_F(SysmanEventsFixture, pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsThenEventListenAPIReturnsAfterReceivingEventWithinTimeout) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -389,6 +393,7 @@ TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredE pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleWhenEventRegisterIsCalledThenSuccessIsReturned) { @@ -397,6 +402,10 @@ TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleWhenEventRegisterIsCalledThenS TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsAndIfUeventReceivedWithWrongPropertyValueThenEventListenAPIReturnsWithinTimeout) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -447,10 +456,15 @@ TEST_F(SysmanEventsFixture, pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsAndIfDrmEventReceivedButChangeEventNotReceivedThenEventListenAPIReturnsWithinTimeout) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -502,10 +516,15 @@ TEST_F(SysmanEventsFixture, pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForResetRequiredEventsAndIfUeventReceivedWithNullPropertyValueThenEventListenAPIReturnsWithinTimeout) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { return 1; }); @@ -556,6 +575,68 @@ TEST_F(SysmanEventsFixture, pEventsImp->pOsEvents = pOsEventOriginal; delete pUdevLibLocal; delete pPublicLinuxEventsImp; + delete pMockFwInterface; +} + +HWTEST2_F(SysmanEventsFixture, + GivenValidDeviceHandleWhenListeningForResetRequiredEventsAfterInFieldRepairAndIfUeventReceivedWithNullPropertyValueThenEventListenAPIReturnsResetEvent, IsPVC) { + VariableBackup backupFwUtil(&pLinuxSysmanImp->pFwUtilInterface); + auto pMockFwInterface = new MockEventsFwInterface; + pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface; + + VariableBackup mockPoll(&SysCalls::sysCallsPoll, [](struct pollfd *pollFd, unsigned long int numberOfFds, int timeout) -> int { + return 1; + }); + VariableBackup mockOpen(&SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int { + if (strcmp(pathname, "i915.iaf.31/iaf_fabric_id") == 0) { + return fabricDeviceFd; + } else { + return drmDeviceFd; + } + }); + VariableBackup mockFstat(&NEO::SysCalls::sysCallsFstat, [](int fd, struct stat *buf) -> int { + if (fd == fabricDeviceFd) { + buf->st_rdev = 10; + } else { + buf->st_rdev = 0; + } + return 0; + }); + + // Step 1: Initialize a mocked udev lib object for this test case + auto pUdevLibLocal = new UdevLibMock(); + int a = 0; + void *ptr = &a; // Initialize a void pointer with dummy data + pUdevLibLocal->allocateDeviceToReceiveDataResult = ptr; + pUdevLibLocal->getEventGenerationSourceDeviceResult = 0; + pUdevLibLocal->getEventPropertyValueResult = nullptr; + + // Step 2: Create a new PublicLinuxEventsImp, where we will attach the above created Udev Lib object + auto pPublicLinuxEventsImp = new PublicLinuxEventsImp(pOsSysman); + pPublicLinuxEventsImp->pUdevLib = pUdevLibLocal; + + // Step 3: Backup original pOsEvent created during set up + auto pOsEventOriginal = pEventsImp->pOsEvents; + pEventsImp->pOsEvents = static_cast(pPublicLinuxEventsImp); + + // Step 4: Call APIs for validation + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEventRegister(device->toHandle(), ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED)); + zes_device_handle_t *phDevices = new zes_device_handle_t[1]; + phDevices[0] = device->toHandle(); + uint32_t numDeviceEvents = 0; + pMockFwInterface->mockIfrStatus = true; + zes_event_type_flags_t *pDeviceEvents = new zes_event_type_flags_t[1]; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDriverEventListen(driverHandle->toHandle(), 1u, 1u, phDevices, &numDeviceEvents, pDeviceEvents)); + EXPECT_EQ(1u, numDeviceEvents); + EXPECT_EQ(ZES_EVENT_TYPE_FLAG_DEVICE_RESET_REQUIRED, pDeviceEvents[0]); + + // Step 5: Cleanup + delete[] phDevices; + delete[] pDeviceEvents; + pEventsImp->pOsEvents = pOsEventOriginal; + delete pUdevLibLocal; + delete pPublicLinuxEventsImp; + delete pMockFwInterface; } TEST_F(SysmanEventsFixture, GivenValidDeviceHandleWhenListeningForCurrentlyUnsupportedEventsThenEventListenAPIWaitForTimeoutIfEventNotReceived) {