[Sysman]: Add support for Fabric APIs

Add support for Fabric APIs in new sysman design.
This design is independent of level zero core.

Related-To: LOCI-4091
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2023-03-06 15:46:51 +00:00
committed by Compute-Runtime-Automation
parent 2e0c68af43
commit 266a495837
49 changed files with 7385 additions and 14 deletions

View File

@@ -0,0 +1,24 @@
#
# Copyright (C) 2020-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_SYSMAN_FABRICPORT
${CMAKE_CURRENT_SOURCE_DIR}/fabric_port.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fabric_port.h
${CMAKE_CURRENT_SOURCE_DIR}/fabric_port_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fabric_port_imp.h
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port.h
)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${L0_SRCS_SYSMAN_FABRICPORT}
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
)
add_subdirectories()
# Make our source files visible to parent
set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT ${L0_SRCS_SYSMAN_FABRICPORT})

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/fabric_port.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/debug_helpers.h"
#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h"
namespace L0 {
namespace Sysman {
FabricPortHandleContext::FabricPortHandleContext(OsSysman *pOsSysman) {
pFabricDevice = new FabricDeviceImp(pOsSysman);
UNRECOVERABLE_IF(nullptr == pFabricDevice);
handleList.clear();
}
FabricPortHandleContext::~FabricPortHandleContext() {
UNRECOVERABLE_IF(nullptr == pFabricDevice);
for (FabricPort *pFabricPort : handleList) {
delete pFabricPort;
}
handleList.clear();
delete pFabricDevice;
pFabricDevice = nullptr;
}
ze_result_t FabricPortHandleContext::init() {
UNRECOVERABLE_IF(nullptr == pFabricDevice);
uint32_t numPorts = pFabricDevice->getNumPorts();
for (uint32_t portNum = 0; portNum < numPorts; portNum++) {
FabricPort *pFabricPort = new FabricPortImp(pFabricDevice, portNum);
UNRECOVERABLE_IF(nullptr == pFabricPort);
handleList.push_back(pFabricPort);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricPortHandleContext::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) {
std::call_once(initFabricPortOnce, [this]() {
this->init();
});
uint32_t handleListSize = static_cast<uint32_t>(handleList.size());
uint32_t numToCopy = std::min(*pCount, handleListSize);
if (0 == *pCount || *pCount > handleListSize) {
*pCount = handleListSize;
}
if (nullptr != phPort) {
for (uint32_t i = 0; i < numToCopy; i++) {
phPort[i] = handleList[i]->toZesHandle();
}
}
return ZE_RESULT_SUCCESS;
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/api/sysman/zes_handles_struct.h"
#include <level_zero/zes_api.h>
#include <mutex>
#include <vector>
namespace L0 {
namespace Sysman {
struct OsSysman;
class OsFabricDevice;
class FabricDevice {
public:
virtual ~FabricDevice() = default;
virtual OsFabricDevice *getOsFabricDevice() = 0;
virtual uint32_t getNumPorts() = 0;
};
class FabricPort : _zes_fabric_port_handle_t {
public:
~FabricPort() override = default;
virtual ze_result_t fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) = 0;
virtual ze_result_t fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) = 0;
virtual ze_result_t fabricPortGetConfig(zes_fabric_port_config_t *pConfig) = 0;
virtual ze_result_t fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) = 0;
virtual ze_result_t fabricPortGetState(zes_fabric_port_state_t *pState) = 0;
virtual ze_result_t fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) = 0;
virtual ze_result_t fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) = 0;
inline zes_fabric_port_handle_t toZesHandle() { return this; }
static FabricPort *fromHandle(zes_fabric_port_handle_t handle) {
return static_cast<FabricPort *>(handle);
}
};
struct FabricPortHandleContext : NEO::NonCopyableOrMovableClass {
FabricPortHandleContext(OsSysman *pOsSysman);
~FabricPortHandleContext();
ze_result_t init();
ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort);
FabricDevice *pFabricDevice = nullptr;
std::vector<FabricPort *> handleList = {};
private:
std::once_flag initFabricPortOnce;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h"
#include "shared/source/helpers/debug_helpers.h"
#include <chrono>
namespace L0 {
namespace Sysman {
uint32_t FabricDeviceImp::getNumPorts() {
UNRECOVERABLE_IF(nullptr == pOsFabricDevice);
return pOsFabricDevice->getNumPorts();
}
FabricDeviceImp::FabricDeviceImp(OsSysman *pOsSysman) {
pOsFabricDevice = OsFabricDevice::create(pOsSysman);
UNRECOVERABLE_IF(nullptr == pOsFabricDevice);
}
FabricDeviceImp::~FabricDeviceImp() {
delete pOsFabricDevice;
pOsFabricDevice = nullptr;
}
void fabricPortGetTimestamp(uint64_t &timestamp) {
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
timestamp = std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
}
ze_result_t FabricPortImp::fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) {
return pOsFabricPort->getProperties(pProperties);
}
ze_result_t FabricPortImp::fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) {
return pOsFabricPort->getLinkType(pLinkType);
}
ze_result_t FabricPortImp::fabricPortGetConfig(zes_fabric_port_config_t *pConfig) {
return pOsFabricPort->getConfig(pConfig);
}
ze_result_t FabricPortImp::fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) {
return pOsFabricPort->setConfig(pConfig);
}
ze_result_t FabricPortImp::fabricPortGetState(zes_fabric_port_state_t *pState) {
return pOsFabricPort->getState(pState);
}
ze_result_t FabricPortImp::fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) {
return pOsFabricPort->getErrorCounters(pErrors);
}
ze_result_t FabricPortImp::fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) {
fabricPortGetTimestamp(pThroughput->timestamp);
return pOsFabricPort->getThroughput(pThroughput);
}
void FabricPortImp::init() {
}
FabricPortImp::FabricPortImp(FabricDevice *pFabricDevice, uint32_t portNum) {
pOsFabricPort = OsFabricPort::create(pFabricDevice->getOsFabricDevice(), portNum);
UNRECOVERABLE_IF(nullptr == pOsFabricPort);
init();
}
FabricPortImp::~FabricPortImp() {
delete pOsFabricPort;
pOsFabricPort = nullptr;
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/fabric_port/fabric_port.h"
#include "level_zero/sysman/source/fabric_port/os_fabric_port.h"
#include <level_zero/zes_api.h>
namespace L0 {
namespace Sysman {
class FabricDeviceImp : public FabricDevice, NEO::NonCopyableOrMovableClass {
public:
FabricDeviceImp() = delete;
FabricDeviceImp(OsSysman *pOsSysman);
~FabricDeviceImp() override;
uint32_t getNumPorts() override;
OsFabricDevice *getOsFabricDevice() override { return pOsFabricDevice; }
protected:
OsFabricDevice *pOsFabricDevice = nullptr;
};
class FabricPortImp : public FabricPort, NEO::NonCopyableOrMovableClass {
public:
ze_result_t fabricPortGetProperties(zes_fabric_port_properties_t *pProperties) override;
ze_result_t fabricPortGetLinkType(zes_fabric_link_type_t *pLinkType) override;
ze_result_t fabricPortGetConfig(zes_fabric_port_config_t *pConfig) override;
ze_result_t fabricPortSetConfig(const zes_fabric_port_config_t *pConfig) override;
ze_result_t fabricPortGetState(zes_fabric_port_state_t *pState) override;
ze_result_t fabricPortGetThroughput(zes_fabric_port_throughput_t *pThroughput) override;
ze_result_t fabricPortGetErrorCounters(zes_fabric_port_error_counters_t *pErrors) override;
FabricPortImp() = delete;
FabricPortImp(FabricDevice *pFabricDevice, uint32_t portNum);
~FabricPortImp() override;
protected:
void init();
OsFabricPort *pOsFabricPort = nullptr;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,45 @@
#
# Copyright (C) 2020-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_SYSMAN_FABRICPORT_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
)
if(NEO_ENABLE_i915_PRELIM_DETECTION)
list(APPEND L0_SRCS_SYSMAN_FABRICPORT_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp_prelim.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp_prelim.h
)
if(LIBGENL_FOUND)
set(L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS
${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
)
else()
set(L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS
${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_stub.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fabric_device_access_stub.h
)
endif()
else()
list(APPEND L0_SRCS_SYSMAN_FABRICPORT_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.h
)
endif()
if(UNIX)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${L0_SRCS_SYSMAN_FABRICPORT_LINUX}
${L0_SRCS_SYSMAN_FABRICPORT_LINUX_ACCESS}
)
endif()
# Make our source files visible to parent
set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT_LINUX ${L0_SRCS_SYSMAN_FABRICPORT_LINUX})

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/linux/fs_access.h"
#include "level_zero/zes_api.h"
#include <vector>
namespace L0 {
namespace Sysman {
struct OsSysman;
class FabricDeviceAccess : NEO::NonCopyableOrMovableClass {
public:
virtual ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) = 0;
virtual ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) = 0;
virtual ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) = 0;
virtual ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) = 0;
virtual ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t enable(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t disable(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t enableUsage(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t disableUsage(const zes_fabric_port_id_t portId) = 0;
virtual ze_result_t forceSweep() = 0;
virtual ze_result_t routingQuery(uint32_t &start, uint32_t &end) = 0;
virtual ze_result_t getPorts(std::vector<zes_fabric_port_id_t> &ports) = 0;
virtual void 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) = 0;
virtual ~FabricDeviceAccess() = default;
static FabricDeviceAccess *create(OsSysman *pOsSysman);
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,254 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_imp.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
#include <limits>
namespace L0 {
namespace Sysman {
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) {
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;
IafPortSpeed maxRxSpeed = {};
IafPortSpeed maxTxSpeed = {};
IafPortSpeed rxSpeed = {};
IafPortSpeed 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:
case ZES_FABRIC_PORT_STATUS_FAILED: {
auto it = guidMap.find(guid);
if (guidMap.end() == it) {
populateGuidMap();
it = guidMap.find(guid);
}
if (guidMap.end() != it) {
state.remotePortId = it->second;
state.remotePortId.portNumber = portNumber;
}
} break;
default:
break;
}
return result;
}
ze_result_t FabricDeviceAccessNl::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
const IafPortId iafPortId(portId.fabricId, portId.attachId, portId.portNumber);
return pIafNlApi->portUsageDisable(iafPortId);
}
ze_result_t FabricDeviceAccessNl::forceSweep() {
return pIafNlApi->remRequest();
}
ze_result_t FabricDeviceAccessNl::routingQuery(uint32_t &start, uint32_t &end) {
return pIafNlApi->routingGenQuery(start, end);
}
ze_result_t FabricDeviceAccessNl::getPorts(std::vector<zes_fabric_port_id_t> &ports) {
std::vector<IafPort> 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 : fabricPorts) {
ports.push_back(port.portId);
}
return ZE_RESULT_SUCCESS;
}
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 : fabricPorts) {
UNRECOVERABLE_IF(portId.fabricId != port.portId.fabricId);
if (portId.attachId == port.portId.attachId && portId.portNumber == port.portId.portNumber) {
model = port.model;
onSubdevice = port.onSubdevice;
subdeviceId = port.portId.attachId;
maxRxSpeed = port.maxRxSpeed;
maxTxSpeed = port.maxTxSpeed;
return;
}
}
}
ze_result_t FabricDeviceAccessNl::getAllFabricIds(std::vector<uint32_t> &fabricIds) {
return pIafNlApi->deviceEnum(fabricIds);
}
ze_result_t FabricDeviceAccessNl::getNumSubdevices(const uint32_t fabricId, uint32_t &numSubdevices) {
return pIafNlApi->fabricDeviceProperties(fabricId, numSubdevices);
}
ze_result_t FabricDeviceAccessNl::getSubdevice(const uint32_t fabricId, const uint32_t subdevice, uint64_t &guid, std::vector<uint8_t> &ports) {
return pIafNlApi->subdevicePropertiesGet(fabricId, subdevice, guid, ports);
}
void FabricDeviceAccessNl::populateGuidMap() {
std::vector<uint32_t> fabricIds;
if (ZE_RESULT_SUCCESS != getAllFabricIds(fabricIds)) {
return;
}
for (auto fabricId : fabricIds) {
uint32_t numSubdevices = 0;
if (ZE_RESULT_SUCCESS != getNumSubdevices(fabricId, numSubdevices)) {
return;
}
for (uint32_t subdevice = 0; subdevice < numSubdevices; subdevice++) {
uint64_t guid;
std::vector<uint8_t> ports;
if (ZE_RESULT_SUCCESS != getSubdevice(fabricId, subdevice, guid, ports)) {
return;
}
zes_fabric_port_id_t portId;
portId.fabricId = fabricId;
portId.attachId = subdevice;
portId.portNumber = ports.size();
guidMap[guid] = portId;
}
}
return;
}
FabricDeviceAccessNl::FabricDeviceAccessNl(OsSysman *pOsSysman) {
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pIafNlApi = new IafNlApi;
UNRECOVERABLE_IF(nullptr == pIafNlApi);
}
FabricDeviceAccessNl::~FabricDeviceAccessNl() {
if (nullptr != pIafNlApi) {
delete pIafNlApi;
pIafNlApi = nullptr;
}
}
FabricDeviceAccess *FabricDeviceAccess::create(OsSysman *pOsSysman) {
return new FabricDeviceAccessNl(pOsSysman);
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h"
#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
namespace L0 {
namespace Sysman {
struct Port {
bool onSubdevice;
zes_fabric_port_id_t portId;
std::string model;
zes_fabric_port_speed_t maxRxSpeed;
zes_fabric_port_speed_t maxTxSpeed;
};
class FabricDeviceAccessNl : public FabricDeviceAccess {
public:
FabricDeviceAccessNl() = delete;
FabricDeviceAccessNl(OsSysman *pOsSysman);
~FabricDeviceAccessNl() override;
ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) override;
ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) override;
ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) override;
ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) override;
ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) override;
ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) override;
ze_result_t enable(const zes_fabric_port_id_t portId) override;
ze_result_t disable(const zes_fabric_port_id_t portId) override;
ze_result_t enableUsage(const zes_fabric_port_id_t portId) override;
ze_result_t disableUsage(const zes_fabric_port_id_t portId) override;
ze_result_t forceSweep() override;
ze_result_t routingQuery(uint32_t &start, uint32_t &end) override;
ze_result_t getPorts(std::vector<zes_fabric_port_id_t> &ports) override;
void 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) override;
private:
ze_result_t init();
void populateGuidMap();
ze_result_t getAllFabricIds(std::vector<uint32_t> &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<uint8_t> &ports);
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<uint64_t, zes_fabric_port_id_t> guidMap = {};
protected:
IafNlApi *pIafNlApi = nullptr;
std::vector<Port> fabricPorts = {};
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access_stub.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
namespace L0 {
namespace Sysman {
ze_result_t FabricDeviceAccessStub::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::enablePortBeaconing(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::disablePortBeaconing(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::enable(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::disable(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::enableUsage(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::disableUsage(const zes_fabric_port_id_t portId) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::forceSweep() {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::routingQuery(uint32_t &start, uint32_t &end) {
return ZE_RESULT_SUCCESS;
}
ze_result_t FabricDeviceAccessStub::getPorts(std::vector<zes_fabric_port_id_t> &ports) {
return ZE_RESULT_SUCCESS;
}
void FabricDeviceAccessStub::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) {
model = "";
onSubdevice = false;
subdeviceId = 0U;
maxRxSpeed.width = -1;
maxRxSpeed.bitRate = -1L;
maxTxSpeed.width = -1;
maxTxSpeed.bitRate = -1L;
}
FabricDeviceAccessStub::FabricDeviceAccessStub(OsSysman *pOsSysman) {
}
FabricDeviceAccessStub::~FabricDeviceAccessStub() {
}
FabricDeviceAccess *FabricDeviceAccess::create(OsSysman *pOsSysman) {
return new FabricDeviceAccessStub(pOsSysman);
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h"
namespace L0 {
namespace Sysman {
class FabricDeviceAccessStub : public FabricDeviceAccess {
public:
FabricDeviceAccessStub() = delete;
FabricDeviceAccessStub(OsSysman *pOsSysman);
~FabricDeviceAccessStub();
ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t &state) override;
ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t &througput) override;
ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) override;
ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) override;
ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId) override;
ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId) override;
ze_result_t enable(const zes_fabric_port_id_t portId) override;
ze_result_t disable(const zes_fabric_port_id_t portId) override;
ze_result_t enableUsage(const zes_fabric_port_id_t portId) override;
ze_result_t disableUsage(const zes_fabric_port_id_t portId) override;
ze_result_t forceSweep() override;
ze_result_t routingQuery(uint32_t &start, uint32_t &end) override;
ze_result_t getPorts(std::vector<zes_fabric_port_id_t> &ports) override;
void 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) override;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp.h"
#include <cstdio>
namespace L0 {
namespace Sysman {
uint32_t LinuxFabricDeviceImp::getNumPorts() {
return numPorts;
}
LinuxFabricDeviceImp::LinuxFabricDeviceImp(OsSysman *pOsSysman) {
}
LinuxFabricDeviceImp::~LinuxFabricDeviceImp() {
}
ze_result_t LinuxFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) {
::snprintf(pLinkType->desc, ZES_MAX_FABRIC_LINK_TYPE_SIZE, "%s", "SAMPLE LINK, VERBOSE");
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) {
*pConfig = config;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) {
config = *pConfig;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::getState(zes_fabric_port_state_t *pState) {
pState->status = ZES_FABRIC_PORT_STATUS_UNKNOWN;
pState->qualityIssues = 0U;
pState->failureReasons = 0U;
pState->remotePortId.fabricId = 0U;
pState->remotePortId.attachId = 0U;
pState->remotePortId.portNumber = 0U;
pState->rxSpeed.bitRate = 0LU;
pState->rxSpeed.width = 0U;
pState->txSpeed.bitRate = 0LU;
pState->txSpeed.width = 0U;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) {
pThroughput->rxCounter = 0LU;
pThroughput->txCounter = 0LU;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t LinuxFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) {
::snprintf(pProperties->model, ZES_MAX_FABRIC_PORT_MODEL_SIZE, "%s", this->model.c_str());
pProperties->onSubdevice = false;
pProperties->subdeviceId = 0U;
pProperties->portId = this->portId;
pProperties->maxRxSpeed = this->maxRxSpeed;
pProperties->maxTxSpeed = this->maxTxSpeed;
return ZE_RESULT_SUCCESS;
}
LinuxFabricPortImp::LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
this->portNum = portNum;
model = std::string("EXAMPLE");
}
LinuxFabricPortImp::~LinuxFabricPortImp() {
}
OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) {
LinuxFabricDeviceImp *pLinuxFabricDeviceImp = new LinuxFabricDeviceImp(pOsSysman);
return pLinuxFabricDeviceImp;
}
OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
LinuxFabricPortImp *pLinuxFabricPortImp = new LinuxFabricPortImp(pOsFabricDevice, portNum);
return pLinuxFabricPortImp;
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h"
#include "level_zero/sysman/source/fabric_port/os_fabric_port.h"
#include "level_zero/sysman/source/linux/fs_access.h"
namespace L0 {
namespace Sysman {
class LinuxFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass {
public:
uint32_t getNumPorts() override;
LinuxFabricDeviceImp() = delete;
LinuxFabricDeviceImp(OsSysman *pOsSysman);
~LinuxFabricDeviceImp() override;
private:
uint32_t numPorts = 0;
};
class LinuxFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override;
ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override;
ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override;
ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override;
ze_result_t getState(zes_fabric_port_state_t *pState) override;
ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override;
ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override;
LinuxFabricPortImp() = delete;
LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum);
~LinuxFabricPortImp() override;
private:
uint32_t portNum = 0;
std::string model = "";
zes_fabric_port_id_t portId = {};
zes_fabric_port_speed_t maxRxSpeed = {};
zes_fabric_port_speed_t maxTxSpeed = {};
zes_fabric_port_config_t config = {};
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,321 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/linux/os_fabric_port_imp_prelim.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/helpers/debug_helpers.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
#include <cstdio>
namespace L0 {
namespace Sysman {
uint32_t LinuxFabricDeviceImp::getNumPorts() {
pFabricDeviceAccess->getPorts(portIds);
return static_cast<uint32_t>(portIds.size());
}
void LinuxFabricDeviceImp::getPortId(uint32_t portNumber, zes_fabric_port_id_t &portId) {
UNRECOVERABLE_IF(getNumPorts() <= portNumber);
portId = portIds[portNumber];
}
void LinuxFabricDeviceImp::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) {
pFabricDeviceAccess->getProperties(portId, model, onSubdevice, subdeviceId, maxRxSpeed, maxTxSpeed);
}
ze_result_t LinuxFabricDeviceImp::getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t *pState) {
return pFabricDeviceAccess->getState(portId, *pState);
}
ze_result_t LinuxFabricDeviceImp::getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t *pThroughput) {
return pFabricDeviceAccess->getThroughput(portId, *pThroughput);
}
ze_result_t LinuxFabricDeviceImp::getErrorCounters(const zes_fabric_port_id_t portId, zes_fabric_port_error_counters_t *pErrors) {
FsAccess *pFsAccess = &pLinuxSysmanImp->getFsAccess();
SysfsAccess *pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
std::string devicePciPath("");
ze_result_t result = pSysfsAccess->getRealPath("device/", devicePciPath);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to get device path> <result: 0x%x>\n", __func__, result);
return result;
}
std::string path("");
std::vector<std::string> list;
result = pFsAccess->listDirectory(devicePciPath, list);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to get list of files in device directory> <result: 0x%x>\n", __func__, result);
return result;
}
for (auto entry : list) {
if ((entry.find("i915.iaf.") != std::string::npos) ||
(entry.find("iaf.") != std::string::npos)) {
path = devicePciPath + "/" + entry;
break;
}
}
if (path.empty()) {
// This device does not have a fabric
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <Device does not have fabric>\n", __func__);
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
std::string fabricFwErrorPath = path + "/sd." + std::to_string(portId.attachId);
std::string fabricLinkErrorPath = path + "/sd." + std::to_string(portId.attachId) + "/port." + std::to_string(portId.portNumber);
uint64_t linkErrorCount = 0;
std::string linkFailureFile = fabricLinkErrorPath + "/link_failures";
result = pFsAccess->read(linkFailureFile, linkErrorCount);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to read file %s> <result: 0x%x>\n", __func__, linkFailureFile.c_str(), result);
linkErrorCount = 0;
}
uint64_t linkDegradeCount = 0;
std::string linkDegradeFile = fabricLinkErrorPath + "/link_degrades";
result = pFsAccess->read(linkDegradeFile, linkDegradeCount);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to read file %s> <result: 0x%x>\n", __func__, linkDegradeFile.c_str(), result);
linkDegradeCount = 0;
}
uint64_t fwErrorCount = 0;
std::string fwErrorFile = fabricFwErrorPath + "/fw_error";
result = pFsAccess->read(fwErrorFile, fwErrorCount);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to read file %s> <result: 0x%x>\n", __func__, fwErrorFile.c_str(), result);
fwErrorCount = 0;
}
uint64_t fwCommErrorCount = 0;
std::string fwCommErrorFile = fabricFwErrorPath + "/fw_comm_errors";
result = pFsAccess->read(fwCommErrorFile, fwCommErrorCount);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"error@<%s> <failed to read file %s> <result: 0x%x>\n", __func__, fwCommErrorFile.c_str(), result);
fwCommErrorCount = 0;
}
pErrors->linkFailureCount = linkErrorCount;
pErrors->linkDegradeCount = linkDegradeCount;
pErrors->fwErrorCount = fwErrorCount;
pErrors->fwCommErrorCount = fwCommErrorCount;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricDeviceImp::performSweep() {
uint32_t start = 0U;
uint32_t end = 0U;
ze_result_t result = ZE_RESULT_SUCCESS;
result = forceSweep();
if (ZE_RESULT_SUCCESS != result) {
return result;
}
result = routingQuery(start, end);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
while (end < start) {
uint32_t newStart;
result = routingQuery(newStart, end);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
}
return result;
}
ze_result_t LinuxFabricDeviceImp::getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled) {
return pFabricDeviceAccess->getPortEnabledState(portId, enabled);
}
ze_result_t LinuxFabricDeviceImp::enablePort(const zes_fabric_port_id_t portId) {
ze_result_t result = enable(portId);
// usage should be enabled, but make sure in case of previous errors
enableUsage(portId);
return result;
}
ze_result_t LinuxFabricDeviceImp::disablePort(const zes_fabric_port_id_t portId) {
ze_result_t result = ZE_RESULT_SUCCESS;
result = disableUsage(portId);
if (ZE_RESULT_SUCCESS == result) {
result = disable(portId);
if (ZE_RESULT_SUCCESS == result) {
return enableUsage(portId);
}
}
// Try not so leave port usage disabled on an error
enableUsage(portId);
return result;
}
ze_result_t LinuxFabricDeviceImp::getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled) {
return pFabricDeviceAccess->getPortBeaconState(portId, enabled);
}
ze_result_t LinuxFabricDeviceImp::enablePortBeaconing(const zes_fabric_port_id_t portId) {
return pFabricDeviceAccess->enablePortBeaconing(portId);
}
ze_result_t LinuxFabricDeviceImp::disablePortBeaconing(const zes_fabric_port_id_t portId) {
return pFabricDeviceAccess->disablePortBeaconing(portId);
}
ze_result_t LinuxFabricDeviceImp::enable(const zes_fabric_port_id_t portId) {
ze_result_t result = ZE_RESULT_SUCCESS;
result = pFabricDeviceAccess->enable(portId);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return performSweep();
}
ze_result_t LinuxFabricDeviceImp::disable(const zes_fabric_port_id_t portId) {
ze_result_t result = ZE_RESULT_SUCCESS;
result = pFabricDeviceAccess->disable(portId);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return performSweep();
}
ze_result_t LinuxFabricDeviceImp::enableUsage(const zes_fabric_port_id_t portId) {
ze_result_t result = ZE_RESULT_SUCCESS;
result = pFabricDeviceAccess->enableUsage(portId);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return performSweep();
}
ze_result_t LinuxFabricDeviceImp::disableUsage(const zes_fabric_port_id_t portId) {
ze_result_t result = ZE_RESULT_SUCCESS;
result = pFabricDeviceAccess->disableUsage(portId);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
return performSweep();
}
ze_result_t LinuxFabricDeviceImp::forceSweep() {
return pFabricDeviceAccess->forceSweep();
}
ze_result_t LinuxFabricDeviceImp::routingQuery(uint32_t &start, uint32_t &end) {
return pFabricDeviceAccess->routingQuery(start, end);
}
LinuxFabricDeviceImp::LinuxFabricDeviceImp(OsSysman *pOsSysman) {
pFabricDeviceAccess = FabricDeviceAccess::create(pOsSysman);
UNRECOVERABLE_IF(nullptr == pFabricDeviceAccess);
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
}
LinuxFabricDeviceImp::~LinuxFabricDeviceImp() {
delete pFabricDeviceAccess;
}
ze_result_t LinuxFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) {
::snprintf(pLinkType->desc, ZES_MAX_FABRIC_LINK_TYPE_SIZE, "%s", "XeLink");
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) {
ze_result_t result = ZE_RESULT_SUCCESS;
bool enabled = false;
result = pLinuxFabricDeviceImp->getPortEnabledState(portId, enabled);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
pConfig->enabled = enabled == true;
result = pLinuxFabricDeviceImp->getPortBeaconState(portId, enabled);
if (ZE_RESULT_SUCCESS != result) {
return result;
}
pConfig->beaconing = enabled == true;
return result;
}
ze_result_t LinuxFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) {
ze_result_t result = ZE_RESULT_SUCCESS;
bool enabled = false;
result = pLinuxFabricDeviceImp->getPortEnabledState(portId, enabled);
if (ZE_RESULT_SUCCESS == result && enabled != pConfig->enabled) {
if (pConfig->enabled) {
result = pLinuxFabricDeviceImp->enablePort(portId);
} else {
result = pLinuxFabricDeviceImp->disablePort(portId);
}
}
if (ZE_RESULT_SUCCESS != result) {
return result;
}
bool beaconing = false;
result = pLinuxFabricDeviceImp->getPortBeaconState(portId, beaconing);
if (ZE_RESULT_SUCCESS == result && beaconing != pConfig->beaconing) {
if (pConfig->beaconing) {
result = pLinuxFabricDeviceImp->enablePortBeaconing(portId);
} else {
result = pLinuxFabricDeviceImp->disablePortBeaconing(portId);
}
}
return result;
}
ze_result_t LinuxFabricPortImp::getState(zes_fabric_port_state_t *pState) {
return pLinuxFabricDeviceImp->getState(portId, pState);
}
ze_result_t LinuxFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) {
return pLinuxFabricDeviceImp->getThroughput(portId, pThroughput);
}
ze_result_t LinuxFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) {
return pLinuxFabricDeviceImp->getErrorCounters(portId, pErrors);
}
ze_result_t LinuxFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) {
::snprintf(pProperties->model, ZES_MAX_FABRIC_PORT_MODEL_SIZE, "%s", this->model.c_str());
pProperties->onSubdevice = this->onSubdevice;
pProperties->subdeviceId = this->subdeviceId;
pProperties->portId = this->portId;
pProperties->maxRxSpeed = this->maxRxSpeed;
pProperties->maxTxSpeed = this->maxTxSpeed;
return ZE_RESULT_SUCCESS;
}
LinuxFabricPortImp::LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
pLinuxFabricDeviceImp = static_cast<LinuxFabricDeviceImp *>(pOsFabricDevice);
this->portNum = portNum;
pLinuxFabricDeviceImp->getPortId(this->portNum, this->portId);
pLinuxFabricDeviceImp->getProperties(this->portId, this->model, this->onSubdevice, this->subdeviceId, this->maxRxSpeed, this->maxTxSpeed);
}
LinuxFabricPortImp::~LinuxFabricPortImp() {
}
OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) {
LinuxFabricDeviceImp *pLinuxFabricDeviceImp = new LinuxFabricDeviceImp(pOsSysman);
return pLinuxFabricDeviceImp;
}
OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
LinuxFabricPortImp *pLinuxFabricPortImp = new LinuxFabricPortImp(pOsFabricDevice, portNum);
return pLinuxFabricPortImp;
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h"
#include "level_zero/sysman/source/fabric_port/linux/fabric_device_access.h"
#include "level_zero/sysman/source/fabric_port/os_fabric_port.h"
#include <vector>
namespace L0 {
namespace Sysman {
class LinuxSysmanImp;
class LinuxFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass {
public:
uint32_t getNumPorts() override;
ze_result_t performSweep();
ze_result_t getPortEnabledState(const zes_fabric_port_id_t portId, bool &enabled);
ze_result_t enablePort(const zes_fabric_port_id_t portId);
ze_result_t disablePort(const zes_fabric_port_id_t portId);
ze_result_t getPortBeaconState(const zes_fabric_port_id_t portId, bool &enabled);
ze_result_t enablePortBeaconing(const zes_fabric_port_id_t portId);
ze_result_t disablePortBeaconing(const zes_fabric_port_id_t portId);
ze_result_t getState(const zes_fabric_port_id_t portId, zes_fabric_port_state_t *pState);
ze_result_t getThroughput(const zes_fabric_port_id_t portId, zes_fabric_port_throughput_t *pThroughput);
ze_result_t getErrorCounters(const zes_fabric_port_id_t portId, zes_fabric_port_error_counters_t *pErrors);
void getPortId(const uint32_t portNumber, zes_fabric_port_id_t &portId);
void 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);
LinuxFabricDeviceImp() = delete;
LinuxFabricDeviceImp(OsSysman *pOsSysman);
~LinuxFabricDeviceImp() override;
private:
std::vector<zes_fabric_port_id_t> portIds = {};
ze_result_t forceSweep();
ze_result_t routingQuery(uint32_t &start, uint32_t &end);
ze_result_t enable(const zes_fabric_port_id_t portId);
ze_result_t disable(const zes_fabric_port_id_t portId);
ze_result_t enableUsage(const zes_fabric_port_id_t portId);
ze_result_t disableUsage(const zes_fabric_port_id_t portId);
protected:
LinuxSysmanImp *pLinuxSysmanImp = nullptr;
FabricDeviceAccess *pFabricDeviceAccess = nullptr;
};
class LinuxFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override;
ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override;
ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override;
ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override;
ze_result_t getState(zes_fabric_port_state_t *pState) override;
ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override;
ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override;
LinuxFabricPortImp() = delete;
LinuxFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum);
~LinuxFabricPortImp() override;
private:
LinuxFabricDeviceImp *pLinuxFabricDeviceImp = nullptr;
uint32_t portNum = 0;
zes_fabric_port_id_t portId = {};
std::string model = "";
bool onSubdevice = false;
uint32_t subdeviceId;
zes_fabric_port_speed_t maxRxSpeed = {};
zes_fabric_port_speed_t maxTxSpeed = {};
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/sysman/source/os_sysman.h"
#include <level_zero/zes_api.h>
namespace L0 {
namespace Sysman {
class OsFabricDevice {
public:
virtual uint32_t getNumPorts() = 0;
static OsFabricDevice *create(OsSysman *pOsSysman);
virtual ~OsFabricDevice() = default;
};
class OsFabricPort {
public:
virtual ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) = 0;
virtual ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) = 0;
virtual ze_result_t getConfig(zes_fabric_port_config_t *pConfig) = 0;
virtual ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) = 0;
virtual ze_result_t getState(zes_fabric_port_state_t *pState) = 0;
virtual ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) = 0;
virtual ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) = 0;
static OsFabricPort *create(OsFabricDevice *pOsFabricDevice, uint32_t portNum);
virtual ~OsFabricPort() = default;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,21 @@
#
# Copyright (C) 2020-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_SYSMAN_FABRICPORT_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_fabric_port_imp.h
)
if(WIN32)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${L0_SRCS_SYSMAN_FABRICPORT_WINDOWS}
)
endif()
## Make our source files visible to parent
set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_FABRICPORT_WINDOWS ${L0_SRCS_SYSMAN_FABRICPORT_WINDOWS})

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/fabric_port/windows/os_fabric_port_imp.h"
#include <cstring>
namespace L0 {
namespace Sysman {
uint32_t WddmFabricDeviceImp::getNumPorts() {
return numPorts;
}
WddmFabricDeviceImp::WddmFabricDeviceImp(OsSysman *pOsSysman) {
}
WddmFabricDeviceImp::~WddmFabricDeviceImp() {
}
ze_result_t WddmFabricPortImp::getLinkType(zes_fabric_link_type_t *pLinkType) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::getConfig(zes_fabric_port_config_t *pConfig) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::setConfig(const zes_fabric_port_config_t *pConfig) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::getState(zes_fabric_port_state_t *pState) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::getThroughput(zes_fabric_port_throughput_t *pThroughput) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::getErrorCounters(zes_fabric_port_error_counters_t *pErrors) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmFabricPortImp::getProperties(zes_fabric_port_properties_t *pProperties) {
::memset(pProperties->model, '\0', ZES_MAX_FABRIC_PORT_MODEL_SIZE);
pProperties->onSubdevice = false;
pProperties->subdeviceId = 0U;
::memset(&pProperties->portId, '\0', sizeof(pProperties->portId));
::memset(&pProperties->maxRxSpeed, '\0', sizeof(pProperties->maxRxSpeed));
::memset(&pProperties->maxTxSpeed, '\0', sizeof(pProperties->maxTxSpeed));
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
WddmFabricPortImp::WddmFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
}
WddmFabricPortImp::~WddmFabricPortImp() {
}
OsFabricDevice *OsFabricDevice::create(OsSysman *pOsSysman) {
WddmFabricDeviceImp *pWddmFabricDeviceImp = new WddmFabricDeviceImp(pOsSysman);
return pWddmFabricDeviceImp;
}
OsFabricPort *OsFabricPort::create(OsFabricDevice *pOsFabricDevice, uint32_t portNum) {
WddmFabricPortImp *pWddmFabricPortImp = new WddmFabricPortImp(pOsFabricDevice, portNum);
return pWddmFabricPortImp;
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/fabric_port/fabric_port_imp.h"
#include "level_zero/sysman/source/fabric_port/os_fabric_port.h"
namespace L0 {
namespace Sysman {
class WddmFabricDeviceImp : public OsFabricDevice, NEO::NonCopyableOrMovableClass {
public:
uint32_t getNumPorts() override;
WddmFabricDeviceImp() = delete;
WddmFabricDeviceImp(OsSysman *pOsSysman);
~WddmFabricDeviceImp() override;
private:
uint32_t numPorts = 0;
};
class WddmFabricPortImp : public OsFabricPort, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getProperties(zes_fabric_port_properties_t *pProperties) override;
ze_result_t getLinkType(zes_fabric_link_type_t *pLinkType) override;
ze_result_t getConfig(zes_fabric_port_config_t *pConfig) override;
ze_result_t setConfig(const zes_fabric_port_config_t *pConfig) override;
ze_result_t getState(zes_fabric_port_state_t *pState) override;
ze_result_t getThroughput(zes_fabric_port_throughput_t *pThroughput) override;
ze_result_t getErrorCounters(zes_fabric_port_error_counters_t *pErrors) override;
WddmFabricPortImp() = delete;
WddmFabricPortImp(OsFabricDevice *pOsFabricDevice, uint32_t portNum);
~WddmFabricPortImp() override;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,24 @@
#
# Copyright (C) 2020-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(LIBGENL_FOUND)
set(L0_SRCS_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()
if(UNIX)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${L0_SRCS_SYSMAN_LINUX_NL_API}
)
endif()
# Make our source files visible to parent
set_property(GLOBAL PROPERTY L0_SRCS_SYSMAN_LINUX_NL_API ${L0_SRCS_SYSMAN_LINUX_NL_API})

View File

@@ -0,0 +1,871 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/linux/nl_api/iaf_nl_api.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "shared/source/utilities/directory.h"
#include <fcntl.h>
#include <limits>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
#include <sys/socket.h>
namespace L0 {
namespace Sysman {
extern "C" {
// C linkage callback routines for Netlink
static int globalHandleMsg(struct nl_msg *msg, void *arg) {
IafNlApi *pIafNlApi = reinterpret_cast<IafNlApi *>(arg);
return pIafNlApi->handleMsg(msg);
}
static int globalNlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info, void *arg) {
IafNlApi *pIafNlApi = reinterpret_cast<IafNlApi *>(arg);
return pIafNlApi->nlOperation(ops, cmd, info);
}
}
static const struct {
int id;
char *name;
} iafCmds[] = {
{.id = IAF_CMD_OP_DEVICE_ENUM, .name = const_cast<char *>("DEVICE_ENUM")},
{.id = IAF_CMD_OP_PORT_ENABLE, .name = const_cast<char *>("PORT_ENABLE")},
{.id = IAF_CMD_OP_PORT_DISABLE, .name = const_cast<char *>("PORT_DISABLE")},
{.id = IAF_CMD_OP_PORT_STATE_QUERY, .name = const_cast<char *>("PORT_STATE_QUERY")},
{.id = IAF_CMD_OP_PORT_USAGE_ENABLE, .name = const_cast<char *>("PORT_USAGE_ENABLE")},
{.id = IAF_CMD_OP_PORT_USAGE_DISABLE, .name = const_cast<char *>("PORT_USAGE_DISABLE")},
{.id = IAF_CMD_OP_PORT_USAGE_STATE_QUERY, .name = const_cast<char *>("PORT_USAGE_STATE_QUERY")},
{.id = IAF_CMD_OP_PORT_BEACON_ENABLE, .name = const_cast<char *>("PORT_BEACON_ENABLE")},
{.id = IAF_CMD_OP_PORT_BEACON_DISABLE, .name = const_cast<char *>("PORT_BEACON_DISABLE")},
{.id = IAF_CMD_OP_PORT_BEACON_STATE_QUERY, .name = const_cast<char *>("PORT_BEACON_STATE_QUERY")},
{.id = IAF_CMD_OP_PORT_ROUTED_QUERY, .name = const_cast<char *>("PORT_ROUTED_QUERY")},
{.id = IAF_CMD_OP_REM_REQUEST, .name = const_cast<char *>("REM_REQUEST")},
{.id = IAF_CMD_OP_ROUTING_GEN_QUERY, .name = const_cast<char *>("ROUTING_GEN_QUERY")},
{.id = IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, .name = const_cast<char *>("FABRIC_DEVICE_PROPERTIES")},
{.id = IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, .name = const_cast<char *>("SUB_DEVICE_PROPERTIES_GET")},
{.id = IAF_CMD_OP_FPORT_STATUS_QUERY, .name = const_cast<char *>("FPORT_STATUS_QUERY")},
{.id = IAF_CMD_OP_SUB_DEVICE_TRAP_COUNT_QUERY, .name = const_cast<char *>("FPORT_EVENT_COUNT_QUERY")},
{.id = IAF_CMD_OP_FPORT_PROPERTIES, .name = const_cast<char *>("FPORT_PROPERTIES")},
{.id = IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS, .name = const_cast<char *>("FPORT_XMIT_RECV_COUNTS")},
{.id = 0, .name = nullptr},
};
struct PortProperties {
uint64_t neighborGuid;
uint8_t neighborPortNumber;
int32_t enabledRxWidth;
int64_t enabledRxBitrate;
int32_t activeRxWidth;
int64_t activeRxBitrate;
int32_t enabledTxWidth;
int64_t enabledTxBitrate;
int32_t activeTxWidth;
int64_t activeTxBitrate;
};
struct Subdevice {
uint64_t guid;
std::vector<uint8_t> ports;
};
struct Generation {
uint32_t start;
uint32_t end;
};
ze_result_t IafNlApi::allocMsg(const uint16_t cmdOp, struct nl_msg *&msg) {
msg = pNlApi->nlmsgAlloc();
if (nullptr == msg) {
return ZE_RESULT_ERROR_UNKNOWN;
}
if (nullptr == pNlApi->genlmsgPut(msg, NL_AUTO_PID, NL_AUTO_SEQ, familyId, 0, 0, cmdOp, 1)) {
pNlApi->nlmsgFree(msg);
msg = nullptr;
return ZE_RESULT_ERROR_UNKNOWN;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, const uint8_t portNumber, void *pOutput) {
ze_result_t result = init();
if (ZE_RESULT_SUCCESS != result) {
return result;
}
struct nl_msg *msg;
result = allocMsg(cmdOp, msg);
if (ZE_RESULT_SUCCESS == result) {
pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId);
pNlApi->nlaPutU8(msg, IAF_ATTR_SD_INDEX, attachId);
pNlApi->nlaPutU8(msg, IAF_ATTR_FABRIC_PORT_NUMBER, portNumber);
result = performTransaction(cmdOp, msg, pOutput);
}
cleanup();
return result;
}
ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, void *pOutput) {
ze_result_t result = init();
if (ZE_RESULT_SUCCESS != result) {
return result;
}
struct nl_msg *msg;
result = allocMsg(cmdOp, msg);
if (ZE_RESULT_SUCCESS == result) {
pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId);
pNlApi->nlaPutU8(msg, IAF_ATTR_SD_INDEX, attachId);
result = performTransaction(cmdOp, msg, pOutput);
}
cleanup();
return result;
}
ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, const uint32_t fabricId, void *pOutput) {
ze_result_t result = init();
if (ZE_RESULT_SUCCESS != result) {
return result;
}
struct nl_msg *msg;
result = allocMsg(cmdOp, msg);
if (ZE_RESULT_SUCCESS == result) {
pNlApi->nlaPutU32(msg, IAF_ATTR_FABRIC_ID, fabricId);
result = performTransaction(cmdOp, msg, pOutput);
}
cleanup();
return result;
}
ze_result_t IafNlApi::issueRequest(const uint16_t cmdOp, void *pOutput) {
ze_result_t result = init();
if (ZE_RESULT_SUCCESS != result) {
return result;
}
struct nl_msg *msg;
result = allocMsg(cmdOp, msg);
if (ZE_RESULT_SUCCESS == result) {
result = performTransaction(cmdOp, msg, pOutput);
}
cleanup();
return result;
}
ze_result_t IafNlApi::performTransaction(const uint16_t cmdOp, struct nl_msg *msg, void *pOutput) {
Operation *pOperation = new Operation(cmdOp, pOutput);
uint64_t context = reinterpret_cast<uint64_t>(pOperation);
pNlApi->nlaPutU64(msg, IAF_ATTR_CMD_OP_CONTEXT, context);
pNlApi->nlaPutU8(msg, IAF_ATTR_CMD_OP_MSG_TYPE, IAF_CMD_MSG_REQUEST);
validContexts.push_back(context);
if (0 > pNlApi->nlSendAuto(nlSock, msg)) {
pOperation->done = true;
}
pNlApi->nlmsgFree(msg);
while (!pOperation->done) {
int res = pNlApi->nlRecvmsgsDefault(nlSock);
if (0 > res) {
if (-NLE_PERM == res) {
pOperation->result = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
pOperation->done = true;
}
}
validContexts.remove(context);
ze_result_t result = pOperation->result;
delete pOperation;
return result;
}
ze_result_t IafNlApi::handleResponse(const uint16_t cmdOp, struct genl_info *info, void *pOutput) {
switch (cmdOp) {
case IAF_CMD_OP_FPORT_STATUS_QUERY:
return fPortStatusQueryRsp(info, pOutput);
case IAF_CMD_OP_FPORT_XMIT_RECV_COUNTS:
return getThroughputRsp(info, pOutput);
case IAF_CMD_OP_PORT_STATE_QUERY:
return portStateQueryRsp(info, pOutput);
case IAF_CMD_OP_PORT_BEACON_STATE_QUERY:
return portBeaconStateQueryRsp(info, pOutput);
case IAF_CMD_OP_ROUTING_GEN_QUERY:
return routingGenQueryRsp(info, pOutput);
case IAF_CMD_OP_DEVICE_ENUM:
return deviceEnumRsp(info, pOutput);
case IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES:
return fabricDevicePropertiesRsp(info, pOutput);
case IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET:
return subdevicePropertiesGetRsp(info, pOutput);
case IAF_CMD_OP_FPORT_PROPERTIES:
return fportPropertiesRsp(info, pOutput);
case IAF_CMD_OP_PORT_BEACON_ENABLE:
case IAF_CMD_OP_PORT_BEACON_DISABLE:
case IAF_CMD_OP_PORT_ENABLE:
case IAF_CMD_OP_PORT_DISABLE:
case IAF_CMD_OP_PORT_USAGE_ENABLE:
case IAF_CMD_OP_PORT_USAGE_DISABLE:
case IAF_CMD_OP_REM_REQUEST:
return ZE_RESULT_SUCCESS;
default:
return ZE_RESULT_ERROR_UNKNOWN;
}
}
ze_result_t IafNlApi::fPortStatusQueryRsp(struct genl_info *info, void *pOutput) {
IafPortState *pState = reinterpret_cast<IafPortState *>(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) {
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:
pState->healthStatus = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ISSUE_LQI:
pState->lqi = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ISSUE_LWD:
pState->lwd = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ISSUE_RATE:
pState->rate = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ERROR_FAILED:
pState->failed = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ERROR_ISOLATED:
pState->isolated = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ERROR_FLAPPING:
pState->flapping = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ERROR_LINK_DOWN:
pState->linkDown = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN:
pState->didNotTrain = pNlApi->nlaGetU8(cur);
break;
default:
break;
}
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::getThroughputRsp(struct genl_info *info, void *pOutput) {
IafPortThroughPut *pThroughput = reinterpret_cast<IafPortThroughPut *>(pOutput);
pThroughput->txCounter = 0UL;
pThroughput->rxCounter = 0UL;
if (info->attrs[IAF_ATTR_FPORT_TX_BYTES]) {
pThroughput->txCounter = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_FPORT_TX_BYTES]);
}
if (info->attrs[IAF_ATTR_FPORT_RX_BYTES]) {
pThroughput->rxCounter = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_FPORT_RX_BYTES]);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::portStateQueryRsp(struct genl_info *info, void *pOutput) {
bool *pEnabled = reinterpret_cast<bool *>(pOutput);
const struct nlmsghdr *nlh = info->nlh;
*pEnabled = false;
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->nlaIsNested(nla)) {
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_ENABLED_STATE:
*pEnabled = (0 != pNlApi->nlaGetU8(cur));
break;
default:
break;
}
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::portBeaconStateQueryRsp(struct genl_info *info, void *pOutput) {
bool *pEnabled = reinterpret_cast<bool *>(pOutput);
const struct nlmsghdr *nlh = info->nlh;
*pEnabled = false;
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->nlaIsNested(nla)) {
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_ENABLED_STATE:
*pEnabled = (0 != pNlApi->nlaGetU8(cur));
break;
default:
break;
}
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::routingGenQueryRsp(struct genl_info *info, void *pOutput) {
Generation *pGeneration = reinterpret_cast<Generation *>(pOutput);
if (info->attrs[IAF_ATTR_ROUTING_GEN_START]) {
pGeneration->start = pNlApi->nlaGetU32(info->attrs[IAF_ATTR_ROUTING_GEN_START]);
}
if (info->attrs[IAF_ATTR_ROUTING_GEN_END]) {
pGeneration->end = pNlApi->nlaGetU32(info->attrs[IAF_ATTR_ROUTING_GEN_END]);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::deviceEnumRsp(struct genl_info *info, void *pOutput) {
std::vector<uint32_t> *pFabricIds = reinterpret_cast<std::vector<uint32_t> *>(pOutput);
const struct nlmsghdr *nlh = info->nlh;
pFabricIds->clear();
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->nlaIsNested(nla)) {
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_FABRIC_ID:
pFabricIds->push_back(pNlApi->nlaGetU32(cur));
break;
default:
break;
}
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::fabricDevicePropertiesRsp(struct genl_info *info, void *pOutput) {
uint32_t *pNumSubdevices = reinterpret_cast<uint32_t *>(pOutput);
*pNumSubdevices = 0;
if (info->attrs[IAF_ATTR_SUBDEVICE_COUNT]) {
*pNumSubdevices = pNlApi->nlaGetU8(info->attrs[IAF_ATTR_SUBDEVICE_COUNT]);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::subdevicePropertiesGetRsp(struct genl_info *info, void *pOutput) {
Subdevice *pSubdevice = reinterpret_cast<Subdevice *>(pOutput);
const struct nlmsghdr *nlh = info->nlh;
if (info->attrs[IAF_ATTR_GUID]) {
pSubdevice->guid = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_GUID]);
}
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 port = 0;
uint8_t type = IAF_FPORT_TYPE_DISCONNECTED;
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_FABRIC_PORT_NUMBER:
port = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FABRIC_PORT_TYPE:
type = pNlApi->nlaGetU8(cur);
break;
default:
break;
}
}
if (0 != port && IAF_FPORT_TYPE_DISCONNECTED != type) {
pSubdevice->ports.push_back(port);
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t IafNlApi::fportPropertiesRsp(struct genl_info *info, void *pOutput) {
PortProperties *pPortProperties = reinterpret_cast<PortProperties *>(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) {
int32_t activeWidth = -1;
int32_t degradedRxWidth = -1;
int32_t degradedTxWidth = -1;
int64_t activeBitrate = -1;
int64_t maxBitrate = -1;
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_NEIGHBOR_GUID:
pPortProperties->neighborGuid = pNlApi->nlaGetU64(cur);
break;
case IAF_ATTR_FPORT_NEIGHBOR_PORT_NUMBER:
pPortProperties->neighborPortNumber = pNlApi->nlaGetU8(cur);
break;
case IAF_ATTR_FPORT_LINK_WIDTH_ENABLED:
pPortProperties->enabledRxWidth = pPortProperties->enabledTxWidth = translateWidth(pNlApi->nlaGetU8(cur));
break;
case IAF_ATTR_FPORT_LINK_WIDTH_ACTIVE:
activeWidth = translateWidth(pNlApi->nlaGetU8(cur));
break;
case IAF_ATTR_FPORT_BPS_LINK_SPEED_ACTIVE:
activeBitrate = pNlApi->nlaGetU64(cur);
break;
case IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_RX_ACTIVE:
degradedRxWidth = translateWidth(pNlApi->nlaGetU8(cur));
break;
case IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_TX_ACTIVE:
degradedTxWidth = translateWidth(pNlApi->nlaGetU8(cur));
break;
case IAF_ATTR_FPORT_BPS_LINK_SPEED_MAX:
maxBitrate = pNlApi->nlaGetU64(cur);
break;
default:
break;
}
}
if (-1 != degradedRxWidth) {
pPortProperties->activeRxWidth = degradedRxWidth;
} else {
pPortProperties->activeRxWidth = activeWidth;
}
if (-1 != degradedTxWidth) {
pPortProperties->activeTxWidth = degradedTxWidth;
} else {
pPortProperties->activeTxWidth = activeWidth;
}
if (0 != activeBitrate) {
pPortProperties->activeRxBitrate = pPortProperties->activeTxBitrate = activeBitrate;
}
if (0 != maxBitrate) {
pPortProperties->enabledRxBitrate = pPortProperties->enabledTxBitrate = maxBitrate;
}
}
}
return ZE_RESULT_SUCCESS;
}
int32_t IafNlApi::translateWidth(uint8_t width) {
if (width & 0x8) {
return 4;
}
if (width & 0x4) {
return 3;
}
if (width & 0x2) {
return 2;
}
if (width & 0x1) {
return 1;
}
return -1;
}
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<void *>(&state));
}
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<void *>(&throughput));
}
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<void *>(&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<void *>(&enabled));
}
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 IafPortId portId) {
return issueRequest(IAF_CMD_OP_PORT_BEACON_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr);
}
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 IafPortId portId) {
return issueRequest(IAF_CMD_OP_PORT_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr);
}
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 IafPortId portId) {
return issueRequest(IAF_CMD_OP_PORT_USAGE_DISABLE, portId.fabricId, portId.attachId, portId.portNumber, nullptr);
}
ze_result_t IafNlApi::remRequest() {
return issueRequest(IAF_CMD_OP_REM_REQUEST, nullptr);
}
ze_result_t IafNlApi::routingGenQuery(uint32_t &start, uint32_t &end) {
Generation gen;
gen.start = gen.end = 0;
ze_result_t result = issueRequest(IAF_CMD_OP_ROUTING_GEN_QUERY, reinterpret_cast<void *>(&gen));
if (ZE_RESULT_SUCCESS == result) {
start = gen.start;
end = gen.end;
}
return result;
}
ze_result_t IafNlApi::deviceEnum(std::vector<uint32_t> &fabricIds) {
return issueRequest(IAF_CMD_OP_DEVICE_ENUM, reinterpret_cast<void *>(&fabricIds));
}
ze_result_t IafNlApi::fabricDeviceProperties(const uint32_t fabricId, uint32_t &numSubdevices) {
return issueRequest(IAF_CMD_OP_FABRIC_DEVICE_PROPERTIES, fabricId, reinterpret_cast<void *>(&numSubdevices));
}
ze_result_t IafNlApi::subdevicePropertiesGet(const uint32_t fabricId, const uint32_t attachId, uint64_t &guid, std::vector<uint8_t> &ports) {
Subdevice sd;
sd.guid = 0;
sd.ports.clear();
ze_result_t result = issueRequest(IAF_CMD_OP_SUB_DEVICE_PROPERTIES_GET, fabricId, attachId, reinterpret_cast<void *>(&sd));
if (ZE_RESULT_SUCCESS == result) {
guid = sd.guid;
ports = sd.ports;
}
return result;
}
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;
portProperties.enabledRxWidth = -1;
portProperties.enabledRxBitrate = -1L;
portProperties.activeRxWidth = -1;
portProperties.activeRxBitrate = -1L;
portProperties.enabledTxWidth = -1;
portProperties.enabledTxBitrate = -1L;
portProperties.activeTxWidth = -1;
portProperties.activeTxBitrate = -1L;
ze_result_t result = issueRequest(IAF_CMD_OP_FPORT_PROPERTIES, portId.fabricId, portId.attachId, portId.portNumber, reinterpret_cast<void *>(&portProperties));
if (ZE_RESULT_SUCCESS == result) {
neighborGuid = portProperties.neighborGuid;
neighborPortNumber = portProperties.neighborPortNumber;
maxRxSpeed.width = portProperties.enabledRxWidth;
maxRxSpeed.bitRate = portProperties.enabledRxBitrate;
rxSpeed.width = portProperties.activeRxWidth;
rxSpeed.bitRate = portProperties.activeRxBitrate;
maxTxSpeed.width = portProperties.enabledTxWidth;
maxTxSpeed.bitRate = portProperties.enabledTxBitrate;
txSpeed.width = portProperties.activeTxWidth;
txSpeed.bitRate = portProperties.activeTxBitrate;
}
return result;
}
int IafNlApi::handleMsg(struct nl_msg *msg) {
return pNlApi->genlHandleMsg(msg, reinterpret_cast<void *>(this));
}
int IafNlApi::nlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info) {
if (info->attrs[IAF_ATTR_CMD_OP_CONTEXT]) {
uint64_t context = pNlApi->nlaGetU64(info->attrs[IAF_ATTR_CMD_OP_CONTEXT]);
bool found = false;
for (auto i : validContexts) {
if (context == i) {
found = true;
break;
}
}
if (!found) {
return NL_STOP;
}
Operation *pOperation = reinterpret_cast<Operation *>(context);
if (cmd->c_id == pOperation->cmdOp && info->attrs[IAF_ATTR_CMD_OP_RESULT] && info->attrs[IAF_ATTR_CMD_OP_MSG_TYPE]) {
if ((pNlApi->nlaGetU8(info->attrs[IAF_ATTR_CMD_OP_MSG_TYPE]) == IAF_CMD_MSG_RESPONSE) && (pNlApi->nlaGetU8(info->attrs[IAF_ATTR_CMD_OP_RESULT]) == IAF_CMD_RSP_SUCCESS)) {
pOperation->result = handleResponse(pOperation->cmdOp, info, pOperation->pOutput);
}
}
pOperation->done = true;
}
return NL_OK;
}
ze_result_t IafNlApi::init() {
if (!pNlApi) {
return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
}
if (!initted) {
if (!pNlApi->loadEntryPoints()) {
pNlApi.reset(nullptr);
return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
}
initted = true;
}
int retval = pNlApi->genlRegisterFamily(&ops);
if (-NLE_EXIST == retval) {
// Temporary error
return ZE_RESULT_NOT_READY;
} else if (!retval) {
nlSock = pNlApi->nlSocketAlloc();
if (nullptr != nlSock) {
if (!pNlApi->genlConnect(nlSock)) {
if (!pNlApi->genlOpsResolve(nlSock, &ops)) {
familyId = pNlApi->genlCtrlResolve(nlSock, std::string(ops.o_name).c_str());
if (0 <= familyId) {
if (!pNlApi->nlSocketModifyCb(nlSock, NL_CB_VALID, NL_CB_CUSTOM,
globalHandleMsg, reinterpret_cast<void *>(this))) {
pNlApi->nlSocketDisableSeqCheck(nlSock);
return ZE_RESULT_SUCCESS;
}
}
}
}
pNlApi->nlSocketFree(nlSock);
nlSock = nullptr;
}
pNlApi->genlUnregisterFamily(&ops);
}
return ZE_RESULT_ERROR_UNKNOWN;
}
void IafNlApi::cleanup() {
pNlApi->nlSocketFree(nlSock);
nlSock = nullptr;
pNlApi->genlUnregisterFamily(&ops);
}
ze_result_t IafNlApi::initPorts(const uint32_t fabricId, std::vector<IafPort> &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<uint8_t> 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<IafPort> &ports) {
std::string path;
path.clear();
std::vector<std::string> 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<uint32_t>::max()) {
return ZE_RESULT_ERROR_UNKNOWN;
}
if (ZE_RESULT_SUCCESS != initPorts(static_cast<uint32_t>(myFabricId), ports)) {
return ZE_RESULT_ERROR_UNKNOWN;
}
return ZE_RESULT_SUCCESS;
}
IafNlApi::IafNlApi() {
validContexts.clear();
pNlApi.reset(new NlApi);
memset(policy, 0, sizeof(nla_policy) * _IAF_ATTR_COUNT);
policy[IAF_ATTR_CMD_OP_MSG_TYPE].type = NLA_U8;
policy[IAF_ATTR_CMD_OP_CONTEXT].type = NLA_U64;
policy[IAF_ATTR_CMD_OP_RESULT].type = NLA_U8;
policy[IAF_ATTR_FABRIC_ID].type = NLA_U32;
policy[IAF_ATTR_SD_INDEX].type = NLA_U8;
policy[IAF_ATTR_ENTRIES].type = NLA_U16;
policy[IAF_ATTR_FABRIC_DEVICE].type = NLA_NESTED;
policy[IAF_ATTR_DEV_NAME].type = NLA_NUL_STRING;
policy[IAF_ATTR_PARENT_DEV_NAME].type = NLA_NUL_STRING;
policy[IAF_ATTR_SOCKET_ID].type = NLA_U8;
policy[IAF_ATTR_PCI_SLOT_NUM].type = NLA_U8;
policy[IAF_ATTR_SUBDEVICE_COUNT].type = NLA_U8;
policy[IAF_ATTR_VERSION].type = NLA_U8;
policy[IAF_ATTR_PRODUCT_TYPE].type = NLA_U8;
policy[IAF_ATTR_SUB_DEVICE].type = NLA_NESTED;
policy[IAF_ATTR_GUID].type = NLA_U64;
policy[IAF_ATTR_EXTENDED_PORT_COUNT].type = NLA_U8;
policy[IAF_ATTR_FABRIC_PORT_COUNT].type = NLA_U8;
policy[IAF_ATTR_SWITCH_LIFETIME].type = NLA_U8;
policy[IAF_ATTR_ROUTING_MODE_SUPPORTED].type = NLA_U8;
policy[IAF_ATTR_ROUTING_MODE_ENABLED].type = NLA_U8;
policy[IAF_ATTR_EHHANCED_PORT_0_PRESENT].type = NLA_U8;
policy[IAF_ATTR_FABRIC_PORT].type = NLA_NESTED;
policy[IAF_ATTR_FABRIC_PORT_NUMBER].type = NLA_U8;
policy[IAF_ATTR_FABRIC_PORT_TYPE].type = NLA_U8;
policy[IAF_ATTR_BRIDGE_PORT_NUMBER].type = NLA_U8;
policy[IAF_ATTR_ENABLED_STATE].type = NLA_U8;
policy[IAF_ATTR_ROUTING_GEN_START].type = NLA_U32;
policy[IAF_ATTR_ROUTING_GEN_END].type = NLA_U32;
policy[IAF_ATTR_FPORT_HEALTH].type = NLA_U8;
policy[IAF_ATTR_FPORT_ISSUE_LQI].type = NLA_U8;
policy[IAF_ATTR_FPORT_ISSUE_LWD].type = NLA_U8;
policy[IAF_ATTR_FPORT_ISSUE_RATE].type = NLA_U8;
policy[IAF_ATTR_FPORT_ERROR_FAILED].type = NLA_U8;
policy[IAF_ATTR_FPORT_ERROR_ISOLATED].type = NLA_U8;
policy[IAF_ATTR_FPORT_ERROR_FLAPPING].type = NLA_U8;
policy[IAF_ATTR_FPORT_ERROR_LINK_DOWN].type = NLA_U8;
policy[IAF_ATTR_FPORT_ERROR_DID_NOT_TRAIN].type = NLA_U8;
policy[IAF_ATTR_SUB_DEVICE_TRAP_COUNT].type = NLA_U64;
policy[IAF_ATTR_FPORT_PM_PORT_STATE].type = NLA_U8;
policy[IAF_ATTR_FPORT_ROUTED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LOGICAL_STATE].type = NLA_U8;
policy[IAF_ATTR_FPORT_PHYSICAL_STATE].type = NLA_U8;
policy[IAF_ATTR_FPORT_FID].type = NLA_U32;
policy[IAF_ATTR_FPORT_LINK_DOWN_COUNT].type = NLA_U32;
policy[IAF_ATTR_FPORT_NEIGHBOR_GUID].type = NLA_U64;
policy[IAF_ATTR_FPORT_PORT_ERROR_ACTION].type = NLA_U32;
policy[IAF_ATTR_FPORT_NEIGHBOR_PORT_NUMBER].type = NLA_U8;
policy[IAF_ATTR_FPORT_PORT_LINK_MODE_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_NEIGHBOR_LINK_DOWN_REASON].type = NLA_U8;
policy[IAF_ATTR_FPORT_H_O_Q_LIFETIME].type = NLA_U8;
policy[IAF_ATTR_FPORT_VL_CAP].type = NLA_U8;
policy[IAF_ATTR_FPORT_OPERATIONAL_VLS].type = NLA_U8;
policy[IAF_ATTR_FPORT_NEIGHBOR_MTU].type = NLA_U8;
policy[IAF_ATTR_FPORT_LTP_CRC_MODE_SUPPORTED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LTP_CRC_MODE_ENABLED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LTP_CRC_MODE_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_WIDTH_SUPPORTED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_WIDTH_ENABLED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_WIDTH_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_SPEED_SUPPORTED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_SPEED_ENABLED].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_SPEED_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_RX_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_WIDTH_DOWNGRADE_TX_ACTIVE].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_INIT_REASON].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_DOWN_REASON].type = NLA_U8;
policy[IAF_ATTR_FPORT_LQI_OFFLINE_DISABLED_REASON].type = NLA_U8;
policy[IAF_ATTR_FPORT_LQI_NEIGHBOR_NORMAL].type = NLA_U8;
policy[IAF_ATTR_FPORT_LINK_QUALITY_INDICATOR].type = NLA_U8;
policy[IAF_ATTR_FPORT_BPS_LINK_SPEED_ACTIVE].type = NLA_U64;
policy[IAF_ATTR_TIMESTAMP].type = NLA_U64;
policy[IAF_ATTR_FPORT_TX_BYTES].type = NLA_U64;
policy[IAF_ATTR_FPORT_RX_BYTES].type = NLA_U64;
policy[IAF_ATTR_FPORT_BPS_LINK_SPEED_MAX].type = NLA_U64;
policy[IAF_ATTR_FPORT_LQI_CHANGE_COUNT].type = NLA_U32;
int i;
memset(cmds, 0, sizeof(genl_cmd) * _IAF_CMD_OP_COUNT);
for (i = 0; nullptr != iafCmds[i].name; i++) {
cmds[i].c_id = iafCmds[i].id;
cmds[i].c_name = iafCmds[i].name;
cmds[i].c_maxattr = _IAF_ATTR_COUNT - 1,
cmds[i].c_msg_parser = &globalNlOperation,
cmds[i].c_attr_policy = policy;
}
ops.o_name = const_cast<char *>("iaf_ze");
ops.o_hdrsize = 0U;
ops.o_cmds = cmds;
ops.o_ncmds = i;
}
IafNlApi::~IafNlApi() {
if (nullptr != nlSock) {
pNlApi->nlSocketFree(nlSock);
nlSock = nullptr;
}
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/sysman/source/linux/nl_api/nl_api.h"
#include <level_zero/zes_api.h>
#include "iaf/iaf_netlink.h"
#include <linux/types.h>
#include <list>
#include <netlink/genl/genl.h>
#include <netlink/genl/mngt.h>
#include <vector>
namespace L0 {
namespace Sysman {
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 {
public:
uint16_t cmdOp;
bool done = false;
void *pOutput;
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
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 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<uint32_t> &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<uint8_t> &ports);
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<IafPort> &ports);
std::list<uint64_t> validContexts = {};
int handleMsg(struct nl_msg *msg);
int nlOperation(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info);
protected:
std::unique_ptr<NlApi> pNlApi;
ze_result_t init();
void cleanup();
private:
ze_result_t allocMsg(const uint16_t cmdOp, struct nl_msg *&msg);
ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, const uint8_t portNumber, void *pOutput);
ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, const uint32_t attachId, void *pOutput);
ze_result_t issueRequest(const uint16_t cmdOp, const uint32_t fabricId, void *pOutput);
ze_result_t issueRequest(const uint16_t cmdOp, void *pOutput);
ze_result_t performTransaction(const uint16_t cmdOp, struct nl_msg *msg, void *pOutput);
ze_result_t fPortStatusQueryRsp(struct genl_info *info, void *pOutput);
ze_result_t getThroughputRsp(struct genl_info *info, void *pOutput);
ze_result_t portStateQueryRsp(struct genl_info *info, void *pOutput);
ze_result_t portBeaconStateQueryRsp(struct genl_info *info, void *pOutput);
ze_result_t routingGenQueryRsp(struct genl_info *info, void *pOutput);
ze_result_t deviceEnumRsp(struct genl_info *info, void *pOutput);
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<IafPort> &iafPorts);
int32_t translateWidth(uint8_t width);
bool initted = false;
struct nl_sock *nlSock = nullptr;
int familyId = 0;
struct nla_policy policy[_IAF_ATTR_COUNT] = {};
struct genl_cmd cmds[_IAF_CMD_OP_COUNT] = {};
struct genl_ops ops = {};
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,260 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "nl_api.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/os_interface/os_library.h"
namespace L0 {
namespace Sysman {
static constexpr std::string_view libgenlFile = "libnl-genl-3.so.200";
static constexpr std::string_view genlConnectRoutine = "genl_connect";
static constexpr std::string_view genlCtrlResolveRoutine = "genl_ctrl_resolve";
static constexpr std::string_view genlHandleMsgRoutine = "genl_handle_msg";
static constexpr std::string_view genlmsgPutRoutine = "genlmsg_put";
static constexpr std::string_view genlOpsResolveRoutine = "genl_ops_resolve";
static constexpr std::string_view genlRegisterFamilyRoutine = "genl_register_family";
static constexpr std::string_view genlUnregisterFamilyRoutine = "genl_unregister_family";
static constexpr std::string_view nlRecvmsgsDefaultRoutine = "nl_recvmsgs_default";
static constexpr std::string_view nlSendAutoRoutine = "nl_send_auto";
static constexpr std::string_view nlSocketAllocRoutine = "nl_socket_alloc";
static constexpr std::string_view nlSocketDisableSeqCheckRoutine = "nl_socket_disable_seq_check";
static constexpr std::string_view nlSocketFreeRoutine = "nl_socket_free";
static constexpr std::string_view nlSocketModifyCbRoutine = "nl_socket_modify_cb";
static constexpr std::string_view nlaDataRoutine = "nla_data";
static constexpr std::string_view nlaGetU32Routine = "nla_get_u32";
static constexpr std::string_view nlaGetU64Routine = "nla_get_u64";
static constexpr std::string_view nlaGetU8Routine = "nla_get_u8";
static constexpr std::string_view nlaIsNestedRoutine = "nla_is_nested";
static constexpr std::string_view nlaLenRoutine = "nla_len";
static constexpr std::string_view nlaNextRoutine = "nla_next";
static constexpr std::string_view nlaOkRoutine = "nla_ok";
static constexpr std::string_view nlaPutU16Routine = "nla_put_u16";
static constexpr std::string_view nlaPutU32Routine = "nla_put_u32";
static constexpr std::string_view nlaPutU64Routine = "nla_put_u64";
static constexpr std::string_view nlaPutU8Routine = "nla_put_u8";
static constexpr std::string_view nlaTypeRoutine = "nla_type";
static constexpr std::string_view nlmsgAllocRoutine = "nlmsg_alloc";
static constexpr std::string_view nlmsgAttrdataRoutine = "nlmsg_attrdata";
static constexpr std::string_view nlmsgAttrlenRoutine = "nlmsg_attrlen";
static constexpr std::string_view nlmsgFreeRoutine = "nlmsg_free";
static constexpr std::string_view nlmsgHdrRoutine = "nlmsg_hdr";
template <class T>
bool NlApi::getSymbolAddr(const std::string_view &name, T &sym) {
sym = reinterpret_cast<T>(genlLibraryHandle->getProcAddress(std::string(name)));
return nullptr != sym;
}
bool NlApi::loadEntryPoints() {
if (!isAvailable())
return false;
bool ok = true;
ok = getSymbolAddr(genlConnectRoutine, genlConnectEntry);
ok = ok && getSymbolAddr(genlCtrlResolveRoutine, genlCtrlResolveEntry);
ok = ok && getSymbolAddr(genlHandleMsgRoutine, genlHandleMsgEntry);
ok = ok && getSymbolAddr(genlmsgPutRoutine, genlmsgPutEntry);
ok = ok && getSymbolAddr(genlOpsResolveRoutine, genlOpsResolveEntry);
ok = ok && getSymbolAddr(genlRegisterFamilyRoutine, genlRegisterFamilyEntry);
ok = ok && getSymbolAddr(genlUnregisterFamilyRoutine, genlUnregisterFamilyEntry);
ok = ok && getSymbolAddr(nlRecvmsgsDefaultRoutine, nlRecvmsgsDefaultEntry);
ok = ok && getSymbolAddr(nlSendAutoRoutine, nlSendAutoEntry);
ok = ok && getSymbolAddr(nlSocketAllocRoutine, nlSocketAllocEntry);
ok = ok && getSymbolAddr(nlSocketDisableSeqCheckRoutine, nlSocketDisableSeqCheckEntry);
ok = ok && getSymbolAddr(nlSocketFreeRoutine, nlSocketFreeEntry);
ok = ok && getSymbolAddr(nlSocketModifyCbRoutine, nlSocketModifyCbEntry);
ok = ok && getSymbolAddr(nlaDataRoutine, nlaDataEntry);
ok = ok && getSymbolAddr(nlaGetU32Routine, nlaGetU32Entry);
ok = ok && getSymbolAddr(nlaGetU64Routine, nlaGetU64Entry);
ok = ok && getSymbolAddr(nlaGetU8Routine, nlaGetU8Entry);
ok = ok && getSymbolAddr(nlaIsNestedRoutine, nlaIsNestedEntry);
ok = ok && getSymbolAddr(nlaLenRoutine, nlaLenEntry);
ok = ok && getSymbolAddr(nlaNextRoutine, nlaNextEntry);
ok = ok && getSymbolAddr(nlaOkRoutine, nlaOkEntry);
ok = ok && getSymbolAddr(nlaPutU16Routine, nlaPutU16Entry);
ok = ok && getSymbolAddr(nlaPutU32Routine, nlaPutU32Entry);
ok = ok && getSymbolAddr(nlaPutU64Routine, nlaPutU64Entry);
ok = ok && getSymbolAddr(nlaPutU8Routine, nlaPutU8Entry);
ok = ok && getSymbolAddr(nlaTypeRoutine, nlaTypeEntry);
ok = ok && getSymbolAddr(nlmsgAllocRoutine, nlmsgAllocEntry);
ok = ok && getSymbolAddr(nlmsgAttrdataRoutine, nlmsgAttrdataEntry);
ok = ok && getSymbolAddr(nlmsgAttrlenRoutine, nlmsgAttrlenEntry);
ok = ok && getSymbolAddr(nlmsgFreeRoutine, nlmsgFreeEntry);
ok = ok && getSymbolAddr(nlmsgHdrRoutine, nlmsgHdrEntry);
return ok;
}
int NlApi::genlConnect(struct nl_sock *sock) {
UNRECOVERABLE_IF(nullptr == genlConnectEntry);
return (*genlConnectEntry)(sock);
}
int NlApi::genlCtrlResolve(struct nl_sock *sock, const char *name) {
UNRECOVERABLE_IF(nullptr == genlCtrlResolveEntry);
return (*genlCtrlResolveEntry)(sock, name);
}
int NlApi::genlHandleMsg(struct nl_msg *msg, void *arg) {
UNRECOVERABLE_IF(nullptr == genlHandleMsgEntry);
return (*genlHandleMsgEntry)(msg, arg);
}
void *NlApi::genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) {
UNRECOVERABLE_IF(nullptr == genlmsgPutEntry);
return (*genlmsgPutEntry)(msg, port, seq, family, hdrlen, flags, cmd, version);
}
int NlApi::genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) {
UNRECOVERABLE_IF(nullptr == genlOpsResolveEntry);
return (*genlOpsResolveEntry)(sock, ops);
}
int NlApi::genlRegisterFamily(struct genl_ops *ops) {
UNRECOVERABLE_IF(nullptr == genlRegisterFamilyEntry);
return (*genlRegisterFamilyEntry)(ops);
}
int NlApi::genlUnregisterFamily(struct genl_ops *ops) {
UNRECOVERABLE_IF(nullptr == genlUnregisterFamilyEntry);
return (*genlUnregisterFamilyEntry)(ops);
}
int NlApi::nlRecvmsgsDefault(struct nl_sock *sock) {
UNRECOVERABLE_IF(nullptr == nlRecvmsgsDefaultEntry);
return (*nlRecvmsgsDefaultEntry)(sock);
}
int NlApi::nlSendAuto(struct nl_sock *sock, struct nl_msg *msg) {
UNRECOVERABLE_IF(nullptr == nlSendAutoEntry);
return (*nlSendAutoEntry)(sock, msg);
}
struct nl_sock *NlApi::nlSocketAlloc() {
UNRECOVERABLE_IF(nullptr == nlSocketAllocEntry);
return (*nlSocketAllocEntry)();
}
void NlApi::nlSocketDisableSeqCheck(struct nl_sock *sock) {
UNRECOVERABLE_IF(nullptr == nlSocketDisableSeqCheckEntry);
(*nlSocketDisableSeqCheckEntry)(sock);
return;
}
void NlApi::nlSocketFree(struct nl_sock *sock) {
UNRECOVERABLE_IF(nullptr == nlSocketFreeEntry);
(*nlSocketFreeEntry)(sock);
return;
}
int NlApi::nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) {
UNRECOVERABLE_IF(nullptr == nlSocketModifyCbEntry);
return (*nlSocketModifyCbEntry)(sock, type, kind, cb, arg);
}
void *NlApi::nlaData(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaDataEntry);
return (*nlaDataEntry)(attr);
}
uint32_t NlApi::nlaGetU32(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaGetU32Entry);
return (*nlaGetU32Entry)(attr);
}
uint64_t NlApi::nlaGetU64(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaGetU64Entry);
return (*nlaGetU64Entry)(attr);
}
uint8_t NlApi::nlaGetU8(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaGetU8Entry);
return (*nlaGetU8Entry)(attr);
}
int NlApi::nlaIsNested(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaIsNestedEntry);
return (*nlaIsNestedEntry)(attr);
}
int NlApi::nlaLen(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaLenEntry);
return (*nlaLenEntry)(attr);
}
struct nlattr *NlApi::nlaNext(const struct nlattr *attr, int *remaining) {
UNRECOVERABLE_IF(nullptr == nlaNextEntry);
return (*nlaNextEntry)(attr, remaining);
}
int NlApi::nlaOk(const struct nlattr *attr, int remaining) {
UNRECOVERABLE_IF(nullptr == nlaOkEntry);
return (*nlaOkEntry)(attr, remaining);
}
int NlApi::nlaPutU16(struct nl_msg *msg, int id, uint16_t data) {
UNRECOVERABLE_IF(nullptr == nlaPutU16Entry);
return (*nlaPutU16Entry)(msg, id, data);
}
int NlApi::nlaPutU32(struct nl_msg *msg, int id, uint32_t data) {
UNRECOVERABLE_IF(nullptr == nlaPutU32Entry);
return (*nlaPutU32Entry)(msg, id, data);
}
int NlApi::nlaPutU64(struct nl_msg *msg, int id, uint64_t data) {
UNRECOVERABLE_IF(nullptr == nlaPutU64Entry);
return (*nlaPutU64Entry)(msg, id, data);
}
int NlApi::nlaPutU8(struct nl_msg *msg, int id, uint8_t data) {
UNRECOVERABLE_IF(nullptr == nlaPutU8Entry);
return (*nlaPutU8Entry)(msg, id, data);
}
int NlApi::nlaType(const struct nlattr *attr) {
UNRECOVERABLE_IF(nullptr == nlaTypeEntry);
return (*nlaTypeEntry)(attr);
}
struct nl_msg *NlApi::nlmsgAlloc() {
UNRECOVERABLE_IF(nullptr == nlmsgAllocEntry);
return (*nlmsgAllocEntry)();
}
struct nlattr *NlApi::nlmsgAttrdata(const struct nlmsghdr *hdr, int attr) {
UNRECOVERABLE_IF(nullptr == nlmsgAttrdataEntry);
return (*nlmsgAttrdataEntry)(hdr, attr);
}
int NlApi::nlmsgAttrlen(const struct nlmsghdr *hdr, int attr) {
UNRECOVERABLE_IF(nullptr == nlmsgAttrlenEntry);
return (*nlmsgAttrlenEntry)(hdr, attr);
}
void NlApi::nlmsgFree(struct nl_msg *msg) {
UNRECOVERABLE_IF(nullptr == nlmsgFreeEntry);
(*nlmsgFreeEntry)(msg);
return;
}
struct nlmsghdr *NlApi::nlmsgHdr(struct nl_msg *msg) {
UNRECOVERABLE_IF(nullptr == nlmsgHdrEntry);
return (*nlmsgHdrEntry)(msg);
}
NlApi::NlApi() {
genlLibraryHandle.reset(NEO::OsLibrary::load(std::string(libgenlFile)));
}
NlApi::~NlApi() = default;
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include <memory>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/mngt.h>
#include <string>
#include <sys/socket.h>
namespace NEO {
class OsLibrary;
} // namespace NEO
namespace L0 {
namespace Sysman {
typedef int (*pGenlConnect)(struct nl_sock *);
typedef int (*pGenlCtrlResolve)(struct nl_sock *, const char *);
typedef int (*pGenlHandleMsg)(struct nl_msg *, void *);
typedef int (*pGenlOpsResolve)(struct nl_sock *, struct genl_ops *);
typedef int (*pGenlRegisterFamily)(struct genl_ops *);
typedef int (*pGenlUnregisterFamily)(struct genl_ops *);
typedef void *(*pGenlmsgPut)(struct nl_msg *, uint32_t, uint32_t, int, int, int, uint8_t, uint8_t);
typedef int (*pNlRecvmsgsDefault)(struct nl_sock *);
typedef int (*pNlSendAuto)(struct nl_sock *, struct nl_msg *);
typedef struct nl_sock *(*pNlSocketAlloc)();
typedef void (*pNlSocketDisableSeqCheck)(struct nl_sock *);
typedef void (*pNlSocketFree)(struct nl_sock *);
typedef int (*pNlSocketModifyCb)(struct nl_sock *, enum nl_cb_type, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *);
typedef void *(*pNlaData)(const struct nlattr *);
typedef uint32_t (*pNlaGetU32)(const struct nlattr *);
typedef uint64_t (*pNlaGetU64)(const struct nlattr *);
typedef uint8_t (*pNlaGetU8)(const struct nlattr *);
typedef int (*pNlaIsNested)(const struct nlattr *);
typedef int (*pNlaLen)(const struct nlattr *);
typedef struct nlattr *(*pNlaNext)(const struct nlattr *, int *);
typedef int (*pNlaOk)(const struct nlattr *, int);
typedef int (*pNlaPutU16)(struct nl_msg *, int, uint16_t);
typedef int (*pNlaPutU32)(struct nl_msg *, int, uint32_t);
typedef int (*pNlaPutU64)(struct nl_msg *, int, uint64_t);
typedef int (*pNlaPutU8)(struct nl_msg *, int, uint8_t);
typedef int (*pNlaType)(const struct nlattr *);
typedef struct nl_msg *(*pNlmsgAlloc)();
typedef struct nlattr *(*pNlmsgAttrdata)(const struct nlmsghdr *, int);
typedef int (*pNlmsgAttrlen)(const struct nlmsghdr *, int);
typedef void (*pNlmsgFree)(struct nl_msg *);
typedef struct nlmsghdr *(*pNlmsgHdr)(struct nl_msg *);
class NlApi : public NEO::NonCopyableOrMovableClass {
public:
MOCKABLE_VIRTUAL int genlConnect(struct nl_sock *sock);
MOCKABLE_VIRTUAL int genlCtrlResolve(struct nl_sock *sock, const char *name);
MOCKABLE_VIRTUAL int genlHandleMsg(struct nl_msg *msg, void *arg);
MOCKABLE_VIRTUAL int genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops);
MOCKABLE_VIRTUAL int genlRegisterFamily(struct genl_ops *ops);
MOCKABLE_VIRTUAL int genlUnregisterFamily(struct genl_ops *ops);
MOCKABLE_VIRTUAL void *genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version);
MOCKABLE_VIRTUAL int nlRecvmsgsDefault(struct nl_sock *sock);
MOCKABLE_VIRTUAL int nlSendAuto(struct nl_sock *sock, struct nl_msg *msg);
MOCKABLE_VIRTUAL struct nl_sock *nlSocketAlloc();
MOCKABLE_VIRTUAL void nlSocketDisableSeqCheck(struct nl_sock *sock);
MOCKABLE_VIRTUAL void nlSocketFree(struct nl_sock *sock);
MOCKABLE_VIRTUAL int nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg);
MOCKABLE_VIRTUAL void *nlaData(const struct nlattr *attr);
MOCKABLE_VIRTUAL uint32_t nlaGetU32(const struct nlattr *attr);
MOCKABLE_VIRTUAL uint64_t nlaGetU64(const struct nlattr *attr);
MOCKABLE_VIRTUAL uint8_t nlaGetU8(const struct nlattr *attr);
MOCKABLE_VIRTUAL int nlaIsNested(const struct nlattr *attr);
MOCKABLE_VIRTUAL int nlaLen(const struct nlattr *attr);
MOCKABLE_VIRTUAL struct nlattr *nlaNext(const struct nlattr *attr, int *remaining);
MOCKABLE_VIRTUAL int nlaOk(const struct nlattr *attr, int remaining);
MOCKABLE_VIRTUAL int nlaPutU16(struct nl_msg *msg, int id, uint16_t data);
MOCKABLE_VIRTUAL int nlaPutU32(struct nl_msg *msg, int id, uint32_t data);
MOCKABLE_VIRTUAL int nlaPutU64(struct nl_msg *msg, int id, uint64_t data);
MOCKABLE_VIRTUAL int nlaPutU8(struct nl_msg *msg, int id, uint8_t data);
MOCKABLE_VIRTUAL int nlaType(const struct nlattr *attr);
MOCKABLE_VIRTUAL struct nl_msg *nlmsgAlloc();
MOCKABLE_VIRTUAL struct nlattr *nlmsgAttrdata(const struct nlmsghdr *hdr, int attr);
MOCKABLE_VIRTUAL int nlmsgAttrlen(const struct nlmsghdr *hdr, int attr);
MOCKABLE_VIRTUAL void nlmsgFree(struct nl_msg *msg);
MOCKABLE_VIRTUAL struct nlmsghdr *nlmsgHdr(struct nl_msg *msg);
bool isAvailable() { return nullptr != genlLibraryHandle.get(); }
MOCKABLE_VIRTUAL bool loadEntryPoints();
NlApi();
MOCKABLE_VIRTUAL ~NlApi();
protected:
template <class T>
bool getSymbolAddr(const std::string_view &name, T &sym);
std::unique_ptr<NEO::OsLibrary> genlLibraryHandle;
pGenlConnect genlConnectEntry = nullptr;
pGenlCtrlResolve genlCtrlResolveEntry = nullptr;
pGenlHandleMsg genlHandleMsgEntry = nullptr;
pGenlOpsResolve genlOpsResolveEntry = nullptr;
pGenlRegisterFamily genlRegisterFamilyEntry = nullptr;
pGenlUnregisterFamily genlUnregisterFamilyEntry = nullptr;
pGenlmsgPut genlmsgPutEntry = nullptr;
pNlRecvmsgsDefault nlRecvmsgsDefaultEntry = nullptr;
pNlSendAuto nlSendAutoEntry = nullptr;
pNlSocketAlloc nlSocketAllocEntry = nullptr;
pNlSocketDisableSeqCheck nlSocketDisableSeqCheckEntry = nullptr;
pNlSocketFree nlSocketFreeEntry = nullptr;
pNlSocketModifyCb nlSocketModifyCbEntry = nullptr;
pNlaData nlaDataEntry = nullptr;
pNlaGetU32 nlaGetU32Entry = nullptr;
pNlaGetU64 nlaGetU64Entry = nullptr;
pNlaGetU8 nlaGetU8Entry = nullptr;
pNlaIsNested nlaIsNestedEntry = nullptr;
pNlaLen nlaLenEntry = nullptr;
pNlaNext nlaNextEntry = nullptr;
pNlaOk nlaOkEntry = nullptr;
pNlaPutU16 nlaPutU16Entry = nullptr;
pNlaPutU32 nlaPutU32Entry = nullptr;
pNlaPutU64 nlaPutU64Entry = nullptr;
pNlaPutU8 nlaPutU8Entry = nullptr;
pNlaType nlaTypeEntry = nullptr;
pNlmsgAlloc nlmsgAllocEntry = nullptr;
pNlmsgAttrdata nlmsgAttrdataEntry = nullptr;
pNlmsgAttrlen nlmsgAttrlenEntry = nullptr;
pNlmsgFree nlmsgFreeEntry = nullptr;
pNlmsgHdr nlmsgHdrEntry = nullptr;
};
} // namespace Sysman
} // namespace L0

View File

@@ -25,5 +25,10 @@ SysmanDevice *SysmanDevice::create(NEO::ExecutionEnvironment &executionEnvironme
return pSysmanDevice;
}
ze_result_t SysmanDevice::fabricPortGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->fabricPortGet(pCount, phPort);
}
} // namespace Sysman
} // namespace L0

View File

@@ -9,6 +9,7 @@
#include "shared/source/execution_environment/execution_environment.h"
#include "level_zero/core/source/device/device.h"
#include "level_zero/sysman/source/fabric_port/fabric_port.h"
#include <level_zero/ze_api.h>
#include <level_zero/zes_api.h>
@@ -22,6 +23,9 @@ struct SysmanDevice : _ze_device_handle_t {
virtual ~SysmanDevice() = default;
static SysmanDevice *create(NEO::ExecutionEnvironment &executionEnvironment, const uint32_t rootDeviceIndex);
virtual const NEO::HardwareInfo &getHardwareInfo() const = 0;
static ze_result_t fabricPortGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_fabric_port_handle_t *phPort);
virtual ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) = 0;
};
} // namespace Sysman

View File

@@ -21,11 +21,13 @@ SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment
this->executionEnvironment->incRefInternal();
pOsSysman = OsSysman::create(this);
UNRECOVERABLE_IF(nullptr == pOsSysman);
pFabricPortHandleContext = new FabricPortHandleContext(pOsSysman);
}
SysmanDeviceImp::~SysmanDeviceImp() {
executionEnvironment->decRefInternal();
freeResource(pOsSysman);
freeResource(pFabricPortHandleContext);
}
ze_result_t SysmanDeviceImp::init() {
@@ -36,5 +38,9 @@ ze_result_t SysmanDeviceImp::init() {
return result;
}
ze_result_t SysmanDeviceImp::fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) {
return pFabricPortHandleContext->fabricPortGet(pCount, phPort);
}
} // namespace Sysman
} // namespace L0

View File

@@ -35,6 +35,9 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
NEO::ExecutionEnvironment *getExecutionEnvironment() const { return executionEnvironment; }
uint32_t getRootDeviceIndex() const { return rootDeviceIndex; }
FabricPortHandleContext *pFabricPortHandleContext = nullptr;
ze_result_t fabricPortGet(uint32_t *pCount, zes_fabric_port_handle_t *phPort) override;
private:
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
const uint32_t rootDeviceIndex;