oem_ibm: Implement timer for Surveillance Pings
This commit introduces a timer for surveillance pings sent by the
remote terminus to monitor the BMC. If a ping is not received
within 120 seconds, an informational error will be logged.
Signed-off-by: Sagar Srinivas <sagar.srinivas@ibm.com>
Change-Id: Ia52ed2461b2c2f8ea0102e60ed2a22c7691b2d2a
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index 2bcf36f..3b14ea8 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -113,6 +113,14 @@
/** @brief Interface to the process setEventReceiver*/
virtual void processSetEventReceiver() = 0;
+ /** @brief Interface to monitor the surveillance pings from remote terminus
+ *
+ * @param[in] tid - TID of the remote terminus
+ * @param[in] value - true or false, to indicate if the timer is
+ * running or not
+ * */
+ virtual void setSurvTimer(uint8_t tid, bool value) = 0;
+
virtual ~Handler() = default;
protected:
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 6c77159..2a19e66 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -360,7 +360,14 @@
rc = PLDM_SUCCESS;
if (oemPlatformHandler)
{
- oemPlatformHandler->resetWatchDogTimer();
+ if (oemPlatformHandler->watchDogRunning())
+ {
+ oemPlatformHandler->resetWatchDogTimer();
+ }
+ else
+ {
+ oemPlatformHandler->setSurvTimer(tid, true);
+ }
}
}
else
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 4f3969c..8e207be 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -650,6 +650,43 @@
this->setEventReceiver();
}
+void pldm::responder::oem_ibm_platform::Handler::startStopTimer(bool value)
+{
+ if (value)
+ {
+ timer.restart(
+ std::chrono::seconds(HEARTBEAT_TIMEOUT + HEARTBEAT_TIMEOUT_DELTA));
+ }
+ else
+ {
+ timer.setEnabled(value);
+ }
+}
+
+void pldm::responder::oem_ibm_platform::Handler::setSurvTimer(uint8_t tid,
+ bool value)
+{
+ if ((hostOff || hostTransitioningToOff || (tid != HYPERVISOR_TID)) &&
+ timer.isEnabled())
+ {
+ startStopTimer(false);
+ return;
+ }
+ if (value)
+ {
+ startStopTimer(value);
+ }
+ else if (timer.isEnabled())
+ {
+ info(
+ "Failed to stop surveillance timer while remote terminus status is ‘{HOST_TRANST_OFF}’ with Terminus ID ‘{TID}’ ",
+ "HOST_TRANST_OFF", hostTransitioningToOff, "TID", tid);
+ startStopTimer(value);
+ pldm::utils::reportError(
+ "xyz.openbmc_project.PLDM.Error.setSurvTimer.RecvSurveillancePingFail");
+ }
+}
+
} // namespace oem_ibm_platform
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index 9ad016f..319d1f7 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -10,6 +10,10 @@
#include <libpldm/oem/ibm/state_set.h>
#include <libpldm/platform.h>
+#include <sdbusplus/bus/match.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/utility/timer.hpp>
+
typedef ibm_oem_pldm_state_set_firmware_update_state_values CodeUpdateState;
namespace pldm
@@ -26,6 +30,10 @@
constexpr uint32_t HOST_PDR_START_RANGE = 0x01000000;
constexpr uint32_t HOST_PDR_END_RANGE = 0x01FFFFFF;
+const pldm::pdr::TerminusID HYPERVISOR_TID = 208;
+
+static constexpr uint8_t HEARTBEAT_TIMEOUT_DELTA = 10;
+
enum SetEventReceiverCount
{
SET_EVENT_RECEIVER_SENT = 0x2,
@@ -42,7 +50,10 @@
oem_platform::Handler(dBusIntf),
codeUpdate(codeUpdate), platformHandler(nullptr), mctp_fd(mctp_fd),
mctp_eid(mctp_eid), instanceIdDb(instanceIdDb), event(event),
- handler(handler)
+ handler(handler),
+ timer(event, std::bind(std::mem_fn(&Handler::setSurvTimer), this,
+ HYPERVISOR_TID, false)),
+ hostTransitioningToOff(true)
{
codeUpdate->setVersions();
setEventReceiverCnt = 0;
@@ -66,11 +77,19 @@
hostOff = true;
setEventReceiverCnt = 0;
disableWatchDogTimer();
+ startStopTimer(false);
}
else if (propVal ==
"xyz.openbmc_project.State.Host.HostState.Running")
{
hostOff = false;
+ hostTransitioningToOff = false;
+ }
+ else if (
+ propVal ==
+ "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
+ {
+ hostTransitioningToOff = true;
}
}
});
@@ -217,6 +236,16 @@
platformHandler->setEventReceiver();
}
+ /** @brief Method to Enable/Disable timer to see if remote terminus sends
+ * the surveillance ping and logs informational error if remote terminus
+ * fails to send the surveillance pings
+ *
+ * @param[in] tid - TID of the remote terminus
+ * @param[in] value - true or false, to indicate if the timer is
+ * running or not
+ */
+ void setSurvTimer(uint8_t tid, bool value);
+
~Handler() = default;
pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
@@ -243,6 +272,13 @@
sdeventplus::Event& event;
private:
+ /** @brief Method to reset or stop the surveillance timer
+ *
+ * @param[in] value - true or false, to indicate if the timer
+ * should be reset or turned off
+ */
+ void startStopTimer(bool value);
+
/** @brief D-Bus property changed signal match for CurrentPowerState*/
std::unique_ptr<sdbusplus::bus::match_t> chassisOffMatch;
@@ -252,8 +288,13 @@
/** @brief D-Bus property changed signal match */
std::unique_ptr<sdbusplus::bus::match_t> hostOffMatch;
+ /** @brief Timer used for monitoring surveillance pings from host */
+ sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
+
bool hostOff = true;
+ bool hostTransitioningToOff;
+
int setEventReceiverCnt = 0;
};