Support for hardware dump collection from OCMB
This commit introduces the capability to collect hardware dumps from
Odyssey-based OCMB chips in addition to existing processor dump.
This commit addresses the need for additional failure data across
both processors and their associated OCMB chips.
Key changes include:
- Enabled hardware dump collection specifically for Odyssey OCMB chips.
- Optimized the collection process to occur only when the chip clock
is on to minimize overall dump collection time.
- Sequential dump collection from OCMB chips associated with each
processor.
Change-Id: Iea70912f9fef9c337ba5ca7c508728586be25af8
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
diff --git a/dump/sbe_dump_collector.cpp b/dump/sbe_dump_collector.cpp
index 3e74736..16ac9a7 100644
--- a/dump/sbe_dump_collector.cpp
+++ b/dump/sbe_dump_collector.cpp
@@ -42,7 +42,7 @@
initializePdbg();
- std::vector<struct pdbg_target*> targets;
+ TargetMap targets;
struct pdbg_target* target = nullptr;
pdbg_for_each_class_target("proc", target)
@@ -61,7 +61,32 @@
}
if (includeTarget)
{
- targets.push_back(target);
+ targets[target] = std::vector<struct pdbg_target*>();
+
+ // Hardware dump needs OCMB data if present
+ if (type == openpower::dump::SBE::SBE_DUMP_TYPE_HARDWARE)
+ {
+ struct pdbg_target* ocmbTarget;
+ pdbg_for_each_target("ocmb", target, ocmbTarget)
+ {
+ if (!is_ody_ocmb_chip(ocmbTarget))
+ {
+ continue;
+ }
+
+ if (pdbg_target_probe(ocmbTarget) != PDBG_TARGET_ENABLED)
+ {
+ continue;
+ }
+
+ if (!openpower::phal::pdbg::isTgtFunctional(ocmbTarget))
+ {
+ continue;
+ }
+
+ targets[target].push_back(ocmbTarget);
+ }
+ }
}
}
@@ -110,32 +135,46 @@
std::vector<std::future<void>> SbeDumpCollector::spawnDumpCollectionProcesses(
uint8_t type, uint32_t id, const std::filesystem::path& path,
- uint64_t failingUnit, uint8_t cstate,
- const std::vector<struct pdbg_target*>& targets)
+ uint64_t failingUnit, uint8_t cstate, const TargetMap& targetMap)
{
std::vector<std::future<void>> futures;
- for (auto target : targets)
+ for (const auto& [procTarget, ocmbTargets] : targetMap)
{
- if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED ||
- !openpower::phal::pdbg::isTgtFunctional(target))
- {
- continue;
- }
-
- auto future =
- std::async(std::launch::async,
- [this, target, path, id, type, cstate, failingUnit]() {
+ auto future = std::async(std::launch::async,
+ [this, procTarget, ocmbTargets, path, id, type,
+ cstate, failingUnit]() {
try
{
- this->collectDumpFromSBE(target, path, id, type, cstate,
+ this->collectDumpFromSBE(procTarget, path, id, type, cstate,
failingUnit);
}
catch (const std::exception& e)
{
lg2::error(
- "Failed to collect dump from SBE on Proc-({PROCINDEX})",
- "PROCINDEX", pdbg_target_index(target));
+ "Failed to collect dump from SBE on Proc-({PROCINDEX}) {ERROR}",
+ "PROCINDEX", pdbg_target_index(procTarget), "ERROR", e);
+ }
+
+ // Collect OCMBs only with clock on
+ if (cstate == SBE_CLOCK_ON)
+ {
+ // Handle OCMBs serially after handling the proc
+ for (auto ocmbTarget : ocmbTargets)
+ {
+ try
+ {
+ this->collectDumpFromSBE(ocmbTarget, path, id, type,
+ cstate, failingUnit);
+ }
+ catch (const std::exception& e)
+ {
+ lg2::error(
+ "Failed to collect dump from OCMB -({OCMBINDEX}) {ERROR}",
+ "OCMBINDEX", pdbg_target_index(ocmbTarget), "ERROR",
+ e);
+ }
+ }
}
});
@@ -149,8 +188,10 @@
const openpower::phal::sbeError_t& sbeError, uint64_t chipPos,
SBETypes sbeType, uint32_t cmdClass, uint32_t cmdType)
{
+ std::string chipName;
try
{
+ chipName = sbeTypeAttributes.at(sbeType).chipName;
std::string event = sbeTypeAttributes.at(sbeType).chipOpFailure;
auto dumpIsRequired = false;
@@ -181,9 +222,9 @@
}
catch (const std::exception& e)
{
- lg2::error("SBE Dump request failed, chip position({CHIPPOS}), "
- "Error: {ERROR}",
- "CHIPPOS", chipPos, "ERROR", e);
+ lg2::error("SBE Dump request failed, chip type({CHIPTYPE}) "
+ "position({CHIPPOS}), Error: {ERROR}",
+ "CHIPTYPE", chipName, "CHIPPOS", chipPos, "ERROR", e);
}
}
@@ -197,10 +238,10 @@
SBETypes sbeType = getSBEType(chip);
auto chipName = sbeTypeAttributes.at(sbeType).chipName;
lg2::info(
- "Collecting dump from proc({PROC}): path({PATH}) id({ID}) "
- "type({TYPE}) clockState({CLOCKSTATE}) failingUnit({FAILINGUNIT})",
- "PROC", chipPos, "PATH", path.string(), "ID", id, "TYPE", type,
- "CLOCKSTATE", clockState, "FAILINGUNIT", failingUnit);
+ "Collecting dump from ({CHIPTYPE}) ({POSITION}): path({PATH}) id({ID}) "
+ "type({TYPE}) clockState({CLOCKSTATE}) failingUnit({FAILINGUNIT})",
+ "CHIPTYPE", chipName, "POSITION", chipPos, "PATH", path.string(), "ID",
+ id, "TYPE", type, "CLOCKSTATE", clockState, "FAILINGUNIT", failingUnit);
util::DumpDataPtr dataPtr;
uint32_t len = 0;