Add support for phosphor logging error logs
Provide a compile option to report error logs through phosphor logging.
Change-Id: Id6fc5040c13beac649f96b73443cb5ec3fcff84f
Signed-off-by: Eddie James <eajames@linux.ibm.com>
diff --git a/ecc_manager.cpp b/ecc_manager.cpp
index 6a4f9a8..0f09442 100644
--- a/ecc_manager.cpp
+++ b/ecc_manager.cpp
@@ -4,11 +4,17 @@
#include <phosphor-logging/elog-errors.hpp>
+#include <chrono>
+#include <ctime>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
+#ifdef ECC_PHOSPHOR_LOGGING
+#include <xyz/openbmc_project/Memory/MemoryECC/error.hpp>
+#endif
+
using namespace phosphor::logging;
namespace phosphor
@@ -21,7 +27,10 @@
auto retries = 3;
static constexpr auto delay = std::chrono::milliseconds{100};
-static constexpr auto interval = 1000000;
+static constexpr auto interval = std::chrono::seconds{1};
+#ifdef ECC_PHOSPHOR_LOGGING
+static constexpr auto ceInterval = std::chrono::hours{1};
+#endif
static constexpr uint16_t selBMCGenID = 0x0020;
void ECC::init()
{
@@ -103,7 +112,7 @@
std::function<void()> callback(std::bind(&ECC::read, this));
try
{
- _timer.restart(std::chrono::microseconds(interval));
+ _timer.restart(interval);
_bus.attach_event(_event.get(), SD_EVENT_PRIORITY_IMPORTANT);
_event.loop();
@@ -120,28 +129,43 @@
{
std::string errorMsg = "ECC error(memory error logging limit reached)";
std::vector<uint8_t> eccLogFullEventData{0x05, 0xff, 0xfe};
- bool assert = true;
-
auto total = ceCount + ueCount;
- bool isReached = false;
+
if (total == 0)
{
- // someone reset edac report from driver
- // so clear all parameter
+ // someone reset edac report from driver, so clear all parameter
EccInterface::ceCount(ceCount);
EccInterface::ueCount(ueCount);
previousCeCounter = 0;
previousUeCounter = 0;
- EccInterface::isLoggingLimitReached(isReached);
+ EccInterface::isLoggingLimitReached(false);
+#ifdef ECC_PHOSPHOR_LOGGING
+ startCeCount = 0;
+ maxCeLimitReached = false;
+#endif
+ return;
}
- else if (total >= maxECCLog)
+
+ if (total >= maxECCLog)
{
+#ifdef ECC_PHOSPHOR_LOGGING
+ if (((previousCeCounter - startCeCount) >= maxECCLog) &&
+ !maxCeLimitReached)
+ {
+ using error = sdbusplus::xyz::openbmc_project::Memory::MemoryECC::
+ Error::isLoggingLimitReached;
+ report<error>();
+
+ maxCeLimitReached = true;
+ maxCeLimitReachedTime = std::chrono::system_clock::now();
+ }
+#else
// add SEL log
- addSELLog(errorMsg, OBJPATH, eccLogFullEventData, assert, selBMCGenID);
- isReached = true;
- EccInterface::isLoggingLimitReached(isReached);
- controlEDACReport(CLOSE_EDAC_REPORT);
+ addSELLog(errorMsg, OBJPATH, eccLogFullEventData, true, selBMCGenID);
+#endif
// set ECC state
+ EccInterface::isLoggingLimitReached(true);
+ controlEDACReport(CLOSE_EDAC_REPORT);
EccInterface::state(MemoryECC::ECCStatus::LogFull);
}
}
@@ -155,15 +179,36 @@
fullPath.append(item);
value = std::stoi(getValue(fullPath));
std::vector<uint8_t> eccCeEventData{0x00, 0xff, 0xfe};
- bool assert = true;
- while (previousCeCounter < value)
+#ifdef ECC_PHOSPHOR_LOGGING
+ auto currentTime = std::chrono::system_clock::now();
+
+ // Start logging CE after user defined elaspsed time
+ if (maxCeLimitReached &&
+ (currentTime - maxCeLimitReachedTime >= ceInterval))
{
- previousCeCounter++;
- // add phosphor-logging log
- EccInterface::ceCount(previousCeCounter);
+ if (value)
+ startCeCount = previousCeCounter = value;
+ else
+ startCeCount = previousCeCounter = 0;
+ maxCeLimitReached = false;
+ }
+#endif
+ for (int64_t i = previousCeCounter + 1; i <= value; i++)
+ {
+ previousCeCounter = i;
+ EccInterface::ceCount(i);
+#ifdef ECC_PHOSPHOR_LOGGING
+ if ((i - startCeCount) < maxECCLog)
+ {
+ using warning = sdbusplus::xyz::openbmc_project::Memory::MemoryECC::
+ Error::ceCount;
+ report<warning>();
+ }
+#else
// add SEL log
- addSELLog(errorMsg, OBJPATH, eccCeEventData, assert, selBMCGenID);
+ addSELLog(errorMsg, OBJPATH, eccCeEventData, true, selBMCGenID);
+#endif
// set ECC state
EccInterface::state(MemoryECC::ECCStatus::CE);
}
@@ -179,15 +224,23 @@
fullPath.append(item);
value = std::stoi(getValue(fullPath));
std::vector<uint8_t> eccUeEventData{0x01, 0xff, 0xfe};
- bool assert = true;
while (previousUeCounter < value)
{
previousUeCounter++;
// add phosphor-logging log
EccInterface::ueCount(previousUeCounter);
+#ifdef ECC_PHOSPHOR_LOGGING
+ if (previousUeCounter == 1)
+ {
+ using error = sdbusplus::xyz::openbmc_project::Memory::MemoryECC::
+ Error::ueCount;
+ report<error>();
+ }
+#else
// add SEL log
- addSELLog(errorMsg, OBJPATH, eccUeEventData, assert, selBMCGenID);
+ addSELLog(errorMsg, OBJPATH, eccUeEventData, true, selBMCGenID);
+#endif
// set ECC state
EccInterface::state(MemoryECC::ECCStatus::UE);
}
diff --git a/ecc_manager.hpp b/ecc_manager.hpp
index d92b178..df990dd 100644
--- a/ecc_manager.hpp
+++ b/ecc_manager.hpp
@@ -7,6 +7,8 @@
#include <sdeventplus/utility/timer.hpp>
#include <xyz/openbmc_project/Memory/MemoryECC/server.hpp>
+#include <chrono>
+
namespace phosphor
{
namespace memory
@@ -49,6 +51,11 @@
int64_t previousCeCounter = 0;
int64_t previousUeCounter = 0;
int64_t maxECCLog = 0;
+#ifdef ECC_PHOSPHOR_LOGGING
+ int64_t startCeCount = 0;
+ bool maxCeLimitReached = false;
+ std::chrono::system_clock::time_point maxCeLimitReachedTime{};
+#endif
void run();
void controlEDACReport(std::string);
diff --git a/meson.build b/meson.build
index 87b0a49..420a780 100644
--- a/meson.build
+++ b/meson.build
@@ -32,6 +32,7 @@
conf_data.set('OBJPATH', '"/xyz/openbmc_project/metrics/memory/BmcECC"')
conf_data.set('sysfsRootPath', '"/sys/devices/system/edac/mc/mc0/"')
conf_data.set('sysfsEDACReportPath', '"/sys/module/edac_core/parameters/edac_report"')
+conf_data.set('ECC_PHOSPHOR_LOGGING', get_option('ecc-phosphor-logging').enabled())
configure_file(output : 'config.h',
configuration : conf_data)
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..aed2358
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,2 @@
+option('ecc-phosphor-logging', type: 'feature', value: 'disabled',
+ description: 'Create Event logs by using phosphor-logging.')