summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-12-11 14:44:50 -0600
committerMatt Spinler <spinler@us.ibm.com>2020-01-27 08:06:26 -0600
commita943b15b54861a0cb136a062eb822d0ba1362788 (patch)
tree7a3ac58ac836855b29b2851db12ae30c844127f4
parentf60ac27e3ee4aa7166065db93a3fc0ae2d9481ac (diff)
downloadphosphor-logging-a943b15b54861a0cb136a062eb822d0ba1362788.tar.gz
phosphor-logging-a943b15b54861a0cb136a062eb822d0ba1362788.zip
PEL: Logic to enqueue a PEL to send to host
Fill in the function to determine if a PEL needs to be placed on the qeueue to be sent up to the host. It involves checking both the host and HMC transmission states, as well as the PEL action flags field. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I9f1a9fba1b7e6dc7a167f1c7e9dfd6c40d90883f
-rw-r--r--extensions/openpower-pels/host_notifier.cpp28
-rw-r--r--extensions/openpower-pels/host_notifier.hpp5
-rw-r--r--test/openpower-pels/host_notifier_test.cpp124
-rw-r--r--test/openpower-pels/pel_utils.hpp4
4 files changed, 155 insertions, 6 deletions
diff --git a/extensions/openpower-pels/host_notifier.cpp b/extensions/openpower-pels/host_notifier.cpp
index ec5db41..2956b66 100644
--- a/extensions/openpower-pels/host_notifier.cpp
+++ b/extensions/openpower-pels/host_notifier.cpp
@@ -76,6 +76,34 @@ bool HostNotifier::addPELToQueue(const PEL& pel)
bool HostNotifier::enqueueRequired(uint32_t id) const
{
bool required = true;
+ Repository::LogID i{Repository::LogID::Pel{id}};
+
+ if (auto attributes = _repo.getPELAttributes(i); attributes)
+ {
+ auto a = attributes.value().get();
+
+ if ((a.hostState == TransmissionState::acked) ||
+ (a.hostState == TransmissionState::badPEL))
+ {
+ required = false;
+ }
+ else if (a.actionFlags.test(hiddenFlagBit) &&
+ (a.hmcState == TransmissionState::acked))
+ {
+ required = false;
+ }
+ else if (a.actionFlags.test(dontReportToHostFlagBit))
+ {
+ required = false;
+ }
+ }
+ else
+ {
+ using namespace phosphor::logging;
+ log<level::ERR>("Host Enqueue: Unable to find PEL ID in repository",
+ entry("PEL_ID=0x%X", id));
+ required = false;
+ }
return required;
}
diff --git a/extensions/openpower-pels/host_notifier.hpp b/extensions/openpower-pels/host_notifier.hpp
index ee1ba0c..19ed64d 100644
--- a/extensions/openpower-pels/host_notifier.hpp
+++ b/extensions/openpower-pels/host_notifier.hpp
@@ -54,6 +54,11 @@ class HostNotifier
* @brief Specifies if the PEL needs to go onto the queue to be
* set to the host.
*
+ * Only returns false if:
+ * - Already acked by the host (or they didn't like it)
+ * - Hidden and the HMC already got it
+ * - The 'do not report to host' bit is set
+ *
* @param[in] id - The PEL ID
*
* @return bool - If enqueue is required
diff --git a/test/openpower-pels/host_notifier_test.cpp b/test/openpower-pels/host_notifier_test.cpp
index 2d50dcf..2f2e1f0 100644
--- a/test/openpower-pels/host_notifier_test.cpp
+++ b/test/openpower-pels/host_notifier_test.cpp
@@ -38,6 +38,20 @@ const size_t actionFlags1Offset = 67;
class HostNotifierTest : public CleanPELFiles
{
+ public:
+ HostNotifierTest()
+ {
+ auto r = sd_event_default(&event);
+ EXPECT_TRUE(r >= 0);
+ }
+
+ ~HostNotifierTest()
+ {
+ sd_event_unref(event);
+ }
+
+ protected:
+ sd_event* event;
};
/**
@@ -100,6 +114,112 @@ TEST_F(HostNotifierTest, TestHostStateChange)
EXPECT_FALSE(called);
}
+// Test dealing with how acked PELs are put on the
+// notification queue.
+TEST_F(HostNotifierTest, TestPolicyAckedPEL)
+{
+ Repository repo{repoPath};
+ MockDataInterface dataIface;
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ auto pel = makePEL();
+ repo.add(pel);
+
+ // This is required
+ EXPECT_TRUE(notifier.enqueueRequired(pel->id()));
+
+ // Not in the repo
+ EXPECT_FALSE(notifier.enqueueRequired(42));
+
+ // Now set this PEL to host acked
+ repo.setPELHostTransState(pel->id(), TransmissionState::acked);
+
+ // Since it's acked, doesn't need to be enqueued or transmitted
+ EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
+}
+
+// Test the 'don't report' PEL flag
+TEST_F(HostNotifierTest, TestPolicyDontReport)
+{
+ Repository repo{repoPath};
+ MockDataInterface dataIface;
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ // dontReportToHostFlagBit
+ auto pel = makePEL(0x1000);
+
+ // Double check the action flag is still set
+ std::bitset<16> actionFlags = pel->userHeader().actionFlags();
+ EXPECT_TRUE(actionFlags.test(dontReportToHostFlagBit));
+
+ repo.add(pel);
+
+ // Don't need to send this to the host
+ EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
+}
+
+// Test that hidden PELs need notification when there
+// is no HMC.
+TEST_F(HostNotifierTest, TestPolicyHiddenNoHMC)
+{
+ Repository repo{repoPath};
+ MockDataInterface dataIface;
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ // hiddenFlagBit
+ auto pel = makePEL(0x4000);
+
+ // Double check the action flag is still set
+ std::bitset<16> actionFlags = pel->userHeader().actionFlags();
+ EXPECT_TRUE(actionFlags.test(hiddenFlagBit));
+
+ repo.add(pel);
+
+ // Still need to enqueue this
+ EXPECT_TRUE(notifier.enqueueRequired(pel->id()));
+}
+
+// Don't need to enqueue a hidden log already acked by the HMC
+TEST_F(HostNotifierTest, TestPolicyHiddenWithHMCAcked)
+{
+ Repository repo{repoPath};
+ MockDataInterface dataIface;
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ // hiddenFlagBit
+ auto pel = makePEL(0x4000);
+
+ // Double check the action flag is still set
+ std::bitset<16> actionFlags = pel->userHeader().actionFlags();
+ EXPECT_TRUE(actionFlags.test(hiddenFlagBit));
+
+ repo.add(pel);
+
+ // No HMC yet, so required
+ EXPECT_TRUE(notifier.enqueueRequired(pel->id()));
+
+ repo.setPELHMCTransState(pel->id(), TransmissionState::acked);
+
+ // Not required anymore
+ EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
+}
+
// Test that PELs are enqueued on startup
TEST_F(HostNotifierTest, TestStartup)
{
@@ -113,10 +233,6 @@ TEST_F(HostNotifierTest, TestStartup)
repo.add(pel);
}
- sd_event* event = nullptr;
- auto r = sd_event_default(&event);
- ASSERT_TRUE(r >= 0);
-
std::unique_ptr<HostInterface> hostIface =
std::make_unique<MockHostInterface>(event, dataIface);
diff --git a/test/openpower-pels/pel_utils.hpp b/test/openpower-pels/pel_utils.hpp
index 78c6401..fae62cd 100644
--- a/test/openpower-pels/pel_utils.hpp
+++ b/test/openpower-pels/pel_utils.hpp
@@ -29,14 +29,14 @@ class CleanLogID : public ::testing::Test
class CleanPELFiles : public ::testing::Test
{
protected:
- static void SetUpTestCase()
+ void SetUp() override
{
pelIDFile = openpower::pels::getPELIDFile();
repoPath = openpower::pels::getPELRepoPath();
registryPath = openpower::pels::getMessageRegistryPath();
}
- static void TearDownTestCase()
+ void TearDown() override
{
std::filesystem::remove_all(
std::filesystem::path{pelIDFile}.parent_path());
OpenPOWER on IntegriCloud