platform-mc: Refactor all threshold alarms into helpers
This moves a lot of the common logic around getting/setting
thresholds and their corresponding alarms into small
helper functions. This allows us to refactor out a lot
of the repeated code.
Tested:
Tested on a yosemite4 system where the CPU sensor
is behind a uC with PLDM as the interface to the BMC.
Lower the fan speed and ensure we still get the existing
alarm.
```
root@sled325945102-oob:~# busctl introspect -l xyz.openbmc_project.Logging /xyz/openbmc_project/logging/entry/20 xyz.openbmc_project.Logging.Entry | grep "AdditionalData\|Message\|Resolved"
.AdditionalData property a{ss} <snip>
.Message property s "xyz.openbmc_project.Sensor.Threshold.Error.TemperatureCriticalHigh" emits-change writable
.Resolved property b false
```
Increase the fan speed to allow the CPU to cool down.
```
root@sled325945102-oob:~# busctl introspect -l xyz.openbmc_project.Logging /xyz/openbmc_project/logging/entry/23 xyz.openbmc_project.Logging.Entry | grep "AdditionalData\|Message\|Resolved"
.AdditionalData property a{ss} 5 <snip>
.Message property s "xyz.openbmc_project.Sensor.Threshold.Error.TemperatureCriticalHighClear" emits-change writable
.Resolved property b false
```
Change-Id: Id705828092d2bb6d1b14a56901b9deb96db22c2c
Signed-off-by: Amithash Prasad <amithash@meta.com>
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index e501ed6..7536fe4 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -14,6 +14,11 @@
{
namespace platform_mc
{
+static const std::array<pldm::utils::Level, 3> allThresholdLevels = {
+ pldm::utils::Level::WARNING, pldm::utils::Level::CRITICAL,
+ pldm::utils::Level::HARDSHUTDOWN};
+static const std::array<pldm::utils::Direction, 2> allThresholdDirections = {
+ pldm::utils::Direction::HIGH, pldm::utils::Direction::LOW};
inline bool NumericSensor::createInventoryPath(
const std::string& associationPath, const std::string& sensorName,
@@ -780,6 +785,125 @@
}
return alarm;
}
+void NumericSensor::setWarningThresholdAlarm(pldm::utils::Direction direction,
+ double value, bool newAlarm)
+{
+ if (direction == pldm::utils::Direction::HIGH)
+ {
+ thresholdWarningIntf->warningAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdWarningIntf->warningHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningHighAlarmDeasserted(value);
+ }
+ }
+ else
+ {
+ thresholdWarningIntf->warningAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdWarningIntf->warningLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningLowAlarmDeasserted(value);
+ }
+ }
+}
+
+void NumericSensor::setCriticalThresholdAlarm(pldm::utils::Direction direction,
+ double value, bool newAlarm)
+{
+ if (direction == pldm::utils::Direction::HIGH)
+ {
+ thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdCriticalIntf->criticalHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
+ }
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdCriticalIntf->criticalLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
+ }
+ }
+}
+
+void NumericSensor::setHardShutdownThresholdAlarm(
+ pldm::utils::Direction direction, double value, bool newAlarm)
+{
+ if (direction == pldm::utils::Direction::HIGH)
+ {
+ thresholdHardShutdownIntf->hardShutdownAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdHardShutdownIntf->hardShutdownHighAlarmDeasserted(value);
+ }
+ }
+ else
+ {
+ thresholdHardShutdownIntf->hardShutdownAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdHardShutdownIntf->hardShutdownLowAlarmDeasserted(value);
+ }
+ }
+}
+
+int NumericSensor::setThresholdAlarm(pldm::utils::Level level,
+ pldm::utils::Direction direction,
+ double value, bool newAlarm)
+{
+ if (!isThresholdValid(level, direction))
+ {
+ lg2::error(
+ "Error:Trigger sensor warning event for non warning threshold sensors {NAME}",
+ "NAME", sensorName);
+ return PLDM_ERROR;
+ }
+ auto alarm = getThresholdAlarm(level, direction);
+ if (alarm == newAlarm)
+ {
+ return PLDM_SUCCESS;
+ }
+ switch (level)
+ {
+ case pldm::utils::Level::WARNING:
+ setWarningThresholdAlarm(direction, value, newAlarm);
+ break;
+ case pldm::utils::Level::CRITICAL:
+ setCriticalThresholdAlarm(direction, value, newAlarm);
+ break;
+ case pldm::utils::Level::HARDSHUTDOWN:
+ setHardShutdownThresholdAlarm(direction, value, newAlarm);
+ break;
+ default:
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
+}
void NumericSensor::updateThresholds()
{
@@ -801,131 +925,21 @@
{
value = metricIntf->value();
}
- if (thresholdWarningIntf &&
- std::isfinite(thresholdWarningIntf->warningHigh()))
- {
- auto threshold = thresholdWarningIntf->warningHigh();
- auto alarm = thresholdWarningIntf->warningAlarmHigh();
- auto newAlarm =
- checkThreshold(alarm, true, value, threshold, hysteresis);
- if (alarm != newAlarm)
- {
- thresholdWarningIntf->warningAlarmHigh(newAlarm);
- if (newAlarm)
- {
- thresholdWarningIntf->warningHighAlarmAsserted(value);
- }
- else
- {
- thresholdWarningIntf->warningHighAlarmDeasserted(value);
- }
- }
- }
- if (thresholdWarningIntf &&
- std::isfinite(thresholdWarningIntf->warningLow()))
+ for (auto level : allThresholdLevels)
{
- auto threshold = thresholdWarningIntf->warningLow();
- auto alarm = thresholdWarningIntf->warningAlarmLow();
- auto newAlarm =
- checkThreshold(alarm, false, value, threshold, hysteresis);
- if (alarm != newAlarm)
+ for (auto direction : allThresholdDirections)
{
- thresholdWarningIntf->warningAlarmLow(newAlarm);
- if (newAlarm)
+ auto threshold = getThreshold(level, direction);
+ if (!std::isfinite(threshold))
{
- thresholdWarningIntf->warningLowAlarmAsserted(value);
+ continue;
}
- else
- {
- thresholdWarningIntf->warningLowAlarmDeasserted(value);
- }
- }
- }
-
- if (thresholdCriticalIntf &&
- std::isfinite(thresholdCriticalIntf->criticalHigh()))
- {
- auto threshold = thresholdCriticalIntf->criticalHigh();
- auto alarm = thresholdCriticalIntf->criticalAlarmHigh();
- auto newAlarm =
- checkThreshold(alarm, true, value, threshold, hysteresis);
- if (alarm != newAlarm)
- {
- thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
- if (newAlarm)
- {
- thresholdCriticalIntf->criticalHighAlarmAsserted(value);
- }
- else
- {
- thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
- }
- }
- }
-
- if (thresholdCriticalIntf &&
- std::isfinite(thresholdCriticalIntf->criticalLow()))
- {
- auto threshold = thresholdCriticalIntf->criticalLow();
- auto alarm = thresholdCriticalIntf->criticalAlarmLow();
- auto newAlarm =
- checkThreshold(alarm, false, value, threshold, hysteresis);
- if (alarm != newAlarm)
- {
- thresholdCriticalIntf->criticalAlarmLow(newAlarm);
- if (newAlarm)
- {
- thresholdCriticalIntf->criticalLowAlarmAsserted(value);
- }
- else
- {
- thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
- }
- }
- }
-
- if (thresholdHardShutdownIntf &&
- std::isfinite(thresholdHardShutdownIntf->hardShutdownHigh()))
- {
- auto threshold = thresholdHardShutdownIntf->hardShutdownHigh();
- auto alarm = thresholdHardShutdownIntf->hardShutdownAlarmHigh();
- auto newAlarm =
- checkThreshold(alarm, true, value, threshold, hysteresis);
- if (alarm != newAlarm)
- {
- thresholdHardShutdownIntf->hardShutdownAlarmHigh(newAlarm);
- if (newAlarm)
- {
- thresholdHardShutdownIntf->hardShutdownHighAlarmAsserted(value);
- }
- else
- {
- thresholdHardShutdownIntf->hardShutdownHighAlarmDeasserted(
- value);
- }
- }
- }
-
- if (thresholdHardShutdownIntf &&
- std::isfinite(thresholdHardShutdownIntf->hardShutdownLow()))
- {
- auto threshold = thresholdHardShutdownIntf->hardShutdownLow();
- auto alarm = thresholdHardShutdownIntf->hardShutdownAlarmLow();
- auto newAlarm =
- checkThreshold(alarm, false, value, threshold, hysteresis);
- if (alarm != newAlarm)
- {
- thresholdHardShutdownIntf->hardShutdownAlarmLow(newAlarm);
- if (newAlarm)
- {
- thresholdHardShutdownIntf->hardShutdownLowAlarmAsserted(value);
- }
- else
- {
- thresholdHardShutdownIntf->hardShutdownLowAlarmDeasserted(
- value);
- }
+ auto alarm = getThresholdAlarm(level, direction);
+ auto newAlarm =
+ checkThreshold(alarm, direction == pldm::utils::Direction::HIGH,
+ value, threshold, hysteresis);
+ setThresholdAlarm(level, direction, value, newAlarm);
}
}
}
@@ -948,108 +962,7 @@
"TID", eventType, "SID", direction, "VAL", value, "PSTATE", newAlarm,
"ESTATE", assert);
- switch (eventType)
- {
- case pldm::utils::Level::WARNING:
- {
- if (!thresholdWarningIntf)
- {
- lg2::error(
- "Error:Trigger sensor warning event for non warning threshold sensors {NAME}",
- "NAME", sensorName);
- return PLDM_ERROR;
- }
- if (direction == pldm::utils::Direction::HIGH &&
- std::isfinite(thresholdWarningIntf->warningHigh()))
- {
- auto alarm = thresholdWarningIntf->warningAlarmHigh();
- if (alarm == newAlarm)
- {
- return PLDM_SUCCESS;
- }
- thresholdWarningIntf->warningAlarmHigh(newAlarm);
- if (assert)
- {
- thresholdWarningIntf->warningHighAlarmAsserted(value);
- }
- else
- {
- thresholdWarningIntf->warningHighAlarmDeasserted(value);
- }
- }
- else if (direction == pldm::utils::Direction::LOW &&
- std::isfinite(thresholdWarningIntf->warningLow()))
- {
- auto alarm = thresholdWarningIntf->warningAlarmLow();
- if (alarm == newAlarm)
- {
- return PLDM_SUCCESS;
- }
- thresholdWarningIntf->warningAlarmLow(newAlarm);
- if (assert)
- {
- thresholdWarningIntf->warningLowAlarmAsserted(value);
- }
- else
- {
- thresholdWarningIntf->warningLowAlarmDeasserted(value);
- }
- }
- break;
- }
- case pldm::utils::Level::CRITICAL:
- {
- if (!thresholdCriticalIntf)
- {
- lg2::error(
- "Error:Trigger sensor Critical event for non warning threshold sensors {NAME}",
- "NAME", sensorName);
- return PLDM_ERROR;
- }
- if (direction == pldm::utils::Direction::HIGH &&
- std::isfinite(thresholdCriticalIntf->criticalHigh()))
- {
- auto alarm = thresholdCriticalIntf->criticalAlarmHigh();
- if (alarm == newAlarm)
- {
- return PLDM_SUCCESS;
- }
- thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
- if (assert)
- {
- thresholdCriticalIntf->criticalHighAlarmAsserted(value);
- }
- else
- {
- thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
- }
- }
- else if (direction == pldm::utils::Direction::LOW &&
- std::isfinite(thresholdCriticalIntf->criticalLow()))
- {
- auto alarm = thresholdCriticalIntf->criticalAlarmLow();
- if (alarm == newAlarm)
- {
- return PLDM_SUCCESS;
- }
- thresholdCriticalIntf->criticalAlarmLow(newAlarm);
- if (assert)
- {
- thresholdCriticalIntf->criticalLowAlarmAsserted(value);
- }
- else
- {
- thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
- }
- }
- break;
- }
-
- default:
- break;
- }
-
- return PLDM_SUCCESS;
+ return setThresholdAlarm(eventType, direction, value, newAlarm);
}
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp
index 37f4695..b09bcd4 100644
--- a/platform-mc/numeric_sensor.hpp
+++ b/platform-mc/numeric_sensor.hpp
@@ -200,7 +200,7 @@
*
* @return double - Lower HardShutdown threshold
*/
- double getThresholdLowerHardShutdownl()
+ double getThresholdLowerHardShutdown()
{
if (thresholdHardShutdownIntf)
{
@@ -212,6 +212,138 @@
}
};
+ /** @brief Get threshold given level and direction
+ *
+ * @param[in] level - The threshold level (WARNING/CRITICAL/etc)
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ *
+ * @return double - The requested threshold.
+ */
+ double getThreshold(pldm::utils::Level level,
+ pldm::utils::Direction direction)
+ {
+ if (direction != pldm::utils::Direction::HIGH &&
+ direction != pldm::utils::Direction::LOW)
+ {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ switch (level)
+ {
+ case pldm::utils::Level::WARNING:
+ return direction == pldm::utils::Direction::HIGH
+ ? getThresholdUpperWarning()
+ : getThresholdLowerWarning();
+ case pldm::utils::Level::CRITICAL:
+ return direction == pldm::utils::Direction::HIGH
+ ? getThresholdUpperCritical()
+ : getThresholdLowerCritical();
+ case pldm::utils::Level::HARDSHUTDOWN:
+ return direction == pldm::utils::Direction::HIGH
+ ? getThresholdUpperHardShutdown()
+ : getThresholdLowerHardShutdown();
+ default:
+ break;
+ }
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+
+ /* @brief returns true if the given threshold at level/direction is defined.
+ *
+ * @param[in] level - The threshold level (WARNING/CRITICAL/etc)
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ *
+ * @return true if the threshold is valid
+ */
+ bool isThresholdValid(pldm::utils::Level level,
+ pldm::utils::Direction direction)
+ {
+ return std::isfinite(getThreshold(level, direction));
+ }
+
+ /* @brief Get the alarm status of the given threshold
+ *
+ * @param[in] level - The threshold level (WARNING/CRITICAL/etc)
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ *
+ * @return true if the current alarm status is asserted.
+ */
+ bool getThresholdAlarm(pldm::utils::Level level,
+ pldm::utils::Direction direction)
+ {
+ if (!isThresholdValid(level, direction))
+ {
+ return false;
+ }
+ switch (level)
+ {
+ case pldm::utils::Level::WARNING:
+ return direction == pldm::utils::Direction::HIGH
+ ? thresholdWarningIntf->warningAlarmHigh()
+ : thresholdWarningIntf->warningAlarmLow();
+ case pldm::utils::Level::CRITICAL:
+ return direction == pldm::utils::Direction::HIGH
+ ? thresholdCriticalIntf->criticalAlarmHigh()
+ : thresholdCriticalIntf->criticalAlarmLow();
+ case pldm::utils::Level::HARDSHUTDOWN:
+ return direction == pldm::utils::Direction::HIGH
+ ? thresholdHardShutdownIntf->hardShutdownAlarmHigh()
+ : thresholdHardShutdownIntf->hardShutdownAlarmLow();
+ default:
+ break;
+ }
+ return false;
+ }
+
+ /* @brief raises the alarm on the warning threshold
+ *
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ * @param[in] value - The current numeric sensor reading
+ * @param[in] asserted - true if we want to set the alarm, false
+ * if we want to clear it.
+ *
+ * @return PLDM_SUCCESS or a valid error code.
+ */
+ void setWarningThresholdAlarm(pldm::utils::Direction direction,
+ double value, bool asserted);
+
+ /* @brief raises the alarm on the critical threshold
+ *
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ * @param[in] value - The current numeric sensor reading
+ * @param[in] asserted - true if we want to set the alarm, false
+ * if we want to clear it.
+ *
+ * @return PLDM_SUCCESS or a valid error code.
+ */
+ void setCriticalThresholdAlarm(pldm::utils::Direction direction,
+ double value, bool asserted);
+
+ /* @brief raises the alarm on the hard-shutdown threshold
+ *
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ * @param[in] value - The current numeric sensor reading
+ * @param[in] asserted - true if we want to set the alarm, false
+ * if we want to clear it.
+ *
+ * @return PLDM_SUCCESS or a valid error code.
+ */
+ void setHardShutdownThresholdAlarm(pldm::utils::Direction direction,
+ double value, bool asserted);
+
+ /* @brief raises the alarm on the threshold
+ *
+ * @param[in] level - The threshold level (WARNING/CRITICAL/etc)
+ * @param[in] direction - The threshold direction (HIGH/LOW)
+ * @param[in] value - The current numeric sensor reading
+ * @param[in] asserted - true if we want to set the alarm, false
+ * if we want to clear it.
+ *
+ * @return PLDM_SUCCESS or a valid error code.
+ */
+ int setThresholdAlarm(pldm::utils::Level level,
+ pldm::utils::Direction direction, double value,
+ bool asserted);
+
/** @brief Check if value is over threshold.
*
* @param[in] eventType - event level in pldm::utils::Level