Skip to content

Commit

Permalink
Continue creating PciSubDevice upon failures
Browse files Browse the repository at this point in the history
Summary:
When PciDevice is being explored, we have a try/catch to prevent PM to crash when a PciSubDevice creation failed.
However, this also prevents the remaining PciSubDevices to be created.

For example, if an i2c adapter fails, then all the remaining pciSubDevices like SpiMaster, XCVR, watchdog and etc won't get created.
Instead we should just capture the fail and move on to create remaining PciSubDevices.

Reviewed By: somasun

Differential Revision: D67031954

fbshipit-source-id: 1b74dd598dd7b5c13ee536e5b9ea02a58ff39206
  • Loading branch information
Justin Kim authored and facebook-github-bot committed Dec 13, 2024
1 parent a6f5d6a commit 10300eb
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 160 deletions.
162 changes: 95 additions & 67 deletions fboss/platform/platform_manager/PciExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,18 +339,20 @@ void PciExplorer::create(
// 2. PciSubDevice driver binding failure (checkDeviceReadiness =
// false).
if (ret < 0) {
throw std::runtime_error(fmt::format(
"Failed to create new device {} in {} using {}. "
"Args - deviceName: {} instanceId: {}, "
"csrOffset: {:#04x}, iobufOffset: {:#04x}, error: {}",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath(),
pciDevice.charDevPath(),
*fpgaIpBlockConfig.deviceName(),
auxData.id.id,
auxData.csr_offset,
auxData.iobuf_offset,
folly::errnoStr(savedErrno)));
throw PciSubDeviceRuntimeError(
fmt::format(
"Failed to create new device {} in {} using {}. "
"Args - deviceName: {} instanceId: {}, "
"csrOffset: {:#04x}, iobufOffset: {:#04x}, error: {}",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath(),
pciDevice.charDevPath(),
*fpgaIpBlockConfig.deviceName(),
auxData.id.id,
auxData.csr_offset,
auxData.iobuf_offset,
folly::errnoStr(savedErrno)),
*fpgaIpBlockConfig.pmUnitScopedName());
}
if (!Utils().checkDeviceReadiness(
[&]() -> bool {
Expand All @@ -365,17 +367,19 @@ void PciExplorer::create(
auxData.id.id,
pciDevice.sysfsPath(),
kPciWaitSecs.count()))) {
throw std::runtime_error(fmt::format(
"Failed to initialize device {} in {} using {}. "
"Args - deviceName: {} instanceId: {}, "
"csrOffset: {:#04x}, iobufOffset: {:#04x}",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath(),
pciDevice.charDevPath(),
*fpgaIpBlockConfig.deviceName(),
auxData.id.id,
auxData.csr_offset,
auxData.iobuf_offset));
throw PciSubDeviceRuntimeError(
fmt::format(
"Failed to initialize device {} in {} using {}. "
"Args - deviceName: {} instanceId: {}, "
"csrOffset: {:#04x}, iobufOffset: {:#04x}",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath(),
pciDevice.charDevPath(),
*fpgaIpBlockConfig.deviceName(),
auxData.id.id,
auxData.csr_offset,
auxData.iobuf_offset),
*fpgaIpBlockConfig.pmUnitScopedName());
}

XLOG(INFO) << fmt::format(
Expand Down Expand Up @@ -405,8 +409,10 @@ std::vector<uint16_t> PciExplorer::getI2cAdapterBusNums(
}
}
if (fpgaI2cDir.path().empty()) {
throw std::runtime_error(fmt::format(
"Could not find FPGA I2C directory ending with {}", expectedEnding));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find FPGA I2C directory ending with {}", expectedEnding),
*i2cAdapterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
if (*i2cAdapterConfig.numberOfAdapters() > 1) {
// If more than 1 bus exists for this i2c master, then we have to use the
Expand All @@ -417,8 +423,10 @@ std::vector<uint16_t> PciExplorer::getI2cAdapterBusNums(
auto channelFile =
fpgaI2cDir.path() / fmt::format("channel-{}", channelNum);
if (!fs::exists(channelFile) || !fs::is_symlink(channelFile)) {
throw std::runtime_error(fmt::format(
"{} does not exist or not a symlink.", channelFile.string()));
throw PciSubDeviceRuntimeError(
fmt::format(
"{} does not exist or not a symlink.", channelFile.string()),
*i2cAdapterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
busNumbers.push_back(I2cExplorer().extractBusNumFromPath(
fs::read_symlink(channelFile).filename()));
Expand All @@ -435,8 +443,10 @@ std::vector<uint16_t> PciExplorer::getI2cAdapterBusNums(
return {I2cExplorer().extractBusNumFromPath(childDirEntry.path())};
}
}
throw std::runtime_error(fmt::format(
"Could not find any I2C buses in {}", fpgaI2cDir.path().string()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find any I2C buses in {}", fpgaI2cDir.path().string()),
*i2cAdapterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
}

Expand All @@ -463,16 +473,20 @@ std::map<std::string, std::string> PciExplorer::getSpiDeviceCharDevPaths(
}
}
if (spiMasterPath.empty()) {
throw std::runtime_error(fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()),
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
if (!fs::exists(spiMasterPath)) {
throw std::runtime_error(fmt::format(
"Could not find matching SpiController in {}. InstanceId: {}",
spiMasterPath,
instanceId));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find matching SpiController in {}. InstanceId: {}",
spiMasterPath,
instanceId),
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
std::map<std::string, std::string> spiCharDevPaths;
for (const auto& dirEntry : fs::directory_iterator(spiMasterPath)) {
Expand Down Expand Up @@ -514,12 +528,14 @@ std::map<std::string, std::string> PciExplorer::getSpiDeviceCharDevPaths(
return *spiDeviceConfig.chipSelect() == chipSelect;
});
if (itr == spiMasterConfig.spiDeviceConfigs()->end()) {
throw std::runtime_error(fmt::format(
"Unexpected SpiDevice created at {}. \
No matching SpiDeviceConfig defined with ChipSelect {} for SpiController {}",
childDirEntry.path().string(),
chipSelect,
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Unexpected SpiDevice created at {}. \
No matching SpiDeviceConfig defined with ChipSelect {} for SpiController {}",
childDirEntry.path().string(),
chipSelect,
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName()),
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
spiCharDevPaths[*itr->pmUnitScopedName()] = spiCharDevPath;
}
Expand All @@ -539,21 +555,25 @@ std::string PciExplorer::getGpioChipCharDevPath(
return Utils().resolveGpioChipCharDevPath(dirEntry.path().string());
}
}
throw std::runtime_error(fmt::format(
"Couldn't derive GpioChip char device path in ",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Couldn't derive GpioChip {} CharDevPath in {}",
*fpgaIpBlockConfig.pmUnitScopedName(),
pciDevice.sysfsPath()),
*fpgaIpBlockConfig.pmUnitScopedName());
}

std::string PciExplorer::getInfoRomSysfsPath(
const FpgaIpBlockConfig& infoRomConfig,
uint32_t instanceId) {
const auto auxDevSysfsPath = "/sys/bus/auxiliary/devices";
if (!fs::exists(auxDevSysfsPath)) {
throw std::runtime_error(fmt::format(
"Unable to find InfoRom sysfs path for {}. Reason: '{}' path doesn't exist.",
*infoRomConfig.pmUnitScopedName(),
auxDevSysfsPath));
throw PciSubDeviceRuntimeError(
fmt::format(
"Unable to find InfoRom sysfs path for {}. Reason: '{}' path doesn't exist.",
*infoRomConfig.pmUnitScopedName(),
auxDevSysfsPath),
*infoRomConfig.pmUnitScopedName());
}
std::string expectedEnding =
fmt::format(".{}.{}", *infoRomConfig.deviceName(), instanceId);
Expand All @@ -562,10 +582,12 @@ std::string PciExplorer::getInfoRomSysfsPath(
return dirEntry.path().string();
}
}
throw std::runtime_error(fmt::format(
"Couldn't find InfoRom {} sysfs path under {}",
*infoRomConfig.pmUnitScopedName(),
auxDevSysfsPath));
throw PciSubDeviceRuntimeError(
fmt::format(
"Couldn't find InfoRom {} sysfs path under {}",
*infoRomConfig.pmUnitScopedName(),
auxDevSysfsPath),
*infoRomConfig.pmUnitScopedName());
}

std::string PciExplorer::getWatchDogCharDevPath(
Expand All @@ -587,10 +609,12 @@ std::string PciExplorer::getWatchDogCharDevPath(
return Utils().resolveWatchdogCharDevPath(dirEntry.path().string());
}
}
throw std::runtime_error(fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()),
*fpgaIpBlockConfig.pmUnitScopedName());
}

std::string PciExplorer::getFanPwmCtrlSysfsPath(
Expand All @@ -604,10 +628,12 @@ std::string PciExplorer::getFanPwmCtrlSysfsPath(
return dirEntry.path();
}
}
throw std::runtime_error(fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Could not find any directory ending with {} in {}",
expectedEnding,
pciDevice.sysfsPath()),
*fpgaIpBlockConfig.pmUnitScopedName());
}

std::string PciExplorer::getXcvrCtrlSysfsPath(
Expand All @@ -621,10 +647,12 @@ std::string PciExplorer::getXcvrCtrlSysfsPath(
return dirEntry.path().string();
}
}
throw std::runtime_error(fmt::format(
"Couldn't find XcvrCtrl {} under {}",
*fpgaIpBlockConfig.deviceName(),
pciDevice.sysfsPath()));
throw PciSubDeviceRuntimeError(
fmt::format(
"Couldn't find XcvrCtrl {} under {}",
*fpgaIpBlockConfig.deviceName(),
pciDevice.sysfsPath()),
*fpgaIpBlockConfig.pmUnitScopedName());
}

bool PciExplorer::isPciSubDeviceReady(
Expand Down
13 changes: 13 additions & 0 deletions fboss/platform/platform_manager/PciExplorer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
#include "fboss/platform/platform_manager/uapi/fbiob-ioctl.h"

namespace facebook::fboss::platform::platform_manager {
class PciSubDeviceRuntimeError : public std::runtime_error {
public:
explicit PciSubDeviceRuntimeError(
const std::string& msg,
const std::string& pmUnitScopedName)
: std::runtime_error(msg), pmUnitScopedName_(pmUnitScopedName) {}
std::string getPmUnitScopedName() {
return pmUnitScopedName_;
}

private:
std::string pmUnitScopedName_;
};

struct PciDevice {
public:
Expand Down
Loading

0 comments on commit 10300eb

Please sign in to comment.