From 8240f65434e89fc03c6edaad3d6bcbdf013b14b5 Mon Sep 17 00:00:00 2001 From: Joshua Santosh Ranjan Date: Fri, 26 Aug 2022 16:07:22 +0000 Subject: [PATCH] Remove Sysman dependency from Iaf nl interfaces This patch makes iaf nl interfaces in sysman be usable by other modules. 1.change Iaf_nl interfaces to remove sysman dependencies 2.move iaf specific interfaces(getPorts()) to iaf specific file 3.move iaf_nl files to sysman/linux Related-To: LOCI-3357 Signed-off-by: Joshua Santosh Ranjan --- .../sysman/fabric_port/linux/CMakeLists.txt | 2 - .../linux/fabric_device_access_imp.cpp | 185 ++++++++---------- .../linux/fabric_device_access_imp.h | 29 ++- .../source/sysman/linux/nl_api/CMakeLists.txt | 4 +- .../linux => linux/nl_api}/iaf_nl_api.cpp | 171 +++++++++------- .../linux => linux/nl_api}/iaf_nl_api.h | 75 +++++-- .../sysman/linux/nl_api/CMakeLists.txt | 17 +- .../{mock_nl_api.cpp => mock_nl_dll.cpp} | 4 +- .../nl_api/{mock_nl_api.h => mock_nl_dll.h} | 2 +- .../linux/nl_api/test_sysman_nl_api.cpp | 4 +- .../common/libult/linux/directory_linux.cpp | 8 + 11 files changed, 302 insertions(+), 199 deletions(-) rename level_zero/tools/source/sysman/{fabric_port/linux => linux/nl_api}/iaf_nl_api.cpp (86%) rename level_zero/tools/source/sysman/{fabric_port/linux => linux/nl_api}/iaf_nl_api.h (55%) rename level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/{mock_nl_api.cpp => mock_nl_dll.cpp} (99%) rename level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/{mock_nl_api.h => mock_nl_dll.h} (97%) diff --git a/level_zero/tools/source/sysman/fabric_port/linux/CMakeLists.txt b/level_zero/tools/source/sysman/fabric_port/linux/CMakeLists.txt index 2d92e2300a..0a1a3b821a 100644 --- a/level_zero/tools/source/sysman/fabric_port/linux/CMakeLists.txt +++ b/level_zero/tools/source/sysman/fabric_port/linux/CMakeLists.txt @@ -16,8 +16,6 @@ if(NEO_ENABLE_i915_PRELIM_DETECTION) if(LIBGENL_FOUND) set(L0_SRCS_TOOLS_SYSMAN_FABRICPORT_LINUX_ACCESS - ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.h ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access.h ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_imp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_imp.h diff --git a/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.cpp b/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.cpp index 4ce1ddc0b0..8101b6f623 100644 --- a/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.cpp +++ b/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.cpp @@ -13,25 +13,67 @@ namespace L0 { -const std::string iafPath = "device/"; -const std::string iafDirectoryLegacy = "iaf."; -const std::string iafDirectory = "i915.iaf."; -const std::string fabricIdFile = "/iaf_fabric_id"; +void FabricDeviceAccessNl::readIafPortStatus(zes_fabric_port_state_t &state, const IafPortState &iafPortState) { + + state.failureReasons = 0; + state.qualityIssues = 0; + switch (iafPortState.healthStatus) { + case IAF_FPORT_HEALTH_OFF: + state.status = ZES_FABRIC_PORT_STATUS_DISABLED; + break; + case IAF_FPORT_HEALTH_FAILED: + state.status = ZES_FABRIC_PORT_STATUS_FAILED; + if (1 == iafPortState.failed || 1 == iafPortState.isolated || 1 == iafPortState.linkDown) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FAILED; + } + if (1 == iafPortState.didNotTrain) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_TRAINING_TIMEOUT; + } + if (1 == iafPortState.flapping) { + state.failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FLAPPING; + } + break; + case IAF_FPORT_HEALTH_DEGRADED: + state.status = ZES_FABRIC_PORT_STATUS_DEGRADED; + if (1 == iafPortState.lqi) { + state.qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_LINK_ERRORS; + } + if (1 == iafPortState.lwd || 1 == iafPortState.rate) { + state.qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED; + } + break; + case IAF_FPORT_HEALTH_HEALTHY: + state.status = ZES_FABRIC_PORT_STATUS_HEALTHY; + break; + default: + state.status = ZES_FABRIC_PORT_STATUS_UNKNOWN; + break; + } +} ze_result_t FabricDeviceAccessNl::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) { - ze_result_t result = pIafNlApi->fPortStatusQuery(portId, state); + IafPortState iafPortState = {}; + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + ze_result_t result = pIafNlApi->fPortStatusQuery(iafPortId, iafPortState); if (ZE_RESULT_SUCCESS != result) { return result; } + readIafPortStatus(state, iafPortState); + uint64_t guid; uint8_t portNumber; - zes_fabric_port_speed_t maxRxSpeed; - zes_fabric_port_speed_t maxTxSpeed; + IafPortSpeed maxRxSpeed = {}; + IafPortSpeed maxTxSpeed = {}; + IafPortSpeed rxSpeed = {}; + IafPortSpeed txSpeed = {}; - result = pIafNlApi->fportProperties(portId, guid, portNumber, maxRxSpeed, maxTxSpeed, state.rxSpeed, state.txSpeed); + result = pIafNlApi->fportProperties(iafPortId, guid, portNumber, maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed); if (ZE_RESULT_SUCCESS != result) { return result; } + readIafPortSpeed(state.rxSpeed, rxSpeed); + readIafPortSpeed(state.txSpeed, txSpeed); + switch (state.status) { case ZES_FABRIC_PORT_STATUS_HEALTHY: case ZES_FABRIC_PORT_STATUS_DEGRADED: @@ -54,39 +96,51 @@ ze_result_t FabricDeviceAccessNl::getState(const zes_fabric_port_id_t portId, ze } ze_result_t FabricDeviceAccessNl::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) { - return pIafNlApi->getThroughput(portId, througput); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + IafPortThroughPut iafThroughPut = {}; + ze_result_t result = pIafNlApi->getThroughput(iafPortId, iafThroughPut); + readIafPortThroughPut(througput, iafThroughPut); + return result; } ze_result_t FabricDeviceAccessNl::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) { - return pIafNlApi->portStateQuery(portId, enabled); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portStateQuery(iafPortId, enabled); } ze_result_t FabricDeviceAccessNl::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) { - return pIafNlApi->portBeaconStateQuery(portId, enabled); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconStateQuery(iafPortId, enabled); } ze_result_t FabricDeviceAccessNl::enablePortBeaconing(const zes_fabric_port_id_t portId) { - return pIafNlApi->portBeaconEnable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconEnable(iafPortId); } ze_result_t FabricDeviceAccessNl::disablePortBeaconing(const zes_fabric_port_id_t portId) { - return pIafNlApi->portBeaconDisable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portBeaconDisable(iafPortId); } ze_result_t FabricDeviceAccessNl::enable(const zes_fabric_port_id_t portId) { - return pIafNlApi->portEnable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portEnable(iafPortId); } ze_result_t FabricDeviceAccessNl::disable(const zes_fabric_port_id_t portId) { - return pIafNlApi->portDisable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portDisable(iafPortId); } ze_result_t FabricDeviceAccessNl::enableUsage(const zes_fabric_port_id_t portId) { - return pIafNlApi->portUsageEnable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portUsageEnable(iafPortId); } ze_result_t FabricDeviceAccessNl::disableUsage(const zes_fabric_port_id_t portId) { - return pIafNlApi->portUsageDisable(portId); + const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber); + return pIafNlApi->portUsageDisable(iafPortId); } ze_result_t FabricDeviceAccessNl::forceSweep() { @@ -98,13 +152,24 @@ ze_result_t FabricDeviceAccessNl::routingQuery(uint32_t &start, uint32_t &end) { } ze_result_t FabricDeviceAccessNl::getPorts(std::vector &ports) { - ze_result_t result; - result = init(); + + std::vector iafPorts = {}; + std::string iafRealPath = {}; + pLinuxSysmanImp->getSysfsAccess().getRealPath(iafPath, iafRealPath); + ze_result_t result = pIafNlApi->getPorts(iafRealPath, iafPorts); if (ZE_RESULT_SUCCESS != result) { return result; } + + //Update fabricPorts + for (const auto &iafPort : iafPorts) { + Port port = {}; + readIafPort(port, iafPort); + fabricPorts.push_back(port); + } + ports.clear(); - for (auto port : myPorts) { + for (auto port : fabricPorts) { ports.push_back(port.portId); } return ZE_RESULT_SUCCESS; @@ -112,7 +177,7 @@ ze_result_t FabricDeviceAccessNl::getPorts(std::vector &po void FabricDeviceAccessNl::getProperties(const zes_fabric_port_id_t portId, std::string &model, bool &onSubdevice, uint32_t &subdeviceId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) { - for (auto port : myPorts) { + for (auto port : fabricPorts) { UNRECOVERABLE_IF(portId.fabricId != port.portId.fabricId); if (portId.attachId == port.portId.attachId && portId.portNumber == port.portId.portNumber) { model = port.model; @@ -137,46 +202,6 @@ ze_result_t FabricDeviceAccessNl::getSubdevice(const uint32_t fabricId, const ui return pIafNlApi->subdevicePropertiesGet(fabricId, subdevice, guid, ports); } -ze_result_t FabricDeviceAccessNl::getPortSpeeds(const zes_fabric_port_id_t portId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed) { - uint64_t guid; - uint8_t portNumber; - zes_fabric_port_speed_t rxSpeed; - zes_fabric_port_speed_t txSpeed; - - return pIafNlApi->fportProperties(portId, guid, portNumber, maxRxSpeed, maxTxSpeed, rxSpeed, txSpeed); -} - -ze_result_t FabricDeviceAccessNl::initMyPorts(const uint32_t fabricId) { - uint32_t numSubdevices; - - if (ZE_RESULT_SUCCESS != getNumSubdevices(fabricId, numSubdevices)) { - return ZE_RESULT_ERROR_UNKNOWN; - } - for (uint32_t subdevice = 0; subdevice < numSubdevices; subdevice++) { - uint64_t guid; - std::vector ports; - - if (ZE_RESULT_SUCCESS != getSubdevice(fabricId, subdevice, guid, ports)) { - myPorts.clear(); - return ZE_RESULT_ERROR_UNKNOWN; - } - for (auto port : ports) { - Port p; - p.onSubdevice = numSubdevices > 1; - p.portId.fabricId = fabricId; - p.portId.attachId = subdevice; - p.portId.portNumber = port; - p.model = "XeLink"; - if (ZE_RESULT_SUCCESS != getPortSpeeds(p.portId, p.maxRxSpeed, p.maxTxSpeed)) { - myPorts.clear(); - return ZE_RESULT_ERROR_UNKNOWN; - } - myPorts.push_back(p); - } - } - return ZE_RESULT_SUCCESS; -} - void FabricDeviceAccessNl::populateGuidMap() { std::vector fabricIds; @@ -207,44 +232,6 @@ void FabricDeviceAccessNl::populateGuidMap() { return; } -ze_result_t FabricDeviceAccessNl::init() { - if (myPorts.empty()) { - std::string path; - path.clear(); - std::vector list; - if (ZE_RESULT_SUCCESS != pLinuxSysmanImp->getSysfsAccess().scanDirEntries(iafPath, list)) { - // There should be a device directory - return ZE_RESULT_ERROR_UNKNOWN; - } - for (auto entry : list) { - if ((!iafDirectoryLegacy.compare(entry.substr(0, iafDirectoryLegacy.length()))) || (!iafDirectory.compare(entry.substr(0, iafDirectory.length())))) { - // device/iaf.X/iaf_fabric_id or device/i915.iaf.X/iaf_fabric_id, where X is the hardware slot number - path = iafPath + entry + fabricIdFile; - } - } - if (path.empty()) { - // This device does not have a fabric - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; - } - std::string fabricIdStr; - fabricIdStr.clear(); - if (ZE_RESULT_SUCCESS != pLinuxSysmanImp->getSysfsAccess().read(path, fabricIdStr)) { - // This device has a fabric, but the iaf module isn't running - return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; - } - unsigned long myFabricId = 0UL; - size_t end = 0; - myFabricId = std::stoul(fabricIdStr, &end, 16); - if (fabricIdStr.length() != end || myFabricId > std::numeric_limits::max()) { - return ZE_RESULT_ERROR_UNKNOWN; - } - if (ZE_RESULT_SUCCESS != initMyPorts(static_cast(myFabricId))) { - return ZE_RESULT_ERROR_UNKNOWN; - } - } - return ZE_RESULT_SUCCESS; -} - FabricDeviceAccessNl::FabricDeviceAccessNl(OsSysman *pOsSysman) { pLinuxSysmanImp = static_cast(pOsSysman); pIafNlApi = new IafNlApi; diff --git a/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.h b/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.h index 1b08609e8a..6402b286cb 100644 --- a/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.h +++ b/level_zero/tools/source/sysman/fabric_port/linux/fabric_device_access_imp.h @@ -7,8 +7,9 @@ #pragma once +#include "level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.h" + #include "fabric_device_access.h" -#include "iaf_nl_api.h" #include "sysman/linux/os_sysman_imp.h" namespace L0 { @@ -47,20 +48,40 @@ class FabricDeviceAccessNl : public FabricDeviceAccess { private: ze_result_t init(); - ze_result_t initMyPorts(const uint32_t fabricId); void populateGuidMap(); ze_result_t getAllFabricIds(std::vector &fabricIds); ze_result_t getNumSubdevices(const uint32_t fabricId, uint32_t &numSubdevices); ze_result_t getSubdevice(const uint32_t fabricId, const uint32_t subdeviceId, uint64_t &guid, std::vector &ports); - ze_result_t getPortSpeeds(const zes_fabric_port_id_t portId, zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed); LinuxSysmanImp *pLinuxSysmanImp = nullptr; + void readIafPort(Port &port, const IafPort &iafPort) { + port.onSubdevice = iafPort.onSubdevice; + readIafPortId(port.portId, iafPort.portId); + port.model = iafPort.model; + readIafPortSpeed(port.maxRxSpeed, iafPort.maxRxSpeed); + readIafPortSpeed(port.maxTxSpeed, iafPort.maxTxSpeed); + } + void readIafPortStatus(zes_fabric_port_state_t &state, const IafPortState &iafPortState); + void readIafPortId(zes_fabric_port_id_t &portId, const IafPortId &iafPortId) { + portId.attachId = iafPortId.attachId; + portId.fabricId = iafPortId.fabricId; + portId.portNumber = iafPortId.portNumber; + } + void readIafPortSpeed(zes_fabric_port_speed_t &speed, const IafPortSpeed &iafPortspeed) { + speed.bitRate = iafPortspeed.bitRate; + speed.width = iafPortspeed.width; + } + void readIafPortThroughPut(zes_fabric_port_throughput_t &throughPut, const IafPortThroughPut &iafPortThroughPut) { + // Timestamp is cpu timestamp + throughPut.rxCounter = iafPortThroughPut.rxCounter; + throughPut.txCounter = iafPortThroughPut.txCounter; + } std::map guidMap = {}; protected: IafNlApi *pIafNlApi = nullptr; - std::vector myPorts = {}; + std::vector fabricPorts = {}; }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt b/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt index 75f26f0c8f..5933b17b9c 100644 --- a/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt +++ b/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -8,6 +8,8 @@ if(LIBGENL_FOUND) set(L0_SRCS_TOOLS_SYSMAN_LINUX_NL_API ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.h ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/iaf_nl_api.cpp ) endif() diff --git a/level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.cpp b/level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.cpp similarity index 86% rename from level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.cpp rename to level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.cpp index 0113611c18..aa4ab5b985 100644 --- a/level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.cpp +++ b/level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.cpp @@ -7,8 +7,10 @@ #include "iaf_nl_api.h" -#include "level_zero/tools/source/sysman/linux/os_sysman_imp.h" +#include "shared/source/os_interface/linux/sys_calls.h" +#include "shared/source/utilities/directory.h" +#include #include #include #include @@ -219,99 +221,55 @@ ze_result_t IafNlApi::handleResponse(const uint16_t cmdOp, struct genl_info *inf } ze_result_t IafNlApi::fPortStatusQueryRsp(struct genl_info *info, void *pOutput) { - zes_fabric_port_state_t *pState = reinterpret_cast(pOutput); + IafPortState *pState = reinterpret_cast(pOutput); const struct nlmsghdr *nlh = info->nlh; auto nla = pNlApi->nlmsgAttrdata(nlh, GENL_HDRLEN); auto rem = pNlApi->nlmsgAttrlen(nlh, GENL_HDRLEN); for (; pNlApi->nlaOk(nla, rem); nla = pNlApi->nlaNext(nla, &(rem))) { if (pNlApi->nlaType(nla) == IAF_ATTR_FABRIC_PORT) { - uint8_t healthStatus = 0; - uint8_t lqi = 0; - uint8_t lwd = 0; - uint8_t rate = 0; - uint8_t failed = 0; - uint8_t isolated = 0; - uint8_t flapping = 0; - uint8_t linkDown = 0; - uint8_t didNotTrain = 0; - auto cur = (struct nlattr *)pNlApi->nlaData(nla); auto rem = pNlApi->nlaLen(nla); for (; pNlApi->nlaOk(cur, rem); cur = pNlApi->nlaNext(cur, &(rem))) { switch (pNlApi->nlaType(cur)) { case IAF_ATTR_FPORT_HEALTH: - healthStatus = pNlApi->nlaGetU8(cur); + pState->healthStatus = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ISSUE_LQI: - lqi = pNlApi->nlaGetU8(cur); + pState->lqi = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ISSUE_LWD: - lwd = pNlApi->nlaGetU8(cur); + pState->lwd = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ISSUE_RATE: - rate = pNlApi->nlaGetU8(cur); + pState->rate = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ERROR_FAILED: - failed = pNlApi->nlaGetU8(cur); + pState->failed = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ERROR_ISOLATED: - isolated = pNlApi->nlaGetU8(cur); + pState->isolated = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ERROR_FLAPPING: - flapping = pNlApi->nlaGetU8(cur); + pState->flapping = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ERROR_LINK_DOWN: - linkDown = pNlApi->nlaGetU8(cur); + pState->linkDown = pNlApi->nlaGetU8(cur); break; case IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN: - didNotTrain = pNlApi->nlaGetU8(cur); + pState->didNotTrain = pNlApi->nlaGetU8(cur); break; default: break; } } - switch (healthStatus) { - case IAF_FPORT_HEALTH_OFF: - pState->status = ZES_FABRIC_PORT_STATUS_DISABLED; - break; - case IAF_FPORT_HEALTH_FAILED: - pState->status = ZES_FABRIC_PORT_STATUS_FAILED; - pState->failureReasons = 0; - if (1 == failed || 1 == isolated || 1 == linkDown) { - pState->failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FAILED; - } - if (1 == didNotTrain) { - pState->failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_TRAINING_TIMEOUT; - } - if (1 == flapping) { - pState->failureReasons |= ZES_FABRIC_PORT_FAILURE_FLAG_FLAPPING; - } - break; - case IAF_FPORT_HEALTH_DEGRADED: - pState->status = ZES_FABRIC_PORT_STATUS_DEGRADED; - pState->qualityIssues = 0; - if (1 == lqi) { - pState->qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_LINK_ERRORS; - } - if (1 == lwd || 1 == rate) { - pState->qualityIssues |= ZES_FABRIC_PORT_QUAL_ISSUE_FLAG_SPEED; - } - break; - case IAF_FPORT_HEALTH_HEALTHY: - pState->status = ZES_FABRIC_PORT_STATUS_HEALTHY; - break; - default: - pState->status = ZES_FABRIC_PORT_STATUS_UNKNOWN; - break; - } } } return ZE_RESULT_SUCCESS; } ze_result_t IafNlApi::getThroughputRsp(struct genl_info *info, void *pOutput) { - zes_fabric_port_throughput_t *pThroughput = reinterpret_cast(pOutput); + IafPortThroughPut *pThroughput = reinterpret_cast(pOutput); pThroughput->txCounter = 0UL; pThroughput->rxCounter = 0UL; if (info->attrs[IAF_ATTR_FPORT_TX_BYTES]) { @@ -545,43 +503,43 @@ int32_t IafNlApi::translateWidth(uint8_t width) { return -1; } -ze_result_t IafNlApi::fPortStatusQuery(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) { +ze_result_t IafNlApi::fPortStatusQuery(const IafPortId portId, IafPortState &state) { return issueRequest(IAF_CMD_OP_FPORT_STATUS_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&state)); } -ze_result_t IafNlApi::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &throughput) { +ze_result_t IafNlApi::getThroughput(const IafPortId portId, IafPortThroughPut &throughput) { return issueRequest(IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&throughput)); } -ze_result_t IafNlApi::portStateQuery(const zes_fabric_port_id_t portId, bool &enabled) { +ze_result_t IafNlApi::portStateQuery(const IafPortId portId, bool &enabled) { return issueRequest(IAF_CMD_OP_PORT_STATE_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&enabled)); } -ze_result_t IafNlApi::portBeaconStateQuery(const zes_fabric_port_id_t portId, bool &enabled) { +ze_result_t IafNlApi::portBeaconStateQuery(const IafPortId portId, bool &enabled) { return issueRequest(IAF_CMD_OP_PORT_BEACON_STATE_QUERY, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast(&enabled)); } -ze_result_t IafNlApi::portBeaconEnable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portBeaconEnable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_BEACON_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } -ze_result_t IafNlApi::portBeaconDisable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portBeaconDisable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_BEACON_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } -ze_result_t IafNlApi::portEnable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portEnable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } -ze_result_t IafNlApi::portDisable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portDisable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } -ze_result_t IafNlApi::portUsageEnable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portUsageEnable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_USAGE_ENABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } -ze_result_t IafNlApi::portUsageDisable(const zes_fabric_port_id_t portId) { +ze_result_t IafNlApi::portUsageDisable(const IafPortId portId) { return issueRequest(IAF_CMD_OP_PORT_USAGE_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr); } @@ -622,9 +580,9 @@ ze_result_t IafNlApi::subdevicePropertiesGet(const uint32_t fabricId, const uint return result; } -ze_result_t IafNlApi::fportProperties(const zes_fabric_port_id_t portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, - zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed, - zes_fabric_port_speed_t &rxSpeed, zes_fabric_port_speed_t &txSpeed) { +ze_result_t IafNlApi::fportProperties(const IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + IafPortSpeed &maxRxSpeed, IafPortSpeed &maxTxSpeed, + IafPortSpeed &rxSpeed, IafPortSpeed &txSpeed) { PortProperties portProperties; portProperties.neighborGuid = 0UL; portProperties.neighborPortNumber = 0U; @@ -726,6 +684,81 @@ void IafNlApi::cleanup() { pNlApi->genlUnregisterFamily(&ops); } +ze_result_t IafNlApi::initPorts(const uint32_t fabricId, std::vector &iafPorts) { + uint32_t numSubdevices; + + if (ZE_RESULT_SUCCESS != fabricDeviceProperties(fabricId, numSubdevices)) { + return ZE_RESULT_ERROR_UNKNOWN; + } + for (uint32_t subdevice = 0; subdevice < numSubdevices; subdevice++) { + uint64_t guid; + std::vector ports; + + if (ZE_RESULT_SUCCESS != subdevicePropertiesGet(fabricId, subdevice, guid, ports)) { + iafPorts.clear(); + return ZE_RESULT_ERROR_UNKNOWN; + } + for (auto port : ports) { + IafPort p = {}; + IafPortSpeed rxSpeed, txSpeed; + uint8_t neighbourPortNumber = 0; + uint64_t neighbourGuid = 0; + p.onSubdevice = numSubdevices > 1; + p.portId.fabricId = fabricId; + p.portId.attachId = subdevice; + p.portId.portNumber = port; + p.model = "XeLink"; + if (ZE_RESULT_SUCCESS != fportProperties(p.portId, neighbourGuid, neighbourPortNumber, + p.maxRxSpeed, p.maxTxSpeed, rxSpeed, txSpeed)) { + iafPorts.clear(); + return ZE_RESULT_ERROR_UNKNOWN; + } + iafPorts.push_back(p); + } + } + return ZE_RESULT_SUCCESS; +} + +ze_result_t IafNlApi::getPorts(const std::string &devicePciPath, std::vector &ports) { + + std::string path; + path.clear(); + std::vector list = NEO::Directory::getFiles(devicePciPath); + for (auto entry : list) { + if ((entry.find(iafDirectory) != std::string::npos) || + (entry.find(iafDirectoryLegacy) != std::string::npos)) { + path = entry + fabricIdFile; + break; + } + } + if (path.empty()) { + // This device does not have a fabric + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + std::string fabricIdStr(64, '\0'); + int fd = NEO::SysCalls::open(path.c_str(), O_RDONLY); + if (fd < 0) { + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + + ssize_t bytesRead = NEO::SysCalls::pread(fd, fabricIdStr.data(), fabricIdStr.size() - 1, 0); + NEO::SysCalls::close(fd); + if (bytesRead <= 0) { + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + unsigned long myFabricId = 0UL; + size_t end = 0; + myFabricId = std::stoul(fabricIdStr, &end, 16); + if (myFabricId > std::numeric_limits::max()) { + return ZE_RESULT_ERROR_UNKNOWN; + } + if (ZE_RESULT_SUCCESS != initPorts(static_cast(myFabricId), ports)) { + return ZE_RESULT_ERROR_UNKNOWN; + } + + return ZE_RESULT_SUCCESS; +} + IafNlApi::IafNlApi() { validContexts.clear(); pNlApi.reset(new NlApi); diff --git a/level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.h b/level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.h similarity index 55% rename from level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.h rename to level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.h index 264ac1aa1d..581b362b65 100644 --- a/level_zero/tools/source/sysman/fabric_port/linux/iaf_nl_api.h +++ b/level_zero/tools/source/sysman/linux/nl_api/iaf_nl_api.h @@ -10,7 +10,6 @@ #include "level_zero/tools/source/sysman/linux/nl_api/nl_api.h" #include "iaf/iaf_netlink.h" -#include "sysman/linux/os_sysman_imp.h" #include #include @@ -20,6 +19,11 @@ namespace L0 { +const std::string iafPath = "device/"; +const std::string iafDirectoryLegacy = "iaf."; +const std::string iafDirectory = "i915.iaf."; +const std::string fabricIdFile = "/iaf_fabric_id"; + class IafNlApi; class Operation { @@ -31,31 +35,71 @@ class Operation { Operation(uint16_t cmdOp, void *pOutput) : cmdOp(cmdOp), pOutput(pOutput) {} }; +struct IafPortId { + uint32_t fabricId = 0; + uint32_t attachId = 0; + uint8_t portNumber = 0; + + constexpr IafPortId(uint32_t fabricId, uint32_t attachId, uint32_t portNumber) : fabricId(fabricId), attachId(attachId), portNumber(portNumber) {} + IafPortId() = default; +}; + +struct IafPortSpeed { + int64_t bitRate = 0; + int32_t width = 0; +}; + +struct IafPortThroughPut { + uint64_t timestamp = 0; + uint64_t rxCounter = 0; + uint64_t txCounter = 0; +}; + +struct IafPortState { + uint8_t healthStatus = 0; + uint8_t lqi = 0; + uint8_t lwd = 0; + uint8_t rate = 0; + uint8_t failed = 0; + uint8_t isolated = 0; + uint8_t flapping = 0; + uint8_t linkDown = 0; + uint8_t didNotTrain = 0; +}; + +struct IafPort { + bool onSubdevice = false; + IafPortId portId = {}; + std::string model = {}; + IafPortSpeed maxRxSpeed = {}; + IafPortSpeed maxTxSpeed = {}; +}; + class IafNlApi { public: IafNlApi(); virtual ~IafNlApi(); MOCKABLE_VIRTUAL ze_result_t handleResponse(const uint16_t cmdOp, struct genl_info *info, void *pOutput); - MOCKABLE_VIRTUAL ze_result_t fPortStatusQuery(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state); - MOCKABLE_VIRTUAL ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &throughput); - MOCKABLE_VIRTUAL ze_result_t portStateQuery(const zes_fabric_port_id_t portId, bool &enabled); - MOCKABLE_VIRTUAL ze_result_t portBeaconStateQuery(const zes_fabric_port_id_t portId, bool &enabled); - MOCKABLE_VIRTUAL ze_result_t portBeaconEnable(const zes_fabric_port_id_t portId); - MOCKABLE_VIRTUAL ze_result_t portBeaconDisable(const zes_fabric_port_id_t portId); - MOCKABLE_VIRTUAL ze_result_t portEnable(const zes_fabric_port_id_t portId); - MOCKABLE_VIRTUAL ze_result_t portDisable(const zes_fabric_port_id_t portId); - MOCKABLE_VIRTUAL ze_result_t portUsageEnable(const zes_fabric_port_id_t portId); - MOCKABLE_VIRTUAL ze_result_t portUsageDisable(const zes_fabric_port_id_t portId); + MOCKABLE_VIRTUAL ze_result_t fPortStatusQuery(const IafPortId portId, IafPortState &state); + MOCKABLE_VIRTUAL ze_result_t getThroughput(const IafPortId portId, IafPortThroughPut &throughput); + MOCKABLE_VIRTUAL ze_result_t portStateQuery(const IafPortId portId, bool &enabled); + MOCKABLE_VIRTUAL ze_result_t portBeaconStateQuery(const IafPortId portId, bool &enabled); + MOCKABLE_VIRTUAL ze_result_t portBeaconEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portBeaconDisable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portDisable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portUsageEnable(const IafPortId portId); + MOCKABLE_VIRTUAL ze_result_t portUsageDisable(const IafPortId portId); MOCKABLE_VIRTUAL ze_result_t remRequest(); MOCKABLE_VIRTUAL ze_result_t routingGenQuery(uint32_t &start, uint32_t &end); MOCKABLE_VIRTUAL ze_result_t deviceEnum(std::vector &fabricIds); MOCKABLE_VIRTUAL ze_result_t fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices); MOCKABLE_VIRTUAL ze_result_t subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector &ports); - MOCKABLE_VIRTUAL ze_result_t fportProperties(const zes_fabric_port_id_t portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, - zes_fabric_port_speed_t &maxRxSpeed, zes_fabric_port_speed_t &maxTxSpeed, - zes_fabric_port_speed_t &rxSpeed, zes_fabric_port_speed_t &txSpeed); - + MOCKABLE_VIRTUAL ze_result_t fportProperties(const IafPortId portId, uint64_t &neighborGuid, uint8_t &neighborPortNumber, + IafPortSpeed &maxRxSpeed, IafPortSpeed &maxTxSpeed, + IafPortSpeed &rxSpeed, IafPortSpeed &txSpeed); + MOCKABLE_VIRTUAL ze_result_t getPorts(const std::string &devicePciPath, std::vector &ports); std::list validContexts = {}; int handleMsg(struct nl_msg *msg); @@ -82,6 +126,7 @@ class IafNlApi { ze_result_t fabricDevicePropertiesRsp(struct genl_info *info, void *pOutput); ze_result_t subdevicePropertiesGetRsp(struct genl_info *info, void *pOutput); ze_result_t fportPropertiesRsp(struct genl_info *info, void *pOutput); + ze_result_t initPorts(const uint32_t fabricId, std::vector &iafPorts); int32_t translateWidth(uint8_t width); bool initted = false; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt index 311b7a236a..bd2bd5ec58 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt @@ -1,16 +1,25 @@ # -# Copyright (C) 2020 Intel Corporation +# Copyright (C) 2020-2022 Intel Corporation # # SPDX-License-Identifier: MIT # if(UNIX) if(LIBGENL_FOUND) + + set(L0_TESTS_TOOLS_SYSMAN_IAF_NLAPI_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_nl_api.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_dll.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_dll.h + ) + + add_subdirectories() + target_sources(${TARGET_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_nl_api.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_api.cpp + ${L0_TESTS_TOOLS_SYSMAN_IAF_NLAPI_LINUX} ) endif() + endif() diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.cpp similarity index 99% rename from level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp rename to level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.cpp index 17e21fe1b4..3d498bc6f8 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.cpp @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ -#include "mock_nl_api.h" +#include "mock_nl_dll.h" namespace L0 { namespace ult { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h similarity index 97% rename from level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h rename to level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h index 294dd2b929..1b3b7e596e 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h @@ -23,7 +23,7 @@ namespace ult { class MockNlDll : public NEO::OsLibrary { public: - MOCK_METHOD(bool, isLoaded, (), (override)); + bool isLoaded() override { return false; } void *getProcAddress(const std::string &procName) override; void deleteEntryPoint(const std::string &procName); diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp index 31a551abb8..f641693db2 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ -#include "mock_nl_api.h" +#include "mock_nl_dll.h" extern bool sysmanUltsEnable; diff --git a/shared/test/common/libult/linux/directory_linux.cpp b/shared/test/common/libult/linux/directory_linux.cpp index dc6eefaf3a..c27b075dde 100644 --- a/shared/test/common/libult/linux/directory_linux.cpp +++ b/shared/test/common/libult/linux/directory_linux.cpp @@ -11,11 +11,13 @@ #include #include +#include namespace NEO { std::string byPathPattern(std::string(NEO_SHARED_TEST_FILES_DIR) + "/linux/by-path"); std::string deviceDrmPath(std::string(NEO_SHARED_TEST_FILES_DIR) + "/linux/devices/device/drm"); +std::map> directoryFilesMap = {}; std::vector Directory::getFiles(const std::string &path) { std::vector files; @@ -50,6 +52,12 @@ std::vector Directory::getFiles(const std::string &path) { "/sys/class/intel_pmt/telem9", }; } + + auto it = directoryFilesMap.find(path); + if (it != directoryFilesMap.end()) { + return directoryFilesMap[path]; + } + return files; } }; // namespace NEO