diff --git a/level_zero/sysman/source/device/os_sysman.h b/level_zero/sysman/source/device/os_sysman.h index efae24983c..764aba2db8 100644 --- a/level_zero/sysman/source/device/os_sysman.h +++ b/level_zero/sysman/source/device/os_sysman.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -24,6 +24,7 @@ struct OsSysman { static OsSysman *create(SysmanDeviceImp *pSysmanImp); virtual uint32_t getSubDeviceCount() = 0; virtual const NEO::HardwareInfo &getHardwareInfo() const = 0; + virtual void getDeviceUuids(std::vector &deviceUuids) = 0; }; } // namespace Sysman diff --git a/level_zero/sysman/source/device/sysman_device.cpp b/level_zero/sysman/source/device/sysman_device.cpp index 792a22ced3..a31d995915 100644 --- a/level_zero/sysman/source/device/sysman_device.cpp +++ b/level_zero/sysman/source/device/sysman_device.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -34,8 +34,7 @@ SysmanDevice *SysmanDevice::fromHandle(zes_device_handle_t handle) { return nullptr; } if (std::find(globalSysmanDriver->sysmanDevices.begin(), globalSysmanDriver->sysmanDevices.end(), sysmanDevice) == globalSysmanDriver->sysmanDevices.end()) { - PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "SysmanDevice::fromHandle: Device not found in sysmanDevices list%s\n", ""); - return nullptr; + return globalSysmanDriver->getSysmanDeviceFromCoreDeviceHandle(handle); } return sysmanDevice; } diff --git a/level_zero/sysman/source/device/sysman_device.h b/level_zero/sysman/source/device/sysman_device.h index a71e5f74bf..034baa2906 100644 --- a/level_zero/sysman/source/device/sysman_device.h +++ b/level_zero/sysman/source/device/sysman_device.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -138,6 +138,7 @@ struct SysmanDevice : _ze_device_handle_t { static ze_result_t deviceEnumEnabledVF(zes_device_handle_t hDevice, uint32_t *pCount, zes_vf_handle_t *phVFhandle); virtual OsSysman *deviceGetOsInterface() = 0; + virtual void getDeviceUuids(std::vector &deviceUuids) = 0; }; } // namespace Sysman diff --git a/level_zero/sysman/source/device/sysman_device_imp.cpp b/level_zero/sysman/source/device/sysman_device_imp.cpp index 09d0980d6b..26c9b2aa4c 100644 --- a/level_zero/sysman/source/device/sysman_device_imp.cpp +++ b/level_zero/sysman/source/device/sysman_device_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -110,6 +110,9 @@ ze_result_t SysmanDeviceImp::deviceResetExt(zes_reset_properties_t *pProperties) ze_result_t SysmanDeviceImp::deviceGetState(zes_device_state_t *pState) { return pGlobalOperations->deviceGetState(pState); } +void SysmanDeviceImp::getDeviceUuids(std::vector &deviceUuids) { + return pOsSysman->getDeviceUuids(deviceUuids); +} ze_result_t SysmanDeviceImp::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) { return pFabricPortHandleContext->fabricPortGet(pCount, phPort); diff --git a/level_zero/sysman/source/device/sysman_device_imp.h b/level_zero/sysman/source/device/sysman_device_imp.h index d796cf9ab8..2c10837bdb 100644 --- a/level_zero/sysman/source/device/sysman_device_imp.h +++ b/level_zero/sysman/source/device/sysman_device_imp.h @@ -95,6 +95,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableAndNonMovableClass { ze_result_t deviceEnumEnabledVF(uint32_t *pCount, zes_vf_handle_t *phVFhandle) override; OsSysman *deviceGetOsInterface() override; + void getDeviceUuids(std::vector &deviceUuids) override; private: NEO::ExecutionEnvironment *executionEnvironment = nullptr; diff --git a/level_zero/sysman/source/driver/sysman_driver_handle_imp.cpp b/level_zero/sysman/source/driver/sysman_driver_handle_imp.cpp index 2ed3c90fd3..e1af0ceea6 100644 --- a/level_zero/sysman/source/driver/sysman_driver_handle_imp.cpp +++ b/level_zero/sysman/source/driver/sysman_driver_handle_imp.cpp @@ -27,12 +27,55 @@ namespace Sysman { struct SysmanDriverHandleImp *globalSysmanDriver; SysmanDriverHandleImp::SysmanDriverHandleImp() = default; +void SysmanDriverHandleImp::updateUuidMap(SysmanDevice *sysmanDevice) { + std::vector uuidArr; + sysmanDevice->getDeviceUuids(uuidArr); + for (auto &uuid : uuidArr) { + uuidDeviceMap[uuid] = sysmanDevice; + } + return; +} + +SysmanDevice *SysmanDriverHandleImp::findSysmanDeviceFromCoreToSysmanDeviceMap(ze_device_handle_t handle) { + auto iterator = coreToSysmanDeviceMap.find(handle); + if (iterator != coreToSysmanDeviceMap.end()) { + SysmanDevice *sysmanDevice = iterator->second; + return sysmanDevice; + } + return nullptr; +} + +SysmanDevice *SysmanDriverHandleImp::getSysmanDeviceFromCoreDeviceHandle(ze_device_handle_t hDevice) { + const std::lock_guard lock(this->coreToSysmanDeviceMapLock); + if (hDevice == nullptr) { + return nullptr; + } + + SysmanDevice *sysmanDevice = findSysmanDeviceFromCoreToSysmanDeviceMap(hDevice); + if (sysmanDevice != nullptr) { + return sysmanDevice; + } + + ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES}; + Device::fromHandle(hDevice)->getProperties(&deviceProperties); + std::string uuid(reinterpret_cast(deviceProperties.uuid.id)); + auto it = uuidDeviceMap.find(uuid); + if (it == uuidDeviceMap.end()) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "SysmanDriverHandleImp::getSysmanDeviceFromCoreDeviceHandle() - sysman device handle equivalent to core device handle not found!! %s\n", ""); + return nullptr; + } + sysmanDevice = it->second; + coreToSysmanDeviceMap[hDevice] = sysmanDevice; + + return sysmanDevice; +} ze_result_t SysmanDriverHandleImp::initialize(NEO::ExecutionEnvironment &executionEnvironment) { for (uint32_t rootDeviceIndex = 0u; rootDeviceIndex < executionEnvironment.rootDeviceEnvironments.size(); rootDeviceIndex++) { auto pSysmanDevice = SysmanDevice::create(executionEnvironment, rootDeviceIndex); if (pSysmanDevice != nullptr) { this->sysmanDevices.push_back(pSysmanDevice); + updateUuidMap(pSysmanDevice); } } diff --git a/level_zero/sysman/source/driver/sysman_driver_handle_imp.h b/level_zero/sysman/source/driver/sysman_driver_handle_imp.h index 1d02b5f0dd..97dbe53125 100644 --- a/level_zero/sysman/source/driver/sysman_driver_handle_imp.h +++ b/level_zero/sysman/source/driver/sysman_driver_handle_imp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -8,6 +8,7 @@ #pragma once #include "level_zero/sysman/source/driver/sysman_driver_handle.h" +#include #include #include @@ -29,6 +30,16 @@ struct SysmanDriverHandleImp : SysmanDriverHandle { uint32_t numDevices = 0; ze_result_t getExtensionFunctionAddress(const char *pFuncName, void **pfunc) override; struct OsSysmanDriver *pOsSysmanDriver = nullptr; + SysmanDevice *getSysmanDeviceFromCoreDeviceHandle(ze_device_handle_t hDevice); + + private: + void updateUuidMap(SysmanDevice *sysmanDevice); + SysmanDevice *findSysmanDeviceFromCoreToSysmanDeviceMap(ze_device_handle_t handle); + std::mutex coreToSysmanDeviceMapLock; + std::unordered_map coreToSysmanDeviceMap; + + protected: + std::unordered_map uuidDeviceMap; }; extern struct SysmanDriverHandleImp *globalSysmanDriver; diff --git a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp index ce8e3ee242..1f859c1c78 100644 --- a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp +++ b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.cpp @@ -72,6 +72,7 @@ ze_result_t LinuxSysmanImp::init() { osInterface.getDriverModel()->as()->cleanup(); pPmuInterface = PmuInterface::create(this); + return result; } @@ -495,6 +496,100 @@ bool LinuxSysmanImp::getTelemData(uint32_t subDeviceId, std::string &telemDir, s return true; } +void LinuxSysmanImp::getDeviceUuids(std::vector &deviceUuids) { + constexpr uint32_t rootDeviceCount = 1; + uint32_t totalUuidCountForDevice = this->getSubDeviceCount() + rootDeviceCount; + deviceUuids.clear(); + for (uint32_t index = 0; index < totalUuidCountForDevice; index++) { + std::array deviceUuid; + bool uuidValid = this->getUuidFromSubDeviceInfo(index, deviceUuid); + if (uuidValid) { + uint8_t uuid[ZE_MAX_DEVICE_UUID_SIZE] = {}; + std::copy_n(std::begin(deviceUuid), ZE_MAX_DEVICE_UUID_SIZE, std::begin(uuid)); + std::string uuidString(reinterpret_cast(uuid)); + deviceUuids.push_back(uuidString); + } + } +} + +bool LinuxSysmanImp::generateUuidFromPciAndSubDeviceInfo(uint32_t subDeviceID, const NEO::PhysicalDevicePciBusInfo &pciBusInfo, std::array &uuid) { + if (pciBusInfo.pciDomain != NEO::PhysicalDevicePciBusInfo::invalidValue) { + uuid.fill(0); + + // Device UUID uniquely identifies a device within a system. + // We generate it based on device information along with PCI information + // This guarantees uniqueness of UUIDs on a system even when multiple + // identical Intel GPUs are present. + + // We want to have UUID matching between different GPU APIs (including outside + // of compute_runtime project - i.e. other than L0 or OCL). This structure definition + // has been agreed upon by various Intel driver teams. + // + // Consult other driver teams before changing this. + // + + struct DeviceUUID { + uint16_t vendorID; + uint16_t deviceID; + uint16_t revisionID; + uint16_t pciDomain; + uint8_t pciBus; + uint8_t pciDev; + uint8_t pciFunc; + uint8_t reserved[4]; + uint8_t subDeviceID; + }; + + auto &hwInfo = getParentSysmanDeviceImp()->getHardwareInfo(); + DeviceUUID deviceUUID = {}; + deviceUUID.vendorID = 0x8086; // Intel + deviceUUID.deviceID = hwInfo.platform.usDeviceID; + deviceUUID.revisionID = hwInfo.platform.usRevId; + deviceUUID.pciDomain = static_cast(pciBusInfo.pciDomain); + deviceUUID.pciBus = static_cast(pciBusInfo.pciBus); + deviceUUID.pciDev = static_cast(pciBusInfo.pciDevice); + deviceUUID.pciFunc = static_cast(pciBusInfo.pciFunction); + deviceUUID.subDeviceID = subDeviceID; + + static_assert(sizeof(DeviceUUID) == NEO::ProductHelper::uuidSize); + + memcpy_s(uuid.data(), NEO::ProductHelper::uuidSize, &deviceUUID, sizeof(DeviceUUID)); + + return true; + } + return false; +} + +bool LinuxSysmanImp::getUuidFromSubDeviceInfo(uint32_t subDeviceID, std::array &uuid) { + auto subDeviceCount = getSubDeviceCount(); + if (uuidVec.size() == 0) { + constexpr uint32_t rootDeviceCount = 1; + uuidVec.resize(subDeviceCount + rootDeviceCount); + } + if (getParentSysmanDeviceImp()->getRootDeviceEnvironment().osInterface != nullptr) { + auto driverModel = getParentSysmanDeviceImp()->getRootDeviceEnvironment().osInterface->getDriverModel(); + auto &gfxCoreHelper = getParentSysmanDeviceImp()->getRootDeviceEnvironment().getHelper(); + auto &productHelper = getParentSysmanDeviceImp()->getRootDeviceEnvironment().getHelper(); + if (NEO::debugManager.flags.EnableChipsetUniqueUUID.get() != 0) { + if (gfxCoreHelper.isChipsetUniqueUUIDSupported()) { + auto hwDeviceId = getSysmanHwDeviceIdInstance(); + this->uuidVec[subDeviceID].isValid = productHelper.getUuid(driverModel, subDeviceCount, subDeviceID, this->uuidVec[subDeviceID].id); + } + } + + if (!this->uuidVec[subDeviceID].isValid) { + NEO::PhysicalDevicePciBusInfo pciBusInfo = driverModel->getPciBusInfo(); + this->uuidVec[subDeviceID].isValid = generateUuidFromPciAndSubDeviceInfo(subDeviceID, pciBusInfo, this->uuidVec[subDeviceID].id); + } + + if (this->uuidVec[subDeviceID].isValid) { + uuid = this->uuidVec[subDeviceID].id; + } + } + + return this->uuidVec[subDeviceID].isValid; +} + OsSysman *OsSysman::create(SysmanDeviceImp *pParentSysmanDeviceImp) { LinuxSysmanImp *pLinuxSysmanImp = new LinuxSysmanImp(pParentSysmanDeviceImp); return static_cast(pLinuxSysmanImp); diff --git a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h index 88c98dc398..445866f168 100644 --- a/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h +++ b/level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h @@ -50,6 +50,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableAndNonMovableClass { SysmanDeviceImp *getSysmanDeviceImp(); SysmanProductHelper *getSysmanProductHelper(); uint32_t getSubDeviceCount() override; + void getDeviceUuids(std::vector &deviceUuids) override; const NEO::HardwareInfo &getHardwareInfo() const override { return pParentSysmanDeviceImp->getHardwareInfo(); } std::string getPciCardBusDirectoryPath(std::string realPciPath); uint32_t getMemoryType(); @@ -79,6 +80,9 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableAndNonMovableClass { static ze_result_t getResult(int err); bool getTelemData(uint32_t subDeviceId, std::string &telemDir, std::string &guid, uint64_t &telemOffset); + bool getUuidFromSubDeviceInfo(uint32_t subDeviceID, std::array &uuid); + bool generateUuidFromPciAndSubDeviceInfo(uint32_t subDeviceID, const NEO::PhysicalDevicePciBusInfo &pciBusInfo, std::array &uuid); + protected: std::unique_ptr pSysmanProductHelper; std::unique_ptr pSysmanKmdInterface; @@ -94,6 +98,11 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableAndNonMovableClass { std::map> mapOfSubDeviceIdToTelemData; std::map telemNodesInPciPath; std::unique_ptr pTelemData = nullptr; + struct Uuid { + bool isValid = false; + std::array id; + }; + std::vector uuidVec; private: LinuxSysmanImp() = delete; diff --git a/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.cpp b/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.cpp index 290c37d08a..533f34af01 100644 --- a/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.cpp +++ b/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -114,6 +114,83 @@ KmdSysManager &WddmSysmanImp::getKmdSysManager() { return *pKmdSysManager; } +void WddmSysmanImp::getDeviceUuids(std::vector &deviceUuids) { + deviceUuids.clear(); + std::array deviceUuid; + bool uuidValid = this->getUuid(deviceUuid); + if (uuidValid) { + uint8_t uuid[ZE_MAX_DEVICE_UUID_SIZE] = {}; + std::copy_n(std::begin(deviceUuid), ZE_MAX_DEVICE_UUID_SIZE, std::begin(uuid)); + std::string uuidString(reinterpret_cast(uuid)); + deviceUuids.push_back(uuidString); + } +} + +bool WddmSysmanImp::getUuid(std::array &uuid) { + if (getSysmanDeviceImp()->getRootDeviceEnvironment().osInterface != nullptr) { + auto driverModel = getSysmanDeviceImp()->getRootDeviceEnvironment().osInterface->getDriverModel(); + if (!this->uuid.isValid) { + NEO::PhysicalDevicePciBusInfo pciBusInfo = driverModel->getPciBusInfo(); + this->uuid.isValid = generateUuidFromPciBusInfo(pciBusInfo, this->uuid.id); + } + + if (this->uuid.isValid) { + uuid = this->uuid.id; + } + } + + return this->uuid.isValid; +} + +bool WddmSysmanImp::generateUuidFromPciBusInfo(const NEO::PhysicalDevicePciBusInfo &pciBusInfo, std::array &uuid) { + if (pciBusInfo.pciDomain != NEO::PhysicalDevicePciBusInfo::invalidValue) { + uuid.fill(0); + + // Device UUID uniquely identifies a device within a system. + // We generate it based on device information along with PCI information + // This guarantees uniqueness of UUIDs on a system even when multiple + // identical Intel GPUs are present. + // + + // We want to have UUID matching between different GPU APIs (including outside + // of compute_runtime project - i.e. other than L0 or OCL). This structure definition + // has been agreed upon by various Intel driver teams. + // + // Consult other driver teams before changing this. + // + + struct DeviceUUID { + uint16_t vendorID; + uint16_t deviceID; + uint16_t revisionID; + uint16_t pciDomain; + uint8_t pciBus; + uint8_t pciDev; + uint8_t pciFunc; + uint8_t reserved[4]; + uint8_t subDeviceID; + }; + auto &hwInfo = getSysmanDeviceImp()->getHardwareInfo(); + DeviceUUID deviceUUID = {}; + deviceUUID.vendorID = 0x8086; // Intel + deviceUUID.deviceID = hwInfo.platform.usDeviceID; + deviceUUID.revisionID = hwInfo.platform.usRevId; + deviceUUID.pciDomain = static_cast(pciBusInfo.pciDomain); + deviceUUID.pciBus = static_cast(pciBusInfo.pciBus); + deviceUUID.pciDev = static_cast(pciBusInfo.pciDevice); + deviceUUID.pciFunc = static_cast(pciBusInfo.pciFunction); + deviceUUID.subDeviceID = 0; + + static_assert(sizeof(DeviceUUID) == NEO::ProductHelper::uuidSize); + + memcpy_s(uuid.data(), NEO::ProductHelper::uuidSize, &deviceUUID, sizeof(DeviceUUID)); + + return true; + } + + return false; +} + OsSysman *OsSysman::create(SysmanDeviceImp *pParentSysmanDeviceImp) { WddmSysmanImp *pWddmSysmanImp = new WddmSysmanImp(pParentSysmanDeviceImp); return static_cast(pWddmSysmanImp); diff --git a/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.h b/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.h index bac570ac30..e631d0105e 100644 --- a/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.h +++ b/level_zero/sysman/source/shared/windows/zes_os_sysman_imp.h @@ -8,6 +8,8 @@ #pragma once #include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/non_copyable_or_moveable.h" +#include "shared/source/os_interface/driver_info.h" +#include "shared/source/os_interface/product_helper.h" #include "level_zero/sysman/source/device/os_sysman.h" #include "level_zero/sysman/source/device/sysman_device.h" @@ -36,11 +38,14 @@ class WddmSysmanImp : public OsSysman, NEO::NonCopyableAndNonMovableClass { void releaseFwUtilInterface(); uint32_t getSubDeviceCount() override; + void getDeviceUuids(std::vector &deviceUuids) override; SysmanDeviceImp *getSysmanDeviceImp(); const NEO::HardwareInfo &getHardwareInfo() const override { return pParentSysmanDeviceImp->getHardwareInfo(); } PRODUCT_FAMILY getProductFamily() const { return pParentSysmanDeviceImp->getProductFamily(); } SysmanProductHelper *getSysmanProductHelper(); PlatformMonitoringTech *getSysmanPmt(); + bool getUuid(std::array &uuid); + bool generateUuidFromPciBusInfo(const NEO::PhysicalDevicePciBusInfo &pciBusInfo, std::array &uuid); protected: FirmwareUtil *pFwUtilInterface = nullptr; @@ -48,6 +53,10 @@ class WddmSysmanImp : public OsSysman, NEO::NonCopyableAndNonMovableClass { SysmanDevice *pDevice = nullptr; std::unique_ptr pPmt; std::unique_ptr pSysmanProductHelper; + struct { + bool isValid = false; + std::array id; + } uuid; private: SysmanDeviceImp *pParentSysmanDeviceImp = nullptr; diff --git a/level_zero/sysman/test/unit_tests/sources/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/linux/CMakeLists.txt index e5d6307747..a9cc44b7ad 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/linux/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2020-2023 Intel Corporation +# Copyright (C) 2020-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -14,6 +14,7 @@ if(UNIX) ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_driver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_hw_device_id.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_sysman_hw_device_id.h + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_core_handle_support.cpp ) endif() diff --git a/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp index 320fef887b..e5af287066 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp +++ b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman.cpp @@ -7,6 +7,7 @@ #include "shared/test/common/mocks/mock_driver_info.h" #include "shared/test/common/mocks/mock_driver_model.h" +#include "shared/test/common/mocks/mock_product_helper.h" #include "shared/test/common/test_macros/test.h" #include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h" @@ -277,7 +278,7 @@ TEST_F(SysmanDeviceFixture, GivenInvalidPathnameWhenCallingSysFsAccessScanDirEnt std::string path = "noSuchDirectory"; std::vector listFiles; - EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pSysFsAccess->scanDirEntries(path, listFiles)); + EXPECT_NE(ZE_RESULT_SUCCESS, pSysFsAccess->scanDirEntries(path, listFiles)); } TEST_F(SysmanDeviceFixture, GivenSysfsAccessClassAndIntegerWhenCallingReadOnMultipleFilesThenSuccessIsReturned) { @@ -531,6 +532,85 @@ TEST(SysmanErrorCodeTest, GivenDifferentErrorCodesWhenCallingGetResultThenVerify EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, LinuxSysmanImp::getResult(EEXIST)); } +TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleWithInvalidPciDomainWhenCallingGenerateUuidFromPciBusInfoThenFalseIsReturned) { + std::array uuid; + NEO::PhysicalDevicePciBusInfo pciBusInfo = {}; + pciBusInfo.pciDomain = std::numeric_limits::max(); + uint32_t subDeviceId = 0; + bool result = pLinuxSysmanImp->generateUuidFromPciAndSubDeviceInfo(subDeviceId, pciBusInfo, uuid); + EXPECT_FALSE(result); +} + +TEST_F(SysmanDeviceFixture, GivenNullOsInterfaceObjectWhenRetrievingUuidsOfDeviceThenNoUuidsAreReturned) { + auto execEnv = new NEO::ExecutionEnvironment(); + execEnv->prepareRootDeviceEnvironments(1); + execEnv->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + execEnv->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + execEnv->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique()); + + auto pSysmanDeviceImp = std::make_unique(execEnv, 0); + auto pLinuxSysmanImp = static_cast(pSysmanDeviceImp->pOsSysman); + + auto &rootDeviceEnvironment = (pLinuxSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironmentRef()); + rootDeviceEnvironment.osInterface = nullptr; + + std::vector uuids; + pLinuxSysmanImp->getDeviceUuids(uuids); + EXPECT_EQ(0u, uuids.size()); +} + +TEST_F(SysmanDeviceFixture, GivenInvalidPciBusInfoWhenRetrievingUuidThenFalseIsReturned) { + DebugManagerStateRestore restore; + auto execEnv = new NEO::ExecutionEnvironment(); + execEnv->prepareRootDeviceEnvironments(1); + execEnv->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + execEnv->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + + auto driverModel = std::make_unique(); + driverModel->pciSpeedInfo = {1, 1, 1}; + PhysicalDevicePciBusInfo pciBusInfo = {}; + pciBusInfo.pciDomain = std::numeric_limits::max(); + driverModel->pciBusInfo = pciBusInfo; + execEnv->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::move(driverModel)); + + auto pSysmanDeviceImp = std::make_unique(execEnv, 0); + auto pLinuxSysmanImp = static_cast(pSysmanDeviceImp->pOsSysman); + + debugManager.flags.EnableChipsetUniqueUUID.set(0); + + std::array uuid; + uint32_t subDeviceId = 0; + bool result = pLinuxSysmanImp->getUuidFromSubDeviceInfo(subDeviceId, uuid); + EXPECT_FALSE(result); +} + +struct MockSysmanLinuxProductHelper : public ProductHelperHw { + MockSysmanLinuxProductHelper() = default; + bool getUuid(DriverModel *driverModel, const uint32_t subDeviceCount, const uint32_t deviceIndex, std::array &uuid) const override { + auto pDrm = driverModel->as(); + if (pDrm->getFileDescriptor() >= 0) { + return true; + } + return false; + } +}; + +TEST_F(SysmanDeviceFixture, GivenValidDeviceWhenRetrievingUuidThenValidFdIsVerifiedInProductHelper) { + std::unique_ptr mockProductHelper = std::make_unique(); + auto pSysmanDeviceImp = std::make_unique(execEnv, 0); + auto pLinuxSysmanImp = static_cast(pSysmanDeviceImp->pOsSysman); + + auto &rootDeviceEnvironment = (pLinuxSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironmentRef()); + std::swap(rootDeviceEnvironment.productHelper, mockProductHelper); + + std::array uuid; + uint32_t subDeviceId = 0; + bool result = pLinuxSysmanImp->getUuidFromSubDeviceInfo(subDeviceId, uuid); + EXPECT_TRUE(result); + + std::swap(rootDeviceEnvironment.productHelper, mockProductHelper); +} + } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/linux/test_sysman_core_handle_support.cpp b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman_core_handle_support.cpp new file mode 100644 index 0000000000..b7936d9667 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/linux/test_sysman_core_handle_support.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +class SysmanDeviceFixtureWithCore : public SysmanDeviceFixture, public L0::ult::DeviceFixture { + protected: + void SetUp() override { + SysmanDeviceFixture::SetUp(); + L0::ult::DeviceFixture::setUp(); + } + void TearDown() override { + L0::ult::DeviceFixture::tearDown(); + SysmanDeviceFixture::TearDown(); + } +}; + +HWTEST2_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenRetrievingSysmanDeviceThenNonNullHandleIsReturned, IsPVC) { + auto coreDeviceHandle = L0::Device::fromHandle(device->toHandle()); + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); +} + +HWTEST2_F(SysmanDeviceFixtureWithCore, GivenNullCoreHandleWhenSysmanHandleIsQueriedThenNullPtrIsReturned, IsPVC) { + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(nullptr); + EXPECT_EQ(pSysmanDevice, nullptr); +} + +HWTEST2_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenSysmanHandleIsQueriedAndNotFoundInLookUpThenNullPtrIsReturned, IsPVC) { + VariableBackup mockRealPath(&NEO::SysCalls::sysCallsRealpath, [](const char *path, char *buf) -> char * { + constexpr size_t sizeofPath = sizeof("/sys/devices/pci0000:00/0000:00:02.0"); + strcpy_s(buf, sizeofPath, "/sys/devices/pci0000:00/0000:00:02.0"); + return buf; + }); + + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { + std::string str = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128"; + std::memcpy(buf, str.c_str(), str.size()); + return static_cast(str.size()); + }); + + class MockSysmanDriverHandleImp : public SysmanDriverHandleImp { + public: + MockSysmanDriverHandleImp() { + SysmanDriverHandleImp(); + } + void clearUuidDeviceMap() { + uuidDeviceMap.clear(); + } + }; + std::unique_ptr pSysmanDriverHandleImp = std::make_unique(); + EXPECT_EQ(ZE_RESULT_SUCCESS, pSysmanDriverHandleImp->initialize(*(L0::Sysman::ult::SysmanDeviceFixture::execEnv))); + pSysmanDriverHandleImp->clearUuidDeviceMap(); + auto pSysmanDevice = pSysmanDriverHandleImp->getSysmanDeviceFromCoreDeviceHandle(L0::Device::fromHandle(device->toHandle())); + EXPECT_EQ(pSysmanDevice, nullptr); +} + +HWTEST2_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenRetrievingSysmanHandleTwiceThenSuccessAreReturned, IsDG2) { + auto coreDeviceHandle = L0::Device::fromHandle(device->toHandle()); + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); + pSysmanDevice = nullptr; + pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/windows/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/windows/CMakeLists.txt index e5d8dcd116..46fe5ff1cf 100644 --- a/level_zero/sysman/test/unit_tests/sources/windows/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/windows/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2020-2024 Intel Corporation +# Copyright (C) 2020-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -15,6 +15,7 @@ if(WIN32) ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_driver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_core_handle_support.cpp ) endif() -add_subdirectories() \ No newline at end of file +add_subdirectories() diff --git a/level_zero/sysman/test/unit_tests/sources/windows/test_sysman.cpp b/level_zero/sysman/test/unit_tests/sources/windows/test_sysman.cpp index d974c06fc4..8e532d303c 100644 --- a/level_zero/sysman/test/unit_tests/sources/windows/test_sysman.cpp +++ b/level_zero/sysman/test/unit_tests/sources/windows/test_sysman.cpp @@ -1,10 +1,13 @@ /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * * SPDX-License-Identifier: MIT * */ +#include "shared/test/common/mocks/mock_driver_model.h" +#include "shared/test/common/mocks/mock_product_helper.h" + #include "level_zero/sysman/test/unit_tests/sources/windows/mock_sysman_fixture.h" namespace L0 { @@ -104,6 +107,59 @@ TEST_F(SysmanDeviceFixture, GivenInvalidSysmanDeviceHandleWhenCallingSysmanDevic EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, SysmanDevice::deviceEnumEnabledVF(invalidHandle, &count, nullptr)); } +TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleWithInvalidPciDomainWhenCallingGenerateUuidFromPciBusInfoThenFalseIsReturned) { + std::array uuid; + NEO::PhysicalDevicePciBusInfo pciBusInfo = {}; + pciBusInfo.pciDomain = std::numeric_limits::max(); + bool result = pWddmSysmanImp->generateUuidFromPciBusInfo(pciBusInfo, uuid); + EXPECT_EQ(false, result); +} + +TEST_F(SysmanDeviceFixture, GivenNullOsInterfaceObjectWhenRetrievingUuidsOfDeviceThenNoUuidsAreReturned) { + auto execEnv = new NEO::ExecutionEnvironment(); + execEnv->prepareRootDeviceEnvironments(1); + execEnv->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + execEnv->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + execEnv->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique()); + + auto pSysmanDeviceImp = std::make_unique(execEnv, 0); + auto pWddmSysmanImp = static_cast(pSysmanDeviceImp->pOsSysman); + + auto &rootDeviceEnvironment = (pWddmSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironmentRef()); + rootDeviceEnvironment.osInterface = nullptr; + + std::vector uuids; + pWddmSysmanImp->getDeviceUuids(uuids); + EXPECT_EQ(0u, uuids.size()); +} + +TEST_F(SysmanDeviceFixture, GivenInvalidPciBusInfoWhenRetrievingUuidThenFalseIsReturned) { + auto execEnv = new NEO::ExecutionEnvironment(); + execEnv->prepareRootDeviceEnvironments(1); + execEnv->rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + execEnv->rootDeviceEnvironments[0]->osInterface = std::make_unique(); + + auto driverModel = std::make_unique(); + driverModel->pciSpeedInfo = {1, 1, 1}; + PhysicalDevicePciBusInfo pciBusInfo = {}; + pciBusInfo.pciDomain = std::numeric_limits::max(); + driverModel->pciBusInfo = pciBusInfo; + execEnv->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::move(driverModel)); + + auto pSysmanDeviceImp = std::make_unique(execEnv, 0); + auto pWddmSysmanImp = static_cast(pSysmanDeviceImp->pOsSysman); + + std::array uuid; + bool result = pWddmSysmanImp->getUuid(uuid); + EXPECT_FALSE(result); +} + +TEST_F(SysmanDeviceFixture, GivenValidWddmSysmanImpWhenRetrievingUuidThenTrueIsReturned) { + std::array uuid; + bool result = pWddmSysmanImp->getUuid(uuid); + EXPECT_TRUE(result); +} + } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/windows/test_sysman_core_handle_support.cpp b/level_zero/sysman/test/unit_tests/sources/windows/test_sysman_core_handle_support.cpp new file mode 100644 index 0000000000..48e6989cec --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/windows/test_sysman_core_handle_support.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/windows/mock_sysman_fixture.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +class SysmanDeviceFixtureWithCore : public SysmanDeviceFixture, public L0::ult::DeviceFixture { + protected: + void SetUp() override { + SysmanDeviceFixture::SetUp(); + L0::ult::DeviceFixture::setUp(); + } + void TearDown() override { + L0::ult::DeviceFixture::tearDown(); + SysmanDeviceFixture::TearDown(); + } +}; + +TEST_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenRetrievingSysmanDeviceThenNonNullHandleIsReturned) { + auto coreDeviceHandle = L0::Device::fromHandle(device->toHandle()); + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); +} + +TEST_F(SysmanDeviceFixtureWithCore, GivenNullCoreHandleWhenSysmanHandleIsQueriedThenNullPtrIsReturned) { + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(nullptr); + EXPECT_EQ(pSysmanDevice, nullptr); +} + +TEST_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenSysmanHandleIsQueriedAndNotFoundInLookUpThenNullPtrIsReturned) { + class MockSysmanDriverHandleImp : public SysmanDriverHandleImp { + public: + MockSysmanDriverHandleImp() { + SysmanDriverHandleImp(); + } + void clearUuidDeviceMap() { + uuidDeviceMap.clear(); + } + }; + + std::unique_ptr pSysmanDriverHandleImp = std::make_unique(); + EXPECT_EQ(ZE_RESULT_SUCCESS, pSysmanDriverHandleImp->initialize(*(L0::Sysman::ult::SysmanDeviceFixture::execEnv))); + pSysmanDriverHandleImp->clearUuidDeviceMap(); + auto pSysmanDevice = pSysmanDriverHandleImp->getSysmanDeviceFromCoreDeviceHandle(L0::Device::fromHandle(device->toHandle())); + EXPECT_EQ(pSysmanDevice, nullptr); +} + +TEST_F(SysmanDeviceFixtureWithCore, GivenValidCoreHandleWhenRetrievingSysmanHandleTwiceThenSuccessAreReturned) { + auto coreDeviceHandle = L0::Device::fromHandle(device->toHandle()); + auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); + pSysmanDevice = nullptr; + pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(coreDeviceHandle); + EXPECT_NE(pSysmanDevice, nullptr); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0